Hardware Abstraction Layer (HAL)
Flash (Flash System Routine)

General Description

High level interface to the internal flash memory.

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

This driver allows data to be read from and written to flash. It also provides the ability to obtain information about the address and characteristics of the flash block(s) contained on the device. During flash write 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.

Note
A Read while Write violation may occur for some devices when a flash Read operation is initiated in the same or neighboring flash sector where the flash Write, Erase, or Program operation is working. Refer the the device datasheet for more information. This violation may cause a HardFault exception. To avoid the Read while Write violation, the user must carefully split the Read and Write operations on flash sectors which are not neighboring, considering all cores in a multi-processor device. 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.

Features

Code Snippets

Snippet 1: Discovering flash characteristics

Following code snippet demonstrates how to discover flash characteristics. Refer cyhal_flash_info_t for more information.

cyhal_flash_t flash_obj;
cyhal_flash_info_t flash_info;
uint32_t flash_start_address;
uint32_t flash_size;
uint32_t flash_sector_size;
uint32_t flash_page_size;
uint8_t flash_erase_value;
/* Initialize flash object */
cyhal_flash_init(&flash_obj);
/* Get flash characteristics */
cyhal_flash_get_info(&flash_obj, &flash_info);
/* Wait for 100ms for the flash write to complete */
uint32_t timeout = 100;
/* Wait for the command to finish execution */
while((true != cyhal_flash_is_operation_complete(&flash_obj)) && (0 < timeout))
{
timeout--;
cyhal_system_delay_ms(1); /* delay one millisecond each iteration */
}
if(0 != timeout)
{
for(int index = 0; index < flash_info.block_count; index++)
{
const cyhal_flash_block_info_t *block_info = flash_info.blocks;
block_info += index;
flash_start_address = block_info->start_address;
flash_size = block_info->size;
flash_sector_size = block_info->sector_size;
flash_page_size = block_info->page_size;
flash_erase_value = block_info->erase_value;
}
}

Snippet 2: Blocking Flash Write Operation

Following code snippet demonstrates blocking flash write. It uses a constant array with a size equaling the size of one flash row. This array is placed at an address in flash such that it occupies one complete flash row. It uses blocking flash write operation which blocks the caller until the write is completed. It then verifies the flash data by comparing the flash data with the written data.

/* Use cyhal_flash_get_info() to obtain values for the particular device */
#define FLASH_START_ADDR (0x10000000)
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (512)
#define LAST_FLASH_ROW ((FLASH_SIZE/FLASH_PAGE_SIZE) - 1)
/* This array reserves space in the flash for one page of size
* FLASH_PAGE_SIZE. Explicit initialization is required so that memory is
* allocated in flash instead of RAM. */
#define CALCULATE_FLASH_ADDRESS(row_num) (FLASH_START_ADDR + ((row_num) * FLASH_PAGE_SIZE))
/* Make the address point to last user flash page */
const uint8_t *flash_data_ptr = (uint8_t *)CALCULATE_FLASH_ADDRESS(LAST_FLASH_ROW);
cy_rslt_t result; /* Flash Write Status */
uint8_t ram_data[FLASH_PAGE_SIZE]; /* RAM data to be written to Flash */
uint8_t flash_read_data[FLASH_PAGE_SIZE]; /* RAM data read from Flash for validation */
bool compare_status = false; /* Compare Status */
/* Flash object */
cyhal_flash_t flash_obj;
/* Initialize flash object */
cyhal_flash_init(&flash_obj);
/* Initialize the data in RAM that will be written into flash */
for(int index = 0; index < FLASH_PAGE_SIZE; index++)
{
ram_data[index] = (uint8_t)index;
}
/* Blocking flash erase prior to flash write */
result = cyhal_flash_erase(&flash_obj, (uint32_t)flash_data_ptr);
if(result != CY_RSLT_SUCCESS)
{
/* Error erasing flash */
}
/* Blocking flash write */
result = cyhal_flash_write(&flash_obj, (uint32_t)flash_data_ptr, (const uint32_t *)ram_data);
if(CY_RSLT_SUCCESS == result)
{
/* Read flash data */
result = cyhal_flash_read(&flash_obj, (uint32_t)flash_data_ptr, flash_read_data, sizeof(flash_read_data));
if(CY_RSLT_SUCCESS == result)
{
/* Verify the data written into flash by comparing it with the RAM data */
if(0 == memcmp(ram_data, flash_read_data, sizeof(flash_read_data)))
{
compare_status = true;
}
}
}
Note
It is recommended to declare the flash array as global variable.

