Flash WriteBuffer Problem when Flash Overlay Enabled

We are experiencing problems trying to write to flash when the flash overlay is enabled.
Our firmware tries to write 64 bit data to a defined address (e.g. 0x101800) in the main flash using Flash_WriteBuffer but this one does not take effect. That is, it returns successful but the following memory verification (i.e. comparison of expected with actual) shows no data was written.

First of all, Flash Overlay is enabled on RSL10 initialization as follows:

  /* Enable PRAM[3:0] Flash overlay */
  /* PRAM0 Flash overlay */
  memcpy((uint8_t *)PRAM0_BASE,
         (uint8_t *)FLASH_MAIN_BASE,
         PRAM0_SIZE);

  /* PRAM1 Flash overlay */
  memcpy((uint8_t *)PRAM1_BASE,
         (uint8_t *)(FLASH_MAIN_BASE + PRAM0_SIZE),
         PRAM1_SIZE);

  /* PRAM2 Flash overlay */
  memcpy((uint8_t *)PRAM2_BASE,
         (uint8_t *)(FLASH_MAIN_BASE + PRAM0_SIZE + PRAM1_SIZE),
         PRAM2_SIZE);

  /* PRAM3 Flash overlay */
  memcpy((uint8_t *)PRAM3_BASE,
         (uint8_t *)(FLASH_MAIN_BASE + PRAM0_SIZE + PRAM1_SIZE + PRAM2_SIZE),
         PRAM3_SIZE);

  /* Enable PRAM[3:0] Flash overlay */
  SYSCTRL->FLASH_OVERLAY_CFG = 0x0F;

Then, the firmware tries to write to flash as follows (flash unlock/erase/writeBuffer/lock):

bool ret = false;

/* Unlock */
FLASH->MAIN_CTRL = MAIN_LOW_W_ENABLE | MAIN_MIDDLE_W_ENABLE | MAIN_HIGH_W_ENABLE;
FLASH->MAIN_WRITE_UNLOCK = FLASH_MAIN_KEY;

 __disable_irq();
 ret = Flash_EraseSector(RWDATA_START) == FLASH_ERR_NONE);
 __enable_irq();

 PRINTF("> Erase(%s)", ret? "ok" : "notok");

__disable_irq();
ret = (Flash_WriteBuffer(RWDATA_START, sizeof(rw_data), (unsigned int*)&rw_data) == 0);
__enable_irq();

PRINTF(" WriteBuffer(%s)", ret? "ok" : "notok")

bool b = (memcmp((void *)RWDATA_START, (unsigned int*)&rw_data, sizeof(rw_data)) == 0);
        
PRINTF(" memcmp(%s)\n", b? "==" : "!=");

/* Lock */
FLASH->MAIN_CTRL = 0;
FLASH->MAIN_WRITE_UNLOCK = FLASH_MAIN_KEY;

If flash overlay is disabled (takes 0x0) then WriteBuffer writes data to the main flash.
What’s wrong here?

Add-on: Flash Delay is set to the correct value according to the SysClk.

Problem: Firmware tries to *WriteBuffer to an address overlayed or mapped to RAM (e.g. 0x101800 lies within PRAM0).

Though, not sure how the hardware manages OVERLAY, this does not seem to be allowed.

Workaround: do not enable the Overlay PRAM* region where access to main flash (write, read) are defined.

It would be interesting to understand what the root cause

2 Likes

You are correct - you cannot write to flash when the overlay is enabled. The reason is that when the overlay is enabled, accesses to the FLASH addresses in the overlay region are instead targeted to a section of RAM. This allows code in that Flash region to first be copied into the RAM, then the RAM overlaid with the FLASH to allow faster and lower power execution of the code stored in FLASH. More details can be found in the RSL10 Hardware Reference Manual, specifically section 7.2.3.1.

2 Likes