ULP Advisor > Rule 3.1 Use ISRs instead of flag polling

ULPAdvisorBanner.PNG

ULP Advisor - Rule Table

ULP 1.1 Ensure LPM usage
ULP 2.1 Leverage timer module for delay loops
ULP 3.1 Use ISRs instead of flag polling
ULP 4.1 Terminate unused GPIOs
ULP 5.1 Avoid processing-intensive operations: modulo, divide.
ULP 5.2 Avoid processing-intensive operations: floating point
ULP 5.3 Avoid processing-intensive operations: (s)printf()
ULP 6.1 Avoid multiplication on devices without hardware multiplier
ULP 6.2 Use MATHLIB for complex math operations
ULP 6.3 Use Low Energy Accelerator (LEA) software library
ULP 7.1 Use local instead of global variables where possible
ULP 8.1 Use 'static' & 'const' modifiers for local variables
ULP 9.1 Use pass by reference for large variables
ULP 10.1 Minimize function calls from within ISRs
ULP 11.1 Use lower bits for loop program control flow
ULP 11.2 Use lower bits for port bit-banging
ULP 12.1 Use DMA for large memcpy() calls
ULP 12.1b Use DMA for potentially large memcpy() calls
ULP 12.2 Use DMA for repetitive transfer
ULP 13.1 Count down in loops
ULP 14.1 Use unsigned variables for indexing
ULP 15.1 Use bit-masks instead of bit-fields

Let us know what you think! Feedback, suggestions & comments
are welcome @ ULPAdvisorFeedback@list.ti.com

What it means

The MSP430 microcontroller achieves low power consumption by minimizing the time spent in active mode and maximizing the time in low power modes. Peripherals can be configured to operate without CPU intervention and the CPU only needs to wake up to process critical task and quickly return to low power mode. Rather than waiting and periodically polling a flag, MSP430 microcontrollers can enable the CPU to enter a low power mode and leverage one of the integrated peripherals to wake up the CPU. By using low power modes and MSP430 microcontroller's intelligent peripherals, applications can turn off the CPU when it is not needed, only waking up when more intensive tasks are required.

Risks, Severity

Constantly polling a status flag will keep the application in active mode, which will greatly increase power consumption and reduce battery lifetime.

Why it is happening

This remark is issued when ULP Advisor detects empty loops that do flag polling:

 while (!(TA1CTL & TAIFG));
 // or 
 while (!(ADC12IFG & ADC12IFG0));
 // or
 while (ADC12CTL1 & ADC12BUSY);

Remedy

Code Example

 //******************************************************************************
 //  MSP430G2x33/G2x53 Demo - ADC10, Sample A1, AVcc Ref, Set P1.0 if > 0.5*AVcc
 //
 //  Description: A single sample is made on A1 with reference to AVcc.
 //  Software sets ADC10SC to start sample and conversion - ADC10SC
 //  automatically cleared at EOC. ADC10 internal oscillator times sample (16x)
 //  and conversion. In Mainloop MSP430 waits in LPM0 to save power until ADC10
 //  conversion complete, ADC10_ISR will force exit from LPM0 in Mainloop on
 //  reti. If A1 > 0.5*AVcc, P1.0 set, else reset.
 //
 //                MSP430G2x33/G2x53
 //             -----------------
 //         /|\|              XIN|-
 //          | |                 |
 //          --|RST          XOUT|-
 //            |                 |
 //        >---|P1.1/A1      P1.0|-->LED
 //
 //  D. Dang
 //  Texas Instruments Inc.
 //  December 2010
 //   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
 //******************************************************************************
 #include "msp430g2553.h"
 
 void main(void)
 {
   WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
   ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled
   ADC10CTL1 = INCH_1;                       // input A1
   ADC10AE0 |= 0x02;                         // PA.1 ADC option select
   P1DIR |= 0x01;                            // Set P1.0 to output direction
 
   for (;;)
   {
     ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
     __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
     if (ADC10MEM < 0x1FF)
       P1OUT &= ~0x01;                       // Clear P1.0 LED off
     else
       P1OUT |= 0x01;                        // Set P1.0 LED on
   }
 }
 
 // ADC10 interrupt service routine  
 #pragma vector=ADC10_VECTOR
 __interrupt void ADC10_ISR(void)
 {
   __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
 }

See the rest of the code examples for all MSP430 devices here!

More Resources

Want to squeeze a few more nanoAmps out of your application? Leverage the e2e (Engineer-to-Engineer) online community to get all of your ULP questions answered! Or, if you are an Ultra-Low Power pro, give back to the community with your expertise.

Go to MSP430's e2e online forum! 

If you are posting on the forums in relation to this rule, try using the tag "ULP_3.1"

E2e.jpg For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Compiler/diagnostic messages/MSP430/1528 here.