Snippet 3: Non-blocking Flash Write Operation using polling

Following code snippet implements the non-blocking flash write using polling to complete the flash write operation. It uses a constant array with a size equaling the size of one flash row. This array is placed at an address in flash such that it occupies one complete flash row. It uses a polling method to complete the flash write operation. It then verifies the flash data by comparing the flash data with the written data.

/* Use cyhal_flash_get_info() to obtain values for the particular device */
#define FLASH_START_ADDR (0x10000000)
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (512)
#define LAST_FLASH_ROW ((FLASH_SIZE/FLASH_PAGE_SIZE) - 1)
/* This array reserves space in the flash for one page of size
* FLASH_PAGE_SIZE. Explicit initialization is required so that memory is
* allocated in flash instead of RAM. */
#define CALCULATE_FLASH_ADDRESS(row_num) (FLASH_START_ADDR + ((row_num) * FLASH_PAGE_SIZE))
/* Make the address point to last user flash page */
const uint8_t *flash_data_ptr = (uint8_t *)CALCULATE_FLASH_ADDRESS(LAST_FLASH_ROW);
cy_rslt_t result; /* Flash Write Status */
uint8_t ram_data[FLASH_PAGE_SIZE]; /* RAM data to be written to Flash */
uint8_t flash_read_data[FLASH_PAGE_SIZE]; /* RAM data read from Flash for validation */
bool compare_status = false; /* Compare Status */
/* Flash object */
cyhal_flash_t flash_obj;
/* Initialize flash object */
cyhal_flash_init(&flash_obj);
/* Initialize the data in RAM that will be written into flash */
for(int index = 0; index < FLASH_PAGE_SIZE; index++)
{
ram_data[index] = (uint8_t)index;
}
/* Wait for 100ms for the flash write to complete */
uint32_t timeout = 100;
/* Partially blocking flash erase */
result = cyhal_flash_start_erase(&flash_obj, (uint32_t)flash_data_ptr);
while(true != cyhal_flash_is_operation_complete(&flash_obj))
{
/* Wait for the flash erase to be successful */
}
/* Partially-blocking flash write */
result = cyhal_flash_start_write(&flash_obj, (uint32_t)flash_data_ptr, (const uint32_t *)ram_data);
if(CY_RSLT_SUCCESS == result)
{
/* Wait for 100ms for the flash write to complete */
timeout = 100;
/* Wait for the successful flash write */
while((true != cyhal_flash_is_operation_complete(&flash_obj)) && (0 < timeout))
{
timeout--;
cyhal_system_delay_ms(1); /* delay one millisecond each iteration */
}
/* Flag error if the expected flash write status not returned within timeout period */
if(0 != timeout)
{
/* Read flash data */
result = cyhal_flash_read(&flash_obj, (uint32_t)flash_data_ptr, flash_read_data, sizeof(flash_read_data));
if(CY_RSLT_SUCCESS == result)
{
/* Verify the data written into flash by comparing it with the RAM data */
if(0 == memcmp(ram_data, flash_read_data, sizeof(flash_read_data)))
{
compare_status = true;
}
}
}
}
Note
It is recommended to declare the flash array as global variable.

API Reference

 Flash HAL Results
 Flash specific return codes.
 

Data Structures

struct  cyhal_flash_block_info_t
 Information about a single block of flash memory. More...
 
