Elan
Elan

Reputation: 1

NRF52832 encounters low power consumption and sleep problems after turning on HFXO

When verifying the low power consumption of NRF52832, softdevice is not used, high-speed and low-speed crystal oscillators are connected externally, and the external crystal oscillator is used as the clock source. Now I have done a short test, the main functions are: a. Turn on HFXO and LFXO and use external crystal oscillators respectively. b. Enable a GPIO to control a Led, turn on the comparison interrupt 0 of rtc0 as a wake-up, set the time to 5 seconds, and set the next timeout time to 5 seconds in the rtc cc0 ISR. c. The while loop in main() contains the following steps: - Turn off HFXO (reduce power consumption) - Enter sleep (for testing, several writing methods are verified here: WFI, WFE, WFE SEV WFE, SEV WFE WFE) - Exit sleep due to rtc interrupt and restart HFXO - For the LED flash obviously, cycle and wait for a period of time, then turn off the LED

Expected result: LED flashes every 5 seconds

I have the following problems:

  1. In the loop in main, if HFCLK is not turned off before sleeping, the power consumption is relatively high at about 280uA. If HCLK is turned off, the power consumption can be as low as 3uA. But I read from the manual that HFCLK describes that if there is no peripheral that requires HCLK and does not need to be turned off, it will automatically enter the energy-saving mode. Is the 200uA here already in energy-saving mode? It still feels like it's running. Looking at the low-power routines without softdevice in the SDK, HFCLK is not processed before sleeping. enter image description here enter image description here
  2. Based on the requirement in 1, HCLK needs to be turned on and off before sleeping. If WFI is used for sleep, the entire function is normal, but it is abnormal to use WFE or WFE SEV WFE. In fact, it means that when WFE is executed , there are "reasons" why it cannot enter low power consumption. If HFCLK is not turned on and off before and after sleep, you can sleep normally, but the power consumption is high. Post-positioning has nothing to do with turning off HFCLK. It is mainly a problem caused by turning it on. But SEV WFE WFE is normal, because SEV WFE will clear all events, and the subsequent WFE will make the MCU enter a low-power state. But this method is risky. Clearing the event first will cause a real wake-up to go to sleep without preventing it. The problem here is that the interrupts of the clock are all turned on. The interrupt triggered when HFCLK behind the low-power consumption is turned on has already been cleared in the ISR. Why will it affect the subsequent sleep?

Here is the code for the test:

static void _rtc0_timer_callback(nrfx_rtc_int_type_t int_type);

#define LED_PIN 13

static void led_init(void)
{
  nrf_gpio_cfg_output(LED_PIN);
}

static void led_turn_on(void)
{
  nrf_gpio_pin_write(LED_PIN, 0);
}

static void led_turn_off(void)
{
  nrf_gpio_pin_write(LED_PIN, 1);
}

void _rtc_timer_start(void)
{
    nrfx_rtc_t            timer_inst = NRFX_RTC_INSTANCE(0);
    nrfx_rtc_config_t     timer_cfg = NRFX_RTC_DEFAULT_CONFIG;
    
    // low frequency clock
    nrf_clock_lf_src_set((nrf_clock_lfclk_t)1);
    nrfx_clock_lfclk_start();
    
    // config
    timer_cfg.prescaler = RTC_FREQ_TO_PRESCALER(32768);
    
    nrfx_rtc_init(&timer_inst, &timer_cfg, _rtc0_timer_callback);
    nrfx_rtc_counter_clear(&timer_inst);
    nrfx_rtc_overflow_enable(&timer_inst, true);
    nrfx_rtc_enable(&timer_inst);
}

void _rtc_timer_set_next(uint32_t time_us)
{
    uint32_t tick;
    tick = (uint32_t)(time_us / (1000000.0 / 32768));
    
    nrfx_rtc_t timer_inst = NRFX_RTC_INSTANCE(0);
    tick = (tick + nrfx_rtc_counter_get(&timer_inst));
    nrfx_rtc_cc_set(&timer_inst, 0, tick, true);
}

static void _rtc0_timer_callback(nrfx_rtc_int_type_t int_type)
{
    // set next timeout
    _rtc_timer_set_next(5000000);
}

static void clk_event_handler(nrfx_clock_evt_type_t event)
{
}

int main(void)
{
    nrfx_clock_init(clk_event_handler);
    nrfx_clock_enable();
    nrfx_clock_hfclk_start();
    while(nrfx_clock_hfclk_is_running() == false)
    {
    }
    nrfx_clock_lfclk_start();
    while(nrfx_clock_lfclk_is_running() == false)
    {
    }
    
    led_init();
    led_turn_off();
    
    _rtc_timer_start();
    _rtc_timer_set_next(5000000);
    
    while(1)
    {
        // Turn off HFXO, switch hfclk to HFINT, to reduce power consumption
        nrfx_clock_hfclk_stop();
        
        // Execute following code, Led is always on, and MCU can not enter sleep mode.
        // __WFE();
        // __SEV();
        // __WFE();
        
        // Execute following code, Led is flash every 5 secons, but SEV && SFE may clear any event generated before, which may be useful for wakeuo system to handle appropriate event.
        // __SEV();
        // __WFE();
        // __WFE();
        
        // Execute following code, Led is flash every 5 secons
        __WFI();
        
        // Execute following code, Led is always on, and MCU can not enter sleep mode.
        // __WFE();
        
        // Turn on the HFXO, and switch HFCLK to it.
        // As long as this line is commented out, the above sleep behaviors are in line with expectations.
        // But the clock interrupt is enabled, why does it affect the behavior of wfe?
        nrfx_clock_hfclk_start();
        while(nrfx_clock_hfclk_is_running() == false)
        {
        }
        
        // 点亮一会Led,使其观察明显
        led_turn_on();
        for(uint32_t i = 1000000; i > 0; i--)
        {
            __NOP();
        }
        led_turn_off();
    }
}
  1. I want to know why the operation of the clock in the while loop affects the sleep behavior of wfe.
  2. The sleep in the SDK of nrf52832 adopts WFE, SEV and WFE methods, and HFXO is not closed or opened before and after. However, if I do this, it will cause an increase in power consumption. How should I deal with it.

Upvotes: 0

Views: 149

Answers (0)

Related Questions