cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F2 RXNE flag FROM SR register clear without reason

haye
Associate II

Hello,

I am using UART4 from a STM32F2. I am sending a data then my RXNE FLAG from SR register go from 0 to 1. Without doing anything (no read of the DR register and no clearing manually the flag) it go back to 0 after some time. So I am missing the data in my IT routine.

I can't figure out why this happening. Could someone have an idea of what the issue could be ?

19 REPLIES 19

>RXNE should be set when you *receive* data, not when *sending* it from the STM32 USART.

Yeah sure. I am sending a data then the flag is set when I received it.

> How do you know?

Knowing that I'm doing nothing on DR ? or knowing that the flag is going to 0 ? for the second case I am knowing it by checking the SR register

>>RXNE should be set when you *receive* data, not when *sending* it from the STM32 USART.

> Yeah sure. I am sending a data then the flag is set when I received it.

So you have some loopback enabled?

> for the second case I am knowing it by checking the SR register

Okay so post a minimal but complete compilable code exhibiting the problem.

JW

>So you have some loopback enabled?

Yes hardware one my TX is going on my RX pins

> Okay so post a minimal but complete compilable code exhibiting the problem.

Ok I will clean the code to send you the minimal one I used (The application is huge and old) I will clear all the thing I comment and send it.

Thanks for your help !

Here is the code simplified :

main :

int main(void)
{
	DISABLE_INTERRUPTS();
 
	/* Setup STM32 system tickclock, AFIO clocks (alternate function dedicated clock */
	RCC_init();
 
    UART_Init();
 
	ENABLE_INTERRUPTS();
	
	FLAG_IT_UART4 = 0x40004C00;
	FLAG_IT_EN_UART4 = 0x40004C0C;
 
	USART_SendData(UART4, 0x0A);
 
	while(1);
 
	return(0);		//pour traiter warning compilo
}

RCC_init

void RCC_init(void)
{
 
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
							RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD |
							RCC_AHB1Periph_GPIOE, ENABLE);
	/* Enable SYSCFG's APB interface clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
	
	if (SysTick_Config(SystemCoreClock / 100000))  //DORIAN_MPLX passage de 1000 à 100000 pour 10 us
	{
		/* Capture Error */
		while(1);
	}
}

Uart_init

void UART_Init(void)
{
	NVIC_InitTypeDef 		NVIC_InitStructure;
	GPIO_InitTypeDef 		GPIO_InitStructure;
	USART_InitTypeDef 		USART_InitStructure;
 
 
 
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);	/* pour UART4 en PC10, PC11 */
	GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
 
 
    /* Configure the GPIO ports( USARTx Transmit and Receive Lines) */
	/* Configure the USARTx_Tx as Alternate function Push-Pull */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
 
 
	/* Enable USARTx clocks  */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
 
	// Clear structure to default values
	USART_DeInit(USART1);
	USART_DeInit(USART2);
	USART_DeInit(USART3);
	USART_DeInit(UART4);
	USART_DeInit(UART5);
 
 
	/*-- UART MPLX configured as follow:------------------------
		- Word Length = 8 Bits
		- 1 Stop Bit
		- No parity
		- BaudRate = 9600 baud
		- Receive and transmit enabled
  -------------------------------------------------------*/
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 
	USART_Init(UART4, &USART_InitStructure);//WARNING NOT POSSIBLE
	// no USART_ClockInit(), car valeurs par defaut(reset) sont OK, DG 24/03/2011 15:25:48
 
 
	//UART MPLX		Enable Interrupt
	//DORIAN_MPLX ETAPE 1 prio originel : 6
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
    
    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
	USART_ITConfig(UART4, USART_IT_TC, ENABLE);
 
	USART_Cmd(UART4,		ENABLE);
 
}

UART4_IRQHandler:

void UART4_IRQHandler(void)
{
	static u8 u8_Data1;
 
	if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
	{
		u8_Data1 = (USART_ReceiveData(UART4) & 0xFF);
	}
	
	if(USART_GetITStatus(UART4, USART_IT_TC) != RESET)
	{	
    
		USART_ClearITPendingBit(UART4, USART_IT_TC);
        
	}
 
}

haye
Associate II

I put my brake point on the first if before calling receive

And, in the debugger, when the breakpoint is hit, you watch the USART registers?

JW

I am watching the 2 pointer :

  1. FLAG_IT_UART4 = 0x40004C00;
  2. FLAG_IT_EN_UART4 = 0x40004C0C;

First for the SR register

Second for CR1 to be sure everything is well activated

I read all the documentation and don't find answer to this behaviour.

Have you any idea or where to search ?

What toolchain are you using that " FLAG_IT_UART4 = 0x40004C00 " is a pointer?

Don't breakpoint the code.

Don't inspect the USART registers in the debugger.

Read the register SR, and reflect content to a pin or pins, perhaps in SysTick. Perhaps watch for transitions in main() loop and print. Avoid prints in interrupts, or where byte-time critical.

Consider if your handler is reentering due to something debugger (not specified) is doing.

The SR won't auto-clear, you're touching DR/SR somewhere.

Make something absolutely minimal, where you have no interaction for a) other code, b) debugger side access of the SAME hardware registers.

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

Hi Clive,

Thank you for your answer.

yes, FLAG_IT_UART4 is a pointer to an u32.

I follow your advice and apparently it's the monitoring of the SR register through the debugger which reset the flag. Now I don't understand why and I'm asking if you know what could be a reason to this behaviour ? something to configure in the debugger itself ?

Breakpoint doesn't affect the state of the flag.