struct  cyhal_flash_info_t
 Information about all of the blocks of flash memory. More...
 

Functions

cy_rslt_t cyhal_flash_init (cyhal_flash_t *obj)
 Initialize the cyhal_flash_t object for accessing flash through the HAL. More...
 
void cyhal_flash_free (cyhal_flash_t *obj)
 Free resources associated with flash object through the HAL. More...
 
void cyhal_flash_get_info (const cyhal_flash_t *obj, cyhal_flash_info_t *info)
 Gets flash characteristics like the start address, size, erase values etc. More...
 
cy_rslt_t cyhal_flash_read (cyhal_flash_t *obj, uint32_t address, uint8_t *data, size_t size)
 Read data starting at a defined address. More...
 
cy_rslt_t cyhal_flash_erase (cyhal_flash_t *obj, uint32_t address)
 Erase one page starting at a defined address. More...
 
cy_rslt_t cyhal_flash_write (cyhal_flash_t *obj, uint32_t address, const uint32_t *data)
 This function erases the page and writes the new data into the page starting at a defined address. More...
 
cy_rslt_t cyhal_flash_program (cyhal_flash_t *obj, uint32_t address, const uint32_t *data)
 Program one page with given data starting at defined address. More...
 
cy_rslt_t cyhal_flash_start_erase (cyhal_flash_t *obj, uint32_t address)
 Starts an asynchronous erase of a single page of flash. More...
 
cy_rslt_t cyhal_flash_start_write (cyhal_flash_t *obj, uint32_t address, const uint32_t *data)
 Starts an asynchronous write to a single page of flash. More...
 
cy_rslt_t cyhal_flash_start_program (cyhal_flash_t *obj, uint32_t address, const uint32_t *data)
 Starts asynchronous programming of a single page of flash. More...
 
bool cyhal_flash_is_operation_complete (cyhal_flash_t *obj)
 Reports status of the flash operation. More...
 

Data Structure Documentation

◆ cyhal_flash_block_info_t

struct cyhal_flash_block_info_t
Data Fields
uint32_t start_address Start address of the memory.
uint32_t size Size of the flash memory.
uint32_t sector_size Sector size of the memory.
uint32_t page_size Page size of the memory.
uint8_t erase_value The flash erase value.

◆ cyhal_flash_info_t

struct cyhal_flash_info_t
Data Fields
uint8_t block_count The number of distinct flash blocks.
const cyhal_flash_block_info_t * blocks Array of the distinct flash blocks.

Function Documentation

◆ cyhal_flash_init()

cy_rslt_t cyhal_flash_init ( cyhal_flash_t obj)

Initialize the cyhal_flash_t object for accessing flash through the HAL.

Parameters
[out]objPointer to a flash object. The caller must allocate the memory for this object but the init function will initialize its contents.
Returns
The status of the init request. Returns CY_RSLT_SUCCESS on successful operation.

◆ cyhal_flash_free()

void cyhal_flash_free ( cyhal_flash_t obj)

Free resources associated with flash object through the HAL.

Parameters
[out]objThe flash object.

◆ cyhal_flash_get_info()

void cyhal_flash_get_info ( const cyhal_flash_t obj,
cyhal_flash_info_t info 
)

Gets flash characteristics like the start address, size, erase values etc.

Refer cyhal_flash_info_t for more information.

Parameters
[in]objThe flash object.
[out]infoThe flash characteristic info.

Refer Snippet 1: Discovering flash characteristics for more information.

◆ cyhal_flash_read()

cy_rslt_t cyhal_flash_read ( cyhal_flash_t obj,
uint32_t  address,
uint8_t *  data,
size_t  size 
)

Read data starting at a defined address.

Parameters
[in]objThe flash object.
[in]addressAddress to begin reading from.
[out]dataThe buffer to read data into.
[in]sizeThe number of bytes to read.
Returns
The status of the read request. Returns CY_RSLT_SUCCESS on successful operation.

