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:

  1. Define a layout configuration struct as described in Configuring Flash Layout. This struct can be accessed within your quirk function via the Flash_Config *cfg parameter. The config struct includes a void* layoutCfg pointer that references your layout configuration.

  2. Implement your quirk function in flash_nor_ospi.c following the required signature:

    int32_t YourQuirkFunction(Flash_Config *cfg);
    
  3. Register your quirk function by updating the quirk_function field 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;
}
Flash Quirks Fxn Configuration

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 NULL is returned.

Global variables Flash_Config gFlashConfig[] and uint32_t gFlashConfigNum is 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 open

  • params – [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
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
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

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

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.