cancel
Showing results for 
Search instead for 
Did you mean: 

Disabling Uart4 interrupt causes lockup

stenasc
Senior
Posted on August 27, 2017 at 00:02

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

 Bob

void 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          

}
18 REPLIES 18
Posted on August 27, 2017 at 05:21

>>the system locks up

The prescient question is where is it locked up, if you stop it in the debugger where is it stuck.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 28, 2017 at 10:38

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 

Posted on August 28, 2017 at 15:57

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;

}

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 28, 2017 at 21:23

Tried your suggestions but didn't make a difference. Will get a good look at it tomorrow.

Bob

167035CGIL4
Posted on August 30, 2017 at 04:07

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?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
Posted on August 30, 2017 at 09:54

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=false

sebByteVein.h.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyPH&d=%2Fa%2F0X0000000b8A%2FI2GssU3VPPQVRNh_.gE9Z1AjhxI_rC4mx1k2qdfrjrE&asPdf=false
Posted on August 30, 2017 at 09:15

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 

Posted on August 30, 2017 at 10:41

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