6.2. Adding Support For a Custom Flash Device¶
6.2.1. Optimizations¶
Here is a short summary of the performance optimizations discussed in detail in this document.
6.2.2. Introduction¶
The flash driver is supposed to work based on a configuration structure passed on the driver during the initialization time. This configuration structure has been chosen to support the configuration models of a number of flashes from multiple vendors. Currently, this configuration is manually written in a defined structure. This guide details the steps to bring up a custom flash and update the corresponding flash related parameters.
The OSPI interface present in the SOC can support only the 1S-1S-1S mode or 8D-8D-8D for reading from the flash.
The configuration structure can be obtained automatically if the flash supports SFDP (Serial Flash Discoverable Parameter) table.
6.2.3. Serial Flash Discoverable Parameters (SFDP)¶
The Serial Flash Discoverable Parameters (SFDP) is a standard which provides a consistent method of describing the functional and feature capabilities of the flash device in a standard set of internal parameter tables. This table can be queried to identify the configurations and adjustments needed to set the flash in a desired state.
The parsing of the SFDP table is time consuming. Considering this, the SFDP parsing feature is tied with a diagnostic example of the OSPI driver. In flashes where the SFDP is supported, this example can be used to parse the details into a config structure which can aid bringing up the custom flash. As of now the SFDP parsing supports upto JEDS216D standard.
6.2.3.1. SFDP structure and parameters¶
SFDP Parameters |
Parameter Description |
---|---|
flashSize |
flash size in decimal |
pageSize |
flash page size in decimal |
manfId |
flash manufacturer ID in 2 digit hexadecimal with leading 0x |
deviceId |
flash device ID in 4 digit hexadecimal with leading 0x |
numSupportedEraseTypes |
Number of bytes used in addressing flash array read, write and erase |
cmdExtType |
Octal DTR (8D-8D-8D) Command and Command Extension |
byteOrder |
Byte Order in 8D-8D-8D mode |
addrByteSupport |
Number of bytes used in addressing flash array read, write and erase |
fourByteAddrEnSeq |
Defines the supported methods to enter 4-byte addressing mode or to use an extended address register with 3-byte addressing to access memory above 16 MBytes |
fourByteAddrDisSeq |
Exit 4 byte Addressing mode |
dtrSupport |
Indicates the device supports some type of double transfer rate clocking |
deviceBusyType |
Defines various ways the flash device’s busy status may be polled. A zero in a bit position indicates that the device does not support the particular polling method. |
eraseCfg.blockSize |
flash block size in decimal |
eraseCfg.sectorSize |
flash sector size in decimal |
eraseCfg.cmdBlockErase3B |
block erase command in 3B addressing mode |
eraseCfg.cmdBlockErase4B |
block erase command in 4B addressing mode |
eraseCfg.cmdSectorErase3B |
sector erase command in 3B addressing mode |
eraseCfg.cmdSectorErase4B |
sector erase command in 4B addressing mode |
rstType |
reset type supported as 2 digit hexadecimal with leading 0x |
cmdWren |
Command for WREN as 2 digit hexadecimal with leading 0x |
cmdRdsr |
Command for reading status register as 2 digit hexadecimal with leading 0x |
cmdRdsr2 |
Command for reading status register 2 as 2 digit hexadecimal with leading 0x |
cmdWrsr |
Command for writing status register as 2 digit hexadecimal with leading 0x |
srWip |
Bit position of WIP bit in status register as decimal number |
srWel |
Bit position of WEL bit in status register as decimal number |
cmdChipErase |
Command for erasing full chip as 2 digit hexadecimal with leading 0x |
idCfg.cmd |
Command for reading JEDEC ID as 2 digit hexadecimal with leading 0x |
idCfg.numBytes |
Number of bytes to read when reading JEDEC ID in decimal |
idCfg.dummy4 |
Number of dummy cycles to use to read JEDEC ID in quad mode |
idCfg.dummy8 |
Number of dummy cycles to use to read JEDEC ID in quad mode |
protos.isDtr |
true if DTR protocol, false if not |
protos.cmdRd |
Command for reading in the protocol as 2 digit hexadecimal with leading 0x |
protos.cmdWr |
Command for writing/page programming in the protocol as 2 digit hexadecimal with leading 0x |
protos.modeClksRd |
Fast Read Number of Mode Clocks for the corresponding protocol |
protos.dummyClksCmd |
Dummy Cycles for RDSR and REG READ CMDs |
protos.dummyClksRd |
Fast Read Number of Wait states (dummy clocks) needed before valid output |
protos.enableType |
Describes Quad Enable (QE) bit used to enable 1S-1S-4S and 1S-4S-4S quad read or quad program operations. |
protos.enableSeq |
Describes the supported methods to enter 4S-4S-4S, 4S-4D-4D, 8S-8S-8S, 8D-8D-8D mode from 1S-1S-1S mode |
protos.protoCfg |
QPI and OPI mode enablement |
protoCfg.isAddrReg |
true if configured via addressed register, false if not |
protoCfg.cmdRegRd |
Command for reading config register, addressed or otherwise, as 2 digit hexadecimal with leading 0x |
protoCfg.cmdRegWr |
Command for reading config register, addressed or otherwise, as 2 digit hexadecimal with leading 0x |
protoCfg.cfgReg |
Config register address if exists in 8 digit hexadecimal with leading 0x |
protoCfg.shift |
Bits to shift to reach LSB of bit field where the config data needs to written, in decimal |
protoCfg.mask |
Bit mask of the config data in the register, as 2 digit hexadecimal with leading 0x |
protoCfg.cfgRegBitP |
Config data as decimal |
protos.dummyCfg |
Check if variable dummy cycles are supported, and if yes check if it is set through registers |
protos.strDtrCfg |
STR or DTR mode enablement |
xspiWipRdCmd |
Instruction for single input instruction and address and dual output data Fast Read |
xspiWipReg |
Address of Register where Bit is located |
xspiWipBit |
Bit Location of WIP Bit in Register |
flashWriteTimeout |
Time the device typically takes to write a full page |
wrrwriteTimeout |
Time to write |
flashBusyTimeout |
Typical time to erase one chip |
chipEraseTimeout |
Typical time to erase one chip |
6.2.4. Flash Diag Example¶
This is a diagnostic example for NOR-OSPI Flashes. This example first executes read, write and erase functionality and upon successful execution starts extracting flash specific parameters. Extraction of SFDP parameters doesn’t use the flash driver and should ideally pass for any NOR-OSPI flash. This example will always talk to the flash in the lowest settings possible. The flash device is reset, and is expected to support 1S-1S-1S mode after reset. Then the OSPI controller is programmed to work in 1S-1S-1S mode with 3 byte addressing mode.
The test itself is simple, first it tries to read the JEDEC ID of the flash which consists of the flash manufacturer ID and the flash device ID. These are then printed onto the logging console. When doing flash bring-ups in new boards, this example can be run first for sanity. Users can cross check the printed ID with the one in flash datasheet to confirm that basic communication with flash is working.
The test then tries to erase a flash memory block at an offset and then write some known data to that memory. This data is then read back and verified to confirm that reads and writes are working in 1S-1S-1S mode.
6.2.5. Summary of steps needed to enable a new flash device¶
Step 1: Build the flsdiag example.
This example communicates with the flash in 1S-1S-1S mode and queries the flash for the SFDP table (if SFDP is supported by the flash) among other things. The logs from this example would be required later to configure the flash driver.
Before running the flsdiag example, verify the values of fls_config_sfdp_1 structure members in Flash_readsfdp_init API in $MCAL_INSTALL_DIR/mcal/Fls/V2/Fls_Nor_config.c file in the driver. Make changes in the specifications by following the documentation. These includes simple parameters like flash size, page size, read and write command.
Step 2: Configuring the Flash
This involves copying the data obtained by running the example and manually writing the data into a predefined structure.
Let’s get into the details of the steps.
6.2.5.1. Step 1: Building the OSPI Flash Diagnostic example¶
For building flsdiag example, open command prompt inside $MCAL_INSTALL_DIR/build directory and run the following command:
gmake -s flsdiag_ospi_app PLATFORM=am263px
You will need to initialize the SOC in no boot mode and also load and run this example using CCS. Building and running the Flash Diagnostic example is important because regardless of flash supporting SFDP or not, the diagnostic example gives a basic sanity for the flash. If the flash diagnostic doesn’t work, there could be HW connection issues most probably. When you successfully build and run the example, you should get a log with data like this:

