cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407, SPI RXNE flag does not clear

gahelton1
Associate III

I have an STM32F407 micro using the SPI. SPI is setup as a master at 1MHZ clock.

I send a group of data (output only) which operates correctly. The SPI does not receive any useful data at this time. After the last byte has been sent out, I loop and wait for the SPI RXNE flag to become set. This is the flag that I use to indicate that the transmission is complete, and data (not useful) is waiting in the receive portion of the DR.

I read the SPI data register to clear the flag (dummy = SPI->DR;). However, the flag does not clear automatically. This is verified by setting a breakpoint immediately past the point where I read the data register, and looking at the RXNE flag in SPI status register.

It is not until that I single step the code that the RXNE flag is cleared.

I was thinking that this may be some sort of debugger HW artifact, but it doesn't appear to be. Later in the code, it blows right through a portion of code that is checking this flag, and it is still set when it should not be.

Two screen snapshots below are shown. The 1st one is where the code has hit the breakpoint right after reading the SPI DR. The RXNE flag in SPI SR should be clear at this point, and it's not. The 2d screen snapshot shows the RXNE flag is SPI SR after the code was single stepped once.

What's up with that ?

0693W00000GYFo8QAH.jpg0693W00000GYFnyQAH.jpg 

1 ACCEPTED SOLUTION

Accepted Solutions

What's the order of the posts?

I personally refrain from using BSY in SPI, since I've been bitten by it - not related to RXNE, but bad aftertaste remained. There are also some (again unrelated) errata with BSY.

Why is it a problem to read DR on the go?

[EDIT] Okay, on second thought, it's a bit more involved than just that. I never implemented polled SPI on STM32, I admit...[/EDIT]

[EDIT2] I also faintly remember something about one needing to check TXE going empty before starting to poll BSY, I'm not sure it's 'F4-specific [/EDIT2]

[EDIT3] Found it

0693W00000GYGS3QAP.png 

JW

View solution in original post

4 REPLIES 4

I don't see the code before the test, but let me guess. By Tx-ing a bunch of data without reading out the Rx-ed data (as witnessed by SR.OVF) you let RXNE to be set all the time you are Tx-ing. Then, after writing the last byte of the Tx bunch into DR, you immediately test RXNE, oh it's set, so let's read DR and we're done - but no, there's still that one last data being Tx-ed, and after it does, RXNE is set. Only after that debugger succeeds to stop and read out the registers.

JW

gahelton1
Associate III

Hi JW. Thank you for the reply.

Here is the code that transmits the data

You are correct in that I am not reading the DR while I am transmitting, and RXNE will be set all the time.

	bytecount = 0;
	p_buffer = &REU_Encoded_Xmit_Data[0];
 
 
	while(bytecount < 9)
	  {
	  while( (SPI1->SR & SPI_SR_TXE) == 0);
 
	  SPI1->DR = *p_buffer++;
	  bytecount++;
	  }
 
	//*********************************
	// Clear the flag from the last
	// received byte. There is still
	// a byte being transmitted
	// right now, so the RXNE flag
	// will get set again when complete.
	//**********************************
 
	dummy = SPI1->DR;
 
 
	//************************************
	// Wait for last byte to complete
	// Read SPI data register to clear
	// RXNE flag.
	//************************************
 
	while( (SPI1->SR & SPI_SR_RXNE) == 0 );
	dummy = SPI1->DR;
	__NOP();
 
 
	//*******************************
	// Enable external ISR on PB4
	//*******************************
 
	EXTI->IMR |= EXTI_IMR_MR4;
 
 
 
	p_receive_buf = &BREU_Status_Data[0];

But after the last byte has been written to DR, I read the DR to clear RXNE flag from the "previous" byte, then go down and wait for the flag to become set again after the last byte has finished, then clear again. The RXNE flag cannot be accumulative. That is, it can't be set more than once. Once you read the DR, it should be cleared. Can the RXNE flag not be cleared while a byte is "in flight" ?

Ok, I've changed the code to use the BSY flag in SPI SR to determine when the outgoing message is complete, then read the DR to clear the RXNE flag.

I think that this actually makes more sense now that I think about it more.

	bytecount = 0;
	p_buffer = &REU_Encoded_Xmit_Data[0];
 
 
	while(bytecount < 9)
	  {
	  while( (SPI1->SR & SPI_SR_TXE) == 0);
 
	  SPI1->DR = *p_buffer++;
	  bytecount++;
	  }
 
	//**************************************
	// Wait until the last byte has finished
	// transmission, then clear RXNE by
	// reading DR
	//**************************************
 
	while( (SPI1->SR & SPI_SR_BSY) );
	dummy = SPI1->DR;
 
 
	//*******************************
	// Enable external ISR on PB4
	//*******************************
 
	EXTI->IMR |= EXTI_IMR_MR4;

What's the order of the posts?

I personally refrain from using BSY in SPI, since I've been bitten by it - not related to RXNE, but bad aftertaste remained. There are also some (again unrelated) errata with BSY.

Why is it a problem to read DR on the go?

[EDIT] Okay, on second thought, it's a bit more involved than just that. I never implemented polled SPI on STM32, I admit...[/EDIT]

[EDIT2] I also faintly remember something about one needing to check TXE going empty before starting to poll BSY, I'm not sure it's 'F4-specific [/EDIT2]

[EDIT3] Found it

0693W00000GYGS3QAP.png 

JW