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.
Tool/software:
Hi,
I have 2 questions.
1)
I am using the Ti sample (sysctl_power_policy_sleep_to_stop) to change RunSleep0 to Stop2 and vice versa.
However, SYSOSC cannot be enabled after the power policy is changed from Stop2 to RunSleep0. (the return value of DL_SYSCTL_getPowerPolicyRUNSLEEP() is RunSleep3)
I also tested Stop0/1→RunSleep0, Standby0/1→RunSleep0, and all were normal. (the return value of DL_SYSCTL_getPowerPolicyRUNSLEEP() is RunSleep0)
/* * Copyright (c) 2021, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ti_msp_dl_config.h" #define MNG_IntrSysTick SysTick_Handler volatile bool gTogglePolicy; int main(void) { SYSCFG_DL_init(); gTogglePolicy = false; NVIC_EnableIRQ(SW_INT_IRQN); DL_SYSCTL_POWER_POLICY_RUN_SLEEP runsleep; DL_SYSCTL_POWER_POLICY_STOP stop; DL_SYSCTL_POWER_POLICY_STANDBY standby; while (1) { gTogglePolicy = false; runsleep = DL_SYSCTL_getPowerPolicyRUNSLEEP(); stop = DL_SYSCTL_getPowerPolicySTOP(); standby = DL_SYSCTL_getPowerPolicySTANDBY(); DL_SYSCTL_setPowerPolicySTOP2(); //DL_SYSCTL_setPowerPolicySTANDBY0(); while (false == gTogglePolicy) { __WFI(); } gTogglePolicy = false; runsleep = DL_SYSCTL_getPowerPolicyRUNSLEEP(); stop = DL_SYSCTL_getPowerPolicySTOP(); standby = DL_SYSCTL_getPowerPolicySTANDBY(); DL_SYSCTL_setPowerPolicyRUN0SLEEP0(); } } void GROUP1_IRQHandler(void) { switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) { case SW_INT_IIDX: gTogglePolicy = true; break; default: break; } } void MNG_IntrSysTick(void) { }
Hi,
1.We will have a test, thanks. One question: how do you judge whether the SYSOSC is disable or enable?
2.Systick is not available in stop and standby mode.
Regards,
Zoey
Hi,
1) I just had a quick test by checking whether DISABLESTOP is set or not in SOCLOCK.SYSOSCCFG.
2)
> Systick is not available in stop and standby mode.
I think so too. However, it actually does.
My question is, do I have to manually stop the Systick, or will the MCU automatically stop it when entering stop/standby mode by setting something?
You can reproduce it using my example.
For question 2: The MCU will automatically stop it as it enter into low power mode.
Regards,
Zoey
Could you use my code sample attached above to check if the Systick actually stops when entering stop/standby mode?
Here is my environment:
- mspm0l2228 launchpad development kit
- XDS110 USB Debug Probe
- CCS Composer Studio Theia
- sysconfig (I couldn't attach the *.sysconf file so I added ".c" to the file extension)
/** * These arguments were used when this file was generated. They will be automatically applied on subsequent loads * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. * @cliArgs --device "MSPM0L222X" --package "LQFP-80(PN)" --part "Default" --product "mspm0_sdk@2.01.00.03" * @versions {"tool":"1.19.0+3426"} */ /** * Import the modules used in this configuration. */ const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false); const GPIO1 = GPIO.addInstance(); const GPIO2 = GPIO.addInstance(); const GPIO3 = GPIO.addInstance(); const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL"); const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK"); /** * Write custom configuration values to the imported modules. */ GPIO1.port = "PORTA"; GPIO1.$name = "GPIO_LEDS1"; GPIO1.associatedPins[0].$name = "USER_LED_1"; GPIO1.associatedPins[0].assignedPin = "0"; GPIO1.associatedPins[0].initialValue = "SET"; GPIO1.associatedPins[0].pin.$assign = "PA0"; const Board = scripting.addModule("/ti/driverlib/Board", {}, false); Board.configureUnused = true; GPIO2.$name = "GPIO_LEDS2"; GPIO2.port = "PORTB"; GPIO2.associatedPins[0].$name = "USER_LED_2"; GPIO2.associatedPins[0].assignedPin = "10"; GPIO3.$name = "SW"; GPIO3.associatedPins[0].$name = "SWPA18"; GPIO3.associatedPins[0].direction = "INPUT"; GPIO3.associatedPins[0].fastWakeEn = true; GPIO3.associatedPins[0].assignedPort = "PORTA"; GPIO3.associatedPins[0].assignedPin = "18"; GPIO3.associatedPins[0].interruptEn = true; GPIO3.associatedPins[0].polarity = "RISE"; GPIO3.associatedPins[0].pin.$assign = "PA18"; SYSCTL.clockTreeEn = true; SYSTICK.periodEnable = true; SYSTICK.interruptEnable = true; SYSTICK.systickEnable = true; SYSTICK.period = 16000000; /** * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to * re-solve from scratch. */ Board.peripheral.$suggestSolution = "DEBUGSS"; Board.peripheral.swclkPin.$suggestSolution = "PA20"; Board.peripheral.swdioPin.$suggestSolution = "PA19"; GPIO2.associatedPins[0].pin.$suggestSolution = "PB10";
Hi,
I also attach my test result of the 2th issue (systick).
Here is in Stop2 mode
and in Standby1 mode
Hi,
Sorry I am quite busy this week. I will have a test next week. Thanks for your understanding and code.
Regards,
Zoey
Hi Zoey Wei
The sysconf and source file has been updated. Please use it for your test case1(Stop2→RunSleep0) and case2(Systick)
In this sample, I use TimerG0 to wake up from low power mode, and Led1 is used to observe systick activity.
( I tried removing I2C and all UART settings in sysconf, and MCU stops systick as it enter into low power mode. )
sysctl_power_policy_sleep_to_standby.c
/* * Copyright (c) 2021, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ti_msp_dl_config.h" #include <sys/cdefs.h> #define MNG_IntrSysTick SysTick_Handler volatile bool gTogglePolicy; volatile DL_SYSCTL_POWER_POLICY_RUN_SLEEP runsleep; volatile DL_SYSCTL_POWER_POLICY_STOP stop; volatile DL_SYSCTL_POWER_POLICY_STANDBY standby; volatile uint32_t count = 0; int main(void) { SYSCFG_DL_init(); gTogglePolicy = false; NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); DL_TimerG_startCounter(TIMER_0_INST); while (1) { gTogglePolicy = false; runsleep = DL_SYSCTL_getPowerPolicyRUNSLEEP(); stop = DL_SYSCTL_getPowerPolicySTOP(); standby = DL_SYSCTL_getPowerPolicySTANDBY(); DL_SYSCTL_setPowerPolicySTOP2(); //DL_SYSCTL_setPowerPolicySTANDBY1(); while (false == gTogglePolicy) { __WFI(); } gTogglePolicy = false; runsleep = DL_SYSCTL_getPowerPolicyRUNSLEEP(); stop = DL_SYSCTL_getPowerPolicySTOP(); standby = DL_SYSCTL_getPowerPolicySTANDBY(); DL_SYSCTL_setPowerPolicyRUN0SLEEP0(); for (uint8_t blink = 0; blink < 10; blink++) { delay_cycles(1600000); } } } void TIMER_0_INST_IRQHandler(void) { switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMERG_IIDX_ZERO: gTogglePolicy = true; break; default: break; } } void MNG_IntrSysTick(void) { count++; if (count == 32) { count = 0; DL_GPIO_togglePins(GPIO_LEDS1_PORT, GPIO_LEDS1_USER_LED_1_PIN); } }
sysctl_power_policy_sleep_to_standby.syscfg
/** * These arguments were used when this file was generated. They will be automatically applied on subsequent loads * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. * @cliArgs --device "MSPM0L222X" --package "LQFP-80(PN)" --part "Default" --product "mspm0_sdk@2.01.00.03" * @versions {"tool":"1.19.0+3426"} */ /** * Import the modules used in this configuration. */ const Board = scripting.addModule("/ti/driverlib/Board"); const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false); const GPIO1 = GPIO.addInstance(); const I2C = scripting.addModule("/ti/driverlib/I2C", {}, false); const I2C1 = I2C.addInstance(); const SYSCTL = scripting.addModule("/ti/driverlib/SYSCTL"); const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK"); const TIMER = scripting.addModule("/ti/driverlib/TIMER", {}, false); const TIMER1 = TIMER.addInstance(); const UART = scripting.addModule("/ti/driverlib/UART", {}, false); const UART1 = UART.addInstance(); const UART2 = UART.addInstance(); const UART3 = UART.addInstance(); const ProjectConfig = scripting.addModule("/ti/project_config/ProjectConfig"); /** * Write custom configuration values to the imported modules. */ GPIO1.$name = "GPIO_LEDS1"; GPIO1.associatedPins[0].assignedPort = "PORTB"; GPIO1.associatedPins[0].assignedPin = "10"; GPIO1.associatedPins[0].$name = "USER_LED_1"; I2C1.$name = "I2C_0"; I2C1.basicEnableController = true; I2C1.basicControllerStandardBusSpeed = "Fast"; I2C1.advAnalogGlitchFilter = "DISABLED"; I2C1.interruptPriority = "1"; I2C1.peripheral.$assign = "I2C0"; I2C1.peripheral.sdaPin.$assign = "PA8"; I2C1.peripheral.sclPin.$assign = "PA9"; I2C1.sdaPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric6"; I2C1.sclPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric7"; SYSCTL.clockTreeEn = true; SYSTICK.systickEnable = true; SYSTICK.interruptEnable = true; SYSTICK.periodEnable = true; SYSTICK.interruptPriority = "3"; SYSTICK.period = 32000; TIMER1.$name = "TIMER_0"; TIMER1.timerClkSrc = "LFCLK"; TIMER1.timerClkPrescale = 256; TIMER1.timerPeriod = "3000 ms"; TIMER1.interrupts = ["ZERO"]; TIMER1.interruptPriority = "1"; TIMER1.timerMode = "PERIODIC"; TIMER1.peripheral.$assign = "TIMG0"; UART1.$name = "UART_0"; UART1.enabledInterrupts = ["BREAK_ERROR","FRAMING_ERROR","OVERRUN_ERROR","RX","TX"]; UART1.interruptPriority = "1"; UART1.peripheral.$assign = "UART0"; UART1.peripheral.rxPin.$assign = "PA1"; UART1.peripheral.txPin.$assign = "PA0"; UART1.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric0"; UART1.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric1"; UART2.$name = "UART_1"; UART2.enabledInterrupts = ["BREAK_ERROR","FRAMING_ERROR","OVERRUN_ERROR","RX","TX"]; UART2.interruptPriority = "1"; UART2.peripheral.$assign = "UART1"; UART2.peripheral.rxPin.$assign = "PA18"; UART2.peripheral.txPin.$assign = "PA17"; UART2.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric2"; UART2.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric3"; UART3.$name = "UART_2"; UART3.targetBaudRate = 115200; UART3.enabledInterrupts = ["BREAK_ERROR","FRAMING_ERROR","OVERRUN_ERROR","RX","TX"]; UART3.interruptPriority = "2"; UART3.peripheral.$assign = "UART2"; UART3.peripheral.rxPin.$assign = "PA24"; UART3.peripheral.txPin.$assign = "PA23"; UART3.txPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric4"; UART3.rxPinConfig.$name = "ti_driverlib_gpio_GPIOPinGeneric5"; /** * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to * re-solve from scratch. */ Board.peripheral.$suggestSolution = "DEBUGSS"; Board.peripheral.swclkPin.$suggestSolution = "PA20"; Board.peripheral.swdioPin.$suggestSolution = "PA19"; GPIO1.associatedPins[0].pin.$suggestSolution = "PB10";
Thanks & Best Regards
Hi,
I have done the test about the SYSOSC and SYSTICK. Here is the demo code for your reference E2E_SYSOSC_SYSTIC_STOP2_L2228.zip
MCU will goes into stop2. And timer will wake up MCU every 1s, then toggle PA24 to see whether CLOCK is 32MHz(SYSOSC).
In low power mode, if SYSTICK works, PA22 will be toggled every 50ms. But it not, that means in stop2, SYSTICK is not working.
Regards,
Zoey
Thanks for your test and result.
Indeed, systick interrupt does not occur in your example.
But I edited your empty.syscfg by adding I2C, UART and systick works.
Could you test again with it?
Here is my test result.
Hi,
As uart and I2C has enabled Async Clock Request by default, which will stop MCU to enter into low power mode. Please refer to below picture.
Please try to add below code.Thanks
UART_0_INST->GPRCM.CLKCFG = 0xA9000100; UART_1_INST->GPRCM.CLKCFG = 0xA9000100; UART_2_INST->GPRCM.CLKCFG = 0xA9000100; I2C_0_INST->GPRCM.CLKCFG = 0xA9000100;
Regards,
Zoey
Hi Zoey Wei
Thanks for your support. Systick issue is resolved.
However, SYSOSC cannot be enabled after the power policy is changed from Stop2 to RunSleep0. (the return value of DL_SYSCTL_getPowerPolicyRUNSLEEP() is RunSleep3)
What about this issue, could you reproduce it?
As you can see, in demo code I give,
when timer interrupt is coming, MCU will be waken up to run0, and GPIO will be toggled. The toggled time can prove that the CPU is running 32MHz, which means SYSOSC is enabled.
When exits __WFI, the SYSOSC will automatically turn on even if the current power policy of RUNSLEEP is RUN_SLEEP_NOT_ENABLED, and power policy of STOP is STOP2, is it right?
If I want to change power policy from Stop2 to Run0, what should I do?. As described above, I do it by using DL_SYSCTL_setPowerPolicyRUN0SLEEP0(), but the return value of DL_SYSCTL_getPowerPolicyRUNSLEEP() is RunSleep3 instead of RunSleep0.
No
__WFI(); is to make MCU enter into low power mode. You can find detailed information in ARM official website.
DL_SYSCTL_setPowerPolicyRUN0SLEEP0(), is to set low power mode as sleep0 but not enable MCU go into low power mode immediately.
Thanks for your explanation.
In case, I want to go into Sleep0 from Stop2, what about the return value of DL_SYSCTL_getPowerPolicyRUNSLEEP() after DL_SYSCTL_setPowerPolicyRUN0SLEEP0() is called? My expectation is DL_SYSCTL_POWER_POLICY_RUN_SLEEP0, but in fact, it is DL_SYSCTL_POWER_POLICY_RUN_SLEEP2.
Hi Zoey Wei
I applied my application requirement into your sample, and systick operation is so strange.
I know you're busy, but could you please check the following requirement again? I also attached the edited code (.c and .syscfg)
Systick: InterruptPriority = Lowest, CalculatedPeriod = 1ms
Timer: InterruptPriority = Low, TimerClockPrescaler = 256, DesiredTimerPeriod = 10s
E2E_SYSOSC_SYSTIC_STOP2_L2228_edited.zip
Here is my test result
Thanks & Best Regards!
Hi,
It is because once your enter into timer interrupt, systick will work, and counite to count. Then MCU exits interrupt hander and goes in to low power mode, systick will stop working. But until next timer interrupt comming, systick will conuite to count. In this way, the SYSTIC will eventually count to 0 and trigger an interrupt.
Try to add reset systick function in timer. When exits from interrupt hander, systick will be reset and will not conuite to count next time.
void TIMER_0_INST_IRQHandler(void) { switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMERG_IIDX_ZERO: DL_GPIO_clearPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN); //delay_cycles(10000); DL_GPIO_setPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN); SysTick->LOAD = (uint32_t)(32000 - 1UL); break; default: break; } }
Hi Zoey Wei
I tried to add reset systick function in timer, but it doesn't solve the problem.
Moreover, I have 2 questions.
1) Since the Systick interrupt priority level is lower than the timer, if the Systick counts to 0 and triggers an interrupt, the MCU will return to sleep after completing the interrupt handler, causing the Systick to stop.
However, as you can see in the attached image, the systick seems to still be operating in Stop2 mode, even without a timer interrupt. Is there something other than the timer that could wake up the MCU from Stop2 mode in this case?
2) In syscfg, SYSCTL tab, I changed the LowPowerPolicy to STANDBY1, and this problem does not occur, even without resetting the systick in the timer.
According to what you said above, "when the timer comes, the MCU will be woken up to run0". So, what is the difference between Standby1 and Stop2 after wake-up that causes the Systick to behave differently?
Best Regards!
Hi,
what is the difference between Standby1 and Stop2 after wake-up that causes the Systick to behave differently?
Theoretically, Systick can not work in stop2 and standby1 mode. It seems odd in your test. I will do experiment both in L1228 and L1306.
Regards,
Zoey
Hi,
I have done the test and find out when you are in stop mode or standby mode which LFCLK is still enabled, the Systick will still work with LFCLK(32KHz)
Regrads,
Zoey
Hi Zoey Wei
I have done the test and find out when you are in stop mode or standby mode which LFCLK is still enabled
If I use Standby1 mode, LFCLK is auto-disabled, is it right?
For Stop2 mode, Could you teach me disable LFCLK.
By the way, please guide me on how to check if the LFCLK has been disabled or not.
Hi,
If I use Standby1 mode, LFCLK is auto-disabled, is it right?
Yes
For Stop2 mode, Could you teach me disable LFCLK
LFCLK can not be disabled.
By the way, please guide me on how to check if the LFCLK has been disabled or not
Please refer to below register.
Regards,
Zoey
Hi,
Also thanks for your detailed test and finding out this "bug" for our user guide and chip. I will give feedback to our design about SYSTICK odd action in stop mode and standby0
Regards,
Zoey