# Flash

The RSL15 device includes a flash memory instance for use as non-volatile memory. The topics that follow describe its characteristics and use.

## Flash Characteristics

The flash memory instance contains:

- A main flash area consisting of two flash arrays:
  - For RSL15-512 devices, this flash memory provides 512 KB of flash memory divided into a code flash array of 352 KB and a data flash array of 160 KB.
  - For RSL15-284 devices, this flash memory provides 284 KB of flash memory divided into a code flash array of 264 KB and a data flash array of 20 KB.
  - The code flash array is organized into 2048-byte sectors; the data flash array is organized into 256-byte sectors. Both arrays are accessed using the same memory buses, so it is equally efficient to execute code or access data stored to either array.
- Eight non-volatile records (NVR), each consisting of one flash sector of 256 bytes
- One manufacturing non-volatile record (MNVR), consisting of one flash sector that contains two copies of the 128 bytes of redundant data programmed during production
- Redundancy sectors, including:
  - Two sectors for production patching of the code flash array
  - Two sectors for production patching of the data flash array

NOTE: Each user redundancy sector can be set only once, but can be used repeatedly just like any other sector of memory.

Data in this memory is stored as 38-bit words, including six bits of parity data (for error correction coding) for every four bytes of user data.

The flash memory is supported by:

- Timing circuitry configured to ensure proper flash operation. For more information, see Flash.
- Redundancy sectors, including both production sectors (as listed above) and user redundancy sectors, which can be configured as described in Redundancy Sectors

  NOTE: User redundancy sector configuration is the only component of the MNVR record that can be updated outside of production, and each user redundancy sector can be programmed a maximum of one time.

- Error correcting support hardware, as described in Error-Correction Coding.
- A flash copier that can be used to validate the flash contents. For more information, see Flash Copier.

## Flash Delays

The flash instance provided as part of the RSL15 system uses specific timing relative to the SYSCLK frequency to ensure proper flash operation. Relevant flash delays include:

- Read operation delays of 30 ns to code flash sectors and 40 ns to data flash sectors, implemented using wait states on flash read accesses if the clock period is known to be too short to ensure an appropriate delay
- Programming operation delays of 9.6 to 12 µs, including a 1.6 to 2 µs pre-program pulse and an 8 to 10 µs programming pulse
- Sector erase delays of 0.8 to 1 ms
- Mass erase delays of 8 to 10 ms

To ensure that the timing requirements of reading from flash are met, the FLASH_DELAY_CTRL register needs to be configured for a frequency that is at least as high as the highest possible clock frequency at all times. To ensure proper operation for flash programming and erase cycles, the FLASH_DELAY_CTRL register needs to be configured to match a known SYSCLK frequency that is sourced from the crystal oscillator, as an error of greater than ±10% is unacceptable for flash write operations.

NOTE: The flash program and erase operations cannot be supported if the clock has more than 10% frequency error. Because the system RC oscillator has a greater than 10% variation over system operating conditions, we recommend use of the system XTAL oscillator for all program and erase operations.

NOTE: When executing from STANDBYCLK, the FLASH_DELAY_CTRL register needs to be configured to use the setting for a SYSCLK of 3 MHz (FLASH_DELAY_FOR_SYSCLK_3MHZ), and programming is not possible.

## Flash Memory Operations

Writing to flash memory consists of an erase cycle followed by a program cycle. Following the erase cycle, the erased cells have a value of all ones. Programming the flash cells clears some of these cells to zero.

The program and erase operations require several conditions to be met to ensure an accurate clock is available and the operation can be executed properly. The conditions are:

- VDDRF must be enabled (ACS_VDDRF_CTRL_ENABLE bit in the ACS_VDDRF_CTRL register is set) and its supply must be ready (ACS_VDDRF_CTRL_READY bit in the same register is set).
- VDDFLASH must be enabled (ACS_VDDFLASH_CTRL_ENABLE bit in the ACS_VDDRF_CTRL register is set), its supply must be ready (ACS_VDDFLASH_CTRL_READY bit in the same register is set), and it must be trimmed correctly.
- RF power must be enabled (SYSCTRL_RF_POWER_CFG_RF_ENABLE bit in the SYSCTRL_RF_POWER_CFG register is set) and accessible (SYSCTRL_RF_ACCESS_CFG_RF_ACCESS bit in the SYSCTRL_RF_ACCESS_CFG resister is set).
- The clock must be sourced by the RFCLK (48 MHz XTAL), which must be ready for use, i.e.,
  - CLK_SYS_CFG_SYSCLK_SRC_SEL in the CLK_SYS_CFG register is set to SYSCLK_CLKSRC_RFCLK.
  - RF0_XTAL_CTRL_XTAL_CTRL_XO_EN_B_REG in the RF0_XTAL_CTRL register is set to XTAL_CTRL_ENABLE_OSCILLATOR.
  - RF0_ANALOG_INFO_ANALOG_INFO_CLK_DIG_READY in the RF0_ANALOG_INFO register is set to ANALOG_INFO_CLK_DIG_READY.
  - Valid clock division selected (RF0_REG33_CK_DIV_1_6_CK_DIV_1_6 field in the RF0_REG33 register is set to a non-zero value)