Refer Snippet 2: Blocking Flash Write Operation for more information.

◆ cyhal_flash_erase()

cy_rslt_t cyhal_flash_erase ( cyhal_flash_t obj,
uint32_t  address 
)

Erase one page starting at a defined address.

The address must be at page boundary. This will block until the erase operation is complete.

See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the page erase size.
Parameters
[in]objThe flash object
[in]addressThe page starting address
Returns
The status of the erase request. Returns CY_RSLT_SUCCESS on successful operation.

Refer Snippet 2: Blocking Flash Write Operation for more information.

◆ cyhal_flash_write()

cy_rslt_t cyhal_flash_write ( cyhal_flash_t obj,
uint32_t  address,
const uint32_t *  data 
)

This function erases the page and writes the new data into the page starting at a defined address.

The address must be at page boundary. This will block until the write operation is complete.

See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the page write size. The provided data buffer must be at least as large as the flash page_size.
Parameters
[in]objThe flash object
[in]addressThe page starting address
[in]dataThe data to write to the flash
Returns
The status of the write request. Returns CY_RSLT_SUCCESS on successful operation.

Refer Snippet 2: Blocking Flash Write Operation for more information.

◆ cyhal_flash_program()

cy_rslt_t cyhal_flash_program ( cyhal_flash_t obj,
uint32_t  address,
const uint32_t *  data 
)

Program one page with given data starting at defined address.

The address must be at page boundary. This will block until the write operation is complete.

Note
This function does not erase the page prior to writing. The page must be erased first via a separate call to erase.
See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the total page size. The provided data buffer must be at least as large as the flash page_size.
Parameters
[in]objThe flash object
[in]addressThe sector starting address
[in]dataThe data buffer to be programmed
Returns
The status of the program request. Returns CY_RSLT_SUCCESS on successful operation.

◆ cyhal_flash_start_erase()

cy_rslt_t cyhal_flash_start_erase ( cyhal_flash_t obj,
uint32_t  address 
)

Starts an asynchronous erase of a single page of flash.

Returns immediately and reports a successful start or reason for failure. The address must be aligned on a page boundary.

See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the page erase size.
Parameters
[in]objThe Flash object being operated on
[in]addressThe address to start erasing from
Returns
The status of the start_erase request.

Refer Snippet 3: Non-blocking Flash Write Operation using polling for more information.

◆ cyhal_flash_start_write()

cy_rslt_t cyhal_flash_start_write ( cyhal_flash_t obj,
uint32_t  address,
const uint32_t *  data 
)

Starts an asynchronous write to a single page of flash.

Returns immediately and reports a successful start or reason for failure. The address must be aligned on a page boundary.

See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the page write size. The provided data buffer must be at least as large as the flash page_size.
Parameters
[in]objThe Flash object being operated on
[in]addressThe address to start writing to
[in]dataThe data to write to flash
Returns
The status of the start_write request.

Refer Snippet 3: Non-blocking Flash Write Operation using polling for more information.

◆ cyhal_flash_start_program()

cy_rslt_t cyhal_flash_start_program ( cyhal_flash_t obj,
uint32_t  address,
const uint32_t *  data 
)

Starts asynchronous programming of a single page of flash.

Returns immediately and reports a successful start or reason for failure.

Note
Perform erase operation prior to calling this.
See also
cyhal_flash_get_info() to get the flash characteristics for legal address values and the total page size. The provided data buffer must be at least as large as the flash page_size.
Parameters
[in]objThe Flash object being operated on
[in]addressThe address to start programming
[in]dataThe data to write to flash
Returns
The status of the start_program request. Returns CY_RSLT_SUCCESS on successful operation.

◆ cyhal_flash_is_operation_complete()

bool cyhal_flash_is_operation_complete ( cyhal_flash_t obj)

Reports status of the flash operation.

Parameters
[in]objThe Flash object being operated on
Returns
true if flash operation is complete. false otherwise.