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

Write to UICR CUSTOMER register not working

Hi,

Update:

Module: nRF52832

SDK v 14.2, SD v5.0, windows platform

I am trying to write to save a value to UICR customer register. My routine for saving the value to the register goes like this: 

            err_code = sd_softdevice_disable();
            if(err_code == 0)
            {
              NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een<<NVMC_CONFIG_WEN_Pos;
              while(NRF_NVMC->READY == NVMC_READY_READY_Busy){};

              NRF_UICR->CUSTOMER[4] = 0x0A0A0A0A;

              NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren<<NVMC_CONFIG_WEN_Pos;
              while(NRF_NVMC->READY == NVMC_READY_READY_Busy){};
              printf("HW calibration exited.\r\n");
              nrf_delay_ms(5);
              NVIC_SystemReset();
            }

While debugging, i can see the CONFIG register is changed to Wen and after writing, changed back to Ren. But after rebooting, i dont see the value being written to the register. 

Would  any of you what i am doing wrong here? Followed the process as mentioned in some of the forums here and the reference manual for NRF52832.

Thank you.

Parents
  • Why not use the functions in \modules\nrfx\hal\nrf_nvmc.h. E.g. use nrf_nvmc_write_bytes. You should also consider making sure the UICR area you are trying to write to is blank.

  • UICR is by default 0xFFFFFFFF. Do i need to erase UICR before writing to it? 

    for nrf_nvmc, i will have to check. Can you provide any example for its use.

    Thank you.

  • No, you do not need to erase the uicr before writing to it. If you know you will only call that functions once, I guess you do not have to check. But if you might end up calling it again, it would be a good idea to check the content to make sure it's empty before writing.

    Guess you saw the description:

    /**
     * @brief Write consecutive bytes to flash.
     *
     * @param address   Address to write to.
     * @param src       Pointer to data to copy from.
     * @param num_bytes Number of bytes in src to write.
     */
    void nrf_nvmc_write_bytes(uint32_t  address, const uint8_t * src, uint32_t num_bytes);

    So do something like this, p_src being what you want to write to uicr:

    UICR_START_ADDR                  ((uint32_t)&NRF_UICR->CUSTOMER[0])
    
    uint32_t num_bytes = p_src_length; //also check against your maximum allowed length
    nrf_nvmc_write_bytes(UICR_START_ADDR, (const uint8_t *) p_src, num_bytes);

Reply
  • No, you do not need to erase the uicr before writing to it. If you know you will only call that functions once, I guess you do not have to check. But if you might end up calling it again, it would be a good idea to check the content to make sure it's empty before writing.

    Guess you saw the description:

    /**
     * @brief Write consecutive bytes to flash.
     *
     * @param address   Address to write to.
     * @param src       Pointer to data to copy from.
     * @param num_bytes Number of bytes in src to write.
     */
    void nrf_nvmc_write_bytes(uint32_t  address, const uint8_t * src, uint32_t num_bytes);

    So do something like this, p_src being what you want to write to uicr:

    UICR_START_ADDR                  ((uint32_t)&NRF_UICR->CUSTOMER[0])
    
    uint32_t num_bytes = p_src_length; //also check against your maximum allowed length
    nrf_nvmc_write_bytes(UICR_START_ADDR, (const uint8_t *) p_src, num_bytes);

Children
Related