# Flash (Flash System Routine)¶

group group_flash

Internal flash memory programming.

The functions and other declarations used in this driver are in cy_flash.h. You can include cy_pdl.h to get access to all functions and declarations in the PDL.

Flash memory in PSoC devices provides non-volatile storage for user firmware, user configuration data, and bulk data storage.

Flash operations are implemented as system calls. System calls are executed out of SROM in the privileged mode of operation. Users have no access to read or modify the SROM code. The driver API requests the system call by acquiring the Inter-processor communication (IPC) and writing the SROM function opcode and parameters to its input registers. As a result, an NMI interrupt is invoked and the requested SROM function is executed. The operation status is returned to the driver context and a release interrupt is triggered.

Writing to flash can take up to 20 milliseconds. During this time, the device should not be reset (including XRES pin, software reset, and watchdog) or unexpected changes may be made to portions of the flash. Also, the low-voltage detect circuits should be configured to generate an interrupt instead of a reset.

A Read while Write violation occurs when a flash Read operation is initiated in the same or neighboring (neighboring restriction is applicable just for the CY8C6xx6, CY8C6xx7 devices) flash sector where the flash Write, Erase, or Program operation is working. This violation may cause a HardFault exception. To avoid the Read while Write violation, carefully split the Read and Write operation on flash sectors which are not neighboring, considering both cores in the multi-processor device. If the flash is divided into four equal sectors, you may edit the linker script to place the code into neighboring sectors. For example, use sectors number 0 and 1 for code and sectors 2 and 3 for data storage.

Configuration Considerations

Introduction:

The PSoC 6 MCU user-programmable Flash consists of:

• Application flash memory (from 2 to 8 sectors) - 128KB/256KB each.

• EE emulation flash memory - 32KB.

Write operation may be done as Blocking or Partially Blocking, defined as follows:

Blocking:

In this case, the entire Flash block is not available for the duration of the Write (16ms). Therefore, no Flash accesses (from any Bus Master) can occur during that time. CPU execution can be performed from SRAM. All pre-fetching must be disabled. Code execution from Flash is blocked for the Flash Write duration for both cores.

Constraints for Blocking Flash operations:

1. During write to flash, the device should not be reset (including XRES pin, software reset, and watchdog), or unexpected changes may be made to portions of the flash.

2. The low-voltage detect circuits should be configured to generate an interrupt instead of a reset.

3. Flash rite operation is allowed only in one of the following CM4 states:

1. CM4 is Active and initialized:

call

Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR). Note: If desired user may put CM4 core in Deep Sleep any time after calling Cy_SysEnableCM4().

2. CM4 is Off and disabled:

call

Cy_SysDisableCM4(). Note: In this state Debug mode is not supported.

4. Flash Write cannot be performed in Ultra Low Power (core voltage 0.9V) mode.

5. Interrupts must be enabled on both active cores. Do not enter a critical section during flash operation.

6. For the CY8C6xx6, CY8C6xx7 devices user must guarantee that system pipe interrupts (IPC interrupts 3 and 4) have the highest priority, or at least that pipe interrupts are not interrupted or in a pending state for more than 700 s.

7. User must guarantee that during flash write operation no flash read operations are performed by bus masters other than CM0+ and CM4 (DMA and Crypto).

8. For the CY8C6xx6, CY8C6xx7 devices if you do not use the default startup, perform the following steps before any flash write/erase operations:


/* 1. Allocate and initialize IPC semaphores for the system operations */
static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD];

(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray);

/* 2. Create an array of endpoint structures and configure an IPC pipe infrastructure */
static cy_stc_ipc_pipe_ep_t ipcPipeEpArray[CY_IPC_MAX_ENDPOINTS];

Cy_IPC_Pipe_Config(ipcPipeEpArray);

/* 3. Create an array of client callbacks and initialize a system pipe by a configuration structure */
static cy_ipc_pipe_callback_ptr_t sysIpcPipeCbArray[CY_SYS_CYPIPE_CLIENT_CNT];

