This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2155: MSP430FR2155 interrupt lock

Part Number: MSP430FR2155

Hi,

I need a little help on how to sync interrupt and main. 

I have a UART connection where data comes, and in the main loop i process this data. Whenever a data comes its stored on ring buffer on interrupt. Main loops runs forever and if there is a new data on ring buffer it process this. I want to implement LPM but i see some risks about it.

Accoring to the below code, if a data comes from UART right after "if(get_size_ring_buffer() < 1)" and before execute this command "__bis_SR_register( LPM3_bits | GIE );" it will be on LPM mode but there would be data on ring buffer which needs to be processed. How i can i solve this problem? Any suggestion?

while(1)
{
    if(get_size_ring_buffer() > 0)
    {
       process_data();
    }

    if(get_size_ring_buffer() < 1)
    {
       __bis_SR_register( LPM3_bits | GIE );
    {
}


#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
    uint8_t Data;

    switch (__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG))
    {
    case USCI_UART_UCRXIFG:
        
        Data = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
       
        ring_buffer_put(rb, &Data)
            LPM3_EXIT; 
        break;
    }
}

  • Precede the second if() -- the one with the LPM -- with __disable_interrupt(), and follow the if-block with __enable_interrupt(). The GIE in the LPM assures you'll wake up.

    You'll some of the time be (re-)enabling unnecessarily, but it's cheaper than checking.

  • while(1)
    {
        if(get_size_ring_buffer() > 0)
        {
           process_data();
        }
    
    __disable_interrupt();
    
        if(get_size_ring_buffer() < 1)
        {
           __bis_SR_register( LPM3_bits);
        {
    
    __enable_interrupt();
    }

    You suggest below code, right?

    But this time shouldnt i lost the incoming data from UART(if any) between disabling and enabling interrupts?

  • No. Please put back the GIE you had in the LPM statement:

           __bis_SR_register( LPM3_bits | GIE );

    This assures you will wake up.

    If executing get_size_ring_buffer() takes longer than 2 character times, you can lose data. I'm guessing it doesn't take that long.

  • Thank you for kind help. Can you please explain what you mean by 2 character times?

  • Hi,

    the reason is the disabling of the interrupt. This means until reaching

    __bis_SR_register( LPM3_bits);

    or

    __enable_interrupt();

    you will not react upon incoming data from UART. As long as during this period of deactivated interrupts only one byte comes in, it will not hurt you, as the flag for UART RX will be set and as soon as you re-enable GIE you will execute the interrupt service routine. But if two or more bytes/characters should come in, the last one will overwrite the previous in the UART module buffer, and thus you would lose it.

    Best regards

    Peter

**Attention** This is a public forum