2017-08-26 03:02 PM
Hello Forum,
I have a function that I call to read data from Uart4. As there are a number of critical times that I need Uart4 interrupt disabled, I enable the interrupt on entry to the function and disable it after priocessing the uart data. However, I found that the
system locks up after executing the NVIC_DisableIRQ(USART3_8_IRQn) command. I've tried many things but I cannot seem to get it working. My code is as follows. Any help greatly appreciated. Kind Regards Bobvoid Enable_Usart4_Interrupts(void)
{ NVIC_EnableIRQ(USART3_8_IRQn); }void Disable_Usart4_Interrupts(void){ NVIC_DisableIRQ(USART3_8_IRQn); }void Usart4Init_RS485(void){ USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Enable GPIOC and DMA clock RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); // Enable USART4 APB clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART4, ENABLE); // Connect pin to Periph GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_0); // USART4 TX GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_0); // USART4 RX // Configure pins as AF pushpull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure); 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(USART4, &USART_InitStructure); USART_Cmd(USART4, ENABLE); // Enable the COM4 Receive interrupt: this interrupt is generated when the// COM4 receive data register is not empty USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);// USART4 IRQ Channel configuration
NVIC_InitStructure.NVIC_IRQChannel = USART3_8_IRQn;// USART4 IRQ Channel priority
NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART3_8_IRQHandler(void){ uint8_t rx_byteby = 0; USART_ClearITPendingBit(USART4, USART_IT_RXNE); //Clear any pending uart interrupts bits while (USART_GetITStatus(USART4, USART_IT_RXNE) != RESET) // Received characters modify string { rx_byteby = USART_ReceiveData(USART4); rx_str[U4_rx_count++] = rx_byteby; }}int Read_From_Uart4(void){ Enable_Usart4_Interrupts(); // Enable Usart4 interrupts for Uart4 data // Receive and process UART4 data// .....// ...
Disable_Usart4_Interrupts(); // Disable Usart4 interrupts }2017-08-26 08:21 PM
>>the system locks up
The prescient question is where is it locked up, if you stop it in the debugger where is it stuck.
2017-08-28 03:38 AM
Hi Clive,
Appreciate you getting back to me. It hasn't locked up. It just remains in the interrupt handler and seems to loop continuously which seems very surprising as I would have expected the
NVIC_DisableIRQ(USART3_8_IRQn) to allow it to exit cleanly
. I'll get a chance to look at the flags and registers later today.Bob
2017-08-28 08:57 AM
Wouldn't
USART_ITConfig(USART4, USART_IT_RXNE, DISABLE/ENABLE); be the more appropriate?
This is a bit nonsensical
void USART3_8_IRQHandler(void)
{
uint8_t rx_byteby = 0;
USART_ClearITPendingBit(USART4, USART_IT_RXNE); //Clear any pending uart interrupts bits
while (USART_GetITStatus(USART4, USART_IT_RXNE) != RESET) // Received characters modify string
{
rx_byteby = USART_ReceiveData(USART4);
rx_str[U4_rx_count++] = rx_byteby;
}
}
The interrupt source is self clearing, and there is a single byte buffer on the USART, just check the RXNE bit in the status, not the interrupt, and scope the buffer depth so it doesn't overrun and corrupt things.
void USART3_8_IRQHandler(void)
{ if (USART_GetFlagStatus(USART4, USART_FLAG_RXNE) != RESET) // Received characters modify string { uint8_t rx_byteby = USART_ReceiveData(USART4);if (U4_rx_count < sizeof(rx_str))
rx_str[U4_rx_count++] = rx_byteby; }}2017-08-28 02:23 PM
Tried your suggestions but didn't make a difference. Will get a good look at it tomorrow.
Bob
2017-08-29 05:32 PM
2017-08-29 07:07 PM
Stops in the sense of you stepping it, or is there when you hit the stop button in the debugger?
This is with what part? If a Cortex-M0, is the vector table copied into RAM?
2017-08-30 12:54 AM
Could you explain the application and the reason to stop the USART interrupt?
Usually interrupt priority will be used to make sure other peripherals will be processed first.
Is disabling the interrupt purpose to make sure the buffer is 'stopped'? Because in this case, it would be better to implement a SW FIFO between the USART that push bytes in, and the other task that reads bytes in.
For fun, implemented something like a ring buffer which could be used as FIFO or STACK (see attached).
The notification of the buffer empty/non-empty can be used to enable/disable peripherals.
________________ Attachments : SebByteVein.c.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hxpe&d=%2Fa%2F0X0000000b8F%2F49K0EbWwog.r1HF__blvwRAXQc.nnNm14MWWNjN8qVo&asPdf=falsesebByteVein.h.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyPH&d=%2Fa%2F0X0000000b8A%2FI2GssU3VPPQVRNh_.gE9Z1AjhxI_rC4mx1k2qdfrjrE&asPdf=false2017-08-30 02:15 AM
Hi Clive,
It's there when I hit stop in the debugger. The part is an
stm32f091 (Cortex M0). Don't quite understand regarding the vector table copying. Would you not expect all other interrupts to cause problems if there was a vector table issue?
Regards
Bob
2017-08-30 03:41 AM
At regular intervals, data is written to memory and it was noticed that erroneous writes were occurring. After the interrupt was disabled, writes were fine. However, I don't think it is an issue with disabling the interrupt. The problem occurs after I re-enable it when it remains in the handler and doesn't return to the main loop.
Bob