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.

Tower of Babel --- LPM etc.



One of the MSP430 power-saving features is the function/usage of 4 of the 16 bits in the Status Register SR. These bits are called: BIT7 = SCG, BIT6 = SCG0, BIT5 = OSCOFF, BIT4 = CPUOFF

When set to 1, they turn off certain power consuming circuits.

After Power-on-reset POR or Brown-out-reset BOR, the entire SR, including these 4 bits, the GIE bit, as well as all others, are cleared to 0.

The program code can set any combination of these 4 bits to 1 or clear any combination of them to 0 to control power consumption at will.

The program code can also set or clear the GIE bit in SR to enable or disable General Interrupt.

When an interrupt is acknowledged, the current content of SR is automatically pushed to the stack and SR itself is cleared. When the interrupt service routine ISR returns from interrupt, the saved SR is automatically popped. Thus normally, the ISR will be executed at full power, and when it finishes, the power saving settings before the interrupt will be restored.

But the ISR can also change this behavior deliberately. It can change the setting of these bits in the current SR. In this case, the new settings will take effect immediately for the rest of the ISR. The ISR can also change the setting of these bits in the saved copy of SR in the stack. In this case, the new settings will not take effect until the ISR returns from interrupt.

In my opinion, the above is easy to understand and should be understood by anyone who attempts to use this feature.

Now comes the not so easy part (according to me).

First, the hardware has a lot of what TI calls fail-safe features, which adds if-and-but fine prints to the above simplistic description. I cannot even enumerate these fine prints.

Next, TI defined some terminology, which I think are very artificial and unnecessary. Those 4 bit in SR naturally have 16 different combinations. Not all these 16 combinations are useful or even make sense. TI picked 5 out of the 16 and artificially calls them Active Mode, LPM0, etc. This may be convenient to some users but is somewhat confusing too.

So far we are still speaking with a single tongue and c-compilers cannot allow that. How dare us build a tower so high? Thus, here comes a barrage of header files and I hear people uttering babbles about things like:

__bic_SR_register

__bic_SR_register_on_exit

__bis_SR_register

__bis_SR_register_on_exit

__get_SR_register

__low_power_mode_0

__low_power_mode_1

__low_power_mode_2

__low_power_mode_3

__low_power_mode_4

__low_power_mode_off_on_exit

_BIC_SR

_BIC_SR_IRQ

_BIS_SR

_BIS_SR_IRQ

LPM0

LPM0_bits

LPM0_EXIT

LPM1

LPM1_bits

LPM1_EXIT

LPM2

LPM2_bits

LPM2_EXIT

LPM3

LPM3_bits

LPM3_EXIT

LPM4

LPM4_bits

LPM4_EXIT

... ...

Do they know that some of them are identical to each other, while some others are only almost identical? Do they know that LPMx_bits include not only low power bits? What a mess.

  • Hello old_cow_yellow,

    I agree with you that these header definitions are not easy to understand (at least not without inspecting the header files) and are partially redundant. From a C-perspective, I see four different categories (Note: I'm only discussing the syntax used in IAR Embedded Workbench for MSP430 and TI's Code Composer Studio, since these are the two main platforms we release collateral for):

    1. Real intrinsic functions, using a single-leading underscore WRITTEN IN ALL CAPS notation such as  _NOP() and _BIC_SR() [*N]
    2. Real intrinsic functions, using double leading underscores and spelled-out lowercase notation such as __bis_SR_register() and __bic_SR_register_on_exit() [:Y]
    3. Macros that define a set of status-register bits to enter or exit a TI-defined low-power mode, such as LPM3_bits, LPM0_bits [:Y]
    4. Various convenience macros that combine the intrinsics (1 or 2) with the LPM-definitions (3), such as LPM3 or LPM4_EXIT [*N]

    What I'm actually trying to do for a while already is to promote internally that we don't use any of the intrinsics as described under 1 since these intrinsics are considered depreciated. Instead, use only the ones that follow the scheme as shown under (2). It is not easy to root them out everywhere, but if you check recent collateral (code examples, app notes, etc.) released by MSP430 you should see the new-style intrinsics (2) used consistently.

    Regarding (4), I would discourage the use of such definitions since they bring an arbitrary and I think unnecessary level of abstraction that one needs to reverse-engineer first. To properly use the MSP430, it is very important to understand the scheme of how low-power modes are entered, where the necessary bits are (status register, or on the stack), and how they are manipulated. So I think it's good to explicitly code things like __bis_SR_register(LPM3_bits). And of course anyone is free to add their own abstraction-macros specific to their needs.

    Thanks and Regards,
    Andreas

  • I went through a similar process earlier this year from the C++ perspective. As Andre suggested, I utilize only the double underscore intrinsics.

    One of the issues (probably the major issue for me) is that the compiler has assumed responsibility for avoiding whatever errata it can. For instance, the latest msp430f543x errata sheet lists 68 separate items. Some errata have the comment 'The compiler will not generate..." in their respective workarounds.

    My assumption and expectation is that the compiler will generate errata workarounds in all known cases, especially in the intrinsics.  I'm sure the compiler vendors have similar expectations of their users; one of which is to incorporate the latest intrinsics, etc.

    Thanks for the thought provoking post.

     

     

**Attention** This is a public forum