Large current spikes (1Hz) with softdevice enabled

Hello, 

I am using an nRF52840 on a custom board running the BLE stack from SDK16.0.0. I have an application that periodically advertises for 10s and is idle in between these advertising events. During this idle period I measure very large current spikes (up to ~15mA) which occur at 1Hz. The WDT is enabled with a reload value of 2000, and set to CONFIG_BEHAVIOUR 8 (Pause in SLEEP, Run in HALT). Captures of the current waveform are provided below. 

Curiously, I modified the CONFIG_BEHAVIOUR to 0 (Pause in SLEEP and HALT), and the current spikes were still present but with reduced peak values (up to ~5mA).

I also went through and stepped through each part of initialization, and found that these spikes do not occur until I enabled the softdevice before going idle. Completely disabling the watchdog does not yield any further reductions. This leads me to believe the softdevice is responsible for this behavior, but I have not had luck at figuring how to fix this. Any suggestions would be appreciated, thank you!

Parents
  • I dug into the idle state management and found what is causing the CPU to wake up every 1s. Looking at nrf_pwr_mgnt.c, a timer is created with a period of 1s (shown below). I was able to modify this timer and saw the current spikes shift respectively as well. PWR_MGMT_TIMER_REQUIRED is defined due to NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY being defined in sdk_config.h. Setting this value to 0, disables this timer and gets rid of the current spikes altogether, which is great. However, I do not understand what implication this might have on the application because I don't have more detail on what a "blocked shutdown procedure" is. Can you please explain what this event is so I can understand how it affects the application?

    snippet from nrf_pwr_mgnt.c

    #ifdef PWR_MGMT_TIMER_REQUIRED
        #include "app_timer.h"
        #define PWR_MGMT_TIMER_CREATE()     pwr_mgmt_timer_create()
    
        APP_TIMER_DEF(m_pwr_mgmt_timer);    /**< Timer used by this module. */
    
        /**@brief Handle events from m_pwr_mgmt_timer.
         */
        static void nrf_pwr_mgmt_timeout_handler(void * p_context)
        {
            PWR_MGMT_CPU_USAGE_MONITOR_UPDATE();
            PWR_MGMT_AUTO_SHUTDOWN_RETRY();
            PWR_MGMT_STANDBY_TIMEOUT_CHECK();
        }
    
        __STATIC_INLINE ret_code_t pwr_mgmt_timer_create(void)
        {
            ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer,
                                                   APP_TIMER_MODE_REPEATED,
                                                   nrf_pwr_mgmt_timeout_handler);
            if (ret_code != NRF_SUCCESS)
            {
                return ret_code;
            }
    
            return app_timer_start(m_pwr_mgmt_timer, APP_TIMER_TICKS(1000), NULL);
        }

    #if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
        #undef  PWR_MGMT_TIMER_REQUIRED
        #define PWR_MGMT_TIMER_REQUIRED

    snippet from sdk_config.h

    // <q> NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY  - Blocked shutdown procedure will be retried every second.
     
    
    #ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
    #define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 1
    #endif

Reply
  • I dug into the idle state management and found what is causing the CPU to wake up every 1s. Looking at nrf_pwr_mgnt.c, a timer is created with a period of 1s (shown below). I was able to modify this timer and saw the current spikes shift respectively as well. PWR_MGMT_TIMER_REQUIRED is defined due to NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY being defined in sdk_config.h. Setting this value to 0, disables this timer and gets rid of the current spikes altogether, which is great. However, I do not understand what implication this might have on the application because I don't have more detail on what a "blocked shutdown procedure" is. Can you please explain what this event is so I can understand how it affects the application?

    snippet from nrf_pwr_mgnt.c

    #ifdef PWR_MGMT_TIMER_REQUIRED
        #include "app_timer.h"
        #define PWR_MGMT_TIMER_CREATE()     pwr_mgmt_timer_create()
    
        APP_TIMER_DEF(m_pwr_mgmt_timer);    /**< Timer used by this module. */
    
        /**@brief Handle events from m_pwr_mgmt_timer.
         */
        static void nrf_pwr_mgmt_timeout_handler(void * p_context)
        {
            PWR_MGMT_CPU_USAGE_MONITOR_UPDATE();
            PWR_MGMT_AUTO_SHUTDOWN_RETRY();
            PWR_MGMT_STANDBY_TIMEOUT_CHECK();
        }
    
        __STATIC_INLINE ret_code_t pwr_mgmt_timer_create(void)
        {
            ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer,
                                                   APP_TIMER_MODE_REPEATED,
                                                   nrf_pwr_mgmt_timeout_handler);
            if (ret_code != NRF_SUCCESS)
            {
                return ret_code;
            }
    
            return app_timer_start(m_pwr_mgmt_timer, APP_TIMER_TICKS(1000), NULL);
        }

    #if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
        #undef  PWR_MGMT_TIMER_REQUIRED
        #define PWR_MGMT_TIMER_REQUIRED

    snippet from sdk_config.h

    // <q> NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY  - Blocked shutdown procedure will be retried every second.
     
    
    #ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
    #define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 1
    #endif

Children
No Data
Related