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

Writing to nvram

I would like help in understanding the limitations of the NVRAM. The documentation for the nRF52840 and the nRF52832 are different. This is what the nRF52840 reads:

Nvram write 52840 doc

Do I understand correctly that, for any word in a 4K block, it can only be written twice before the entire page must be erased?

The nRF52832 seems to have a different limitation:

nvram writing nRF52840

This is more complicated. Here the page is divided into 512 byte blocks and the limitations is 181 writes per block before page erase is needed. Here nothing is said about a 32 bit word write.

The reason I ask is that I am using Gazell pairing. It seems to me that, for part of the database in nvram, it partitions up its information into 4bit chunks, 8 to a 32 bit word. It shuffles bits and requires a byte to be written, I think for each pairing, which of course turns into a 32 bit word being written per byte demanded i.e. potentially 8 times. It would appear therefore that the nRF52840 is incompatible with the current version of Gazell, which, to say the least is worrying to me since I am sort-of committed to both. What is wrong with my understanding above?

  • Just a suggestion to your software gurus, once you have checked that writing a 1 to an already written zero in nvram has no impact, here is my suggestion for a much simplified byte write routine:

    //Here is a suggestion. Perhaps only for the nRF52840??
    //I have no test harness to check if it is valid.
    //This is simple but relies entirely that writing a 1 to an existing zero does no harm.
    //You have to be a bit careful in C with type casting here.
    
    void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
    {
        uint32_t byte_shift = address & (uint32_t)0x03; //the address of the byte in a 32 bit word.
        uint32_t address32 = address & ~byte_shift; // Address of the word this byte is in.
        //Then, take the value to be written, negate it as 8 bits only, convert to 32 bits,
        //shift it into position and XOR to 0xFFFFFFFF.
        //Thus the result will all ones outside the byte to be written.
        uint32_t value32 = 0xFFFFFFFF ^ (((uint32_t)(uint8_t)(~value)) << (byte_shift << 3));
    
        // Enable write.
        NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
        __ISB();
        __DSB();
        //actually do the write.
        *(uint32_t*)address32 = value32;
        wait_for_flash_ready();
    
        NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
        __ISB();
        __DSB();
    }

    Unless the same byte is written to more than once, zeros are only written once.

    I hope that I have given sufficient explanation and my proposal for modification is not too presumptious.

    Ray

    PS, there is a "word write" which I have not yet checked.

  • I have updated the internal jira case with your suggestions, I will let you know when I learn more.

  • Hello, thank you for your response. There is an even more optimal solution where the demand zeros are checked against the existing zeros to avoid trying to re-write them. I will try to give a coding example. It isn't very complicated.

    PS, what is "jira"?

    Regards, Ray

  • Oh, oh, Am I misleading people here. I have just discovered that there are TWO versions of write to nvram and I am probably looking at the wrong one. The one that I have been analysing is nrf_nvmc_write_byte which is included in my project. It is still extant in sdk V17 and is one of only two .c program in the .hal subdirectory under "nrfx". I have just found a version which is nrfx_nvmc_write_byte which is much more generic and, at first glance, looks like it doesn't have the same problem. That is in 

    nRF5_SDK_17.0.0_9d13099\modules\nrfx\drivers\src

    I wish that someone had mentioned that I was using out-of date software as from SDK V16 - would have saved me some time. Also, how are users supposed to know when they can change from nrf to nrfx versions? I obviously missed something.

    So, I think I will close the case after a bit of study of how the nrfx version works simply with the remark that "If you continue to use the nrf versions on the nRF52840, you will be contravening the hardware limitations. Switch to those in nRF5_SDK_17.0.0_9d13099\modules\nrfx\drivers to avoid that". Sigh.

    (edit) not so fast - being as the name is changed the software for gzp no longer links. I will have to look at how the old and new match and maybe edit gzp software which I am not too keen on. - more later.

Related