AnsweredAssumed Answered

STM32F4 SPI buffer overrun problem

Question asked by khorvongkarn.prach on Jul 10, 2014


I'm trying to establish SPI communication between PIC18F2580 as master and STM32F4 Discovery as slave.
Using logic analyzer, I found that PIC and STM32F4 actually sending bytes (PIC's MOSI and STM32F4's MISO data are correct). However, PIC and STM32F4 are not receiving correct bytes (PIC's MISO and STM32F4's MOSI are always 0xFF).
Please note that everything works fine when STM32F4 is master and PIC is slave.
In my SPI_send() function, I send data byte, wait until transmission is completed, wait until reception is completed, and wait until SPI is not busy anymore. The code is as follows:

/* This funtion is used to transmit and receive data 
 * with SPI1
 *          data --> data to be transmitted
 *          returns received value
uint8_t SPI1_send(uint8_t data){
    SPI1->DR = data; // write data to be transmitted to the SPI data register
    while(!(SPI1->SR & SPI_I2S_FLAG_TXE)); // wait until transmit complete
    while(!(SPI1->SR & SPI_I2S_FLAG_RXNE)); // wait until receive complete
    while(SPI1->SR & SPI_I2S_FLAG_BSY); // wait until SPI is not busy anymore
    return SPI1->DR; // return received data from SPI data register

However, when I set breakpoint at "return SPI1->DR;" line, the value of SPI1->SR register is 0xC3 (0b11000011).

This means that even if I wait for transmission and reception to be finished before returning the received bytes, the following conditions still occur:
- receive buffer is not empty (yes, I wait until RXNE is cleared)
- SPI is busy (yes, I wait until BSY is cleared)
- buffer overrun occurs

How could these happen?

Also, in an attempt to clear the overrun flag, I refer to STM32F4 reference manual. The manual states that:

"Clearing the OVR bit is done by a read from the SPI_DR register followed by a read access to the SPI_SR register."

So I tried to read DR and SR registers at the beginning of function, to make sure that overrun flag is cleared. But I still get the same SR value (0xC3) which means the overrun flag is not cleared.

So Is there appropriate (and safe) way to implement SPI byte exchange function? I tried many implementation I found on the internet, but none of them work for my case.

Any help will be highly appreciated.

Best Regards,