cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 SPI code only works in debug mode

LLOLO.1
Associate II

Hi I am trying to read ID of an external FLASH.

The code which reads it is shown below.

uint16_t FLASH_ReadID(void)
{
	uint16_t tempData = 0x0000;
 
	//Read ID
	GPIOB->BSRR |= GPIO_BSRR_BR2; //Reset FLASH CS
	while(!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = 0x9E;
 
	while(!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = 0xFF;
	while((SPI1->SR & SPI_SR_BSY));
	tempData = (SPI1->DR << 8);
 
	while(!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = 0xFF;
	while((SPI1->SR & SPI_SR_BSY));
	tempData |= SPI1->DR;
 
	GPIOB->BSRR |= GPIO_BSRR_BS2; //Set FLASH CS
 
	return tempData;
}

After reading 2byte ID (0x20, 0xBA)I am transmitting the ID information to PC through USART. I use a serial terminal program which called Hterm. Problem is when I run the code, the FLASH ID returns as 0x00, 0x20. I set SPI baudrate as 42Mbps. When I set the baudrate to lower speeds output becomes 0x00, 0x00. After getting 0x00, 0x00 if I call the function one more time I get 0x80, 0x80.

The most interesting part is when I debug the code it seems to return correct value of 0x20, 0xBA.

Why does the code work properly when in debug mode step by step?

This discussion is locked. Please start a new topic to ask your question.
4 REPLIES 4
TDK
Super User

From the reference manual:

Note: Do not use the BSY flag to handle each data transmission or reception. It is better to use the

TXE and RXNE flags instead.

If you feel a post has answered your question, please click "Accept as Solution".

I updated the code as below.

uint16_t FLASH_ReadID(void)
{
	uint16_t tempData = 0x0000;
 
	//Read ID
	GPIOB->BSRR |= GPIO_BSRR_BR2; //Reset FLASH CS
 
	SPI1->DR = 0x9E;
	while(!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = 0xFF;
	while(!(SPI1->SR & SPI_SR_RXNE));
	tempData = (SPI1->DR << 8);
	while(!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = 0xFF;
	while(!(SPI1->SR & SPI_SR_RXNE));
	tempData |= SPI1->DR;
	while((SPI1->SR & SPI_SR_BSY));
 
	GPIOB->BSRR |= GPIO_BSRR_BS2; //Set FLASH CS
 
	return tempData;
}

And I scoped the SPI line. The screenshot shown below.

0693W00000BaM4GQAV.jpg 

In scope everything seems to be fine but when I try to read the registers first I read 0x00, 0x20 and when I recall the function again I read 0xBA, 0x00 and if I recall the function again I read 0x20, 0x00. From this point whenever I call the function I read only 0x20,0x00. I am confused

Instead of polling RXNE and TX I decided to use RXNE interrupt for receiving data. It seems to work correct but I wonder why polling does not work?

TDK
Super User

For every byte you send, you need to read a byte, even if you don't care about it, in order to keep the RXNE flag in sync. Your code sends 3 bytes but only reads 2.

If you feel a post has answered your question, please click "Accept as Solution".