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

nRF51422 cannot be waken after sleep/wake quite a few times.

Hi, I am now developing a product which uses nrf51422 chip. In this product, I use buttons to turn on and off (since I don't have hard-power cut off circuit, we use system-off sleep for power off and normal mode for active mode). To turn off the device, users need to press and hold the button for 3seconds (here I just used sd_power_system_off() function to go into system-off sleep mode) and to turn on the device, users need to do the same action. I completed the firmware tested a few times and it was OK. But now we found out that after we turn on/off for a few times (23times for a unit, 50times for another unit,it's inconsistent) , the device cannot be waken up at all. But after I remove the battery and put again (power reset), then it's working again. Does anyone encounter this kind of issue before? Please help me. The device is going to be in production soon and urgently need your help.

here is some details for the device,

MCU - nrf51422

SDK - v11.0.0

SD version - SD130

System-off sleep

            if(Flag.PowerOnOff==1)
            {
                if( nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN) == false) // if the power on button is pressed
                {
                    for(uint8_t i=0;i<=6;i++)
                    {
                        nrf_delay_ms(500);
                        if( nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN) == true)
                            break;
                        if( i==6)
                        {
                            TurnOff_LEDs();
                            nrf_delay_ms(10);
    
                           //Disable some interrupt to prevent from waking up
                          nrf_drv_gpiote_in_uninit(SW_EMERGENGY_PIN);
                          nrf_drv_gpiote_in_event_disable(SW_EMERGENGY_PIN);
                          nrf_gpiote_int_disable(SW_EMERGENGY_PIN);
        
                          nrf_drv_gpiote_in_uninit(INT_PIN);
                          nrf_drv_gpiote_in_event_disable(INT_PIN);
                          nrf_gpiote_int_disable(INT_PIN);

                         // Go to system-off mode (this function will not return; wakeup will cause a reset).
                         err_code = sd_power_system_off();
                         APP_ERROR_CHECK(err_code);

                     }
                    }
                }
                
            }

Wake up Check whether from power reset or sleep reset

        if((NRF_POWER->RESETREAS & 0x00010000)== 0x00010000) // If reset from system off mode
        
        {
            if(nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN)==false)
            {
                for(temp=0;temp<=6;temp++)
                {
                    nrf_delay_ms(500);
                    if(nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN)==true)
                    {
                        TurnOff_LEDs();
                        
                        //Disable Hi G, Low G and Emergency Interrupt pin to prevent System-off wakeup
                        nrf_drv_gpiote_in_uninit(SW_EMERGENGY_PIN);
                        nrf_drv_gpiote_in_event_disable(SW_EMERGENGY_PIN);
                            
                       
                        nrf_drv_gpiote_in_uninit(INT_PIN);
                        nrf_drv_gpiote_in_event_disable(INT_PIN);
                        
                        NRF_POWER->SYSTEMOFF = 1; // if the power on button is released within 3seconds, goto system off again
                    }
                }
            }
            
        }

