How to write UICR at runtime in the nRF5340

Hi,

I would like to know how to write to the UICR OTP (0x00FF8300) in the application core of the nRF5340 at runtime.
This procedure should be performed once at the factory via BLE (not possible to use the programmer); afterwards, the firmware should only access it as read-only.

I tried running this code (simplified), but it didn’t work.

Board: nRF5340-DK
VS Code, SDK 2.5.0

#define TARGET_ADDRESS 0x00FF8300

void UICR_write(uint32_t data)
{
    NRF_NVMC_Type nvcm;

    // Enable write mode
    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
    __ISB();
    __DSB();

    // Write the value
    *(uint32_t *)TARGET_ADDRESS = data;

    // Wait until write is finished
    while (!nrf_nvmc_ready_check(&nvcm)) {}
    
    // Disable write mode
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
    __ISB();
    __DSB();

    // Reset to apply changes
    sys_reboot(SYS_REBOOT_COLD);
}


void main (void)
{
    UICR_write(0x12345678);
}

After reset, I read the register with the nrfjprog command:

nrfjprog -f nrf53 --memrd 0x00FF8300 --w 8 --n 4
0x00FF8300: FF FF FF FF             |....|

However, when I write to it using nrfjprog, the value is written.

nrfjprog -f nrf53 --memwr 0x00FF8300 --val 0x12345678
Parsing parameters.
Writing.

nrfjprog -f nrf53 --memrd 0x00FF8300 --w 8 --n 4
0x00FF8300: 78 56 34 12


What would be the correct method for writing to the UICR OTP in the application core of the nRF5340 at runtime?

Thanks!

  • Sorry, my fault!

    This is the corrected code:

    void UICR_write(uint32_t data)
    {
        NRF_NVMC_Type* nvmc;
    
        nvmc = NRF_NVMC;
    
        // Enable write mode
        nvmc->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
        __ISB();
        __DSB();
    
        // Write the value
        *(uint32_t *)TARGET_ADDRESS = data;
    
        // Wait until write is finished
        while (!nrf_nvmc_ready_check(nvmc)) {}
        
        // Disable write mode
        nvmc->CONFIG = NVMC_CONFIG_WEN_Ren;
        __ISB();
        __DSB();
    
        // Reset to apply changes
        sys_reboot(SYS_REBOOT_COLD);
    }
    

Related