WHY I AM GETTIG THE 66.3 microA for this code in the nrf52840


#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_clock.h"
#include "nrf_power.h"
#include "nrfx_rtc.h"
#include "app_error.h"


#define WAKEUP_SECONDS 10
#define TICKS 8
// Configuration
const nrfx_rtc_t rtc_inst = NRFX_RTC_INSTANCE(2);

/** @brief Handler for RTC interrupts */
void rtc_handler(nrfx_rtc_int_type_t int_type)
{
if (int_type == NRFX_RTC_INT_COMPARE0)
{
// 1. Get the current counter value
uint32_t current_ticks = nrfx_rtc_counter_get(&rtc_inst);

// 2. Set the next wakeup relative to "now"
uint32_t next_wakeup = current_ticks + (WAKEUP_SECONDS * TICKS);

// 3. Handle the 24-bit mask (RTC counter is 24-bit)
next_wakeup &= RTC_COUNTER_COUNTER_Msk;

nrfx_rtc_cc_set(&rtc_inst, 0, next_wakeup, true);
}
}

/** @brief Start LFRC (Internal RC) for ION_RAMOFF_RTC 1.50 uA profile */
static void lfclk_config(void)
{
// Use direct register access to avoid "nrf_clock_lf_src_t" type errors
// 0 = RC Oscillator
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);

NRF_CLOCK->TASKS_LFCLKSTART = 1;

while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
}

/** @brief Configure RTC2 */
static void rtc_config(void)
{
nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
config.prescaler = 4095; // 8 Hz

uint32_t err_code = nrfx_rtc_init(&rtc_inst, &config, rtc_handler);
APP_ERROR_CHECK(err_code);

nrfx_rtc_cc_set(&rtc_inst, 0,WAKEUP_SECONDS*TICKS, true);
nrfx_rtc_enable(&rtc_inst);
}

/** @brief Disable RAM retention to hit the 1.50 uA target */
static void disable_ram_retention(void)
{
// On nRF52840, there are 9 RAM sections.
// We disable sections 2-8 to preserve the stack (usually in section 0 or 1).
// Writing 0xFFFFFFFF to POWERCLR turns off Power and Retention for that block.
for (int i = 1; i <= 6; i++)
{
NRF_POWER->RAM[i].POWERCLR = /*0xFFFFFFFF*/1;
}
}


void power_off_all_unused_peripherals(void)
{
// 1. Reset all GPIO pins to 'Input Disconnected' (The default reset state)
// nRF52840 has 32 pins on Port 0 and 16 pins on Port 1.
for (uint32_t i = 0; i < 32; i++) {
NRF_P0->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
}
for (uint32_t i = 0; i < 16; i++) {
NRF_P1->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
}

// 2. Disable high-power EasyDMA peripherals
NRF_UARTE0->ENABLE = 0; NRF_UARTE1->ENABLE = 0;
NRF_SPIM0->ENABLE = 0; NRF_SPIM1->ENABLE = 0;
NRF_SPIM2->ENABLE = 0; NRF_SPIM3->ENABLE = 0;
NRF_TWIM0->ENABLE = 0; NRF_TWIM1->ENABLE = 0;
NRF_QSPI->ENABLE = 0;

// 3. Power cycle DMA blocks (Workaround for base current leakage)
*(volatile uint32_t *)0x40002FFC = 0; // UARTE0
*(volatile uint32_t *)0x40003FFC = 0; // SPIM0/TWIM0
*(volatile uint32_t *)0x40004FFC = 0; // SPIM1/TWIM1
*(volatile uint32_t *)0x40023FFC = 0; // SPIM2
*(volatile uint32_t *)0x40028FFC = 0; // UARTE1
*(volatile uint32_t *)0x40029FFC = 0; // QSPI
*(volatile uint32_t *)0x4002FFFC = 0; // SPIM3

// 4. Disable Radio and Analog blocks
NRF_SAADC->ENABLE = 0;
NRF_RADIO->TASKS_DISABLE = 1;
NRF_NFCT->TASKS_DISABLE = 1;
NRF_COMP->ENABLE = 0;
NRF_LPCOMP->ENABLE = 0;

// 5. Disable PWM, PDM, and I2S
NRF_PWM0->ENABLE = 0; NRF_PWM1->ENABLE = 0;
NRF_PWM2->ENABLE = 0; NRF_PWM3->ENABLE = 0;
NRF_PDM->ENABLE = 0; NRF_I2S->ENABLE = 0;

// 6. Stop unused Timers/RTCs (Keep RTC2 active!)
NRF_TIMER0->TASKS_STOP = 1; NRF_TIMER1->TASKS_STOP = 1;
NRF_TIMER2->TASKS_STOP = 1; NRF_TIMER3->TASKS_STOP = 1;
NRF_TIMER4->TASKS_STOP = 1;
NRF_RTC0->TASKS_STOP = 1; NRF_RTC1->TASKS_STOP = 1;

// 7. Kill PPI and GPIOTE
NRF_PPI->CHEN = 0;
for (int i = 0; i < 8; i++) { NRF_GPIOTE->CONFIG[i] = 0; }

NRF_CLOCK->TASKS_HFCLKSTOP = 1;
}