Parents
  • Have you measured the current consumption, just to check if the chip is really in sleep?

    I was thinking you can add a nvic_systemreset() after the system OFF command(s), just to catch any potential failure here (can't think of any, but might be worth a test to see if it impact the issue).

    I recommend that you disable global interrupts if if(Flag.PowerOnOff==1) is true, just to make sure you don't have any interrupts when you start configuring the gpio's as wakeup sources.

  • Hi Kenneth, I already put in the code snippet that you suggested and tested but the issue is still there. When I checked the supply voltage of the MCU when this issue happen, I found the supply voltage is there (which means it's not the hardware).Can I get any more suggestions? Thanks and waiting for your reply.

  • Can you provide detailed chip markings on the nRF51422 ic?

    Can you try adding a 1Mohm between SWDIO and GND and check if you experience the same?

    Can you send me your updated if(Flag.PowerOnOff==1){}?

  • Hi Kenneth,

    Can you provide detailed chip markings on the nRF51422 ic?

    the chip marking => N51422 QFACA1 170BAE

    Can you try adding a 1Mohm between SWDIO and GND and check if you experience the same?

    no I havent tried before and I will do it and may I know what's the purpose for this?

    Can you send me your updated if(Flag.PowerOnOff==1){}?

    I just added a single NVIC Reset command after system off sleep mode as I state in the comment.

    if(Flag.PowerOnOff==1)
    {

    if( nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN) == false) // if the power on button is pressed
      {
       for(uint8_t i=0;i<=6;i++)
        {
          nrf_delay_ms(500);
          if( nrf_drv_gpiote_in_is_set(SW_PWR_ON_PIN) == true)
          break;
          if( i==6)
          {
            sleep_mode_enter();
          }
        }
      }

    }

    static void sleep_mode_enter(void)
    {
        //uint32_t err_code;
            TurnOff_LEDs();
            nrf_delay_ms(10);
        
            //Disable Hi G, Low G and Emergency Interrupt pin to prevent System-off wakeup
            nrf_drv_gpiote_in_uninit(SW_EMERGENGY_PIN);
            nrf_drv_gpiote_in_event_disable(SW_EMERGENGY_PIN);
            nrf_gpiote_int_disable(SW_EMERGENGY_PIN);
            
            nrf_drv_gpiote_in_uninit(LOWG_INT_PIN);
            nrf_drv_gpiote_in_event_disable(LOWG_INT_PIN);
            nrf_gpiote_int_disable(LOWG_INT_PIN);

            // Go to system-off mode (this function will not return; wakeup will cause a reset).
        sd_power_system_off();
            NVIC_SystemReset();  // I just added this code
        
        //APP_ERROR_CHECK(err_code);
    }

  • And I want to test like this. In stead of going to system-off deep sleep mode, I want to try to go to system on sleep mode (power_manage) command but I want to turn off BLE and when the user press and hold the button again, I will just turn on the BLE and continue. Although it's not good for power saving, I want to eliminate this issue first.

    So how can I do to turn off BLE and put the MCU in system on sleep mode and and turn on BLE again?

    Thanks.

Reply
  • And I want to test like this. In stead of going to system-off deep sleep mode, I want to try to go to system on sleep mode (power_manage) command but I want to turn off BLE and when the user press and hold the button again, I will just turn on the BLE and continue. Although it's not good for power saving, I want to eliminate this issue first.

    So how can I do to turn off BLE and put the MCU in system on sleep mode and and turn on BLE again?

    Thanks.

Children
  • See my suggestion inline (look for //KME 3 places):

    static void sleep_mode_enter(void)
    {
        //uint32_t err_code;
            TurnOff_LEDs();
            
            // KME: Disable all interrupts here, e.g. __disable_irq() 
            
            nrf_delay_ms(10);
        
            //Disable Hi G, Low G and Emergency Interrupt pin to prevent System-off wakeup
            nrf_drv_gpiote_in_uninit(SW_EMERGENGY_PIN);
            nrf_drv_gpiote_in_event_disable(SW_EMERGENGY_PIN);
            nrf_gpiote_int_disable(SW_EMERGENGY_PIN);
            
            nrf_drv_gpiote_in_uninit(LOWG_INT_PIN);
            nrf_drv_gpiote_in_event_disable(LOWG_INT_PIN);
            nrf_gpiote_int_disable(LOWG_INT_PIN);
    
            //KME: Enable wakeup on the pins you want to wakeup on by calling nrf_gpio_cfg_input() and nrf_gpio_cfg_sense_set().
            
            // Go to system-off mode (this function will not return; wakeup will cause a reset).
            sd_power_system_off(); // KME: You can use NRF_POWER->SYSTEMOFF = 1; directly here.
            NVIC_SystemReset();  // I just added this code 
    
        //APP_ERROR_CHECK(err_code);
    }

  • Thanks Kenneth for your prompt reply. I will try this and let you know about the outcome.

    Thanks again for your great help and hope this will solve my issue.

  • Hi Kenneth, when I tried this

    static void sleep_mode_enter(void)
    {
    //uint32_t err_code;
    TurnOff_LEDs();

    __disable_irq()

    nrf_delay_ms(10);

    //Disable Hi G, Low G and Emergency Interrupt pin to prevent System-off wakeup
    nrf_drv_gpiote_in_uninit(SW_EMERGENGY_PIN);
    nrf_drv_gpiote_in_event_disable(SW_EMERGENGY_PIN);
    nrf_gpiote_int_disable(SW_EMERGENGY_PIN);

    nrf_drv_gpiote_in_uninit(LOWG_INT_PIN);
    nrf_drv_gpiote_in_event_disable(LOWG_INT_PIN);
    nrf_gpiote_int_disable(LOWG_INT_PIN);

    nrf_gpio_cfg_sense_input(SW_PWR_ON_PIN,NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);

     NRF_POWER->SYSTEMOFF = 1;
    NVIC_SystemReset(); // I just added this code

    //APP_ERROR_CHECK(err_code);
    }

    the device cannot wake up anymore.

    so I added, __enable_irq() before NRF_POWER->SYSTEMOFF=1 and 

    it still cannot wake up after deepsleep (the symptom is the same as in my issue)

  • Dont' enable irq again, instead follow my comment:

    Enable wakeup on the pins you want to wakeup on by calling nrf_gpio_cfg_input() and nrf_gpio_cfg_sense_set().

Related