cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI slave mode doesn't transmit properly

NNida.1
Associate

I am using an STM32G030C8T6 as an SPI (Slave device) which receives characters from a Raspberry pi (Master device), receiving works perfectly! no problems there, however when i try to send data from STM32 to Pi, it seems that the STM32 gets stuck for a while and Pi rx buffer is filled with only one bit in repeat e.g., if i send char buf[6] = {0,1,2,3,4,5}; Pi receives (111111) or (333333) depending on how many characters i am sending.

What do i actually want to do?

I want to transmit ADC data from STM32(slave mode) to Pi(master mode), so far it only receives one bit i repeat.

Can someone please help me achieve this?

Here's my SPI config:

void MX_SPI1_Init(void)
{
 
  /* USER CODE BEGIN SPI1_Init 0 */
 
  /* USER CODE END SPI1_Init 0 */
 
  /* USER CODE BEGIN SPI1_Init 1 */
 
  /* USER CODE END SPI1_Init 1 */
  /* 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 = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
 
  /* USER CODE END SPI1_Init 2 */
 
}

then the functions to read characters, send data and string

char SPI_read(void)
{
    // SPI1->SR is the STATUS REGISTER on SPI1 Bus
    // SPI1->DR is the DATA REGISTER on SPI1 Bus
 
    char data;
    while(!(SPI1->SR & SPI_SR_RXNE));
 
 
    while(SPI1->SR & SPI_SR_BSY);
 
    data = SPI1->DR;
 
    printmsg("%c",data);
 
    return data;
}
 
 
void spi_Send(char caracSend)
{
    while(!(SPI1->SR & SPI_SR_TXE));
 
    SPI1->DR = caracSend;
}
 
 
void spi_send_string(char* stringSend)
{
    int i=0;
    unsigned int sizeChar = 0;
 
    sizeChar = strlen(stringSend);
 
    __NOP();
 
    for(i=0;i<sizeChar;i++)
    {
        spi_Send(stringSend[i]);
    }
}

Here's my function to receive data from Pi which i call in the main while loop.

void SPI_Receive_Commands(void)
{
 
    while(HAL_GPIO_ReadPin(SPI_SS_GPIO_Port, SPI_SS_Pin) == GPIO_PIN_RESET);
  {
        HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buf, 10, 100);
 
    if(spi_buf[0] == 'v')
    {
      memset(spi_buf,'*',10);
 
      printmsg("Character V received\r\n");
 
      Battery_Voltage();
      spi_send_string(batteryVoltage);
      spi_Send('v');
 
      printmsg("Sending battery voltage\r\n");
    }
}
}

Thank you so much for helping me out in advance.

2 REPLIES 2
TDK
Guru

You're using a mix of HAL functions and register access. Why not use HAL_SPI_Transmit to send the string? Also need to ensure the PI is waiting long enough for the STM32 to process the 6 bytes and get ready to send a response.

If you feel a post has answered your question, please click "Accept as Solution".
S.Ma
Principal

Ah if there was an example provided as SPI RAM emulation using interrupt and DMA and EXTI to catch NSS edges, it would work pretty well and in the background, patches included, if the SPI has the fifos.