How to use NVR1 for saving application data?

Hello,
Below function is for saving some data to NVR1.
And NVR1_WriteEnable function is copied from NVR2_WriteEnable and just changed “NVR2” to “NVR1”.
But as the Table 9. Application Specific Information from firmware reference,
It seems that FLASH_NVR1_BASE should not be used as the starting address for writing my data.
Is it right? then cannot use Flash_EraseSector also…? How to use NVR1?

FlashStatus Flash_WriteNVRData(void)
{
FlashStatus status;
unsigned int wordLen;

wordLen = Get_WordLength(DATA_TYPE_NVR);

NVR1_WriteEnable(true);
status = Flash_EraseSector(FLASH_NVR1_BASE);
if (status != FLASH_ERR_NONE)
{
	DBG_PRINT("Flash Erase Error:FLASH_NVR1_BASE, %x\r\n", status);
	return status;
}
status = Flash_WriteBuffer(FLASH_NVR1_BASE, wordLen, (unsigned int*)&nvrData);
NVR1_WriteEnable(false);

return status;

}

void NVR1_WriteEnable(bool enable)
{
/* Lock or unlock NVR1 region */
FLASH->NVR_CTRL = NVR1_WRITE_ENABLE;
FLASH->NVR_WRITE_UNLOCK = enable ? FLASH_NVR_KEY : 0;

/* Check the lock/unlock operation result */
bool NVR1_unlocked = (FLASH->IF_STATUS & 0x3FF) == 0x20;

/* Error checking: this application needs to write in flash. If an error
 * occurred while locking/unlocking NVR1, wait for a watchdog reset */
if (NVR1_unlocked != enable)
{
    /* Disable all interrupts and clear any pending interrupts */
    Sys_NVIC_DisableAllInt();
    Sys_NVIC_ClearAllPendingInt();
    while (1)
    {
        /* Wait for Watchdog Reset to Occur */
        __ASM("nop");
    }
}

}

@Calvin

RSL10 do have SYS_INFO_START_ADDR and SYS_INFO_START_MEM_CFG 8 bytes at NVR1.
If you still need to use this , you can back it up first , then do sector erase and then restore it.

Besides preserving the first 8 bytes of NVR1, the code you show doesn’t work because it’s testing the wrong bit for NVR1_unlocked. That line should be:

/* Check the lock/unlock operation result */
bool NVR1_unlocked = (FLASH->IF_STATUS & 0x3FF) == 0x10;

Thank you for using our community forum!

2 Likes

Thank you Martin,

I changed the 0x20 to 0x10 and tested but it falls to while statement.
Is there something more wrong?

The test condition could fail if more than one section of Flash is unlocked or other status bits are set in FLASH->IF_STATUS. Try this test instead:

bool NVR1_unlocked = (FLASH->IF_STATUS & FLASH_NVR1_W_UNLOCKED) == FLASH_NVR1_W_UNLOCKED;

1 Like

It’s working.
Thank you very much.

1 Like