cancel
Showing results for 
Search instead for 
Did you mean: 

L152RE, entering standby via HAL call, execution continues after WFI - huh?

Posted on March 12, 2016 at 00:38

I'm encountering a very bizarre behavior with standby.

My code enters standby using HAL_PWR_EnterSTANDBYMode(). At power-on, it enters standby properly, comes out correctly after one intentional IWDG event (the reasons for which I can't get into due to confidentiality issues), enters standby properly a second time, and comes out correctly again after a WKUP.

Then, in response to a button press, it's supposed to go into standby again... only it doesn't. In this third case, execution continues after the WFI instruction. Yes, I mean that literally - I can step over the WFI instruction itself, inside the HAL call - NO reset occurs. I've never seen this before.

Everything was working fine, then I implemented a multi-task watchdog scheme and this started to happen. I can't exactly pin down an answer to ''what did you change?'' due to the extent of the additions, but the added watchdog scheme does not actually make use of the IWDG yet; what makes it even more odd is the lack of a reset after the WFI.

Platform, etc:

- STM32L152RET6 rev A silicon

- IAR EWARM 7/50.2.10505

- STM32CubeMX v. 4.12.0

- There's an RTOS, but I can't be more specific

The part that has me utterly flummoxed is watching execution continue after the WFI with no reset. I have not found information concerning any cases where execution could continue without a reset, when the settings required for entry into standby / Cortex-M3 deepsleep mode are done.

HAL_PWR_EnterSTANDBYMode() sets the PDDS bit in PWR_CR and the SLEEPDEEP flag in the SCR prior to the WFI; my own code clears the WUF bit in PWR_CSR shortly after execution begins and uses no RTC wakeup sources.

Is anyone aware of any situation where standby entry will NOT occur on a WFI and execution will continue with no reset?

 

I've even tried explicitly disabling the WKUP source associated with my button, clearing the WUF, and re-enabling the button WKUP, all just before the HAL standby call, with no change.

I'm not even sure where to go next. There's a mention of a standby-related issue in the errata for rev. A silicon, but it doesn't describe this scenario (execution continuing past WFI).

Many, many thanks in advance for any relevant clues!

#stm32l152-standby-wfi-deepsleep
6 REPLIES 6
Posted on March 12, 2016 at 00:57

What is the behaviour without the debugger attached?

Is there anything driving the NRST high externally?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on March 12, 2016 at 01:26

Hi, Clive! Thank you for the reply!

The behavior is identical when running without the debugger attached. (I have an LED configured to give an ''about to enter standby'' flash, and due to the way the internal state machine is constructed, the standby attempt gets repeated, and so does the flash.)

I'm certain that NRST isn't being pulled low at any point in time; besides which, that should cause a reset, which should never permit execution to continue, let alone execution of the next instructions after the WFI.

I'm grasping at straws, but I imagine it must somehow have something to do with the fact that the previous standby was exited due to WKUP2 (which is where my button is connected).

Posted on March 12, 2016 at 01:28

Ooops - my apologies: I misread your question!

No, there's nothing driving NRST high externally - no active line, no pull-up.

Posted on March 12, 2016 at 01:58

I mention NRST being driven high, as this is a classic cause for the part not actually resetting, but that would tend to break IWDG too.

With the Sleep/Standby there are requirements that everything is cleared prior to entry, so if there is any pending status holding over that could be an issue. ie EXTI, flags, etc. sanitize everything.

With an RTOS, one might want to be conscious of User vs System run state (Master vs Process in ARM speak), and resuming control through an interrupt. ie say the boot-loader has an EXTI IRQ from a button, and then it arbitrarily jumps off into the app code, rather than unraveling the interrupt state.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on March 12, 2016 at 02:13

That's an interesting tidbit concerning NRST - I'll file it away for future reference!

RTOS comment acknowledged, but I don't think it applies in this case (if I needed to dig, I have the source).

It did occur to me that the reference manual and datasheet could be missing details concerning other things like EXTI and so forth... Before starting the final code related to standby, I do these things:

- call __disable_interrupt()

- loop until the button input (PC13/WKUP2) goes low for a good 100 ms

- disable WKUP2 (WKUP1 isn't used yet)

- clear the WUF in PWR_CR (CWUF)

- disable the button EXTI

- clear any pending button EXTI (it's the EXTI10-EXTI15 IRQ)

- enable WKUP2

- enter standby via the HAL call

Some of those items are not supposed to be necessary, but at this point I'm experimenting with whatever might be even remotely related.

Are there any other checks / tests you can think of that I can do which might shed some light on what's going on internally?

Posted on March 14, 2016 at 22:13

Clive - thank you for the ''sanitize everything'' encouragement. I finally found the problem. It was related to the RTOS being allowed to run. It wasn't the RTOS's fault - it's doing exactly what it should be doing.

The core problem (pardon the pun) was that there was a pending SysTick exception hanging around. I added code to clear it out (ICSR, PENDSTCLR) after disabling the interrupt (SYST_CSR, TICKINT), and that was the magic I was looking for.

Sometimes a nudge is all that is needed! (Well, it also didn't hurt to have a copy of the Cortex-M3 and ARMv7-M docs at my fingertips...)

Thanks again!