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.

RTOS/MSP432P401R: Looking for examples and design help

Part Number: MSP432P401R

Tool/software: TI-RTOS

I need the MSP432 to wake up periodically from an internal timer and from I2C requests (MSP432 as I2C slave on two separate busses).

At the same time I need to minimize power consumption. From reading the TRM, it can wake up automatically from I2C requests in from LPM0?

But, I believe LPM3 would consume much less power. I would have to use the RTC for the internal wakeups and I could add interrupt lines from the two I2C masters to wake up the MSP432 when they want to request I2C data. This would be a little more complicated. Or maybe the best choice would be to use low-frequency LPM0 and ramp up the frequency on wakeup?

Could you give me some power consumption estimates for these three choices?

Also, I am looking for some simple examples that show how to get into these modes.

I ran the provided deepsleep example, but can't get it out of sleep. I added a GPIO button interrupt where I toggle an LED, but it will only trigger once.

The sleep example uses ~2.6mA, which is too much, so I want to try the low-frequency LPM0, but not sure how to get it there.

Thanks.

  • I tried modifying the powerdeepsleep example to toggle between the deepsleep and 'regular' sleep policies. I can initially get it into deepsleep and then out again, but then it will never go into deepsleep again.

    main_tirtos.c (added second thread)

    /*
     *  ======== main_tirtos.c ========
     */
    #include <stdint.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    
    /* RTOS header files */
    #include <ti/sysbios/BIOS.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    extern void *deepSleepThread(void *arg0);
    extern void *sleepThread(void *arg0);
    
    /* Stack size in bytes */
    #define THREADSTACKSIZE    1024
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        pthread_t           thread;
        pthread_attr_t      pAttrs;
        struct sched_param  priParam;
        int                 retc;
        int                 detachState;
    
        /* Call driver init functions */
        Board_initGeneral();
        Board_initGPIO();
    
        /* Set priority and stack size attributes */
        pthread_attr_init(&pAttrs);
        priParam.sched_priority = 1;
    
        detachState = PTHREAD_CREATE_DETACHED;
        retc = pthread_attr_setdetachstate(&pAttrs, detachState);
        if (retc != 0) {
            /* pthread_attr_setdetachstate() failed */
            while (1);
        }
    
        pthread_attr_setschedparam(&pAttrs, &priParam);
    
        retc |= pthread_attr_setstacksize(&pAttrs, THREADSTACKSIZE);
        if (retc != 0) {
            /* pthread_attr_setstacksize() failed */
            while (1);
        }
    
        retc = pthread_create(&thread, &pAttrs, sleepThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1);
        }
    
        retc = pthread_create(&thread, &pAttrs, deepSleepThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1);
        }
    
        BIOS_start();
    
        return (0);
    }

    powersleep.c

    /*
     *  ======== powersleep.c ========
     */
    
    /* Driver Header files */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Board Header file */
    #include "Board.h"
    
    /*
     *  ======== gpioButtonFxn0 ========
     *  Callback function for the GPIO interrupt on Board_GPIO_BUTTON0.
     */
    
    void gpioButtonFxn1(uint_least8_t x)
    {
        GPIO_clearInt(Board_GPIO_BUTTON1);
    
        GPIO_toggle(Board_GPIO_LED1);
    
        Power_setPolicy((Power_PolicyFxn)PowerMSP432_sleepPolicy);
    }
    
    /*
     *  ======== sleepThread ========
     */
    void *sleepThread(void *arg0)
    {
        GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_ON);
    
        GPIO_setCallback(Board_GPIO_BUTTON1, gpioButtonFxn1);
        GPIO_enableInt(Board_GPIO_BUTTON1);
    
        return NULL;
    }

    powerdeepsleep.c

    /*
     *  ======== powerdeepsleep.c ========
     */
    
    /* Driver Header files */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Board Header file */
    #include "Board.h"
    
    /*
     *  ======== gpioButtonFxn0 ========
     *  Callback function for the GPIO interrupt on Board_GPIO_BUTTON0.
     */
    
    void gpioButtonFxn0(uint_least8_t x)
    {
        GPIO_clearInt(Board_GPIO_BUTTON0);
    
        //GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
        //GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
        GPIO_toggle(Board_GPIO_LED0);
    
        /* Select PowerMSP432_deepSleepPolicy to enable transition
         * into the PowerMSP432_DEEPSLEEP_1 (LPM4)state
         */
        Power_setPolicy((Power_PolicyFxn)PowerMSP432_deepSleepPolicy);
    
        /* Refer to Device datasheet for Wake-up Sources From Low Power Modes to wake up from
         * PowerMSP432_DEEPSLEEP_1
         */
    }
    
    /*
     *  ======== deepSleepThread ========
     */
    void *deepSleepThread(void *arg0)
    {
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        GPIO_setCallback(Board_GPIO_BUTTON0, gpioButtonFxn0);
        GPIO_enableInt(Board_GPIO_BUTTON0);
    
        return NULL;
    }

    In 'free run', it seems to only go into gpioButtonFxn0() on the very first button0 press. Subsequent button0 presses don't toggle the led and so it never enters deepsleep again. But, if I insert a breakpoint in that function, it does go there and toggles the led. button1 works as expected and toggles the led.

    Thanks.

  • Hello,
    I will start looking at this. I did not see a version number for the MSP432 or the TI_RTOS. If you could let me know then that would be helpful.

    Regards,
    Chris
  • Ferdster,


    Please refer to the files attached. This is an LPM3 example that wakes up with RTC. Notice that attached is a release.cfg file. This file is apart of the tirtos kernal project that you have in CCS. In order to enable the RTC, in the powerdeepsleep project, under main_tirtos.c, you will notice that the RTC_C_IRQHandler calls Clock_tick();. This calls the Clock configuration in the release.cfg where you can specify that user defines the clock tick source and period. To open release.cfg, right click it, click open with, and click XDCscript Editor.


    In powerdeepsleep.c, you will notice that the line: Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1); prevents TIRTOS from entering LPM4 in the power policy, effectively causing TIRTOS to automatically send the device to LPM3 upon idle. Please let me know if you need any more descriptions or have any questions.

    LPM3RTC.zip

  • Ferdster,

    I should also comment that we are working on provided more training content on RTOS's and managing power policies and other things soon. This will definitely be something we will more specifically focus on in the future :)
  • Hi Evan,

    Thanks for the example. I have a couple questions.

    1. The release.cfg file has the parameter 'Clock.tickPeriod' that was set to 2000us in your example. What is this? Changing it to a really large value like 25000000us (25ms) doesn't seem to affect anything - the interrupt handler still gets called every 2ms.

    2. Is the longest possible period 8ms (MAP_RTC_C_definePrescaleEvent(RTC_C_PRESCALE_0, RTC_C_PSEVENTDIVIDER_256);)? What if I wanted to wake up every 90 seconds, would I need to do that using my own counter?

    3. I measured the current and it's 0.236mA, which is still way too high This is with all jumpers removed, powered by an external 3.3V psu.

    4. LPM3 also supports gpio interrupts. What needs to be added to make BUTTON0 work from LPM3?

    Thanks.

  • Ferdster,


    Wanted to let you know that I will look into your follow up questions but have been out of town on international travel and just now catching up on my forum questions.

    Will reply back as soon as possible :)

  • Hi Ferdster,

    Again thanks for the patience.

    1) With the default release.cfg, your clock configuration is set to 1000us (1ms) by default. When you call sleep(1); in code, you are asking the device to sleep for 1 second. Therefore 1000ms/1ms = 1000 ticks need to occur before RTOS knows it needs to wake up. The source by default is not the RTC, but the TimerA as you have seen.

    When we change it to our RTC and use an interrupt interval for the RTC to be 2ms, we need to adjust the clock ticks needed to ensure that our device stays asleep for 1 second as expected. Therefore, if you change the RTC to 2ms, you need 2000 ticks to ensure that sleep(1); still stays asleep for 1 second.

    If you want to change your clock ticks to reflect 25ms, you need to adjust the interrupt for the RTC to wake up every 25ms as well.

    2) With this, you should look into section 18.2.6 of the MSP432 TRM (slau356). Here it explains that RT0PSIFG and RT1PSIFG are used in conjunction to create larger interrupt intervals. In this case, you would set up RT0PS to source the RT1PS and adjust the prescalers to your desired length and set the RT1PSIE as enabled instead of the RT0PSIE in the function call 'MAP_RTC_C_enableInterrupt(RTC_C_PRESCALE_TIMER1_INTERRUPT);

    3) Are you performing your measurement with the code I sent you or your own project? Are you making sure you terminate all GPIOs? What hardware are you using, the LaunchPad?

    4) In the example that I sent attached in my first reply, in 'powerdeepsleep.c', I have set the callback function and enabled the interrupt in the *mainThread code.

    The callback function is "gpioButtonFxn0" and basically wakes up, clears the interrupt, clears the LED that was set before entering the while(1) and then goes back to sleep. This code could be changed to just toggle the LED if you wanted. Does this suffice?
  • Closing this thread due to inactivity. if you have another question related to this topic, feel free to ask and it will reopen, otherwise, please post any new questions in a new thread! Thanks!

**Attention** This is a public forum