2014-09-25 03:43 PM
Hi,
I am having issue with the USART interrupt handler in my project. It seems to get stuck in the interrupt handler routine. The status register value is set to 0x1d8 but I don't seem to be able to clear the error state. The interrupt routine used is shown below and I am using the USART_GetITStatus to read error flags/rxne andtc from the status register and USART_ReceiveData to read the data. The communication seems to work for over an hour but then get stuck in the interrupt handler. Paulvoid rs485UsartIRQHandler(void)
{
if (USART_GetITStatus(RS485_USART, USART_IT_PE) == SET)
{
USART_ReceiveData(RS485_USART);
millisSinceLastReceive = 0;
}
if (USART_GetITStatus(RS485_USART, USART_IT_FE) == SET)
{
USART_ReceiveData(RS485_USART);
millisSinceLastReceive = 0;
}
if (USART_GetITStatus(RS485_USART, USART_IT_NE) == SET)
{
USART_ReceiveData(RS485_USART);
millisSinceLastReceive = 0;
}
if (USART_GetITStatus(RS485_USART, USART_IT_ORE) == SET)
{
// Dummy read to clear ORE flag
USART_ReceiveData(RS485_USART);
millisSinceLastReceive = 0;
}
if (USART_GetITStatus(RS485_USART, USART_IT_RXNE) == SET)
{
uint8_t newData = USART_ReceiveData(RS485_USART);
Ringbuf_Put(receiveBuffer, &newData);
millisSinceLastReceive = 0;
}
if (USART_GetITStatus(RS485_USART, USART_IT_TC) == SET)
{
DMA_Cmd(RS485_TX_CHANNEL, DISABLE);
USART_ITConfig(RS485_USART, USART_IT_TC, DISABLE);
GPIO_ResetBits(RS485_DE_PORT, RS485_DE_PIN);
transmitterBusy = false;
}
}
2014-09-26 12:08 AM
Some STM32 (maybe all of them) requires to clear ORE flag explicitely by writing to ICR register, reading DR is not enough. There must be a ClearFlag function to help you in this task.
2014-09-26 12:31 AM
Post the content of all control registers at the moment when the problem happens.
JW2014-09-29 01:53 PM
Hi,
The chip that I am using is a STM32F100VC so it doesn't have the ICR register like in the F3. Juts retested it, the SR is now showing 0xF8 which is showing an overrun error but it does not get clear in the handler. I have step through the handler using gdb but the USART_GetITStatus is not set for the overrun flag. The control registers value are: CR1 = 0x202c // USART, Rx interrupt, RX and TX enabled. CR2 = 0x0 CR3 = 0x80 // DMA transmitter Paul2014-09-29 01:55 PM
The usart flag definition from the st library are:
#define USART_IT_PE ((uint16_t)0x0028)
#define USART_IT_TXE ((uint16_t)0x0727)
#define USART_IT_TC ((uint16_t)0x0626)
#define USART_IT_RXNE ((uint16_t)0x0525)
#define USART_IT_IDLE ((uint16_t)0x0424)
#define USART_IT_LBD ((uint16_t)0x0846)
#define USART_IT_CTS ((uint16_t)0x096A)
#define USART_IT_ERR ((uint16_t)0x0060)
#define USART_IT_ORE ((uint16_t)0x0360)
#define USART_IT_NE ((uint16_t)0x0260)
#define USART_IT_FE ((uint16_t)0x0160)
2014-09-30 12:01 AM
> Juts retested it, the SR is now showing 0xF8 which is showing an overrun error but it does
> not get clear in the handler. I have step through the handler using gdb but the > USART_GetITStatus is not set for the overrun flag. It's a well deserved punishment for using the ''library''. Use your head and raw register access. The ''library'' tries to be smart, and masks the flags read from the status register by the respective interrupt enable bit. Particularly, for ORE it masks with the EIE bit, omitting the fact that ORE has another path to trigger an interrupt, through RXNEIE (see ''USART interrupt mapping diagram'', Fig.266 in RM0041 rev 4). Btw. you are lucky you stumbled upon this, otherwise it might have remained as a bomb ticking in your code waiting for the (presumably rare) occurence of overflow... My guess is that there's quite a lot of code out there with this bomb embedded... JW2014-09-30 12:05 AM
Try USART_GetFlagStatus instead of USART_GetITStatus. The first does not care about your interrupt configuration and will detect the ORE condition.
2014-09-30 12:15 AM
This also may be a known ''library'' bug which may be ''corrected'' in a newer version.
As I don't use the ''library'' I have only a random selection of it for various families, and don't attempt to keep them up to date. In one of them I found #define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */ #define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */ while USART_IT_ORE is missing. I still maintain that the ''library'' is superfluous and buggy, and recommend against using it. JW2014-09-30 12:47 AM
Release Notes for STM32F10x Standard Peripherals Library Drivers
[...]V3.6.0 / 27-January-2012
[...]stm32f10x_usart.h/.c
Update procedure to check on overrun error interrupt pending bit, defines for the following flag are added:
USART_IT_ORE_RX:
this flag is set ifoverrun error interrupt
occurs and RXNEIE bit is set
USART_IT_ORE_ER:
this flag is set if
overrun error interrupt
occurs and EIE bit is set