Search code examples
cembeddedstm32spi

SPI transmission errors. RX buffer full and data mismatch


I'm transmitting my data in SPI. uint8_t data[5] = {0xa,0xb,0xc,0xd,0xe}; When I see the output in logic analyzer, the data is mis matched. I dont know what might be the root of the problem. I will share my code and configuration here. Please have a look.

void SPI_Transmit (uint8_t *data, int size)
{
  SPI1->CR1 |= (1<<6);
  int i=0;
    while (i<size)
    {
       while (!((SPI1->SR)&(1<<1))) {};  // wait for TXE bit to set -> This will indicate that the buffer is empty
       SPI1->DR = data[i];  // load the data into the Data Register
       i++;
    }   
    

//  Clear the Overrun flag by reading DR and SR

    while (!((SPI1->SR)&(1<<1))) {};  // wait for TXE bit to set -> This will indicate that the buffer is empty
    while (((SPI1->SR)&(1<<7))) {};  // wait for BSY bit to Reset -> This will indicate that SPI is not busy in communication   

  while (((SPI1->SR)&(1<<0))) 
  {
    uint8_t temp = SPI1->DR;
  }; 
      uint8_t   temp1 = SPI1->SR;
    
  SPI1->CR1 &= ~(1<<6);
}

Here I'm transmitting my data and waiting for my TX empty flag to set and Busy flag to reset. Also, after I transmittting my data, my RX buffer (RXFIFO) is full and RX not empty flag is set. So I have to read data register until RXNE is reset.

I understand SPI communicate through register shifting, for every data sent there will be some received data. But my communication is in Master transmit only mode. I'm only using MOSI not MISO. So I dont understand why there is data in my RX buffer even when I'm using only MOSI wire. I also tested transmitting data without any slave device, still I receive data in RX buffer. I dont understand where this RX data is coming from. The status registe shows RXNE=1 and FRLVL=11.

After programming my SPI transmit function according to my conditions, I transmit the data. When I see output in logic analyzer, the data is mismatch. The Baud Rate is 625.0KBits/s and sampling rate is 2MS/s.

Here is my SPI configuration

static void MX_SPI1_Init(void)
{

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  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.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  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();
  }

}

enter image description here


Solution

  • One of the most important thing to work with SPI is phasing. With two parameters CPOL and CPHA the phasing should be configured. In your problem in these two are named as CLKPolarity and CLKPhase in hspi1.Init respectively. These two parameters includes 4 states (0,0 - 0,1 - 1,0 - 1,1). It's better to try each state. For more information please check Here, section: Clock Polarity and Clock Phase.