- The SystemCoreClock must reflect the clock frequency setting.
- The flash delay is set to match the configured clock frequency setting.

IMPORTANT: The flash library contains functions that the user application can use to perform different operations on the flash. All functions provided by the flash library must be executed from RAM or ROM, as executing them from flash can result in hidden, flash-access-related failures. As a result, a copy of this flash library is provided in the RSL15 Program ROM, and can be used to access the flash at any time.

Commands are issued explicitly to the flash interface by writes to the FLASH_CMD_CTRL_COMMAND bit-field of the FLASH_CMD_CTRL register, or as side effects of writes to the FLASH_IF_CTRL register that change the value of the FLASH_IF_CTRL_VREAD1_MODE, FLASH_IF_CTRL_RECALL, or FLASH_IF_CTRL_LP_MODE bits. Commands that can be executed on the flash are listed in the "Flash" table. All commands return to the idle state, except the sequential programming (CMD_PROGRAM_SEQ) and the deep power down (CMD_DPD) commands. If the flash is already busy, the command is ignored along with writes to all other flash registers, except:

- FLASH_DATA* when new data is requested for a CMD_PROGRAM_SEQ command
- FLASH_CMD_CTRL_CMD_END from FLASH_CMD_CTRL, which can be used to terminate the current command
- FLASH_DELAY_CTRL, which updates the flash timing as described in Flash
- FLASH_ECC_CTRL, which updates the use of the error correction coding as described in Error-Correction Coding

CAUTION: While changing FLASH_ECC_CTRL is possible while executing a flash command, changing the FLASH_ECC_CTRL_CMD_ECC_CTRL bit while executing a read or write command results in undefined behavior for the flash operation. Since this can result in an unknown value written to or read from flash, this bit-field must not be changed while writing to or reading from flash.

NOTE: While any flash operations are in progress, the flash memory instance cannot be accessed from the Arm Cortex-M33 processor's code bus. This includes any case where a flash command is issued through a write to the FLASH_CMD_CTRL register or when a low-level flash command is triggered by writing to the FLASH_IF_CTRL register. Access to the flash while a flash operation is being processed results in a bus fault.

