embeddedspikeilstm32f4discoverystm32f4

How to program STM32f4 as SPI Slave


i have an issue in coding of STM32F407 in SPI Slave mode, In my case , Master is ADE7880 IC and Slave is STM32F407, enter image description here.

I am a beginner , i have connected the same pins mentioned in ADE7880 Datasheet and code generated using STM32cubeMX,

    static void MX_SPI1_Init(void)
{

  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

Then in main

hal_status=HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buf, 1, 100);
// hal_status = HAL_SPI_TransmitReceive(&hspi1, tx_data, rx_data, 2, 1000);

it Return Timeout error , is my programming side ok????


Solution

  • hspi1.Init.NSS = SPI_NSS_SOFT;

    This line is configuring the slave select line to be managed by the software.

    You want

    hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
    

    You will want to trigger an interrupt for RXNE. You need to specify the callback function in your configuration like this

    hspi2.RxISR = callback_func;
    

    Enable the interrupt like so

    __HAL_SPI_ENABLE_IT(&hspi1, SPI_IT_RXNE);
    

    Lastly, the CLK polarity and phase settings

    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

    are wrong for the ADE7880. These are high and trailing respectively for that IC. You can tell this by reading the SPI timing diagram in the ADE7880 datasheet. You should change them to:

      hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
      hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;