Hi
we are in the process of developing power Manager for our MCU SW for NXP - S32K146. The power manager uses the following three states.
RUN Mode
VPLR Mode
VPLS Mode
Furthermore, the following clock source options are being utilized.
FIRC
SIRC
During the start our clock source is FIRC, and the power mode is RUN Mode. Afterwards we are configuring SPLL. During this time, the MCU power mode is still RUN Mode. After the RUN Mode, when the MCU needs to go to VLPR -> VLPS Mode, we are doing the following steps:
Normal Operation:
During the VLPS mode an interrupt is received on PORTE for the monitored Pin with the flag value being true, first IRQ is disabled followed by a soft reset of MCU which resets the MCU and the operations starts again normally from the Startup.
We are facing the following issues and therefore would like your support to understand if we are doing anything incorrectly.
Issue: Sometimes randomly the MCU gets stuck to a state from where the only recovery is reset through Power off and Power on.
Our Assumptions: During the above state where MCU is stuck we assumed that the following scenarios might have occurred.
Hi @Sami2098
The steps described for RUN->VLPR->VLPS seem correct. Are you able to connect to the board once it goes into "halt" state? (By using the "Attach to target" option).
This issue may be caused by clock configuration. This is described in ERR011063 (from S32K146_0N73V
This only applies to routines which enter VLPS mode from VLPR mode, which in your case applies. Please try changing VCCR configuration.
Best regards,
Julián
Meanwhile we have also checked the clock frequencies using NXP API:
uint32_t sysClk = 0;
uint32_t busClk = 0;
/* Get System clock frequency */
CLOCK_SYS_GetFreq(CORE_CLOCK, &sysClk);
/* Get Bus clock frequency */
CLOCK_SYS_GetFreq(BUS_CLOCK, &busClk);
We received the following values in the RUN Mode:
CORE/System Clock: 8 MHz
BUS Clock: 4 MHz
We received the following values in the VLPR Mode:
CORE/System Clock: 4 MHz
BUS Clock: 4 MHz
These values were received after calling the NXP API to go from RUN mode to VLPR Mode:
POWER_SYS_SetMode(POWER_MANAGER_VLPR, POWER_MANAGER_POLICY_FORCIBLE);
This issue happens rarely. It occurred two weeks ago, but at that time we just did POR. Since then, we have not been able to reproduce the issue.
I am currently using the NXP SDK APIs for power mode switching, and in those APIs the SIRC clock is being set. So, do I need to manually check the clock frequency before switching? I think the APIs are already handling this.
The API I am using is:
status_t POWER_SYS_SetMode(uint8_t powerModeIndex,
power_manager_policy_t policy);
And I am calling it like this:
POWER_SYS_SetMode(POWER_MANAGER_VLPR, POWER_MANAGER_POLICY_FORCIBLE);
POWER_SYS_SetMode(POWER_MANAGER_VLPS, POWER_MANAGER_POLICY_FORCIBLE);
Questions:
Can we find the root cause of this issue?
Currently, we deinitialize the watchdog before entering VLPR. Can we instead deinitialize it after VLPR but before entering VLPS mode?
Is there any demo application available to manually configure VCCR?
Hi @Sami2098,
Unless you try to connect once the MCU goes to halt, I can't really pinpoint the root cause for this issue.
Is VLPR needed for the project? It can go from RUN to VLPS directly. This will also mitigate the risk of ERR011063.
For mode transition, please refer to chapter 5.6 from AN5425: Power Management for S32K1xx. But your routine seems to be correct; disable first the peripherals that are using the clock sources, switch the system clock to SIRC and disabled all the other clock sources.
Best regards,
Julián
Hello @Julián_AragónM
Today while testing we got stuck in MCU halt state again. Everything was working fine since last 3 weeks. We have bypassed VLPR state completely. Now we go from Run to VLPS directly (no VLPR in between). We have also confirmed this from clock frequency the bus clock was 4Mhz and system clock was 8Mhz. We also confirmed that before going to VLPS the clock source was SIRC and all other clock sources were disabled.
In MCU halt state, we connected JTag and was able to connect using RTT Viewer. Following is the screenshot of RTT viewer in MCU halt state.
Nothing is working to bring the MCU alive. The only way we are sure that will work is the power cut. We have our MCU currently in this state and we will wait for your reply if there is something you want us to try in this state. This is because it is hard to reproduce this issue and we don't know when it will happen again. Waiting for your reply.
We are currently using 3 DMA channels, 0, 1 and 3.
0 is mapped to Flex I/O UART.
1 is mapped to LPUART 0 RX
3 is mapped to LPUART 1 RX
When we goto VLPS we observed that only DMA 0 is enabled. We checked the status of DMA using
for (int ch = 0; ch < 16; ch++) { // S32K146 has 16 channels
if (DMA->ERQ & (1 << ch)) {
printf("DMA channel %d is ENABLED\r\n", ch);
}
}
This for loop is used only in debug version and not in release. We are not explicitly disabling DMA 1 and 3 but observed that they are still disabled maybe by driver function static void LPUART_DRV_StopRxDma(uint32_t instance).
We have tried to disable the DMA channels explicitly before going to VLPS using status_t EDMA_DRV_Deinit(void).
Our intention is to make sure that DMA transfer is stopped before entering VLPS state. Is our approach correct?
This statement however has nothing to do with MCU halt issue we are currently facing. We have observed that we got the halt state with and without the above steps. Just want to ask if there is a need to explicitly call status_t EDMA_DRV_Deinit(void) before going to VLPS.
Hi @Sami2098,
Yes, when entering VLPS, a request is made for non-CPU bus masters to enter Stop mode:
You have to be mindful with DMA configuration for VLPS mode. This is related to ERR011063:
However, if this issue is still happening when DMA is disabled, then maybe the issue is not directly related to this. EDMA_DRV_Deinit() function is correct approach if DMA is not needed in VLPS or directly after.
As for the device in halt state.... are you able to measure current consumption? Is the device on VLPS or does it never enter low power? Are you able to share a register dump in this state?
Additionally, are you configuring sleep on exit feature? There was once a reported issue where MCU was stuck at halt state when trying to process an ISR and return to VLPS via sleep on exit. The workaround was to place a data synchronization barrier to ensure any data manipulation was completed before continuing.
My recommendations are to ensure no interrupts are pending before entering VLPS (i think a simple if ((NVIC->ISPR[0] & NVIC->ISER[0]) == 0) check will suffice), and to use DSB + ISB instructions to ensure proper synchronization before going to VLPS again.
Best regards,
Julián
Hi @Julián_AragónM ,
Thanks for your continuous support. Please find below the answers to your questions.
As for the device in halt state.... are you able to measure current consumption?
Unfortunately, we did not connect ammeter before the issue occurred and as the issue happens rarely, using an ammeter would require to break the Battery connection thus POR.
Is the device on VLPS or does it never enter low power?
This we cannot say for sure currently. The intention is that the device should go to VLPS. However, it is possible that it gets stuck to some unknown state.
Are you able to share a register dump in this state?
Currently the MCU is no more in this state. However, if this issue reoccurs then how should I take the register values dump when MCU is running the release version.
Additionally, are you configuring sleep on exit feature?
No, currently we are not using Sleep on exit feature.
/* Do not re-enter (deep) sleep state on ISR exit */
S32_SCB->SCR &= ~(S32_SCB_SCR_SLEEPONEXIT_MASK);
I have a few questions regarding your recommendations.
As we are not using Sleep on Exit feature, do we need to "use DSB + ISB instructions to ensure proper synchronization before going to VLPS"?
If yes, then is it correct approach to call functions in this way?
/* Cpu is going into deep sleep state */
__asm("DSB");
__asm("ISB");
STANDBY(); // where STADBY() -> #define STANDBY() __asm volatile ("wfi")
We are working on the application layer. So do I need to call the following function, just before switching the power mode to VLPS?
void INT_SYS_ClearPending(IRQn_Type irqNumber); // <- call this function before switching to VLPS?
POWER_SYS_SetMode(POWER_MANAGER_VLPS, POWER_MANAGER_POLICY_FORCIBLE);
Thanks and Best Regards,
Hi @Sami2098,
Currently the MCU is no more in this state. However, if this issue reoccurs then how should I take the register values dump when MCU is running the release version.
If you happen to enter this state again, you can try to connect to the MCU with "Attach to running target" configuration in debugger. For example, with S32DS "Registers" view, and export. Or exporting the values to a CSV with TRACE32: debugging - how to export a variable values from TRACE32 - Stack Overflow.
As we are not using Sleep on Exit feature, do we need to "use DSB + ISB instructions to ensure proper synchronization before going to VLPS"? If yes, then is it correct approach to call functions in this way?
That was just two suggestions, since in the past there was a similar problem as this, and customer was using Sleep on Exit feature. I wanted to confirm if the configuration was the same.
DSB + ISB looks fine in your implementation. These are mainly to ensure that any ongoing data manipulations are completed before continuing to VLPS.
Calling INT_SYS_ClearPending() also looks good, this will check for pending interrupts before entering low power.
This is a very strange issue, since it is very hard to reproduce.
Best regards,
Julián
Hi,
thank you for your support. Your are right. We do not really need to transition to VLPR in our project and have bypassed it. Following your comment, we would like to further ask if there is a need to also deinitialize the LPTMR IRQ. The LPTMR interrupt is triggerred every 1ms and is basically running the complete MCU code. When the MCU transitions to VLPS state we are not using this LPTMR interrupt anymore. Instead we are using GPIO pins as wake up source. So practically we do not need LPTMR IRQ in VLPS mode.
So should we deinitialize LPTMR IRQ as well as it is a peripheral using clock source?
Hi @Sami2098,
Yes, if not used as wake-up interrupt, you should disable LPTRM IRQ and clock source. This shaves off unnecessary current and avoids an unwanted ISR the moment you leave VLPS.
Best regards,
Julián