cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupts - USART corrupted data

Omar Suárez
Senior
Posted on July 04, 2017 at 11:16

Hi everyone,

I am designing a system that needs a bunch of interrupts working. By now I have three possible source of interrupts working:

+ USART6

+ SPI2

+ TIM6

The USART6 works sending and receiving data from PC.

When SPI2 and TIM6 are not working the USART works with no problems, I can receive and send data prefectly.

The protocol between the PC and the system is this:

- I constantly send data packets to the PC until I receive an END data frame from it. At this moment I should stop sending packets and change to other state to make other tasks.

The problem is when I am using SPI and TIM interrupts: TIM is a timer to trigger and data over the SPI to another IC, while I need to send data to the PC using USART.

While the system sends data to PC all works OK, but when it tries to receive the END from the PC I go to an overrun error in the USART.

I am trying to configure the priority this way:

NVIC_SetPriorityGrouping(4);  

NVIC_SetPriority(USART6_IRQn, 0);

NVIC_SetPriority(TIM6_DAC_IRQn, 1);

NVIC_SetPriority(SPI2_IRQn, 1);

but still the same problem occurs.

I also tried to disable all the interrupt when entering the USART interrupt handler:

void USART6_IRQHandler(void)

{

    __set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS));

  hal_uart_handle_interrupt(&uartHandle);

    

    __set_BASEPRI(0U); // remove the BASEPRI masking

}

but also the same problem.

I am not sure whether I need to configure anything else in the MCU to control the interrupts so I am stuck.

I need to say that I am not using the HAL from ST. I am using my own USART, SPI and TIM6 drivers.

Thanks in advanced,

Omar

#stm32f7 #interrups #usart
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on July 06, 2017 at 11:02

Hi again,

I finally solved this issue. It was an error in the structure of the code I was using. Inside one function called from the USART interrupt I was using a delay to switch on and off a LED so when I needed to simultaneously transmit and receive data the delay was too large at some point and doesn't allow to the interrupt to read the RDR register. So finally you were right, the ISR was too slow due to this delay.

Thanks for helping,

Omar

View solution in original post

8 REPLIES 8
Osto
Senior
Posted on July 04, 2017 at 11:38

Dear Omar,

please let me know the serial config (Baud rate, Data bits,...) and whats your END.

best regards,

Osto

Osto
Senior
Posted on July 04, 2017 at 12:38

Dear Omar,

I dont see which CPU you are using and how fast its running.With 115200 baud, you receive a character every 83.33µS. So you have to take care that the interrupt service routine have to be done in less than 83µS. For me, this seems to happen. I mean your ISR need more than 83µS to process a record. You can test it when you test at every end of ISR if at that time the Overrun bit is already set. If its set then you need too long to process and you need to optimize your ISR else there is another problem.

Please take care the printf and scanf functions need very long time to process and they are usually not thread safe. So they cannot run in an ISR or in RTOS environment.

You can also test this when you reduce for test purposes the baudrate to 9600. Then this shouldnt happen if the proccessing time is too long.

Regards,

Osto

Posted on July 04, 2017 at 11:45

 ,

 ,

Hi Osto,

this is my USART6 config,

 , , , /* enable clock for USART6 */

 ,

 , ,  ,_HAL_RCC_USART6_CLK_ENABLE(),

 ,

 , ,  ,

 ,

 , ,  ,uartHandle.Instance = USART_6,

 ,

 , ,  ,

 ,

 , ,  ,uartHandle.Init.BaudRate  , ,  , , ,  , , ,  , , ,  ,= USART_BAUD_115200,

 ,

 , ,  ,uartHandle.Init.WordLength  , ,  , , ,  , , ,  , , ,  ,= USART_WL_8,

 ,

 , ,  ,uartHandle.Init.StopBits , ,  , , ,  , , ,  , , ,  ,= USART_STOP_BITS_1,

 ,

 , ,  ,uartHandle.Init.Parity , ,  , , ,  , , ,  , , ,  , , ,  ,= USART_PARITY_NONE,

 ,

 , ,  ,uartHandle.Init.Mode  , ,  , , ,  , , ,  , , ,  , , ,  ,= USART_MODE_TX_RX,

 ,

 , ,  ,uartHandle.Init.OverSampling , ,  , , ,  , , ,  ,= USART_OVER16_ENABLE,

My end (STOP) data FRAME is writting this way from the PC (written in C ♯ :(

private

byte

[] tramaSTOPexper()

 , , , , , , , {

 , , , , , , , , , , , tramaReset =

new

byte

[39],

 , , , , , , , , , , , tramaReset[0] =

Convert

.ToByte(

'S'

),

 , , , , , , , , , , , tramaReset[1] =

Convert

.ToByte(

'T'

),

 , , , , , , , , , , , tramaReset[2] =

Convert

.ToByte(

'O'

),

 , , , , , , , , , , , tramaReset[3] =

Convert

.ToByte(

'P'

),

 , , , , , , , , , , , tramaReset[4] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[5] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[6] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[7] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[8] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[9] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[10] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[11] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[12] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[13] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[14] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[15] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[16] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[17] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[18] =

Convert

.ToByte(0),

 , , ,  , , , , , , , ,tramaReset[19] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[20] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[21] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[22] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[23] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[24] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[25] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[26] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[27] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[28] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[29] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[30] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[31] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[32] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[33] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[34] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[35] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[36] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[37] =

Convert

.ToByte(0),

 , , , , , , , , , , , tramaReset[38] =

Convert

.ToByte(

'F'

),

 ,

 , , , , , , , , , , ,

return

tramaReset,

 , , , , , , , }

This is then written in the SerialPort.

Thanks,

Omar

Posted on July 04, 2017 at 13:02

Sorry, I forgot to specify the MCU, in this case I am using a STM32F769 with a HSE of 25 MHz.

The fact is that I can send and receive data without any problem using only the USART interrupt (no SPI or TIM6) so I guess that is not a problem with the baudrate and the ISR routine. That is the reason why I set the USART priority higher than the others, so in case I receive or send anything using the USART I can stop all the other tasks to process it. Then I understand that with a higher priority could receive the data at 115200 like in the case when I am not using other sources of interrupts but the USART.

Regards,

Omar

Osto
Senior
Posted on July 04, 2017 at 16:54

Hi Omar,

Its still not clear with which speed your core is running. 25MHz is HSE speed but how is the PLL configured. Do you use STMCube or do you setup PLL by hand? Whats the core speed?

In my opinion either your ISR hangs somewhere and return too late or your core speed is not fast enough. With 9600 baud you normally shouldnt have any problem with timing.

Osto

Posted on July 04, 2017 at 16:34

Hi Osto,

I have made some tests to confirm that the baudrate is not the problem and the issue is still there using 9600 bps.

Posted on July 04, 2017 at 17:01

I use the HSE directly without any PLL so the core speed is 25MHz also. I am not using STM32CubeMX I am configuring the clock manually.

I tested it using 9600 and obtained the same behaviour.

Posted on July 06, 2017 at 11:02

Hi again,

I finally solved this issue. It was an error in the structure of the code I was using. Inside one function called from the USART interrupt I was using a delay to switch on and off a LED so when I needed to simultaneously transmit and receive data the delay was too large at some point and doesn't allow to the interrupt to read the RDR register. So finally you were right, the ISR was too slow due to this delay.

Thanks for helping,

Omar