Table: Flash Low-Level Commands
Command | Description
--- | ---
CMD_IDLE | No flash command is active or pending.
CMD_WAKE_UP | This power-up sequence starts automatically when the flash isolation is removed through the SYSCTRL_MEM_ACCESS_CFG register.
CMD_LOAD_TRIM | Transfer from the MNVR sector to the PATCH_ADDR[7:0] registers and to the flash internal configuration registers. The status bit TRIMMED_STATUS is updated at the end of the command, indicating if there has been an uncorrectable ECC error or a word pair containing all 1s or 0s when reading MNVR, in which case the default trim values are used to guarantee the proper flash read functionality.
CMD_SET_CONF_REG | Copy from FLASH_DATA[1:0] registers to the flash internal configuration registers specified by the FLASH_ADDR register (only used for Production test).
CMD_DPD | This command that does not complete by itself, but requires CMD_END for this. While this command is active, the BUSY bit of the FLASH_IF_STATUS register is set and any CBus access to the flash results in a bus fault.
CMD_READ | Execute a read access, mainly for test purposes. If ECC is enabled, a pair of 32-bit words is read from the flash. If ECC is disabled, a single 38-bit word is read from the flash.
CMD_PROGRAM_NOS EQ | Execute a non-sequential programming access. This command is only accepted when the sector addressed by FLASH_ADDR is in an unlocked flash zone. A single word is written in the flash. The RETRY field of FLASH_IF_CTRL must be set to FLASH_RETRY_4.
CMD_PROGRAM_SEQ | Initiates a sequential programming access. This command is only accepted when the sector addressed by FLASH_ADDR is in an unlocked flash zone. Up to 128 words can be written in the same row within a Code sector and up to 32 words can be written in the same row within a Data sector. The RETRY field of FLASH_IF_CTRL must be set to FLASH_RETRY_4. This command that does not complete by itself, but requires CMD_END for this. While this command is active, the BUSY bit of the FLASH_IF_STATUS register is set and any CBus access to the flash results in a bus fault.
CMD_PRE_PROGRAM_NOS EQ | Execute a non-sequential programming access with a pre-programming step. The pre-program is needed if an endurance higher than 10 k is required. This command is only accepted when the sector addressed by FLASH_ADDR is in an unlocked flash zone. A single word is written in the flash. The RETRY field of FLASH_IF_CTRL must be set to FLASH_RETRY_4. This command must be follow by the CMD_PROGRAM_NOSEQ command with the same address and the same data written with the CMD_PRE_PROGRAM_NOSEQ command.
CMD_PRE_PROGRAM_SEQ | Initiates a sequential programming access with a pre-programming step. The pre-program is needed if an endurance higher than 10 k is required. This command is only accepted when the sector addressed by FLASH_ADDR is in an unlocked flash zone. Up to 128 words can be written in the same row within a Code sector and up to 32 word can be written in the same row within a Data sector. The RETRY field of the FLASH_IF_CTRL register must be set to FLASH_RETRY_4. This command that does not complete by itself, but requires CMD_END for this. While this command is active, the BUSY bit of the FLASH_IF_STATUS register is set and any CBus access to the flash results in a bus fault. This command must be followed by the CMD_PROGRAM_SEQ command with the same addresses and the data written with the CMD_PRE_PROGRAM_SEQ command.
CMD_END | Terminates a sequential programming access (with or without pre-program) or exits deep power down mode. This command is only accepted when the PROG_SEQ_DATA_REQ bit of the FLASH_IF_STATUS register is set, or while in deep power down mode. Note that it is not an actual flash command, but a write action bit.
CMD_SECTOR_ERASE | This sector erase command is only accepted when the sector addressed by FLASH_ADDR is in an unlocked Flash zone. The RETRY field of FLASH_IF_CTRL determines the erase strength; see Flash Memory Registers for more details.
CMD_MASS_ERASE | This mass erase command is only accepted when all MAIN zones are unlocked, and NVR zones are locked. All MAIN sectors (code & data arrays), including the redundancy sectors, are erased except when NVR0 through NVR7 are unlocked. The RETRY field of FLASH_IF_CTRL must be set to FLASH_RETRY_4. The write cycle endurance of the Flash is impacted by performing a mass erase. It is therefore recommended to only use sector erase in the application.
CMD_SET_LOW_POWER | Sets the LPWR Flash pin respecting the hold & setup time. This command is called automatically when the LP_MODE bit in the FLASH_IF_CTRL register is changed from 0 to 1.
CMD_UNSET_LOW_POWER | Unsets the LPWR Flash pin respecting the hold & setup time. This command is called automatically when the LP_MODE bit in theFLASH_IF_CTRL register is changed from 1 to 0.
CMD_SET_RECALL | Sets the RECALL Flash pin respecting the hold & setup time. This command is called automatically when the RECALL bit in theFLASH_IF_CTRL register is changed from 0 to 1.
CMD_UNSET_RECALL | Unsets the RECALL Flash pin respecting the hold & setup time. This command is called automatically when the RECALL bit in the FLASH_IF_CTRL register is changed from 1 to 0.
CMD_SET_VREAD1 | Sets the VREAD1 Flash pin respecting the hold & setup time. This command is called automatically when the VREAD1_MODE bit in the FLASH_IF_CTRL register is changed from 0 to 1
CMD_UNSET_VREAD1 | Sets the VREAD1 Flash pin respecting the hold & setup time. This command is called automatically when the VREAD1_MODE bit in the FLASH_IF_CTRL register is changed from 1 to 0.
CMD_WRITE_USER_RED | Writes FLASH_DATA[0] into MNVR. FLASH_DATA[1] indicates the redundancy sector.

## Redundancy Sectors

The RSL15 flash provides four redundancy sectors, including:

- Two sectors that can be used in production to patch any code array sectors
- Two sectors that can be used in production to patch any data array sectors

The flash also supports the use of four sectors that can be used as user redundancy sectors, including:

- The last two flash code sectors that can be used by the user application to patch any other code array sectors
- The last two flash data sectors that can be used by the user application to patch any other data array sectors

The addresses of the sectors to be patched are stored in MNVR, and loaded during flash initialization to the FLASH_PATCH_ADDR* registers. If a flash redundancy sector is not used, the FLASH_PATCH_ADDR_PATCH_NOT_VALID bit from its FLASH_PATCH_ADDR* register is set.

Information on the available flash redundancy sectors is provided in the "Flash" table.

