Flash
The driver takes care of all sequencing necessary to perform writes across pages and the application need not take care of the programming intricacies.
Features Supported
APIs to read and write to a flash offset
Provides API to return flash attributes like block size, page size etc
API for block erases
Flash Layout
The NOR flash S28HS512T present in AM62 SoCs allows users to configure flash in different layouts by writing to the configuration registers, a feature not supported by other NOR flash devices. Other NOR flash parts from vendors like Micron, Macronix, ISSI, and Winbond only support uniform flash layouts, where the entire flash is divided into blocks of uniform size, with blocks further divided into sectors. In these standard flash devices, block erase and sector erase operations can be performed at any offset, erasing either an entire block or a sector based on the operation chosen.
In contrast, the S28HS512T supports sector erase operations only in non-uniform mode specifically on the 4KB sectors. In uniform mode, only block erase operations are allowed, and attempting sector erase operations has no effect.
The S28HS512T supports four different flash layouts:
Uniform: The entire flash is divided into uniform 256KB blocks.
Bottom Hybrid: The first 256KB of flash is divided into 32 sectors of 4KB each and 1 block of 128KB, while the remaining flash is divided into 256KB blocks.
Top Hybrid: The last 256KB of flash is divided into 32 sectors of 4KB each and 1 block of 128KB, while the remaining flash is divided into 256KB blocks.
Split Hybrid: The first and last blocks are each divided into 16 sectors of 4KB and 1 block of 192KB, with the middle portion of flash divided into 256KB blocks.
How To Configure Hybrid Layout
Flash Layout Configuration
The S28HS512T NOR flash supports multiple memory layout configurations that affect sector organization
and erase operations. The driver automatically configures the flash layout during initialization through
the Flash_quirkSpansionConfigureLayout function in flash_nor_ospi.c.
Configuring Flash Layout
To customize the flash layout, modify the layout configuration using Flash_NorOspiHybridLayoutCfg
structure before calling flash open.
typedef struct {
uint32_t isHybridLayout; /* 0: Uniform layout, 1: Hybrid layout */
uint32_t hybridLayoutType; /* Hybrid layout type (see table below) */
} Flash_NorOspiHybridLayoutCfg;
Available Layout Options
Main Layout Types
Layout Type |
Value |
Description |
|---|---|---|
Uniform Layout |
0U |
Standard uniform sector sizes throughout the entire flash memory |
Hybrid Layout |
1U |
Mixed sector sizes for more flexible memory management |
Hybrid Layout Configurations
When isHybridLayout is set to 1, you must specify the hybrid layout type using
hybridLayoutType:
Hybrid Layout Type |
Value |
Description |
|---|---|---|
Bottom Hybrid |
0U |
Smaller sectors at the bottom (low addresses) of flash memory |
Top Hybrid |
1U |
Smaller sectors at the top (high addresses) of flash memory |
Split Hybrid |
2U |
Smaller sectors at both bottom and top of flash memory |
Example Configuration
For a hybrid layout with smaller sectors at both the bottom and top of memory (Split Hybrid):
/* Get the layout configuration from flash config */
Flash_NorOspiHybridLayoutCfg *layoutCfg = (Flash_NorOspiHybridLayoutCfg*)(gFlashConfig[CONFIG_FLASH0].layoutCfg);
/* Configure for split hybrid layout */
layoutCfg->isHybridLayout = 1U; /* Hybrid layout */
layoutCfg->hybridLayoutType = 2U; /* Split hybrid type */
Custom Flash Layout Implementation
Developers can implement their own custom configuration function to accommodate specific flash layouts according to flash datasheet specifications. This is particularly useful when:
Working with flash devices that have non-standard sector arrangements
Implementing custom command sequences
Supporting specialized flash memory with unique organization requirements
To add a custom flash configuration function:
Define a layout configuration struct as described in Configuring Flash Layout. This struct can be accessed within your quirk function via the
Flash_Config *cfgparameter. The config struct includes avoid* layoutCfgpointer that references your layout configuration.Implement your quirk function in
flash_nor_ospi.cfollowing the required signature:int32_t YourQuirkFunction(Flash_Config *cfg);
Register your quirk function by updating the
quirk_functionfield in the flash section of your board configuration.
Example implementation:
/* In flash_nor_ospi.c */
int32_t myQuirksFxn(Flash_Config *cfg)
{
int32_t status = SystemP_SUCCESS;
/* Access layout configuration if needed */
MyFlashLayoutCfg *layoutCfg = (MyFlashLayoutCfg *)cfg->layoutCfg;
/* Your code for handling quirks goes here */
/* For example: modify flash timing parameters, handle special initialization, etc. */
return status;
}
SysConfig Features
Note
It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.
Option to select flash type based on board
Supported flash devices
S28HS512T
Features NOT Supported
NA
Important Usage Guidelines
Typically before writing to an offset, erase the block which corresponds to the offset
Flash writes can only be done to a page size aligned offset, otherwise the write API returns an error
Example Usage
Include the below file to access the APIs
//! [include]
#include <board/flash.h>
//! [include]
Flash Read API
//! [read]
uint32_t offset;
/* Set offset to read from */
offset = 0;
/* Do the read */
status = Flash_read(handle, offset, buffer, 100);
DebugP_assert(SystemP_SUCCESS == status);
//! [read]
Flash Write API
//! [write]
uint32_t offset;
/* Set offset to write to */
offset = 0;
/* Do the write */
status = Flash_write(handle, offset, buffer, 100);
DebugP_assert(SystemP_SUCCESS == status);
//! [write]
Flash Erase API
//! [erase]
uint32_t offset, blk, page;
/* Set offset to erase */
offset = 0;
/* Find the block number corresponding to the offset */
status = Flash_offsetToBlkPage(handle, offset, &blk, &page);
DebugP_assert(SystemP_SUCCESS == status);
/* Erase the block */
status = Flash_eraseBlk(handle,blk);
DebugP_assert(SystemP_SUCCESS == status);
//! [erase]
API Reference
Flash driver implementation callbacks
-
typedef int32_t (*Flash_OpenFxn)(Flash_Config *config, Flash_Params *params)
Driver implementation to open a specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Param params:
[in] User controllable parameters when opening the flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef void (*Flash_CloseFxn)(Flash_Config *config)
Driver implementation to close a specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_ReadFxn)(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len)
Driver implementation to read from flash using a specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Param offset:
[in] Offset in the flash from where to start the read
- Param buf:
[in] Buffer into which to read the data into
- Param len:
[in] Length of the data to read, in bytes
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_WriteFxn)(Flash_Config *config, uint32_t offset, uint8_t *buf, uint32_t len)
Driver implementation to write to flash using specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Param offset:
[in] Offset in the flash from where to start the write.
- Param buf:
[in] Buffer which has the data to write.
- Param len:
[in] Length of the data to write, in bytes
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_EraseFxn)(Flash_Config *config, uint32_t blockNum)
Driver implementation to erase a block using a specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Param blockNum:
[in] Block number to erase.
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_EraseSectorFxn)(Flash_Config *config, uint32_t sectorNum)
Driver implementation to erase a sector using a specific flash driver.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Param sectorNum:
[in] Sector number to erase.
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_ResetFxn)(Flash_Config *config)
Driver implementation to soft reset the flash.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_EnablePhyPipelineFxn)(Flash_Config *config)
Driver implementation to enable PHY pipeline mode in Flash.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_DisablePhyPipelineFxn)(Flash_Config *config)
Driver implementation to disable PHY pipeline mode in Flash.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_quirksFxn)(Flash_Config *config)
User implementation of a custom function to handle vendor specific quirks.
Typically this callback is hidden from the end application and is implemented when a new type of flash device needs to be implemented.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_custProtocolFxn)(Flash_Config *config)
User implementation of a custom function to configure flash to operate in a specific protocol.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
-
typedef int32_t (*Flash_PhyTuneFxn)(Flash_Config *config)
Driver implementation to perform phy tuning using a specific flash driver.
- Param config:
[in] Flash configuration for the specific flash device
- Return:
SystemP_SUCCESS on success, else failure
Defines
-
FLASH_INVALID_VALUE
-
CONFIG_FLASH_TYPE_SERIAL
-
CONFIG_FLASH_TYPE_PARALLEL
-
CONFIG_FLASH_TYPE_SERIAL_NOR
Flash type supported.
-
CONFIG_FLASH_TYPE_SERIAL_NAND
-
CONFIG_FLASH_TYPE_PARALLEL_NOR
-
CONFIG_FLASH_TYPE_PARALLEL_NAND
-
CONFIG_FLASH_TYPE_INVALID
-
FLASH_NOR_UPDATE_RD_DUMMY_VALUE
-
FLASH_NAND_UPDATE_RD_DUMMY_VALUE
Typedefs
-
typedef void *Flash_Handle
Handle to the FLash driver returned by Flash_opem()
Functions
-
void Flash_Params_init(Flash_Params *params)
Set default parameters in the Flash_Params_s structure.
Call this API to set defaults and then override the fields as needed before calling Flash_open.
- Parameters:
params – [out] Initialized parameters
-
Flash_Handle Flash_open(uint32_t instanceId, Flash_Params *params)
Open flash driver.
Make sure the SOC peripheral driver is opened before calling this API. Drivers_open function generated by SysCfg opens the underlying SOC peripheral driver, e.g OSPI.
Internally this API also reads the device and manufacture ID and checks if it matches the expected value for the flash device, if there is mismatch then
NULLis returned.Global variables
Flash_Config gFlashConfig[]anduint32_t gFlashConfigNumis instantiated by SysCfg to describe the flash configuration based on user selection in SysCfg.- Parameters:
instanceId – [in] Index within
Flash_Config gFlashConfig[]denoting the flash driver to openparams – [in] Open parameters
- Returns:
Handle to flash driver which should be used in subsequent API call
- Returns:
NULL in case of failure
-
void Flash_close(Flash_Handle handle)
Close flash driver.
- Parameters:
handle – [in] Flash driver handle from Flash_open
-
Flash_Handle Flash_getHandle(uint32_t instanceId)
Get handle to flash driver.
- Parameters:
instanceId – [in] Index within
Flash_Config gFlashConfig[]- Returns:
Handle to flash driver
- Returns:
NULL in case of failure
-
int32_t Flash_read(Flash_Handle handle, uint32_t offset, uint8_t *buf, uint32_t len)
Read data from flash.
Internally it will use DMA and do the needed cache sync operations as needed.
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [in] Offset in the flash from where to start the read
buf – [in] Buffer into which to read the data into
len – [in] Length of the data to read, in bytes
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_write(Flash_Handle handle, uint32_t offset, uint8_t *buf, uint32_t len)
Write to flash.
Make sure the block is erased before writing
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [in] Offset in the flash from where to start the write.
buf – [in] Buffer which has the data to write.
len – [in] Length of the data to write, in bytes
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_blkPageToOffset(Flash_Handle handle, uint32_t *offset, uint32_t block, uint32_t page)
Utility API to convert (Block Num, Page Num) to offset in bytes.
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [out] Offset in the flash, in bytes.
block – [in] Block number to convert
page – [in] Page number within the block
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_offsetToBlkPage(Flash_Handle handle, uint32_t offset, uint32_t *block, uint32_t *page)
Utility API to convert offset in bytes to (Block Num, Page Num)
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [in] Offset in the flash, in bytes. MUST be page size aligned.
block – [out] Converted Block number
page – [out] Converted Page number within the block
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_SectorPageToOffset(Flash_Handle handle, uint32_t *offset, uint32_t sector, uint32_t page)
Utility API to convert (Sector Num, Page Num) to offset in bytes.
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [out] Offset in the flash, in bytes.
sector – [in] Sector number to convert
page – [in] Page number within the block
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_offsetToSectorPage(Flash_Handle handle, uint32_t offset, uint32_t *sector, uint32_t *page)
Utility API to convert offset in bytes to (Sector Num, Page Num)
- Parameters:
handle – [in] Flash driver handle from Flash_open
offset – [in] Offset in the flash, in bytes. MUST be page size aligned.
sector – [out] Converted sector number
page – [out] Converted Page number within the block
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_eraseBlk(Flash_Handle handle, uint32_t blockNum)
Erase a block from flash.
Use the utility API Flash_offsetToBlkPage to convert a offset to block number
- Parameters:
handle – [in] Flash driver handle from Flash_open
blockNum – [in] Block number to erase.
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_eraseSector(Flash_Handle handle, uint32_t sectorNum)
Erase a sector from flash.
Use the utility API Flash_offsetToSectorPage to convert a offset to block number
- Parameters:
handle – [in] Flash driver handle from Flash_open
sectorNum – [in] Sector number to erase.
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_reset(Flash_Handle handle)
Do a soft reset of the flash.
- Parameters:
handle – [in] Flash driver handle from Flash_open
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_enablePhyPipeline(Flash_Handle handle)
Enables PHY mode in flash.
- Parameters:
handle – [in] Flash driver handle from Flash_open
- Returns:
SystemP_SUCCESS on success, else failure
-
int32_t Flash_disablePhyPipeline(Flash_Handle handle)
Disable PHY mode in flash.
- Parameters:
handle – [in] Flash driver handle from Flash_open
- Returns:
SystemP_SUCCESS on success, else failure
-
uint32_t Flash_getPhyTuningOffset(Flash_Handle handle)
Return flash offset to write PHY tuning data.
- Parameters:
handle – [in] Flash driver handle from Flash_open
- Returns:
Tuning offset on SUCCESS, else 0xFFFFFFFF if handle is invalid
-
Flash_Attrs *Flash_getAttrs(uint32_t instanceId)
Return flash attributes.
- Parameters:
instanceId – [in] Flash instance ID
- Returns:
Flash_Attrs, else NULL if instanceId is invalid
-
uint32_t Flash_getFlashInterfaceIndex(uint32_t flashType)
Return flash index based on type of flash.
- Parameters:
flashType – [in] Flash Type (Serial/Parallel)
- Returns:
Flash_Attrs driver instance index corresponding to the flash type
-
void Flash_init(void)
This function initializes the Flash module.
-
void Flash_deinit(void)
This function de-initializes the Flash module.
-
int32_t Flash_phyTune(Flash_Handle handle)
This function performs PHY tuning.
Make sure phy is enabled before calling this
- Parameters:
handle – [in] Flash driver handle from Flash_open
- Returns:
SystemP_SUCCESS on success, else failure
-
struct Flash_DevConfig
- #include <flash.h>
Flash device config. This will be part of the flash config, so has to be filled by sysconfig or otherwise before invoking Flash_open.
Public Members
-
uint8_t cmdExtType
-
uint8_t byteOrder
-
uint8_t enable4BAddr
-
uint8_t addrByteSupport
-
uint8_t fourByteAddrEnSeq
-
uint8_t cmdWren
-
uint8_t cmdRdsr
-
uint8_t cmdWrsr
-
uint8_t cmdPageLoad
-
uint8_t cmdPageProg
-
uint8_t srWip
-
uint8_t cmdPageLoadCyc1
-
uint8_t cmdPageLoadCyc2
-
uint8_t cmdRandomReadCyc1
-
uint8_t cmdRandomReadCyc2
-
uint8_t cmdRandomInput
-
uint8_t cmdPageProgCyc1
-
uint8_t cmdPageProgCyc2
-
uint8_t pageColAddrCyc
-
uint8_t pageRowAddrCyc
-
uint8_t cmdReadStatus
-
uint8_t cmdReset
-
uint8_t srWel
-
uint8_t resetType
-
uint8_t deviceBusyType
-
uint8_t xspiWipRdCmd
-
uint32_t srWipReg
-
uint32_t xspiWipReg
-
uint32_t xspiWipBit
-
uint32_t xspiRdsrDummy
-
uint32_t flashWriteTimeout
-
uint32_t flashBusyTimeout
-
FlashCfg_EraseConfig eraseCfg
-
FlashCfg_ReadIDConfig idCfg
-
FlashCfg_ProtoEnConfig protocolCfg
-
uint32_t progStatusReg
-
uint32_t xspiProgStatusReg
-
uint32_t eraseStatusReg
-
uint32_t xspiEraseStatusReg
-
uint8_t srProgStatus
-
uint8_t srEraseStatus
-
uint8_t srWriteProtectReg
-
uint8_t srWriteProtectMask
-
uint8_t cmdExtType
-
struct Flash_Params_s
- #include <flash.h>
Parameters passed during Flash_open()
Forward declaration of Flash_Params_s.
Public Members
-
Flash_quirksFxn quirksFxn
-
Flash_quirksFxn bootQuirksFxn
-
Flash_custProtocolFxn custProtoFxn
-
Flash_quirksFxn quirksFxn
-
struct Flash_Fxns
- #include <flash.h>
Driver implementation callbacks.
Public Members
-
Flash_OpenFxn openFxn
Flash driver implementation specific callback
-
Flash_CloseFxn closeFxn
Flash driver implementation specific callback
-
Flash_ReadFxn readFxn
Flash driver implementation specific callback
-
Flash_WriteFxn writeFxn
Flash driver implementation specific callback
-
Flash_EraseFxn eraseFxn
Flash driver implementation specific callback
-
Flash_EraseSectorFxn eraseSectorFxn
Flash driver implementation specific callback
-
Flash_ResetFxn resetFxn
Flash driver implementation specific callback
-
Flash_EnablePhyPipelineFxn enablePhyPipelineFxn
Flash driver implementation specific callback
-
Flash_DisablePhyPipelineFxn disablePhyPipelineFxn
Flash driver implementation specific callback
-
Flash_PhyTuneFxn phyTuneFxn
Flash driver implementation specific callback
-
Flash_OpenFxn openFxn
-
struct Flash_Attrs
- #include <flash.h>
Flash device attributes, these are filled by SysCfg based on the flash device that is selected.
Public Members
-
uint32_t flashType
Flash type. Whether it’s SERIAL or PARALLEL
-
char *flashName
Flash name. Taken from Sysconfig
-
uint32_t deviceId
Flash device ID as read form the flash device, this will be filled when Flash_open() is called
-
uint32_t manufacturerId
Flash manufacturer ID as read form the flash device, this will be filled when Flash_open() is called
-
uint32_t driverInstance
Underlying SPI peripheral driver instance that is used by the flash driver, e.g OSPI driver
-
uint32_t flashSize
Flash size, in bytes
-
uint32_t blockCount
Number of blocks in the flash the flash
-
uint32_t blockSize
Size of each block, in bytes
-
uint32_t pageCount
Number of pages per block
-
uint32_t pageSize
Size of each page, in bytes
-
uint32_t sectorCount
Number of sectors in the flash, if flash supports sectors
-
uint32_t sectorSize
Size of each flash sector, in bytes
-
uint32_t spareAreaSize
Size of spare area in flash
-
uint32_t flashType
-
struct Flash_Config_s
- #include <flash.h>
Flash driver configuration, these are filled by SysCfg based on the flash device that is selected.
Forward declaration of Flash_Config_s.
Public Members
-
Flash_Attrs *attrs
Flash device attributes
-
Flash_Fxns *fxns
Flash device implementation functions
-
Flash_DevConfig *devConfig
Flash device specific config, like command ID for read, erase, etc
-
void *object
Flash driver object, used to maintain driver implementation state
-
void *fallBackCfg
Flash fallback configs, used to configure flash in
-
void *layoutCfg
Flash fallback configs, used to configure flash layout
-
SemaphoreP_Object lockSem
Semaphore to protect the flash layer calls per instance.
-
Flash_Attrs *attrs