3
votes

I'm using STM32F205's SPI1 in master mode. And the RXNE flag is never set during transactions. Here's a part of SPI initialization:

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_SPE;
SPI1->CR2 = 0;

Then I'm trying to perform transmition/receiving of a single byte:

while(!(SPI1->SR & SPI_FLAG_TXE)) {}  // wait for compeltion of the previous Tx
SPI1->DR = 0xAB;                      // transmit some byte

while(!(SPI1->SR & SPI_FLAG_RXNE)) {}  // wait for byte to be received
uint8_t result = SPI1->DR;

This code stucks at the waiting for RXNE flag. I tried to wait for busy flag BSY = 0 instead of RXNE = 1 and SPI began to work. It seems RXNE is never set.

3
Spupid question first - did you enable SPI1 clocking in apropriate RCC register? Another one - what is SPI_FLAG_TXE and why don't you use SPI_SR_TXE from the standard header?Freddie Chopin
1. Yes, I have enabled clocks. SPI transmits data and is able to receive data if I check flag BSY=0. But I've never seen RXNE flag is set. 2. It's the same. I took it from STM's headers #define SPI_FLAG_TXE SPI_SR_TXEMax

3 Answers

10
votes

I quess Your's SPI communication is 8-bit? (uint8_t result = SPI1->DR). On STM32F051 I have the same problem RXNE flag was not set after recieving 1 byte. The problem is that STM triggers this flag after 16-bit by default. In STM32F0 I found solution (it propably will be the same in F2):

The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register:  If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit). If FRXTH is cleared (default), RXNE goes high and stays high until the RXFIFO level is greater than or equal to 1/2 (16-bit).

So set this bit you can do it using API instruction: SPI_RxFIFOThresholdConfig(SPIx, SPI_RxFIFOThreshold_QF);

Hope it helps, Best wishes from Poland

2
votes

suggestion only:

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_SPE;
SPI1->CR2 = 0;

you are enablling SPI before writing to CR2 register. reverse the above OR enable SPI only after writing to CR2.

1
votes

I had the same problem with STM32L072CZ. My solution was to enable the SPI_CR2_SSOE bit. Still I am not using the SPI1 slave select pin for selecting slave, I am using a software GPIO pin for that.

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR | SPI_CR1_SSM;
SPI1->CR2 = SPI_CR2_SSOE |SPI_CR2_RXNEIE;
SPI1->CR1 |= SPI_CR1_SPE;