Table: Flash Redundancy Sectors
Redundancy Sector | Flash Sector Type | Nominal Address | Patch Register
--- | --- | --- | ---
Code redundancy 1 (RED1) | Code | 0x00060000 | FLASH_PATCH_ADDR0
Code redundancy 2 (RED2) | Code | 0x00060800 | FLASH_PATCH_ADDR1
Data redundancy 1 (RED3) | Data | 0x00061000 | FLASH_PATCH_ADDR2
Data redundancy 2 (RED4) | Data | 0x00061100 | FLASH_PATCH_ADDR3
User code redundancy (USER_RED1) | Code | 0x00157000 | FLASH_PATCH_ADDR4
User code redundancy (USER_RED2) | Code | 0x00157800 | FLASH_PATCH_ADDR5
User data redundancy (USER_RED3) | Data | 0x001D7E00 | FLASH_PATCH_ADDR6
User data redundancy (USER_RED4) | Data | 0x001D7F00 | FLASH_PATCH_ADDR7

IMPORTANT: Each of the user redundancy sectors can be configured once for a device, using the CMD_WRITE_USER_RED flash command. Before configuring a user redundancy sector, a user application must ensure that the sector is not already in use. When running this command, the address of the sector to be patched must be written to the FLASH_DATA[0] register, and the user redundancy index (between 1 and 4) must be written to FLASH_DATA[1], as described in Flash Memory Operations.

NOTE: If multiple flash redundancy sectors are applied to the same address, the following priority is observed (listed from highest to lowest priority): USER_RED2, USER_RED1, RED2, RED1 for flash code array sectors, and USER_RED4, USER_RED3, RED4, RED3 for flash data array sectors.

NOTE: User redundancy sectors can only be patched by production redundancy sectors.

## Error-Correction Coding

To prevent possible issues inherent in flash technology, an Error Correcting Code (ECC) ensures the integrity of the flash content, as follows:

- When writing to the flash, the ECC bits are automatically generated by the flash interface and appended to the data.
- When reading from the flash, the error detection/correction is applied automatically.

The algorithm relies on the (38, 32) extended Hamming code, where 32 data bits are extended by 6 parity bits to form a 38-bit word. This is a Single Error Correcting (SEC) code, which allows correction of a single bit error.

The flash ECC bit generation and the error detection and correction are performed on the fly by a dedicated hardware block with no incurred latency on the read/write operation, as shown in the "Flash" figure.

Figure: Flash Write and Read Operations Sequence with ECC Enabled

When writing to the flash memory with ECC enabled (the FLASH_ECC_CTRL_CMD_ECC_CTRL field in the FLASH_ECC_CTRL register), the 6 parity bits are first computed over the 32-bit FLASH_DATA[0] registers using the extended Hamming encoding scheme. The 32-bit data from the register is left-extended with the resulting 6 parity bits, and written into the flash as a 38-bit word.

When reading from the flash memory with ECC enabled, the 38-bit word is read from the flash address, and the ECC bits are computed over the 38-bit data read from the flash using the extended Hamming encoding scheme. The computed ECC bits are compared to the six parity bits and are then read from the flash.

No errors

If no difference is observed, the status register FLASH_ECC_STATUS is not updated.

One error

If the bit to be corrected is inside the 32-bit data, one error has been detected. The data is corrected before being used, the FLASH_ECC_STATUS_ECC_COR_ERROR_CNT_STATUS bit in the FLASH_ECC_STATUS register is set, the corrupted flash address is saved in the FLASH_ECC_ERROR_ADDR register, and the value of FLASH_ECC_COR_ERROR_CNT counter is incremented by one. When the counter becomes equal to or greater than FLASH_ECC_CTRL_ECC_COR_CNT_INT_THRESHOLD, a FLASH_ECC_INT interrupt is generated.

More than one error

If the corrected bit is outside the 32-bit data, the detected ECC error cannot be corrected. The FLASH_ECC_STATUS_ECC_UNCOR_ERROR_CNT_STATUS bit in the FLASH_ECC_STATUS register is set, the corrupted flash address is saved in the FLASH_ECC_ERROR_ADDR register, the value of the FLASH_ECC_UNCOR_ERROR_CNT counter is incremented by one, and a FLASH_ECC_INT interrupt is generated.

The ECC status flags and FLASH_ECC_ERROR_ADDR register can be cleared using the FLASH_ECC_STATUS_ECC_COR_ERROR_CNT_CLEAR, FLASH_ECC_STATUS_ECC_UNCOR_ERROR_CNT_CLEAR, and FLASH_ECC_STATUS_ECC_ERROR_ADDR_CLEAR bits from the FLASH_ECC_STATUS register.

The total number of detected errors is reported in the FLASH_ECC_UNCOR_ERROR_CNT register. The counter saturates at 255, and can be reset by setting the FLASH_ECC_STATUS_ECC_UNCOR_ERROR_CNT_CLEAR bit in the FLASH_ECC_STATUS register.

The total number of corrected errors is reported in the FLASH_ECC_COR_ERROR_CNT register. The counter saturates at 255, and can be reset by setting the FLASH_ECC_STATUS_ECC_COR_ERROR_CNT_CLEAR bit in the FLASH_ECC_STATUS register.