Reply
Posts: 88
Registered: ‎12-27-2016
Accepted Solution

Immediate wake from EM2 by Fault Exception ?

I have a situation where my code immediately wakes from EM2 by, what I believe, to be a Fault Exception. Although, I have not been able to prove this.

 

The short code segment below is supposed to just go to sleep forever. It should never fall through to the while(1) at the end. If the Fault exceptions are disabled with the __disable_fault_irq(), then the micro goes to sleep and remains there. However, if the fault exceptions are not disabled, the code falls through to the while(1) statement (something wakes the micro from sleep).

 

 

int main(void)
{

  InitSys();


  __disable_irq();
//  __disable_fault_irq();
  EMU_EnterEM2_Fast();

  while(1);

 

I have created short, one statement ISRs for all of the fault exception handlers, and set breakpoints at those statements to find out which Fault ISR is firing, but none of them were hit. This is an example below.  It can't be an application ISR either because they are disabled.

 

void __attribute__((interrupt("IRQ"))) HardFault_Handler(void)
{
  FaultIRQ = 1;
}

 

The function EMU_EnterEM2_Fast() has been reduced to it's simplest elements to enter DEEPSLEEP.

 

void EMU_EnterEM2_Fast(void)
{
  /* Enter Cortex deep sleep mode */

  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __WFI();
}

 

 Any clues on how to proceed ?  What is waking the micro ?

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

I've set breakpoints at all exceptions (including reset), and the code does not hit any of them after the WFI instruction is executed. However, I cleared the CYCCNT just before the WFI instruction, and approximately 34000 machine cycles was executed somewhere in between the WFI instruction, and the breakpoint where while(1) is located.

 

The micro was away "somewhere" for a long time doing "something". Why is the biggest question. Where and what is not as important as why as long as I can prevent it. 

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

The CFSR and HFSR registers show that no fault exceptions have occurred when I get to the while(1) statement, which may be why I did not get any breakpoint hits in the Fault Exception ISR routines.  This doesn't make any sense, because when the Fault Exception interrupts are turned off, the micro goes to sleep, and stays asleep.

 

FaultExceptions.jpg

Posts: 240
Registered: ‎08-16-2012

Re: Immediate wake from EM2 by Fault Exception ?

Which device you are using?

http://community.silabs.com/t5/32-bit-MCU-Knowledge-Base/EMU-E110-Potential-Hard-Fault-when-Exiting-...

 

My views are my own and do not necessarily represent the views of Silicon Labs
Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

My device is an EFM32JG1B100.

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

Here is a snapshot of the System Control Block registers. SCR looks ok. Still no clue what's going on.

 

SCR.jpg

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

Also, I set at breakpoint at the Default_Handler ISR routine, and the code is not going after wake-up either.

Posts: 3,021
Registered: ‎02-07-2002

Re: Immediate wake from EM2 by Fault Exception ?

Is there maybe a chance that you get to the breakpoint before the core has actually fully reached its sleep state? What happens if you insert some nop before the while(1) ?

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

ICSR says there are no pending app interrupts immediately before the WFI instruction is executed. They are disabled, so this still points to a fault interrupt of some kind, but I still don't which one, or why.

 

NoPendingAppInterrupts.jpg

Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

Adding __NOP() instructions after the sleep instruction did not help. I also changed the name of the sleep function from EMU_EnterEM2_Fast() to SleepDeep() - same function contents, different name.

 

As far as I can tell, everything still points to a fault exception waking the micro - OR - it is just blowing right through the stop sign, and never going to sleep at all. But, if it were never going to sleep at all, and blowing through the stop sign, then where did the extra 34000 clock cycles come from ? There are no pending interrupts, so why would that be happening ?  This is a mystery to me.

 

  InitSys();

  FaultIRQ = 0;
  __disable_irq();
//  __disable_fault_irq();
//  EMU_EnterEM2_Fast();
  SleepDeep();

  __NOP();
  __NOP();
  __NOP();
  __NOP();
  __NOP();
  __NOP();
  __NOP();
  __NOP();

  while(1);
Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

More info. The 34000 clock cycle that passed between the WFI instruction, and the while(1) is not an accident. There is a LETIMER0 interrupt that runs at this rate. By changing the time that this interrupt is "supposed" to fire, the 34000 clock cycle count follows the LETIMER0 rate.

 

But that is not the end of the story. Although the local NVIC interrupt is enabled for LETIMER0, the global interrupt is not (PRIMASK = 1). So why is the micro waking up at all ?

 

If the NVIC interrupt for LETIMER0 is not enabled, then the micro doesn't wake at the LETIMER0 time-out. It still wakes up, but it takes much longer. I don't know anything about this problem yet - related or not.

 

Oh, by the way, if a breakpoint is set in the LETIMER0 ISR routine, it is never hit. The code never vectors there at all !

 

This is not looking good at this point. Hope someone can help.

Highlighted
Posts: 88
Registered: ‎12-27-2016

Re: Immediate wake from EM2 by Fault Exception ?

I'm sorry, but I have been chasing ghosts due to my lack of understanding about how the interrupts, sleep, and waking work. I was under the impression that the PRIMASK was used as a "global" interrupt enable, and that no interrupts would fire (wake the processor or be serviced) unless this register was set to "1".

 

My beleive was only partially true. It is true that interrupts won't be serviced unless the PRIMASK register is set to 1. However, ANY NVIC INTERRUPT THAT IS ENABLED WILL WAKE CORE. Although, the ISR may or may not be serviced depending on the state of the PRIMASK register. 

 

Below is a screen snapshot from the ARM manual.

 

Wakeup.jpg

 

There's a lot you've got to know !

Posts: 3,021
Registered: ‎02-07-2002

Re: Immediate wake from EM2 by Fault Exception ?

Well done. Some good hunting down the problem and keeping others posted.