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.

  • Hi Kenneth, I don't know what's wrong with my code, I just tried what you suggested and it bacome even worse. When I tried the below code, my LED will blink twice and the device will go to deepsleep and couldn't be waken up as usual.

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

    __disable_irq();

    //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_drv_gpiote_in_uninit(SW_PWR_ON_PIN);
    nrf_drv_gpiote_in_event_disable(SW_PWR_ON_PIN);
    nrf_gpiote_int_disable(SW_PWR_ON_PIN);

    nrf_gpio_cfg_input(SW_PWR_ON_PIN,NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_sense_set(SW_PWR_ON_PIN,NRF_GPIO_PIN_SENSE_LOW);

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

    NRF_POWER->SYSTEMOFF=1;
    NVIC_SystemReset();

    //APP_ERROR_CHECK(err_code);
    }

  • Hi Kenneth, sorry for my mistakes. Actually, the code is OK, I mean, the device blinking corretly but still the same issue that it cannot be wakeup after I press the button and put the device into deepsleep.

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

    __disable_irq();

    //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_drv_gpiote_in_uninit(SW_PWR_ON_PIN);
    nrf_drv_gpiote_in_event_disable(SW_PWR_ON_PIN);
    nrf_gpiote_int_disable(SW_PWR_ON_PIN);

    nrf_delay_ms(1);

    nrf_gpio_cfg_input(SW_PWR_ON_PIN, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_sense_set(SW_PWR_ON_PIN, NRF_GPIO_PIN_SENSE_LOW);
    //nrf_gpio_cfg_sense_input(SW_PWR_ON_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);

    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    nrf_delay_ms(10);
    NRF_POWER->SYSTEMOFF=1;
    //sd_power_system_off();
    NVIC_SystemReset();

    //APP_ERROR_CHECK(err_code);
    }

  • Are you able to simplify and share your project to run on nrf51-dk so I can recreate the issue here?

    Best regards,
    Kenneth

  • Hi Kenneth, thanks for the suggestion. I will try to do this but could you also help me how to disconnect BLE and stop advertising properly so that I can also try with system on sleep instead of system off sleep? Thanks.

Reply Children
  • To disconnect e.g.:

    sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
    BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

    To stop advertising e.g.:

    (void) sd_ble_gap_adv_stop(p_advertising->adv_handle);

  • Hi Kenneth, thanks and I did as what you mentioned but I still found some issues. I just put these code in the function "sleep_mode_enter()" 

    static void sleep_mode_enter (void)

    {

    /* Turn off other peripherals before go to system on sleep mode */

    sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);

    sd_ble_gap_adv_stop();

    for(;;)

     {

        sd_app_evt_wait();

        if(nrf_gpio_pin_read(SW_PWR_ON_PIN)==0) 

        {

           NVIC_SystemReset();

        } 

     }

    }

    I can see the device goes to system on sleep when sleep_mode_enter function is called and can wake up reset when I press the switch.

    But the problems that I found out are 

    1. If the device is connected to the app and when I turn off the device (sleep_mode_enter called), the device disconnect the app and goes to sleep but it restarts advertising again so the app and the device got connected again.

    2. if the device is not connected, I put sleep after advertisment timeout and when advertisement timeout occurs the device can go to sleep but when I check the current in power profiler kit, the current consumption is too high (about 3mA). But when the device is not connected and turn off the device before advertisement timeout, it goes to sleep and current consumption is acceptable (8uA only).

    So what might be the possiblities?

    (By the way, do I need to create a new topic for this question since this is not related with my previous issue) 

  • Hi

    1. If you are using the ble_advertising module, then you can find that in ble_advertising_on_ble_evt() on BLE_GAP_EVT_DISCONNECTED, that ble_advertising_start() is called automatically, you may consider comment out this.

    2. That was a bit strange, when advertisement timeout I assume the code callback on_adv_evt() and BLE_ADV_EVT_IDLE event, maybe you are calling sleep_mode_enter() from a different place in your code in this case?

    Best regards,
    Kenneth

  • Hi Kenneth,

    thanks for your suggestion, I did check with advertising on event and that I found out the event in the advertise.c file and I put some condition in the event (though it's not a good practice) and now it worked.

    So the device is now just in a system on sleep in idle condition and I also put the watchdog just in case to prevent from the dead loop.

    Thanks again for your great help.

Related