Retained register

Hi,

I need to save a 16 bit counter into a retained register.

I cannot use the 2 GPRETREG since they are already used and I cannot write internal flash.

I cannot use RAM retained.

Is there any other register suitable for this purpose?

Parents Reply Children
  • I see. That is not the case, though. If you compare the old nrf_power_gpregret_set() and nrf_power_gpregret2_set() you can see it takes two parameters. The new nrf_power_gpregret_set() takes three parameters, where one is the register number. So instead of having separate API functions for each GPREGRET register, the same is used for all.

  • Hi, Einar,

    Thanks for the hint. It indeed makes sense to have a single API function for that.
    Quick question though: the reg number is 0 and 1, right? Where 0 stands for GPREGRET1 and 1 for GPREGRET2? Seems logical, but wanted to confirm.
    Are there any restrictions on when GPREGRET2 becomes available boot cycle-wise? I've tried the direct access to it at PRE_KERNEL_1 stage, and it wasn't available - the app hung, while the GPREGRET1 was accessible and I was able to write into it. As far as I know the GPREGRET1 is used by the DFU, while GPREGRET2 is free for use with no chance of it being used by any internal nordic things, like DFU, correct?

  • As an aside, note there are other registers which are retained and could be used for data when the associated peripheral is not used on a particular design (taking care to avoid side-effects of course). Some mapping is required as the bits within the registers are not contiguous. Retained registers on the nRF52832:

    • GPIO: The PIN_CNF registers are retained registers
    • LPCOMP: All LPCOMP registers, including ENABLE, are classified as retained registers when the LPCOMP is enabled. However, when the device wakes up from System OFF, all LPCOMP registers will be reset
  • Hi,

    I am sorry for the late reply. 

    Normally both GPREGRET registers are available and usable. I tested with a modified beacon sample from SDK 3.2 with updated main function like this and see that both are incremented as expected after reset, without any errors. If this still do not work on your end, we need to look more closely at what you do in your design.

    #include <hal/nrf_power.h>
    
    int main(void)
    {
    	int err;
    
    	printk("Starting Beacon Demo\n");
    
    	uint32_t gpregret0_val = nrf_power_gpregret_get(NRF_POWER, 0);
    	uint32_t gpregret1_val = nrf_power_gpregret_get(NRF_POWER, 1);
    
    	/* Initialize the Bluetooth Subsystem */
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    	}
    
    	printk("GPREGRET0: 0x%08X\n", gpregret0_val);
    	printk("GPREGRET1: 0x%08X\n", gpregret1_val);
    
    	gpregret0_val++;
    	gpregret1_val++;
    
    	nrf_power_gpregret_set(NRF_POWER, 0, gpregret0_val);
    	nrf_power_gpregret_set(NRF_POWER, 1, gpregret1_val);
    
    	return 0;
    }
    

  • Hi, Einar,

    Thanks for your answer. I think the only difference of your code and mine is that you access the registers in your main function on the APPLICATION stage, but in my case I've accessed them in a function which is run on a PRE_KERNEL_1 stage.

Related