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

Writing to UICR from application code

Hello,

I am truing to store data in the UICR register "customer area" from application code. The procedure is invoked only once when the registers are still empty. The code is as follows:

void write_to_uicr()
{
        uint32_t data_to_write;

        uint32_t err_code = sd_softdevice_disable();
        APP_ERROR_CHECK(err_code);

        interrupts_disable();
        //...

        data_to_write = get_data();

        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;	
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        *(uint32_t *)0x10001080 = data_to_write ;
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;	
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}

}

Unfortunately the only data written to the registers is 0x00000000 even though I can verify with the debugger that the value of the "data_to_write" variable is different than zero and it is as expected. Optimizations are switched off. I would be more than glad to get any input on this problem. Thank you in advance!

Parents
  • I am adding more details related to the problem in this post. In general the code that I am debugging is in two files. The first file contains a variable which is retrieved and stored in the UICR from the second file.

    Data provider (provider.c):

     ...
    static uint32_t data;
    ...
    
    uint32_t get_data(void)
    {
        return data;
    }
    

    UICR write (write.c)

    ...
    extern uint32_t get_data(void);
    ...
    static void update_uicr_customer_data()
    {
        data = get_data();
    
        if(data != 0){
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
            *(uint32_t *)0x10001080 = data;
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        }else
        {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
            *(uint32_t *)0x10001080 = 0x22222222;
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        }
    }
    

    With the debugger I can verify that the content of the "data" variable is "1234" after the function returns and this is what I expect to get as a result. Then the if statement is executed. The else is there just to prove that data != 0.

    The content of the 0x10001080 at this point is:

    0x10001080: 00001234 FFFFFFFF FFFFFFFF FFFFFFFF
    

    However, after a power-cycle of the chip the content of the memory location reads back as:

    0x10001080: 00000220 FFFFFFFF FFFFFFFF FFFFFFFF
    

    Furthermore, if i replace the call to the external function with a call to function in the same file (write.c) the writing procedure goes as expected and the value is preserved after power-cycle.

    It looks like I am doing something wrong, but I was blaming the UICR write... Do you have comments on this? Thank you in advance.

Reply
  • I am adding more details related to the problem in this post. In general the code that I am debugging is in two files. The first file contains a variable which is retrieved and stored in the UICR from the second file.

    Data provider (provider.c):

     ...
    static uint32_t data;
    ...
    
    uint32_t get_data(void)
    {
        return data;
    }
    

    UICR write (write.c)

    ...
    extern uint32_t get_data(void);
    ...
    static void update_uicr_customer_data()
    {
        data = get_data();
    
        if(data != 0){
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
            *(uint32_t *)0x10001080 = data;
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        }else
        {
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
            *(uint32_t *)0x10001080 = 0x22222222;
            NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        }
    }
    

    With the debugger I can verify that the content of the "data" variable is "1234" after the function returns and this is what I expect to get as a result. Then the if statement is executed. The else is there just to prove that data != 0.

    The content of the 0x10001080 at this point is:

    0x10001080: 00001234 FFFFFFFF FFFFFFFF FFFFFFFF
    

    However, after a power-cycle of the chip the content of the memory location reads back as:

    0x10001080: 00000220 FFFFFFFF FFFFFFFF FFFFFFFF
    

    Furthermore, if i replace the call to the external function with a call to function in the same file (write.c) the writing procedure goes as expected and the value is preserved after power-cycle.

    It looks like I am doing something wrong, but I was blaming the UICR write... Do you have comments on this? Thank you in advance.

Children
No Data
Related