2014-09-28 05:28 PM
Hello everyone:
Here is my problem.I am using the STM32L152. When I execute the WFI instruction, the processor goes to sleep just fine. However, when it wakes up from an external interrupt line, the processor immediately hardfaults. I have breakpoints set just before and after the WFI instruction. When the processor wakes, I should hit the second breakpoint, but instead it just hard faults. Here is some more information. All the registers (to my knowledge) are set correctly. I have looked at all the information I can find on the forum and have tried pretty much every suggestion. The flash is enabled (FLITF), the LPSDSR bit is cleared in the power register, etc.. All clocks are in their correct state. This is a textbook case of sleep mode: no disabling of flash, no low power sleep, just plain sleep mode. The manual says all that is needed is a WFI instruction. Now.. if I set the DEEPSLEEP bit in the cortex m3 SCR, the processor does 'not' hardfault and instead resumes execution where it is supposed to. All other settings being the same. Lastly, I have looked at the hard fault stacking of registers. It seems to be stacking things alright with an odd exception of the xPSR register. When I enter the hard fault, the stacked value for the xPSR register has the Thumb bit cleared. Inspecting the stack and state of the CPU (xPSR, NVIC, registers) at the instruction just before the WFI instruction reveals a proper CPU state as well as the Thumb bit set. I am also running an RTOS. I have tried to run the WFI code inside a task as well as outside a task. The stack being used (be it the process stack or the main stack) does not matter. Either stack hardfaults.Any help is greatly appreciated. I am hoping I am doing something stupid with just a bit being misplaced somewhere.2014-09-30 07:18 AM
Have you tried to examine the CFSR contents after a hardfault ?
You can try Josephs Yiu's famous hardfault handler code to dissect your issue.2014-09-30 07:29 AM
As stated in a previous reply, the CFSR register indicates IACCVIOL and tells me to look at the stacked PC and registers. Nothing out of the ordinary except the Thumb bit in the xPSR being cleared.
The one thing I seem to have not made clear is that there is a 99% chance this has nothing to do with code executing and an instruction / access causing a hard fault from the code. If this were the case, I would be able to trace it in a heartbeat. How do I know this? The only difference between me hard faulting and not is the DEEPSLEEP SCR bit. I have breakpoints set in every place that code 'can' possibly resume after sleeping. None of those breakpoints are hit. The core just jumps to the hard fault handler immediately.2014-09-30 08:11 AM
2014-09-30 08:30 AM
Here is something interesting that I found. I examined the stack pointer that is given as the parameter into the hard fault. I can clearly see all the registers that I previously posted in the stack. HOWEVER, what I can also see is another stack frame. That stack frame has the registers that I posted EXCEPT they are valid! The xPSR register has the thumb bit set, and and the lr and pc registers point exactly where they should - right after the WFI instruction.
Why would the chip stack for an interrupt twice like this? The only interrupt I have enabled is the EXTI and I have already confirmed, that interrupt entry is never touched. I could understand if possibly the chip restacked if an interrupt was interrupted; however, the ICSR tell me no interrupt has been interrupted AND my EXTI handler was never entered. It's like the chip tried to start stacking for the EXTI interrupt and then after stacking it decided something was wrong and hard faulted.2014-09-30 10:56 AM
I tried to reproduce on STL32L DISCOVERY.
It did work with and without DEEPSLEEP. Anyway, I have some difference with your test case: * i am using HSI instead of HSE (because I havo no XTAL on this board) * I only configure PA0 is rising edge interrupt source through EXTI * I am using UART1 as debug stuff (putc here, putc there ...), one can also use GPIO and watch on scope. I suspect the debugger to be too intrusive for WFI stuffs, I recommend to avoid it. I am afraid of what may happen when a breakpoint is hit and debug subsystem not completely wake up or whatever else. That's why I used another mean to test my runtime flow. Uart has the advantage to double check that clocks are running at the good speed when character are successfully output.2014-09-30 11:28 AM
2014-09-30 02:15 PM
I just had similar problem so here's my report. Everything worked ok if DBGMCU_Config was not called (to setup WFI for debugging). If this is called I would get HardFaults (well if not then I could not connect debugger but by blinking leds I would think that everything is ok). My configuration was simple delay function on STM32L100RC.
function delay(ms){configure_timer(ms);start_timerWFIstop_timer}HardFault would happen just after the WFI instruction. I tried to add NOP commands and wrap WFI into function call (by errata for WFE instruction) but without any success, but when I slowed down the clock from 32MHz to 16MHz it did the trick. I guess this should be some kind of chip problem, but I could not investigate further in depth since I'm newcomer to ARMs. Thank you for your post, would be stuck here probably forever without it.2014-09-30 06:48 PM
2016-01-13 12:46 AM
I had a similar problem, which was caused by the clock to the PWR domain not being enabled. When I set RCC->APB1ENR |= RCC_APB1ENR_PWR; the standby and resume work like expected.