How to clear UART interrupt properly?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi,

   

i am still learning how to use the interrupts in PSoC4 and i have the following situation:

   

CY_ISR(UART_RX_INT_myReceiveInt)
{
    BLEtoUART(testbuf, 4, 1);
    GECKO_UART_SpiUartClearRxBuffer();
    source = GECKO_UART_GetRxInterruptSourceMasked();
    GECKO_UART_ClearRxInterruptSource(source);

   

}

   

 

   

VS

   

 

   

CY_ISR(UART_RX_INT_myReceiveInt)
{
    source = GECKO_UART_GetRxInterruptSourceMasked();
    GECKO_UART_ClearRxInterruptSource(source);
    BLEtoUART(testbuf, 4, 1);
    GECKO_UART_SpiUartClearRxBuffer();

   

}

   

VS

   

CY_ISR(UART_RX_INT_myReceiveInt)
{
    BLEtoUART(testbuf, 4, 1);
    GECKO_UART_SpiUartClearRxBuffer();
    source = GECKO_UART_GetRxInterruptSourceMasked();
    GECKO_UART_ClearRxInterruptSource(source);

   

}

   

The second snippet executes the line BLEtoUART(testbuf,4,1) two times. The first one is fine and the third one is fine. Please tell me how to handle the UART interrupt the right way. What i want to achieve ultimately is:

   

1. Detect when a character is received by the UART

   

2. Scan the received frame for start and end FLAG which indicate a valid message

   

3. Extract the message

   

Is there anyway to only throw an interrupt when a specific FLAG character is received by the UART?

   

 

   

Thanks for clarification,

   

Pat

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

@Pat

   

Do not clear the receive buffer. This should be done only in case of an error. You ought to set a (volatile!!) flag in your handler.

   

Do not send data in the interrupt handler, this might stall your system or conflict with the current handled interrupt. Instead poll for the flag or poll for GetRxBufferSize() to see if any characters have arrived. Pick the characters from RxBuffer with the appropriate read function.

   

Clear all interrupt sources or you are unable to see new errors occurring.

   

I usually suggest to increase Rx and Tx buffers to something like 80 and let the component do all the handling. Just query for GetRxBufferSize().

   

Of course you may write as an exercise your own circular buffer function, gives you more flexibility.

   

You may fire your own interrupt: Use an isr component with a hardware connection and call isr_SetPending()

   

 

   

Bob

View solution in original post

0 Likes
6 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

@Pat

   

Do not clear the receive buffer. This should be done only in case of an error. You ought to set a (volatile!!) flag in your handler.

   

Do not send data in the interrupt handler, this might stall your system or conflict with the current handled interrupt. Instead poll for the flag or poll for GetRxBufferSize() to see if any characters have arrived. Pick the characters from RxBuffer with the appropriate read function.

   

Clear all interrupt sources or you are unable to see new errors occurring.

   

I usually suggest to increase Rx and Tx buffers to something like 80 and let the component do all the handling. Just query for GetRxBufferSize().

   

Of course you may write as an exercise your own circular buffer function, gives you more flexibility.

   

You may fire your own interrupt: Use an isr component with a hardware connection and call isr_SetPending()

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Thanks for the answers so far.

   

The thing is that when i dont clear up the UART receive buffer, my UART interrupt seems to fire again and again...i dont get how to do it 😞

   

Right now i have this:

   

/**************************************************************************//**
 * @brief RX interrupt service routine
 *****************************************************************************/
CY_ISR(UART_RX_INT_myReceiveInt)
{
    uint32 source = 0;
    source = GECKO_UART_GetRxInterruptSourceMasked();
    GECKO_UART_ClearRxInterruptSource(source);
    flg_UART_RCV = 1;
}

   

The flag is volatile and gets checked in the main loop. But the interrupt fires over and over when i just send one byte to the UART 😞

0 Likes
rola_264706
Level 8
Level 8
50 likes received 25 likes received 10 likes received

Use Volatile on the interrupt variable. 

   

A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:

   

1. Memory-mapped peripheral registers

   

2. Global variables modified by an interrupt service routine

   

3. Global variables accessed by multiple tasks within a multi-threaded application

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Post your complete project. So we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Hi,

   

from a technical standpoint i would like to do so, but i am not allowed to post the whole project publicly. Can i send it to you privately?

   

Reagrds,

   

Patrick

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Sorry, but "No", I do not accept private mails to help the forum.

   

Alternatively: Create a project that only handles the UART and compiles successfully but showing your interrupt error. Post that project here.

   

 

   

Bob

0 Likes