cancel
Showing results for 
Search instead for 
Did you mean: 

RXNE Flag of STM32F302R8 is never SET

WM_IR
Senior

Hi, I have a problem where my SPI SR RXNE in STM32F302R8 is never SET, causing my program always halt in while loop, waiting the RXNE status to become SET, when receive data.

how I set the RXNE flag is below:

#define SPI_SR_RXNE 0

#define SPI_RXNE_FLAG   (1 << SPI_SR_RXNE)

Here is my main code:

MAIN CODE: In the main code, I stuck at the SPI_ReceiveData() because after I send my desired data to slave, I received a dummy byte. So, to clear the dummy byte, I need to read the RXNE first. But, my code was stuck at that line which is Read the dummy byte.

 while(1)

  {

while(GPIO_ReadFromInputPin(GPIOC,GPIO_PIN_NO_13));

delay();

//enable SPI peripheral (SPE in SPI Control register 1)

SPI_PeripheralControl(SPI2,ENABLE);

//declare variable untuk command code

uint8_t commandcode = COMMAND_LED_CTRL; //0x50

//define ackbyte

uint8_t ackbyte;

//create array

uint8_t args[2];

//Send data

SPI_SendData(SPI2,&commandcode,1);

SPI_ReceiveData(SPI2,&dummy_read,1); MY CODE STUCK RIGHT HERE

SPI_SendData(SPI2,&dummy_write,1);

//then, lets call SPI_ReceiveData untuk receive data from slave.

SPI_ReceiveData(SPI2,&ackbyte,1);

}

THEN, INSIDE SPI_ReceiveData function: When my code execute the SPI_Receive data, it will check the status flag first, if RESET, then it will stuck in the while loop until it SET. As I bold the line below. But, I stuck at here.

void SPI_ReceiveData(SPI_RegDef_t *pSPIx, uint8_t *pRxBuffer, uint32_t Len)

{

while(Len > 0)

  {

   //1. wait until RXNE is SET

   while(SPI_GetFlagStatus(pSPIx, SPI_RXNE_FLAG) == FLAG_RESET);

   //2. TXE set, check dff or CRCL

   if(pSPIx->CR1 & (1 << SPI_CR1_CRCL))

   {

   //16 bit data frame format

   //1. load the data from Data Register(DR) to Rx Buffer address

   *((uint16_t*)pRxBuffer) = pSPIx->DR ; 

   //2. kene decrease len

   Len--;

   Len--; 

   (uint16_t*)pRxBuffer++; 

   }

   else

   {

   //8 bit data frame format

   //1. Load the data into Data Register(DR)

   *(pRxBuffer) = *((volatile uint8_t *)&pSPIx->DR);

   //2.decrease len

   Len--;

   //3.increment pTxBuffer in order to make it point to next data item

   pRxBuffer++;

   }

  }   

}

SPI_GetFlagStatus() function: Here is the code that I check the status flag. here I detected my RXNE flag is not SET.

uint8_t SPI_GetFlagStatus(SPI_RegDef_t *pSPIx, uint32_t FlagName)

{

if(pSPIx->SR & FlagName)

{

return FLAG_SET;

}

return FLAG_RESET;

}

Anyone could help me in this issue? Im using STM32F302R8 nucleo board

11 REPLIES 11

Observe the SCK pin using oscilloscope or logic analyzer.

JW

0693W00000AM1k4QAD.pngHere is the clock, during the first send data,it produce normally, but when to clear the RXNE, it could not produce the SCK.

What is in SPI_SendData()?

Maybe SPI_SendData already clears the RXNE, doesn't it?

JW

Here is what inside the SPI_SendData():

void SPI_SendData(SPI_RegDef_t *pSPIx, uint8_t *pTxBuffer, uint32_t Len)

{

  while(Len > 0)

  {

   //1. wait until TXE is SET

   while(SPI_GetFlagStatus(pSPIx, SPI_TXE_FLAG) == FLAG_RESET);

   //2. lepas TXE set, check dff or CRCL

   if(pSPIx->CR1 & (1 << SPI_CR1_CRCL))

   {

   //16 bit data frame format

   //1. Load the data into Data Register(DR)

   pSPIx->DR = *((uint16_t*)pTxBuffer);

   //2. decrease len

   Len--;

   Len--;

   //3. increment pTxBuffer in order to make it point to next data item

   (uint16_t*)pTxBuffer++;

   }

   else

   {

   //8 bit data frame format

   //1. Load the data into Data Register(DR)

   *((volatile uint8_t *)&pSPIx->DR) = *pTxBuffer;

   //2. decrease len

   Len--;

   //3. increment pTxBuffer in order to make it point to next data item

   pTxBuffer++;

   }

  }

}

But, I suspect that the hardware automatically, clear the RXNE based on this:

0693W00000AMAYMQA5.pngBut, Im not really understand what this means, can you explain it to me?

Watch that reading/viewing DR in the debugger will auto-clear SR.RXNE

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

RXNE works as a watermark on the Rx FIFO. When a byte arrives, it is stored to FIFO, and it's "level" increments by 1; when your read out a byte from FIFO, it's "level" decrements by 1.

If FRXTH=1, if "level">=1, RXNE=1; if "level" < 1 (i.e. "level" == 0, FIFO empty), RXNE = 0.

If FRXTH=0, if "level" >=2, RXNE=1; if "level"<2 (i.e. there is zero or one byte in FIFO), RXNE=0.

You probably want to have FRXTH set to 1.

JW

So, do I need to set the FRXTH manually? If I want to set it, during the SPI want to send data or to read data?

Normally, you would set it once, when you set up the SPI at the beginning of your program.

JW

I have managed to SET the FRXTH bit. After the data is sent, the RXNE goes HIGH. But, after it execute next code line which is SPI_receiveData(), It automatically clear the RXNE. Is this means that the hardware clear the RXNE automatically?

If I want the RXNE stays HIGH, I do not understand what do you mean by the "level" If you could elaborate more, I am very appreciated.

Thank you