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.

MSPM0G3507: Read pin status does not work properly after calling DL_SYSCTL_releaseShutdownIO()

Part Number: MSPM0G3507


In example code below, I configured 2 pins to wake up MSPM0G3 from shutdown mode if the pin logic value is high (GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_PIN, GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_PIN).

I need to read pin value after waking up to identify the wake up cause and turn on the leds.

I run example code and observed behavior as below.

If I send PRESSURE_SWITCH signal to wake up MSPM0G3, MSPM0G3 wake up but RED led is not turned on. It seems that DL_GPIO_readPins() not return high value (I still keep PRESSURE_SWITCH signal high).

If I send CURRENT_OVERLOAD signal to wake up MSPM0G3, MSPM0G3 wake up and GREEN led is turned on. In this case, it work properly.

I think that RED led is not turned on because I read pin value immediately after DL_SYSCTL_releaseShutdownIO(). Is it correct?

Do we need to add delay after releasing IO (DL_SYSCTL_releaseShutdownIO())?

How much time do we need to delay?

int main(void)
{
    volatile DL_SYSCTL_RESET_CAUSE rstCause;

    SYSCFG_DL_init();

    rstCause = DL_SYSCTL_getResetCause();
	if (DL_SYSCTL_RESET_CAUSE_BOR_WAKE_FROM_SHUTDOWN == rstCause)
    {
        /* Release IO after Shutdown before initializing any peripherals */
        DL_SYSCTL_releaseShutdownIO();

        if (DL_GPIO_readPins(GPIO_PRESSURE_SWITCH_PORT, GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_PIN))
        {
            DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
            delayMs(2000);
        }
        else if (DL_GPIO_readPins(GPIO_CURRENT_OVERLOAD_PORT, GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_PIN))
        {
            DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
            delayMs(2000);
        }
    }

   /*
    * Configure Shutdown wake-up pin to wake-up when pin is set
    * to high before changing power policy to SHUTDOWN
    */
    DL_GPIO_initDigitalInputFeatures(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX,
                                     DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                                     DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_1);
    
    DL_GPIO_initDigitalInputFeatures(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX,
                                     DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                                     DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_1);

    DL_SYSCTL_setPowerPolicySHUTDOWN();


    while (1)
    {
        __WFI(); /* Enter selected power policy */
    }

}

  • Hi Dang,

    If I send PRESSURE_SWITCH signal to wake up MSPM0G3, MSPM0G3 wake up but RED led is not turned on. It seems that DL_GPIO_readPins() not return high value (I still keep PRESSURE_SWITCH signal high).

    Can you make sure that after send PRESSURE_SWITCH signal, device is correctly waked up from SHUTDOWN MODE? There is no sign for it. I suggest you set another GPIO to sign it after DL_SYSCTL_releaseShutdownIO().

    I think that RED led is not turned on because I read pin value immediately after DL_SYSCTL_releaseShutdownIO(). Is it correct?

    Do we need to add delay after releasing IO (DL_SYSCTL_releaseShutdownIO())?

    I don't think there is some limits for this. I suggest you add some delay and check, usually set several cycles is enough. To test I suggest you set 1us, and if it works please let me aware. 

    B.R.

    Sal

  • Hi Sal Ye,

    Can you make sure that after send PRESSURE_SWITCH signal, device is correctly waked up from SHUTDOWN MODE? There is no sign for it. I suggest you set another GPIO to sign it after DL_SYSCTL_releaseShutdownIO().

    I added code to blink BLUE led before go to shutdown mode to confirm device waked up and shutdowned.

        DL_GPIO_initDigitalInputFeatures(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX,
                                         DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                                         DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_1);
        
        DL_GPIO_initDigitalInputFeatures(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX,
                                         DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                                         DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_1);
    
        DL_SYSCTL_setPowerPolicySHUTDOWN();
    
        DL_GPIO_setPins(User_Led_PORT, User_Led_PIN_B_LED_PIN);
        delayMs(500);
        DL_GPIO_clearPins(User_Led_PORT, User_Led_PIN_B_LED_PIN);
    
        while (1)
        {
            __WFI(); /* Enter selected power policy */
        }

    I observed result as below

    If I send PRESSURE_SWITCH signal to wake up MSPM0G3, RED led is not turned on, BLUE led is turned on then turned off (device waked up, read signal incorrectly).

    If I send CURRENT_OVERLOAD signal to wake up MSPM0G3, GREEN led is turned on, BLUE led is turned on then turned off (device waked up, read signal correctly).

    I don't think there is some limits for this. I suggest you add some delay and check, usually set several cycles is enough. To test I suggest you set 1us, and if it works please let me aware.

    I added some delays using delay_cycles() function after calling DL_SYSCTL_releaseShutdownIO(), the result as below.

    No delay --> not work properly (RED led is not turned on when device wake up, GREEN led is turned on when device wake up).
    
    5 cycles --> work properly (RED led is turned on when device wake up,GREEN led is turned on when device wake up).
    
    10 cycles --> work properly (RED led is turned on when device wake up, GREEN led is turned on when device wake up).

  • Hi Dang,

    Thanks for your feedback of the test result. According to them, there is neccessary to add several cycles delay before IO operation.

    Currently I think you can add some delay for the workaround.Anything else you can reply here and file a new thread.

    I will also do the test and confirm with our system team, and then we might update some notes in the TRM. If there are other conclusions, I will update here.

    Thanks!

    Sal

  • Hi Dang,

    I have done some test and find the contrary result to your conclusion.

    I added some delays using delay_cycles() function after calling DL_SYSCTL_releaseShutdownIO(), the result as below.

    The delay cycles does not work. Before reading the IO status, when I disable the wakeup function and then it works.

    Below code does not work: [GPIO_SWITCH_USER_SWITCH_1_PIN is the wake up pin and logic 1 wake the device]

        if (DL_SYSCTL_RESET_CAUSE_BOR_WAKE_FROM_SHUTDOWN == rstCause)
        /* Device was woken up from a SHUTDOWN state from this GPIO pin */
        {
            /* Release IO after Shutdown before initializing any peripherals */
            SYSCFG_DL_GPIO_init();
    
            DL_SYSCTL_releaseShutdownIO();
    //        DL_GPIO_disableWakeUp(GPIO_SWITCH_USER_SWITCH_1_IOMUX);
            delay_cycles(1000);
    
            if(DL_GPIO_readPins(GPIO_SWITCH_PORT, GPIO_SWITCH_USER_SWITCH_1_PIN)) {
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            }

    Below code works, LED1 lighting: [GPIO_SWITCH_USER_SWITCH_1_PIN is the wake up pin and logic 1 wake the device]

        if (DL_SYSCTL_RESET_CAUSE_BOR_WAKE_FROM_SHUTDOWN == rstCause)
        /* Device was woken up from a SHUTDOWN state from this GPIO pin */
        {
            /* Release IO after Shutdown before initializing any peripherals */
            SYSCFG_DL_GPIO_init();
    
            DL_SYSCTL_releaseShutdownIO();
            DL_GPIO_disableWakeUp(GPIO_SWITCH_USER_SWITCH_1_IOMUX);
    //        delay_cycles(1000);
    
            if(DL_GPIO_readPins(GPIO_SWITCH_PORT, GPIO_SWITCH_USER_SWITCH_1_PIN)) {
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            }

    Moreover, there is a register to help you check which pin is the wakeup pin.

    Looking forward to your feedback. 

    B.R.

    Sal

  • Hi Sal,

    I tested the code again. The delay cycle still works. I'm not sure what is the difference with your environment.

    I use LP-MSPM0G3507 board, I connect two buttons to simulate 2 wake up signals as below circuit diagram.

    Button circuit

    In my source code, I do not call SYSCFG_DL_GPIO_init() because it is already called at begining of main() function in SYSCFG_DL_init().

    I upload my example project code for reference. Please check and feedback.

    HK_Inflator.zip

  • Hi Dang,

    Thanks for your feedback, I will check it later.

    B.R.

    Sal

  • Hi Sal,

    I recorded video for reference. Please refer link below.

    LP-MSPM0G3507 low power SHUTDOWN test

  • Hi Dang,

    Got it, I will use your code and do some test.

    Currently you can use delay for the workaround. And I am going to figure out what happens here and then update to you.

    B.R.

    Sal

  • Hi Sal,

    Moreover, there is a register to help you check which pin is the wakeup pin.

    I try to use Wake State bit by calling DL_GPIO_isWakeStateGenerated(), but it also doesn't work.

        rstCause = DL_SYSCTL_getResetCause();
    	if (DL_SYSCTL_RESET_CAUSE_BOR_WAKE_FROM_SHUTDOWN == rstCause)
        {
            /* Release IO after Shutdown before initializing any peripherals */
            DL_SYSCTL_releaseShutdownIO();
    
            if (DL_GPIO_isWakeStateGenerated(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX))
            {
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
            }
    
            if (DL_GPIO_isWakeStateGenerated(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX))
            {
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
            }
        }

    both GREEN and RED led do not blink.

  • Hi Dang,

    I haven't test your previous code, but test the behavior you newly mentioned and it works normal.

    I try to use Wake State bit by calling DL_GPIO_isWakeStateGenerated(), but it also doesn't work.

    I think what you miss is that at lease you should call DL_GPIO_disableWakeUp(uint32_t pincmIndex) once before you enter SHUTDOWN mode.

    Below is my test code, can you try it on MSPM0G3507 LaunchPad. After loading the firmware, you can press the S1, and then it will lighting blue LED twice and then lighting the red LED. If you press the S3 (NRST), and then it will only lighting the red LED.

    TestDeom_5F00_E2E_5F00_SHUTDOWN_5F00_IOIssue.zip

    B.R.

    Sal

  • Hi Sal,

    I'm able to run your test code with CCS (I use CSS Theia version). It worked as you described.

    I fixed my test code with DL_GPIO_disableWakeUp(). I find out that it works well with single wake up source but does not work with multiple wake up sources.

    Below code works with single wake up source, RED led blinks.

            if (DL_GPIO_isWakeStateGenerated(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX))
            {
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
            }
            DL_GPIO_disableWakeUp(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX);
    
            // if (DL_GPIO_isWakeStateGenerated(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX))
            // {
            //     DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
            //     delayMs(1000);
            //     DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
            //     delayMs(1000);
            //     DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
            //     delayMs(1000);
            // }
            // DL_GPIO_disableWakeUp(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX);

    Below code does not work with multiple wake up sources, both GREEN and RED led do not blink.

            if (DL_GPIO_isWakeStateGenerated(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX))
            {
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_R_LED_PIN);
                delayMs(1000);
            }
            DL_GPIO_disableWakeUp(GPIO_PRESSURE_SWITCH_PRESSURE_SWITCH_IOMUX);
    
            if (DL_GPIO_isWakeStateGenerated(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX))
            {
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
                DL_GPIO_togglePins(User_Led_PORT, User_Led_PIN_G_LED_PIN);
                delayMs(1000);
            }
            DL_GPIO_disableWakeUp(GPIO_CURRENT_OVERLOAD_CURRENT_OVERLOAD_IOMUX);

  • Hi Dang,

    OK, I see. I will do the test and check what will happen.

    B.R.

    Sal

  • Hi Dang,

    I think maybe other related configuration of your project is incorrect.

    I test it work normal with multi wake up source.

    Below is the test code:

    #include "ti_msp_dl_config.h"
    
    int main(void)
    {
        volatile DL_SYSCTL_RESET_CAUSE rstCause;
        uint8_t counter;
        uint8_t blink;
    
        /*
         * Initialize GPIOs after reset, or re-initialize after waking-up from
         * SHUTDOWN.
         *
         * GPIOs will retain their last state prior to entry into SHUTDOWN and
         * they need to be re-configured before releasing them by calling
         * DL_SYSCTL_enableShutdownIORelease
         */
        SYSCFG_DL_init();
    
        rstCause = DL_SYSCTL_getResetCause();
    
        if (DL_SYSCTL_RESET_CAUSE_BOR_WAKE_FROM_SHUTDOWN == rstCause)
        /* Device was woken up from a SHUTDOWN state from this GPIO pin */
        {
            /* Release IO after Shutdown before initializing any peripherals */
    //        SYSCFG_DL_GPIO_init();
            DL_SYSCTL_releaseShutdownIO();
    //        DL_GPIO_disableWakeUp(GPIO_SWITCH_USER_SWITCH_1_IOMUX);     /* If comment out this code, PIN read value is wrong */
    //        if(DL_GPIO_readPins(GPIO_SWITCH_PORT, GPIO_SWITCH_USER_SWITCH_1_PIN)) {
            if(DL_GPIO_isWakeStateGenerated(GPIO_SWITCH_USER_SWITCH_1_IOMUX)) {
    
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
            }
    
            if(DL_GPIO_isWakeStateGenerated(GPIO_SWITCH_USER_SWITCH_2_IOMUX)) {
    
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
                delay_cycles(16000000);
            }
    
            DL_GPIO_disableWakeUp(GPIO_SWITCH_USER_SWITCH_1_IOMUX);
            DL_GPIO_disableWakeUp(GPIO_SWITCH_USER_SWITCH_2_IOMUX);
    
    
            /* Load save state after wake from SHUTDNSTORE */
            counter = 1 + DL_SYSCTL_getShutdownStorageByte(
                              DL_SYSCTL_SHUTDOWN_STORAGE_BYTE_0);
    
            /* Blink LED a number of times equal to counter */
            for (blink = 0; blink < (2 * counter); blink++) {
                DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_2_PIN);
                delay_cycles(16000000);
            }
    
    //        DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        } else
        /* Device was NOT woken up from a SHUTDOWN state from this GPIO pin */
        {
            counter = 0;
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            delay_cycles(16000000);
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            delay_cycles(16000000);
        }
    
    
            DL_GPIO_initDigitalInputFeatures(GPIO_SWITCH_USER_SWITCH_1_IOMUX,
                DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_1);
    
            DL_GPIO_initDigitalInputFeatures(GPIO_SWITCH_USER_SWITCH_2_IOMUX,
                DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_ON_0);
    
            DL_SYSCTL_setPowerPolicySHUTDOWN();
    
    
        /* Save application state before shutdown using SHUTDNSTORE */
        DL_SYSCTL_setShutdownStorageByte(
            DL_SYSCTL_SHUTDOWN_STORAGE_BYTE_0, counter);
    
        while (1) {
            __WFI(); /* Enter selected power policy */
        }
    }

    Attached the project for your reference:testdemo.zip

    And you can test it on your LaunchPad, you should connect PA31 with J19-1 (closed to R13/R18) to set PA31 pull-up to 3.3V.

    And then if you connect the PA31 to GND, then blue LED will light once and then red LED light. If you press S1 button, then blue LED will light twice and then red LED light.

    B.R.

    Sal