You will see this if your flash supports SFDP.
6.2.5.1.1. Case 1: Flash Supports SFDP¶
If your flash supports SFDP and the flsdiag example is able to print out the SFDP table, configuring the flash is quite easy.
You need to open $MCAL_INSTALL_DIR/mcal/Fls/V2/Fls_Nor_Config.c file and copy the values of NorSpiDevDefines structure variable obtained after running the example into the fls_config_sfdp_1 structure variable in Flash_sfdpParams_init API.
You can cross verify the values with datasheet if required, but mostly this won’t be necessary.
6.2.5.1.2. Case 2: Flash Doesn’t Support SFDP¶
If your flash doesn’t support SFDP, the flash configuration details would need to be filled from the datasheet. This can be a pain point, but mostly flashes without SFDP support wouldn’t have a lot of configuration as well. Only basic things like quad bit enable, etc would need to be looked up in the datasheet.
You need to fill the fls_config_sfdp_1 structure in Flash_sfdpParams_init API in $MCAL_INSTALL_DIR/mcal/Fls/V2/Fls_Nor_Config.c file by following the datasheet.
6.2.5.2. Step 2: Configuring the flash¶
Keep a copy of NorSpiDevDefines structure obtained after building and running the flsdiag example.
Go to the $MCAL_INSTALL_DIR/mcal/Fls/V2/Fls_Nor_Config.c file in the driver and update the corresponding parameters of fls_config_sfdp_1 in Flash_sfdpParams_init API. Update the values manually from NorSpiDevDefines structure obtained after running the example.
6.2.6. Obtaining flash details from the SFDP table OR datasheet¶
This section can be ignored if the flash supports SFDP.
All the details regarding the flash including fast read opcodes, supported erase sizes, dummy clocks needed for each instruction and flash configuration registers information will be available from the flash data sheet.
Flash size, page size and block size can be obtained from the introduction/overview section of the datasheet.
The read, write, register read, register write, read ID and other opcodes can be obtained from “Transaction tables”. There will be transaction tables for each protocol (For example 1S-1S-1S transaction table, 8D-8D-8D transaction table)
The number of dummy cycles required for the read opcodes will also be available from the transaction table.
3 byte addressing can work if you are accessing upto the 16 MB. If the flash size is more than that 4 byte addressing mode should be used
Check the datasheet to see if 4 byte addressing mode is supported. There are multiple ways flash devices support 4 byte addressing mode. In most cases, the flash will have separate set of opcodes for 4 byte addressing mode. Sometimes there will be a configuration register which can be set so that flash switches to 4 byte addressing mode.
OE bit setting is one of the most important settings in 8D-8D-8D protocol. Usually it is part of the SR2 and is non-volatilewritable.
6.2.7. Miscellaneous Debugging Tips and Tricks¶
Sometimes if there is a data mismatch or data showing up with one-off bytes (usually in high speed octal transactions), it is advisable to check the dummy cycles, if the controller and flash are in agreement with the same. In case of data mismatch cross check with the datasheet and provide correct value in the flash config structure.