Retained RAM holds value after dev board unplugged

I am puzzled by what I have observed using retained ram on NRF54L15. I have this overlay (see below). Essentially created 16 KB SRAM at address 0x2002C000. I have a struct, sched_retain_t which i initialise at this address: 

sched_retain_t *p_sched_retain = (sched_retain_t *)0x2002C000;
In my app: 
p_sched_retain->g_u8grtcFlag = GRTC_KEY;
I cut power to the board, and read p_sched_retain->g_u8grtcFlag. Guess what, I read GRTC_KEY. I thought SRAM memory is lost if it loses power. What's going on please? 
/* Retained SRAM (volatile but survives System OFF) */
cpuapp_sram_ret: memory@2002c000 {
compatible = "zephyr,memory-region", "mmio-sram";
reg = <0x2002c000 0x00004000>; /* 16 KiB */
zephyr,memory-region = "RetainedMem";
status = "okay";

retainedmem0: retainedmem {
compatible = "zephyr,retained-ram";
status = "okay";
};
};
  • To expand on this question, my main problem is that I use grtc to wake me up from sys_poweroff (deep sleep). When I wake up from grtc I read resetreas GRTC. The problem is if I unplug and replug the usb cable, I also read wake up from GRTC. So I need to know if there was a power cut during system off. I thought I use a retained variable, but that survives a power cut. Suggestions? 

  • OK so apparently to cut power to this dk unplugging the USB cable is not enough as the PMIC somehow still provides some power to the nrf54l15 which leads to ram being retained. To get a power on reset, I disconnected the jumper on P6, and when I reconnected the jumper, the reset reason was 0 (power-on reset) and ram was not retained. I am not sure what this PMIC on this chip does and how it still supplies power when the usb cable is disconnected. If you can shed some light on what this PMIC is doing that would be appreciated. Thanks. 

  • Hi Nikollao,

    Right, that makes some more sense, as maybe some capacitors were able to hold enough charge to keep the device powered for a bit longer, especially when it is in System OFF mode, which consumes so little power.

    The problem is that I can't reproduce your observation with my kit. I tested with the System OFF sample, which is very similar to your setup.

    Could you please send me information about your kit? The data in the little white label on the front, except for the serial number.

    Please also tell me how long you wait between unplugging and plugging back in the cable. For reference, I went as low as just 1 second but still can't reproduce the issue.

  • Hi,

    Thanks for getting back to me. I have come across the sample you shared before, I am not using the zephyr helpers to store load from retained ram, instead I defined in device tree my retained ram region and initialised a struct at that address. It seems to be working fine. White label info: PCA10156 1.0.0 2025.30. If I simply disconnect the usb cable, retained ram is not lost, if I remove the P6 jumper, retained ram is lost. 

  • Hi,

    I don't have access to a nRF54L15 rev 1.0.0 at the moment, but I will try to find one in the coming days.

    Do you mind also sharing your project? I tried to setup something similar with my rev 0.9.2 DK, starting from just hello_world, but can't get a similar result.

    Here is my main.c for reference:

    #include <stdio.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/hwinfo.h>
    #include <zephyr/sys/poweroff.h>
    
    uint32_t* p_test_var = (uint32_t*) 0x2002C000;
    static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);
    
    void print_reset_cause(uint32_t reset_cause)
    {
    	if (reset_cause & RESET_DEBUG) {
    		printf("Reset by debugger.\n");
    	} else if (reset_cause & RESET_CLOCK) {
    		printf("Wakeup from System OFF by GRTC.\n");
    	} else if (reset_cause & RESET_LOW_POWER_WAKE) {
    		printf("Wakeup from System OFF by GPIO.\n");
    	} else  {
    		printf("Other wake up cause 0x%08X.\n", reset_cause);
    	}
    }
    
    
    int main(void)
    {
    	int rc;
    	uint32_t reset_cause;
    	printf("Hello World! %s %u\n", CONFIG_BOARD_TARGET, *p_test_var);
    
    	*p_test_var = *p_test_var + 1;
    	if (*p_test_var > 1000) {
    		*p_test_var = 0;
    	}
    	
    	hwinfo_get_reset_cause(&reset_cause);
    	print_reset_cause(reset_cause);
    
    		rc = gpio_pin_configure_dt(&sw0, GPIO_INPUT);
    	if (rc < 0) {
    		printf("Could not configure sw0 GPIO (%d)\n", rc);
    		return 0;
    	}
    
    	rc = gpio_pin_interrupt_configure_dt(&sw0, GPIO_INT_LEVEL_ACTIVE);
    	if (rc < 0) {
    		printf("Could not configure sw0 GPIO interrupt (%d)\n", rc);
    		return 0;
    	}
    
    	hwinfo_clear_reset_cause();
    	sys_poweroff();
    
    	return 0;
    }
    

Related