This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Storing variable values in system off mode.

Hi,

I need to store few variables values(long a = 4568;) to RAM (might be some other place) when the system went to sytem off mode .

How I can achieve in the nRF 51822 version 3.1 controller with SDK 6 and SD S110 .

Regards, Anand

  • Hi Anand,

    I am assuming that you are asking on how to put RAM in retention mode just before system off.

    // Switch on both RAM banks when in System OFF mode.
    NRF_POWER->RAMON |= (POWER_RAMON_OFFRAM0_RAM0On << POWER_RAMON_OFFRAM0_Pos) | 
                        (POWER_RAMON_OFFRAM1_RAM1On << POWER_RAMON_OFFRAM1_Pos);
    
    // Enter System OFF and wait for wake up from GPIO detect signal.
    NRF_POWER->SYSTEMOFF = 0x1;
    

    This will put both the RAM banks into retention and your stored values in ram will retain their values after the system wakes up from OFF mode.

    I would also recommend you to use latest SDK available for your projects. developer.nordicsemi.com/.../

    Also do not initialize RAM at every system restart Capture.JPG

  • Hi Aryan,

    I have a variable of below type and I want to retain this value after the system wakeup from the system off mode. Can you please provide me the complete code for the retaining this value. I am using SDK 6 ,nRF3.1 version controller and SD s110.

    unsigned char ManufacturerData[30] ;

  • static void display_failure(void) { while (true) { LEDS_INVERT(LEDS_MASK); nrf_delay_ms(1000); } }

    void HardFault_Handler()
    {
    		display_failure();
        LEDS_ON(LEDS_MASK);
    
        // Loop forever.
        while (true)
        {
     
        }
    }
    
    int main(void)
    {
    		uint8_t ManufacturerData[30] ;
    		uint32_t count = 0;
    		uint8_t * p_ram_test;	
    		
    		p_ram_test = (uint8_t *)&ManufacturerData[0];
        LEDS_CONFIGURE(LEDS_MASK);
        LEDS_OFF(LEDS_MASK);
    
        // This pin is used for waking up from System OFF and is active low, enabling sense capabilities.
        nrf_gpio_cfg_sense_input(PIN_GPIO_WAKEUP, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW);
    	
        // Workaround for PAN_028 rev1.1 anomaly 22 - System: Issues with disable System OFF mechanism
        nrf_delay_ms(1);
    
        // Check if the system woke up from System OFF mode by reading the NRF_POWER->GPREGRET register which has
        // retained the value written before going to System OFF. Below is the layout for usage for
        // NRF_POWER->GPREGRET register.
        //  BITS |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0
        //  --------------------------------------------------------------------
        //       |        SPECIAL_SEQUENCE       
        //  --------------------------------------------------------------------
        ///
    
        if (NRF_POWER->GPREGRET  == RESET_MEMORY_TEST_BYTE)
        {
    			// We can be here only after we woken up from system off after pressing the button.
    			// clear GPREGRET register before exit.
    			NRF_POWER->GPREGRET = 0;
    
    			for(count = 0; count < sizeof(ManufacturerData); count++)
    			{
    				if(*p_ram_test++ != count)
    				{
    					display_failure();	// This means the contents of RAM were not the same that we wrote just before system off
    				}
    			}
    
    			LEDS_ON(1 << SUCCESS_PIN_NUMBER); // RAM retention worked for our variable
    			
    			while (true)
    			{
    					// Do nothing.
    			}
        }
    
        // Write the known sequence to the GPREGRET register.
        NRF_POWER->GPREGRET = RESET_MEMORY_TEST_BYTE;
    
        // Write the known value to the known address in RAM, enable RAM retention, set System OFF, and wait
        // for GPIO wakeup from external source.
    
        LEDS_ON(1 << READY_PIN_NUMBER);
        nrf_delay_ms(1000);
    
        // Switch on both RAM banks when in System OFF mode.
        NRF_POWER->RAMON |= (POWER_RAMON_OFFRAM0_RAM0On << POWER_RAMON_OFFRAM0_Pos) |
                            (POWER_RAMON_OFFRAM1_RAM1On << POWER_RAMON_OFFRAM1_Pos);
    
    		// Write a sequence of numbers to the RAM addresses to be tested
    		for(count = 0; count < sizeof(ManufacturerData); count++)
    		{
    			*p_ram_test++ = count;
    		}
    					
    
        // Enter System OFF and wait for wake up from GPIO detect signal.
        NRF_POWER->SYSTEMOFF = 0x1;
    
    		while(1);	// This is useful to debug systemoff mode
    
    }
    
  • One more thing Anand,

    The value of the ManufacturerData is preserved when the system wakes up from SYSYEMOFF. But your code has to guarentee that it will not be corrupted by stack push and pop operations in the initialization code (system startup). That is something you should take special care of, and that depends on how your function call structure is organized. If there is even one push/pop happening before main (in system startup code), then your ManufacturerData[30] will most likely be corrupted after the chip wakes up from the system off mode .

Related