Flash read / write

We’re planning to use the flash memory to store data. Is there a writeup on doing this? I have searched through the firmware reference and seen write operations but I haven’t found any read.

Thanks in advance.

Jeff

@jeff There is no special function to read the flash… Just perform a read the same way you would read RAM.

2 Likes

@rvs
For the safe method to read the flash, there is an example.

void flash_cmd_read(uint32_t addr, flash_read_t* result)
{
//Wait until flash is idle
while (FLASH->IF_STATUS & FLASH_IF_BUSY);
// Disable interrupts while executing flash commmands
uint32_t intStatus = __get_PRIMASK();
uint32_t previousECC = FLASH->ECC_CTRL;
__set_PRIMASK(PRIMASK_DISABLE_INTERRUPTS);
FLASH->ECC_CTRL |= FLASH_CMD_ECC_ENABLE;
// Perform a CMD_READ with ECC enabled
FLASH->ADDR = addr;
FLASH->CMD_CTRL = CMD_READ;
while (FLASH->IF_STATUS & FLASH_IF_BUSY);
// Read data registers
result->data_ecc_on[0] = FLASH->DATA[0];
result->data_ecc_on[1] = FLASH->DATA[1];
// restore previous ECC configuration
FLASH->ECC_CTRL = previousECC;
// Enable interrupts and restore interrupt configuration
__set_PRIMASK(intStatus);
}

@martin.bela Thanks for this information. I feel like I’m missing a key document. I’m pouring over the FW ref and HW ref but I’m not seeing anything that connects the basics of working with this environment. Specifically, where would I formulate the answer you provided? I have many areas I’d like to get detailed operational information but I seem to be running into only partial information. For example the RW-BLE-GAP-IS_2mbps.pdf has all these defines but does not identify how they are used.

Thanks.

@jeff + @martin.bela I think performing flash read this way is heavy. A better solution is probably to activate ECC and enable FLASH_ECC_IRQn, so you can still read flash the way you would read RAM and rely on the flash ECC interrupt to catch errors.

1 Like

@rvs rvs @jeff
Yes. rvs suggestion is correct. Our example is for “safe method.”
Note:

Default ECC is enabled and ECC interrupt is disabled. (the example code can remove ECC enable part) . Enable ECC interrupt is correct. This can catch any flash error. (This is good idea, but this is not in read function and it could put in flash initialization function. )
Our example is just for “safe method”.
For example. The flash area for reading is code area not data area. We do need disable interrupt and enable interrupt, right?

// Perform a CMD_READ with ECC enabled flash memory
FLASH->ADDR = addr;
FLASH->CMD_CTRL = CMD_READ;
while (FLASH->IF_STATUS & FLASH_IF_BUSY);
// Read data registers
result->data_ecc_on[0] = FLASH->DATA[0];
result->data_ecc_on[1] = FLASH->DATA[1];

Each flash address cover 64-bit flash data.

Reading ECC enabled Flash memory has a bit of difference with reading RAM.

Can you explain the FLASH pointer you are using? I see FLASH_ADDR in the HW Ref but you’re using FLASH->ADDR. The FLASH_ADDR is defined as 0x4000053C.

Thanks in advance.

@jeff

FLASH_ADDR is defined as 0x4000053C. — This is register address.
We just set the read/write address into this FLASH_ADDR register.
For example,
We need read main flash address: 0x00100000.
FLASH->ADDR = 0x00100000;
In my board, I could have 0x20006000 and 0x00100159.

We can also use the J-Link commander to verify this.

or

Debugger

image