title: STM32 Master/Slave SPI communication using HAL_SPI_TransmitReceive()
body: <p>I'm trying to test out a SPI master using HAL_SPI_TransmitReceive() as I will be communicating with an SPI slave. The SPI slave device is not yet available. I have two STM32F4 NUCLEOs that I am using. One that will be the master and one pretending to be the slave device. I've wired them together and am using the following code:</p>
  <p>Master_main.c</p>
  <pre><code>SPI_HandleTypeDef hspi2;
  
  static void MX_SPI2_Init(void);
  
  uint8_t spi_tx_data[9];
  uint8_t spi_rx_data[9];
  
  int main(void)
  {
    MX_SPI2_Init();
  
    spi_tx_data[0] = 0;
    spi_tx_data[1] = 0;
    spi_tx_data[2] = 0;
    spi_tx_data[3] = 0;
    spi_tx_data[4] = 0;
    spi_tx_data[5] = 0;
    spi_tx_data[6] = 0;
    spi_tx_data[7] = 0;
    spi_tx_data[8] = 1;
  
    while (1)
    {
        static HAL_StatusTypeDef spi_error = HAL_OK;
  
        static uint32_t PreviousTicks_GreenLight = 0U;
        uint32_t CurrentTicks_GreenLight = HAL_GetTick();
        if((CurrentTicks_GreenLight - PreviousTicks_GreenLight) &gt;= 500u)
        {
            HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
            PreviousTicks_GreenLight = CurrentTicks_GreenLight;
        }
  
        static uint8_t runonce = 0;
        if (HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin) != 0) {
            if (runonce != 1){
  
                HAL_GPIO_WritePin(GPIO_ADR1_GPIO_Port, GPIO_ADR1_Pin, 0);
                HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
                spi_error = HAL_SPI_TransmitReceive(&amp;hspi2,spi_tx_data, spi_rx_data,18,0x01);
                HAL_Delay(1);
                HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
                HAL_GPIO_WritePin(GPIO_ADR1_GPIO_Port, GPIO_ADR1_Pin, 1);
  
                runonce = 1;
            }
        } else {
            runonce = 0;
        }
  
        static uint32_t PreviousTicks_RedLight = 0U;
        uint32_t CurrentTicks_RedLight = HAL_GetTick();
        if((CurrentTicks_RedLight - PreviousTicks_RedLight) &gt;= 500u)
        {
            if ( spi_error == HAL_TIMEOUT || spi_error == HAL_ERROR){
                HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
            } else {
                if ( spi_rx_data[8] == 2){
                    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
                }
            }
            PreviousTicks_RedLight = CurrentTicks_RedLight;
        }
    }
  }
  
  static void MX_SPI2_Init(void)
  {
    hspi2.Instance = SPI2;
    hspi2.Init.Mode = SPI_MODE_MASTER;
    hspi2.Init.Direction = SPI_DIRECTION_2LINES;
    hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi2.Init.NSS = SPI_NSS_SOFT;
    hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
    hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi2.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(&amp;hspi2) != HAL_OK)
    {
      Error_Handler();
    }
  }
  </code></pre>
  <p>Slave_main.c</p>
  <pre><code>uint8_t spi_tx_data[9];
  uint8_t spi_rx_data[9];
  
  uint8_t rx_cmplt = 0;
  
  void HAL_SPI_RxCpltCallback (SPI_HandleTypeDef *hspi) {
      static uint8_t rx_counter = 0;
  
      if ( rx_counter == 8 ){
          rx_cmplt = 1;
      } else {
          rx_counter++;
      }
      HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  }
  
  int main(void)
  {
    MX_SPI2_Init();
  
    spi_tx_data[0] = 0;
    spi_tx_data[1] = 0;
    spi_tx_data[2] = 0;
    spi_tx_data[3] = 0;
    spi_tx_data[4] = 0;
    spi_tx_data[5] = 0;
    spi_tx_data[6] = 0;
    spi_tx_data[7] = 0;
    spi_tx_data[8] = 2;
  
    while (1)
    {
        static HAL_StatusTypeDef spi_error = HAL_OK;
  
        static uint32_t PreviousTicks_GreenLight = 0U;
        uint32_t CurrentTicks_GreenLight = HAL_GetTick();
        if((CurrentTicks_GreenLight - PreviousTicks_GreenLight) &gt;= 1000u)
        {
            HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
            PreviousTicks_GreenLight = CurrentTicks_GreenLight;
        }
  
        static uint8_t runonce = 0;
        if (HAL_GPIO_ReadPin(GPIO_ADR1_GPIO_Port, GPIO_ADR1_Pin) != 1) {
            if (runonce != 1){
  
                HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
                //spi_error = HAL_SPI_TransmitReceive_IT(&amp;hspi2, spi_tx_data, spi_rx_data, 18);
                spi_error = HAL_SPI_TransmitReceive(&amp;hspi2,spi_tx_data, spi_rx_data,18,0x01);
                HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
  
                runonce = 1;
            }
        } else {
            runonce = 0;
        }
  
        static uint32_t PreviousTicks_RedLight = 0U;
        uint32_t CurrentTicks_RedLight = HAL_GetTick();
        if((CurrentTicks_RedLight - PreviousTicks_RedLight) &gt;= 500u)
        {
            if ( rx_cmplt == 1 ){
                if (spi_rx_data[8] == 1){
                    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 1);
                } else {
                    HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, 1);
                }
            } else {
                if ( spi_error == HAL_TIMEOUT || spi_error == HAL_ERROR){
                    HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
                    if (spi_error == HAL_TIMEOUT){
                        HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
                    }
                }
            }
  
            PreviousTicks_RedLight = CurrentTicks_RedLight;
        }
    }
  }
  
  static void MX_SPI2_Init(void)
  {
    hspi2.Instance = SPI2;
    hspi2.Init.Mode = SPI_MODE_SLAVE;
    hspi2.Init.Direction = SPI_DIRECTION_2LINES;
    hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi2.Init.NSS = SPI_NSS_SOFT;
    hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi2.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(&amp;hspi2) != HAL_OK)
    {
      Error_Handler();
    }
  }
  </code></pre>
  <p>I stripped out various MCU initialization for simplicity. I had made an attempt to use the IT version of TransmitRecieve at an earlier time, but it didn't successfully transmit. If I use the USER button on my master several times it does manage to activate the appropriate lights on the slave but not on the master.</p>