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 Reply Children
  • ON_RAMOFF_RTC System ON, no RAM retention, wake on RTC (running from LFRC clock)
    I want to implement this the my custom board schematic is like below and i want to implement the above  New Project_node_SCH_GPMU (1).pdf
    for the ON_RAMOFF_RTC System ON, no RAM retention, wake on RTC (running from LFRC clock) mechanism what are the things i have to do 
    1)

    #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();
    }
    }
    with this code i am getting the 3 micro ampheres so what are things i have to do for the above thing
    2)now i implemented the ION_RAMON_RTC System ON, full 256 kB RAM retention, wake on RTC (running from LFRC clock)
    3)so help me how to implement the 
    System ON, no RAM retention, wake on RTC (running from LFRC clock)

  • 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

Related