Compile error trying to use nrfx NVMC library with nRF54L15

Hello!

I would like to use OTP storage on the nRF54L15, as explained here:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/security/key_storage.html

That page says to use the nrfx NVMC library:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/data_storage.html#data-storage-nvmc

Which in turn links to the driver API:
https://docs.nordicsemi.com/bundle/nrfx-apis-latest/page/group_nrfx_nvmc.html

It seems I need to set
CONFIG_NRFX_NVMC=y
and use:
#include <nrfx_nvmc.h>

Having done that, my project fails to compile. It seems both nrf_nvmc.h and nrfx_nvmc.h have trouble finding certain symbols. This is an excerpt from the errors:

.../modules/hal/nordic/nrfx/hal/nrf_nvmc.h:75:35: error: 'NVMC_CONFIG_WEN_Ren' undeclared here (not in a function); did you mean 'RRAMC_CONFIG_WEN_Min'?
75 | NRF_NVMC_MODE_READONLY = NVMC_CONFIG_WEN_Ren, ///< NVMC in read-only mode.

.../modules/hal/nordic/nrfx/drivers/include/nrfx_nvmc.h:326:33: error: 'NRF_NVMC' undeclared (first use in this function)
326 | return nrf_nvmc_ready_check(NRF_NVMC);

It seems that NVMC_CONFIG_WEN_Ren and NRF_NVMC are defined in chip-specific include files, but I find no such include file for the nRF54L series.

According to the datasheet, the nRF54L series has UICR and OTP, so I assumed the driver would work:
https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/uicr.html

Any help would be much appreciated. My NCS version is 3.1.0.

Parents
  • Hello,

    The nrf54L is using RRAM instead of FLASH technology for non-volatile storage and has a different controller. Unfortunately, I see this part of the documentation has not yet been updated to reflect this.

    It seems I need to set
    CONFIG_NRFX_NVMC=y
    and use:
    #include <nrfx_nvmc.h>

    Set CONFIG_NRFX_RRAMC=y and include nrfx_rram.h instead. 

    For key storage I recommend having a look at this section of the SDK documentation https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/kmu_basics.html 

    Best regards,

    Vidar

  • I have two possible bugs to report in the RRAMC driver:

    1. OTP can be written even if writing is disabled.
    2. The nrfx_rramc_otp_word_write() function does not behave according to documentation.

    My code:

    static int test_otp(void)
    {
        nrfx_rramc_config_t config = NRFX_RRAMC_DEFAULT_CONFIG(0);
        nrfx_err_t err;
    
        err = nrfx_rramc_init(&config, NULL);
        if (err != NRFX_SUCCESS && err != NRFX_ERROR_ALREADY)
        {
            LOG_ERR("Failed to initialize RRAMC: 0x%x", err);
            return -ENODEV;
        }
        LOG_INF("RRAMC write enabled: %d", (int) nrfx_rramc_write_enable_check());
        LOG_INF("OTP[0]: 0x%08x", nrfx_rramc_otp_word_read(0));
        LOG_INF("Write to OTP[0]: %d", (int) nrfx_rramc_otp_word_write(0, 0x5a5a5a5a));
        LOG_INF("OTP[0]: 0x%08x", nrfx_rramc_otp_word_read(0));
        LOG_INF("Write to OTP[0]: %d", (int) nrfx_rramc_otp_word_write(0, 0x00000000));
        LOG_INF("OTP[0]: 0x%08x", nrfx_rramc_otp_word_read(0));
        return 0;
    }
    

    The output:

    [00:52:20.486,731] <inf> uicr_test: RRAMC write enabled: 0
    [00:52:20.486,741] <inf> uicr_test: OTP[0]: 0xffffffff
    [00:52:20.486,800] <inf> uicr_test: Write to OTP[0]: 1
    [00:52:20.486,805] <inf> uicr_test: OTP[0]: 0x5a5a5a5a
    [00:52:20.486,809] <inf> uicr_test: Write to OTP[0]: 0
    [00:52:20.486,813] <inf> uicr_test: OTP[0]: 0x5a5a5a5a
    

    Regarding bug 1, the write should not produce a change in the OTP register since according to the API, write is disabled, but the value is changed after the attempted write.

    Regarding bug 2, the way I interpret the documentation, given that write is possible (which it happens to be), nrfx_rramc_otp_word_write() should perform the write unless a 0 to 1 transition is requested in any bit, so both calls should succeed, but the second call fails. There is no 0 to 1 transition in 0xffffffff to 0x5a5a5a5a, and none in 0x5a5a5a5a to 0x00000000. Apparently it instead fails unless the existing value is all 1s?

    The documentation says:

    The OTP is only able to write '0' to bits in the UICR that are erased (set to '1').
    It cannot rewrite a bit back to '1'. This function checks if the value currently residing
    at the specified index can be transformed to the desired value without any '0' to '1' 
    transitions. If yes, then perform the write operation.
    
    Return values
    true	Word can be written into the specified OTP index address.
    false	Word cannot be written into the specified OTP index address. 
            Erase UICR or change index address.

  • Tom Weber said:
    OTP can be written even if writing is disabled.

    The write enable bit is being set inside the nrfx_rramc_otp_word_write() before the actual write, then it's cleared again. See implementation here https://github.com/zephyrproject-rtos/hal_nordic/blob/979a58d0829108b57f10e90b6c3fc35ab6206e4b/nrfx/haly/nrfy_rramc.h#L406 

    Tom Weber said:
    The nrfx_rramc_otp_word_write() function does not behave according to documentation.

    The behavior described in the API documentation does not correspond with the datasheet which states that you can only write once after an Erase All. I will forward this to the developers. Thank you for reporting this.

    Ref. https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/uicr.html 

  • Thank you!

    I assumed that "write" functions in the API would not be usable unless write was enabled, but I see now that they enable the write flag temporarily.

    What does the write flag protect against then - the application trying to write directly to an RRAM address without the API?

  • Happy to help! The HW (RRAM controller) requires you to explicitly set the write enable bit before performing any writes and it is recommended to clear it immediately after. This to mitigate the risk of memory corruption. A stack overflow, for example, could easily lead to corruption of RRAM if the write enable bit were kept enabled.

Reply Children
No Data
Related