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.

MSP430FR2512: Ensuring the CPUOFF bit is cleared

Part Number: MSP430FR2512
Other Parts Discussed in Thread: CC2640R2F, MSP-TS430RHL20, , MSP430WARE

Hi Team,

We have encountered an inconsistent error in using the I2C bus of MSP430FR2512 on MSP-TS430RHL20 when communicating with the CC2640R2F Launchpad. We have probed with an oscilloscope and can confirm that all portions of the I2C transaction are happening correctly.

We have added a line to exit LPM(0 or 4) within the I2C STOP ISR "__bic_SR_register_on_exit(LPM0_bits);".

What we are observing is that the processor will return to the main application where the main program halts awaiting an I2C transaction "__bis_SR_register(LPM0 + GIE);" and the CPUOFF bit within the SR register will remain set. Only clearing every other I2C STOP event.

Furthermore when the CPU does resume running within the main loop the I2C UCSTPIFG bit of the UCG0IFG register is automatically cleared.

The I2C process is configured and executes according to the Multiple Rx and Tx examples within the MSP430WARE Driver Library.

Is there a more appropriate method of insuring the CPUOFF bit is cleared from within the I2C STOP event?


Regards,

Garret

  • The problem has to be elsewhere in your ISR code than that one line. If it executes then the CPUOFF bit will be cleared when the ISR exits.

  • If the ISR issues its wakeup, but main() isn't in LPM, the wakeup is ignored. In that case (and if there are no other wakeups), when main() subsequently goes into LPM, it won't wake up.

    Thus there is a race which will become evident (it's always there) if (a) main is doing other things while the I2C transaction is running or (b) the transaction happens very fast.

    One way of avoiding this is to define a flag e.g. "volatile unsigned char done;". Set this to 0 before starting the transaction, and in the ISR set it to 1. Then main() looks something like:

    while (1) {
        __bic_SR_register(GIE);            // Close the window by disabling 
        if (done) break;                   // Transaction is complete
        __bis_SR_register(LPM0_bits|GIE);  // Open the window and wait
    }
    __bis_SR_register(GIE);                // Re-enable 

    It looks a bit clumsy but it's quick.

**Attention** This is a public forum