2021-04-19 09:50 PM
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
2021-04-19 11:14 PM
Observe the SCK pin using oscilloscope or logic analyzer.
JW
2021-04-20 10:14 AM
Here is the clock, during the first send data,it produce normally, but when to clear the RXNE, it could not produce the SCK.
2021-04-20 03:56 PM
What is in SPI_SendData()?
Maybe SPI_SendData already clears the RXNE, doesn't it?
JW
2021-04-21 03:32 PM
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:
But, Im not really understand what this means, can you explain it to me?
2021-04-21 04:07 PM
Watch that reading/viewing DR in the debugger will auto-clear SR.RXNE
2021-04-21 04:21 PM
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
2021-04-23 12:29 AM
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?
2021-04-23 12:40 AM
Normally, you would set it once, when you set up the SPI at the beginning of your program.
JW
2021-04-23 01:53 AM
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