cancel
Showing results for 
Search instead for 
Did you mean: 

(SOLVED) STM32F103C8 UART Interrupt Flooding

petoknm
Associate II
Posted on February 07, 2015 at 18:42

Hi

I want to receive data from ESP8266 module after restarting it. But after restart, it starts the communication at a higher baud rate and after it's done booting it uses 9600 baud. When I have the UART peripheral enabled and receiving by using interrupts it reads the first part (9600baud) then it detects frame errors on the faster part but then when it switches to 9600baud it can't receive the data. It just fires the interrupt in a very strange way have a look. What you will see is a trace from logic analyzer. Channel 1 is the TX line of the micro. Channel 2 is the RX line and channel 3 is a pin value that changes(toggles) inside the interrupt handler.

http://i.imgur.com/klifwqx.png

http://i.imgur.com/5XbVuPi.png

http://i.imgur.com/CacmtNx.png

http://i.imgur.com/QISnWFE.png

After it begins to receive data at 9600baud again it starts to flood the micro with interrupts on every other byte that is received. To me it seems that it has not properly recovered from the frame errors. Maybe some flags were not cleared or something because before the frame errors it works normally. How can I receive the data after having frame error? Code that initializes the UART peripheral (I am using the new STM32CubeF1 v1.0.0):

uart.Instance=USART2;
uart.Init.BaudRate = 9600;
uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart.Init.Mode = UART_MODE_TX_RX;
uart.Init.OverSampling = UART_OVERSAMPLING_16;
uart.Init.Parity = UART_PARITY_NONE;
uart.Init.StopBits = UART_STOPBITS_1;
uart.Init.WordLength = UART_WORDLENGTH_8B;
if
(HAL_UART_Init(&uart) != HAL_OK) {
...
}
HAL_NVIC_SetPriority(USART2_IRQn,7,0);
HAL_NVIC_EnableIRQ(USART2_IRQn);

Thank you for any suggestions. EDIT (SOLVED) There was a code in the HAL drivers(stm32f1xx_hal_uart.c -> HAL_UART_IRQHandler()) that tells the USART to stop receiving by setting the state to ''ready''. I just commented out the line, like this

if
(huart->ErrorCode != HAL_UART_ERROR_NONE) {
/* Set the UART state ready to be able to start again the process */
//huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}

#uart-stm32-interrupt-serial
1 REPLY 1
gustavo23
Associate II
Posted on April 11, 2015 at 21:45

I just had a similar situation happen; after rebooting a module via a serial command issued by the micro, the HAL_UART_IRQHandler would be called over and over non stop, and my other threads would not run at all. Commenting out the line:

huart->State = HAL_UART_STATE_READY;

as you suggested fixed the issue; ( although I am not totatly sure what the consequences are ).

I also noticed that if I paused the debugger in the HAL_UART_IRQHander function, and let the IDE read the local variables, which includes the uart handle with the UART registers, and then pressed continue, the other threads would resume and the issue disappears. When I did that, when the debugger stopped, the SR register was set to Decimal 250, but as soon as the registers were read, the SR would go to Decimal 192, and at this point it all works again. So it sounds like reading the registers is the solution, but I am not sure where to put this, since no interrupt ( I mean not HAL callback ), is generated when this condition occurs, it just seems to be stuck calling the HAL_UART_IRQHandler.

 

Being that this is in the HAL library, is it wise to change it? I assume this is not a bug in the HAL library? I don't know is it? What are the implications of commenting out that line.

Thanks