Flash writing to NVR and Flash Areas error

Hi Everybody,

For our project we are currently using the RSL10 evaluation board RSL10 SIP.
For our needs I need to save 60KB of data, so we decided to use the onchip flash, form the documentation provided I assume that the flash memory occupancy of the boot loaded, fota and .bin images are continuous, so I decided to start writing on to Flash from 280KB boundary, so my effective start address for data should be “FLASH_MAIN_BASE+0x46000”, when I am trying to erase and write to the area my system is stuck. Below is my code function.

The same system stuck happens when I try to access NVR1 memory and write to it.

From the debugger stepping through the code I see that the program is stuck in the following line in the rsl10_flash.c

    /* Wait until the write is completed and new words can be provided */
    while (FLASH_IF_STATUS->PROG_SEQ_DATA_REQ_ALIAS == 0);

Is there something that I am missing?

Any help is appreciated.

#define FLSHDATABASEADDR (FLASH_MAIN_BASE+0x46000)
void writeTOFlash(uint8_t *buff, uint8_t length)
{

flshaddr = FLSHDATABASEADDR;
uint32_t wrBuff[10];
uint8_t i =0;
if((length%4)==0)
{
while (length)
{
wrBuff[i] = buff[i+3]<<24;
wrBuff[i] |= buff[i+2]<<16;
wrBuff[i] |= buff[i+1]<<8;
wrBuff[i] |= buff[i];
length = length-4;
}
}

#if 1
bool ret = false;
FLASH->MAIN_CTRL = MAIN_LOW_W_ENABLE | MAIN_MIDDLE_W_ENABLE | MAIN_HIGH_W_ENABLE;
FLASH->MAIN_WRITE_UNLOCK = FLASH_MAIN_KEY;
uint32_t flshdelay = FLASH->DELAY_CTRL;

flshdelay|=0x09; // Flash delay as suggested in [KB: Setting the Flash Delay to Ensure Read & Write Operations are Successful]
FLASH->DELAY_CTRL = flshdelay;

 __disable_irq();
 ret = Flash_EraseSector(flshaddr);
 __enable_irq();

__disable_irq();
ret = (Flash_WriteBuffer(flshaddr, sizeof(wrBuff), (unsigned int*)&wrBuff) == 0);
__enable_irq();

bool b = (memcmp((void *)flshaddr, (unsigned int*)&wrBuff, sizeof(wrBuff)) == 0);

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

#endif

wrordswritten = i;

}

Regards,
Prasanna

@Prasanna

I could provide a reference for write main flash example here:
**I used "rsl10_flash_rom.h" not "rsl10_flash.h".**
 
1. First I has a function " FLASH_MAIN_HIGH_WriteEnable(bool enable)"
2. Second I use this function to erase and write the main flash.
/* ---------------------------------------------------------------------------------------------
 * Function      : FLASH_MAIN_HIGH_WriteEnable(bool enable)
 * ---------------------------------------------------------------------------------------------
 * Description   : Enabled or disable Flash write in main flash high region.
 *                 Main flash = 0x0010.0000 – 0x0015.FFFF Access partition
 *                 Part 1: 0x0010.0000 –  0x0011.FFFF  //(128K =0x20000)  -- Main Low
 *                 Part 2: 0x0012.0000 -  0x0013.FFFF  //(128K =0x20000)  -- Main Middle
 *                 Part 3: 0x0014.0000 -  0x0015.FFFF  //(128K =0x20000)  -- Main high
 * Inputs        : boolean of enable/disable
 * Outputs       : N/A
 *
 * Assumptions   : System will reset if the enable fails.
 * ---------------------------------------------------------------------------------------- */
static void  FLASH_MAIN_HIGH_WriteEnable(bool enable)
{
  /* Lock or unlock  FLASH_MAIN_LOW region */
  FLASH->MAIN_CTRL= MAIN_HIGH_W_ENABLE;
  FLASH->MAIN_WRITE_UNLOCK = enable ? FLASH_MAIN_KEY : 0;

  /* Check the lock/unlock operation result */
  bool MAIN_HIGH_W_unlocked = (FLASH->IF_STATUS & 0x04) == 0x04;

  /* Error checking: this application needs to write in flash. If an error
   * occurred while locking/unlocking FLASH_MAIN_LOW, wait for a watchdog reset */
  if (MAIN_HIGH_W_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");
    }
  }
}

Now I use this function to erase and write main flash.

 flashAddress = FLASH_BASE_ADDR(bank);
 FLASH_MAIN_HIGH_WriteEnable ( true );
  __disable_irq();
  Flash_EraseSector(FLASH_BASE_ADDR(bank));
  Flash_WriteBuffer(FLASH_BASE_ADDR(bank), 512, ((unsigned int *) &transferBufferB[0]));
  __enable_irq();
  FLASH_MAIN_HIGH_WriteEnable ( false );

Where:

  1. FLASH_BASE_ADDR(bank) is - start_addr - Start address for the write to flash.
  2. 512 is - length - Number of words to write to flash.
  3. ((unsigned int *) &transferBufferB[0]) is - data - Pointer to the data to write to flash.

Note: For the flash delay setting , I assume that has been done in initialization based on sysclk.

Also reference RSL10 Firmware Reference p396 for “FLASH_WRITEBUFFER”.

How about NVR writing?
We have reference in ble_peripheral_server_bond sample project.

It uses this function “void NVR2_WriteEnable(bool enable)”.

/* ----------------------------------------------------------------------------
 * Function      : unsigned NVR2_WriteEnable(bool enable)
 * ----------------------------------------------------------------------------
 * Description   : Enable/Disable writing to NVR2
 * Inputs        : - enable    - Enable writing when true, disable otherwise
 * Outputs       : None
 * Assumptions   : Function should cause a watchdog reset in case of error
 * ------------------------------------------------------------------------- */
void NVR2_WriteEnable(bool enable)
{
    /* Lock or unlock NVR2 region */
    FLASH->NVR_CTRL = NVR2_WRITE_ENABLE;
    FLASH->NVR_WRITE_UNLOCK = enable ? FLASH_NVR_KEY : 0;

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

    /* Error checking: this application needs to write in flash. If an error
     * occurred while locking/unlocking NVR2, wait for a watchdog reset */
    if (NVR2_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");
        }
    }
}

and then do the NVR2 writing action.

  /* Write new data to flash */
        NVR2_WriteEnable(true);
        unsigned int result = Flash_WriteBuffer((unsigned int)start_addr,
                                                data_size / 4, data_to_write);
        NVR2_WriteEnable(false);

Thank you for using our community forum!

Hi Martin,

Now it works.
The include the “rsl10_flash_rom.h” and removed “rsl10_flash.h”, is the fix.

I would like to know why is this so, just to have an idea what is the difference.

Anyway thanks for your help

Thanks & Regards,
Prasanna

@Prasanna

The difference in the include files is that the “rsl10_flash_rom.h” has some static inline definitions that aren’t in “rsl10_flash.h”. Those functions would need to be defined elsewhere if the rom version isn’t used.
Thank you for using our community forum!