int main(void)
{
// 1. Initialize Clock
// log_init();
power_off_all_unused_peripherals();
lfclk_config();
// 2. Initialize RTC
rtc_config();
// 3. Drop RAM power (RAMOFF state)
disable_ram_retention();
// 4. Enter System ON sleep
while (true)
{
__WFE();
__SEV();
__WFE();
}
}

Parents
  • Hi,

     

    What external devices do you have connected on your board?

     By running this function:

    void power_off_all_unused_peripherals(void)
    {
    // 1. Reset all GPIO pins to 'Input Disconnected' (The default reset state)
    // nRF52840 has 32 pins on Port 0 and 16 pins on Port 1.
    for (uint32_t i = 0; i < 32; i++) {
    NRF_P0->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
    }
    for (uint32_t i = 0; i < 16; i++) {
    NRF_P1->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
    }

    You will leave all GPIOs floating. This is undesired if you have signals that require a pull on external ICs, like a /CE signal.

    Those connected signals must be pulled to its idle state.

     

    Kind regards,

    Håkon

  • Hii Hakon Alseth

    I think it alone cant solve my problem give me the further steps please
    I done your solution i got the 82 micro amps so what are the further steps please.

    Thanks &Regards:
    K.Brahmaiah

  • Hi,

     

    brahmaiah kancharla said:
    with this code i am getting the 3 micro ampheres so what are things i have to do for the above thing

    If you are now getting 3 uA, that is great.

    But; what is the difference in your code here, vs what you have done earlier when you measured ~70 uA?

    brahmaiah kancharla said:
    System ON, no RAM retention, wake on RTC (running from LFRC clock)

    You cannot wake up with unpowered RAM in systemon idle mode. Or you could, but it will fail horribly.

     

    Kind regards,

    Håkon

  • The difference from the 70 uA to the 3 uA is i disconected jlink pins to my the custom board so i got the 3 uA


    #include <stdbool.h>
    #include <stdint.h>
    #include "nrf.h"
    #include "nrf_clock.h"
    #include "nrf_power.h"
    #include "nrfx_rtc.h"
    #include "app_error.h"

    #define WAKEUP_SECONDS 10
    #define TICKS 8

    const nrfx_rtc_t rtc_inst = NRFX_RTC_INSTANCE(2);

    /** @brief Handler for RTC interrupts */
    void rtc_handler(nrfx_rtc_int_type_t int_type)
    {
    if (int_type == NRFX_RTC_INT_COMPARE0)
    {
    uint32_t current_ticks = nrfx_rtc_counter_get(&rtc_inst);
    uint32_t next_wakeup = current_ticks + (WAKEUP_SECONDS * TICKS);
    next_wakeup &= RTC_COUNTER_COUNTER_Msk; // 24-bit mask
    nrfx_rtc_cc_set(&rtc_inst, 0, next_wakeup, true);
    }
    }

    /** @brief Start LFRC (Internal RC oscillator) */
    static void lfclk_config(void)
    {
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    }

    /** @brief Configure RTC2 with 8 Hz tick rate */
    static void rtc_config(void)
    {
    nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
    config.prescaler = 4095; // 32768 / (4095+1) = 8 Hz
    uint32_t err_code = nrfx_rtc_init(&rtc_inst, &config, rtc_handler);
    APP_ERROR_CHECK(err_code);
    nrfx_rtc_cc_set(&rtc_inst, 0, WAKEUP_SECONDS * TICKS, true);
    nrfx_rtc_enable(&rtc_inst);
    }

    /** @brief Disable ALL RAM retention (RAMOFF state) */
    static void disable_ram_retention(void)
    {
    // nRF52840 has RAM blocks 0-8 (9 total).
    // Write 0xFFFFFFFF to POWERCLR to clear all Power and Retention bits.
    for (int i = 0; i <= 8; i++)
    {
    NRF_POWER->RAM[i].POWERCLR = 0xFFFFFFFF;
    }
    }

    /** @brief Shut down all unused peripherals */
    static void power_off_all_unused_peripherals(void)
    {
    // 1. Disconnect all GPIO pins
    for (uint32_t i = 0; i < 32; i++) {
    NRF_P0->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
    }
    for (uint32_t i = 0; i < 16; i++) {
    NRF_P1->PIN_CNF[i] = (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
    }

    // 2. Disable EasyDMA peripherals
    NRF_UARTE0->ENABLE = 0; NRF_UARTE1->ENABLE = 0;
    NRF_SPIM0->ENABLE = 0; NRF_SPIM1->ENABLE = 0;
    NRF_SPIM2->ENABLE = 0; NRF_SPIM3->ENABLE = 0;
    NRF_TWIM0->ENABLE = 0; NRF_TWIM1->ENABLE = 0;
    NRF_QSPI->ENABLE = 0;

    // 3. Power cycle DMA blocks (errata workaround for leakage)
    *(volatile uint32_t *)0x40002FFC = 0; // UARTE0
    *(volatile uint32_t *)0x40003FFC = 0; // SPIM0/TWIM0
    *(volatile uint32_t *)0x40004FFC = 0; // SPIM1/TWIM1
    *(volatile uint32_t *)0x40023FFC = 0; // SPIM2
    *(volatile uint32_t *)0x40028FFC = 0; // UARTE1
    *(volatile uint32_t *)0x40029FFC = 0; // QSPI
    *(volatile uint32_t *)0x4002FFFC = 0; // SPIM3

    // 4. Disable Radio and Analog blocks
    NRF_SAADC->ENABLE = 0;
    NRF_RADIO->TASKS_DISABLE = 1;
    NRF_NFCT->TASKS_DISABLE = 1;
    NRF_COMP->ENABLE = 0;
    NRF_LPCOMP->ENABLE = 0;

    // 5. Disable PWM, PDM, I2S
    NRF_PWM0->ENABLE = 0; NRF_PWM1->ENABLE = 0;
    NRF_PWM2->ENABLE = 0; NRF_PWM3->ENABLE = 0;
    NRF_PDM->ENABLE = 0; NRF_I2S->ENABLE = 0;

    // 6. Stop unused Timers and RTCs (keep RTC2 active!)
    NRF_TIMER0->TASKS_STOP = 1; NRF_TIMER1->TASKS_STOP = 1;
    NRF_TIMER2->TASKS_STOP = 1; NRF_TIMER3->TASKS_STOP = 1;
    NRF_TIMER4->TASKS_STOP = 1;
    NRF_RTC0->TASKS_STOP = 1; NRF_RTC1->TASKS_STOP = 1;

    // 7. Disable PPI and all GPIOTE channels (event mode adds ~17 uA!)
    NRF_PPI->CHEN = 0;
    for (int i = 0; i < 8; i++) { NRF_GPIOTE->CONFIG[i] = 0; }

    // 8. Stop HFCLK
    NRF_CLOCK->TASKS_HFCLKSTOP = 1;
    }

    int main(void)
    {
    // power_off_all_unused_peripherals();
    lfclk_config();
    // Enable DC/DC converter (up to 35% power savings)
    nrf_power_dcdcen_set(true);
    rtc_config();

    // Disable all RAM retention -> RAMOFF state (target: 1.50 uA)
    // disable_ram_retention();

    // System ON sleep loop
    while (true)
    {
    __WFE();
    __SEV();
    __WFE();
    }
    }

  • Hi,

     

    brahmaiah kancharla said:
    The difference from the 70 uA to the 3 uA is i disconected jlink pins to my the custom board so i got the 3 uA

    Great. Glad to hear that you solved your problem!

     

    Kind regards,

    Håkon

  • System ON, no RAM retention, wake on RTC (running from LFRC clock)

    You cannot wake up with unpowered RAM in systemon idle mode. Or you could, but it will fail horribly.

    explain
    then why the above feautre is present in the datasheet explain

  • When you wake up from system on, you will start execution from the program counter.

    If you then access cleared / uninitialised RAM, your firmware will not execute as wanted.

     

    brahmaiah kancharla said:
    then why the above feautre is present in the datasheet explain

    It is to show how much the RAM retention adds in sleep, but I agree; it is not a great metric, since waking up with no RAM retention is not a wanted scenario.

     

    Kind regards,

    Håkon

Reply
  • When you wake up from system on, you will start execution from the program counter.

    If you then access cleared / uninitialised RAM, your firmware will not execute as wanted.

     

    brahmaiah kancharla said:
    then why the above feautre is present in the datasheet explain

    It is to show how much the RAM retention adds in sleep, but I agree; it is not a great metric, since waking up with no RAM retention is not a wanted scenario.

     

    Kind regards,

    Håkon

Children
Related