This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF51422 won't sleep

I am trying to get my system with a hardware RTC generating periodic interrupts every 30 seconds to sleep between interrupts. I'll paste the code below, but here is the problem:

I get the interrupts signalled to my PORT event handler and, in my loop, write a message to a SEGGER RTT console and do some distinctive led flashing just so I know what's happening. I have a sw flag (powerDown) that I set that SHOULD cause the loop to sleep after each 'tic'. The LEDs flash 3 times prior to the _WFE sequence and then produce a distinctive flash on return from the _WFE sequence. What I expect is that I'd get the 3 flashes and then not get anything else for slightly less than 30 seconds. However, I get the distinctive sequence immediately, meaning that there is no sleeping going on...

I'm sure I'm neglecting something, but I've scanned these questions and looked at my code over and over and it looks like all the other cases that work (by the way, I have run the power_down examples "system-on-wakeup-on-gpio" case on a pca10028 and it works, with and without SEGGER RTT).

Update: I've modified the system-on-wakeup-on-gpio test program by adding my routines to initialize the serial flash chip attached via SPI0. I did this mainly because I tried to see how much power was drawn with just this simple case and found it drawing about 24uA when sleeping. Thinking that I needed to put the flash in Ultra power down mode, I had to bring in all the SPI gorp. Well, now it doesn't go to low power mode at all! The CPU sleeps (as it takes a button push to wake it up), but there is no power down (current is about 2.3mA). Any ideas on how to shut down the whole SPI infrastructure? I am doing a spi0_uninit()...

I am using an N5M8 module with nRF51422_xxac, using SDK V10.0.0.0. Here is my code:

while (1)
  {
    if (tic)
    {
      // reset interrupt status
      rtc_resetIF(RTC_TIM_IF | RTC_ALM_IF);
      if (tic_show)
      {
        SEGGER_RTT_printf(0,"tic... %ld, pin:%d \n",(long)(tic_time-prev_time),h_pin);
        printTime();
      }
      prev_time=tic_time;
      tic=false;
      if (powerDown)
      {
        SEGGER_RTT_printf(0,"Powering down!  See ya later... \n");
        blinkLED(3, 20,750);  // blink to signal shutting down
        
        // disable the internal RTC & SPI before sleeping
        spi0_uninit();
        nrf_drv_rtc_disable(&rtc);
        
        // Enter System ON sleep mode
        __WFE();
        // Make sure any pending events are cleared
        __SEV();
        __WFE();

        // re-enable the internal RTC
        nrf_drv_rtc_enable(&rtc);
        spi0_init();
        
        blinkLED(20, 5,50);  // blink to signal wake up
      }
    }

    checkDebug();
  }
Parents
  • Probably the problem is the way your code attempts to go to sleep. You are using this code:

        // Enter System ON sleep mode
        __WFE();
        // Make sure any pending events are cleared
        __SEV();
        __WFE();
    

    But this will probably not do what you think. If we assume that a event is pending, then the first WFE (Wait for Event) instruction will not do what you expect, as the pending event will cause the CPU to wake up again immediately. Then the SEV (Send Event) instruction will signal an event to the CPU. Again, the CPU will wake up immediatly from the next WFE as a event is pending.

    The correct order is this:

        // Make sure any pending events are cleared
        __SEV();
        __WFE();
        // Enter System ON sleep mode
        __WFE();
    

    Here the SEV will make sure that a event is set, in case it is not. The first WFE will make sure the event is cleared. Thus after those two instructions we can be confident that there are no pending events. The last WFE will put the CPU to sleep.

  • Doh! Actually, this makes total sense to me, however, throughout this forum all the examples seemed to be the sequence that I originally used. I've reordered as you've suggested and, indeed, it DOES SLEEP!!! YAY! Thank you very much!

Reply Children
No Data
Related