static const cy_stc_ipc_pipe_config_t systemIpcPipeConfig =
{
/* .ep0ConfigData */
{
/* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP0,
/* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP0,
/* .ipcNotifierMuxNumber */  CY_SYS_INTR_CYPIPE_MUX_EP0,
/* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP0
},
/* .ep1ConfigData */
{
/* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP1,
/* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP1,
/* .ipcNotifierMuxNumber */  0u,
/* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP1
},
/* .endpointClientsCount     */  CY_SYS_CYPIPE_CLIENT_CNT,
/* .endpointsCallbacksArray  */  sysIpcPipeCbArray,
/* .systemPipeIsrHandler     */  &SysIpcPipeIsr
};

Cy_IPC_Pipe_Init(&systemIpcPipeConfig);

/* 4. And finally initialize the flash */
Cy_Flash_Init();

/* Ensure to run these steps on all the MCU cores */


Partially Blocking:

This method has a much shorter time window during which Flash accesses are not allowed. Application code execution from Flash is blocked for only a part of Flash Write duration, for both cores. Blocking duration depends upon the API sequence used.

For API sequence Cy_Flash_StartEraseRow() + Cy_Flash_StartProgram() there are four block-out regions during which Read is blocked. See Figure 1.

This allows both cores to execute for about 80% of Flash Write operation - see Figure 1. This capability is important for communication protocols that rely on fast response.

For the

Cy_Flash_StartWrite() function, the block-out period is different for the two cores. The core that initiates Cy_Flash_StartWrite() is blocked for two periods:
• From start of Erase operation (start of A on Figure 1) till the start of Program operation (end of C on Figure 1).

• During D period on Figure 1.

The core that performs read/execute is blocked identically to the previous scenario - see Figure 1.

This allows the core that initiates Cy_Flash_StartWrite() to execute for about 20% of Flash Write operation. The other core executes for about 80% of Flash Write operation.

Some constraints must be planned for in the Partially Blocking mode which are described in detail below.

Constraints for Partially Blocking Flash operations:

1. During write to flash, the device should not be reset (including XRES pin, software reset, and watchdog) or unexpected changes may be made to portions of the flash.

2. The low-voltage detect circuits should be configured to generate an interrupt instead of a reset.

3. During write to flash, application code should not change the clock settings. Use Cy_Flash_IsOperationComplete() to ensure flash write operation is finished.

4. During write to flash, application code should not start the clock measurements (should not call Cy_SysClk_StartClkMeasurementCounters()).

5. Flash write operation is allowed only in one of the following CM4 states:

1. CM4 is Active and initialized:

call

Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR). Note: If desired user may put CM4 core in Deep Sleep any time after calling Cy_SysEnableCM4().

2. CM4 is Off and disabled:

call

Cy_SysDisableCM4(). Note: In this state Debug mode is not supported.

6. Use the following rules for split by sectors. (In this context, read means read of any bus master: CM0+, CM4, DMA, Crypto, etc.)

1. Do not write to and read/execute from the same flash sector at the same time. This is true for all sectors.

2. Writing rules in application flash (this restriction is applicable just for CY8C6xx6, CY8C6xx7 devices):

1. Any bus master can read/execute from UFLASH S0 and/or S1, during flash write to UFLASH S2 or S3.

2. Any bus master can read/execute from UFLASH S2 and/or S3, during flash write to UFLASH S0 or S1.

Suggestion: in case of bootloading, it is recommended to place code for CM4 in either S0 or S1. CM0+ code resides in S0. Write data to S2 and S3 sections.

7. Flash Write cannot be performed in Ultra Low Power mode (core voltage 0.9V).

8. Interrupts must be enabled on both active cores. Do not enter a critical section during flash operation.

9. For the CY8C6xx6, CY8C6xx7 devices user must guarantee that system pipe interrupts (IPC interrupts 3 and 4) have the highest priority, or at least that pipe interrupts are not interrupted or in a pending state for more than 700 s.

10. For the CY8C6xx6, CY8C6xx7 devices if you do not use the default startup, perform the following steps before any flash write/erase operations:


/* 1. Allocate and initialize IPC semaphores for the system operations */
static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD];

(void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray);

/* 2. Create an array of endpoint structures and configure an IPC pipe infrastructure */
static cy_stc_ipc_pipe_ep_t ipcPipeEpArray[CY_IPC_MAX_ENDPOINTS];

Cy_IPC_Pipe_Config(ipcPipeEpArray);

/* 3. Create an array of client callbacks and initialize a system pipe by a configuration structure */
static cy_ipc_pipe_callback_ptr_t sysIpcPipeCbArray[CY_SYS_CYPIPE_CLIENT_CNT];

static const cy_stc_ipc_pipe_config_t systemIpcPipeConfig =
{
/* .ep0ConfigData */
{
/* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP0,
/* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP0,
/* .ipcNotifierMuxNumber */  CY_SYS_INTR_CYPIPE_MUX_EP0,
/* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP0
},
/* .ep1ConfigData */
{
/* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP1,
/* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP1,
/* .ipcNotifierMuxNumber */  0u,
/* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP1
},
/* .endpointClientsCount     */  CY_SYS_CYPIPE_CLIENT_CNT,
/* .endpointsCallbacksArray  */  sysIpcPipeCbArray,
/* .systemPipeIsrHandler     */  &SysIpcPipeIsr
};

Cy_IPC_Pipe_Init(&systemIpcPipeConfig);

/* 4. And finally initialize the flash */
Cy_Flash_Init();

/* Ensure to run these steps on all the MCU cores */


EEPROM section use:

If you plan to use “cy_em_eeprom” section for different purposes for both of device cores or use Em_EEPROM Middleware together with flash driver write operations you must modify the linker scripts.