8. Serial Nor
8.1. Overview
The Serial Nor component is a universal driver for serial SPI Flash devices, seamlessly supporting various JEDEC-compliant serial SPI Flash chips like W25Q128, W25Q64, etc., enhancing portability and extensibility. Key features include:
Multi-instance support
Supports multiple flash instances with independent configuration parameters
Supports 24-bit and 32-bit addressing
Compatible with SPI/DSPI/QSPI interfaces
Supports read/write/erase operations
Each instance can be independently configured with SPI interface type, address width, data width, clock frequency, etc.
Enables concurrent operation of multiple flash instances
Blocking and non-blocking I/O interfaces
Provides non-blocking read/write functions
Provides blocking read/write functions with timeout mechanisms to ensure error reporting during prolonged unresponsiveness
8.2. Macro Definitions, Enums and Structs
Macro Definitions
Configuration macros for serial Nor Flash features (defined in
hpm_serial_nor_host.h):
/** * @brief Enable single-wire SPI mode (MOSI+MISO) * @note Bit0: Controls single-wire transmission mode */ #define SERIAL_NOR_HOST_SUPPORT_SINGLE_IO_MODE (1UL << 0) /** * @brief Enable dual-wire SPI mode (using IO0 and IO1 as unidirectional data lines) * @note Bit1: Transmits 2 bits per clock cycle when enabled */ #define SERIAL_NOR_HOST_SUPPORT_DUAL_IO_MODE (1UL << 1) /** * @brief Enable quad-wire SPI mode (using IO0-IO3 as unidirectional data lines) * @note Bit2: Transmits 4 bits per clock cycle when enabled */ #define SERIAL_NOR_HOST_SUPPORT_QUAD_IO_MODE (1UL << 2) /** * @brief Enable standard SPI interface protocol * @note Bit3: Indicates device uses basic SPI protocol */ #define SERIAL_NOR_HOST_SUPPORT_SPI_INTERFACE (1UL << 3) /** * @brief Enable DMA data transfer * @note Bit8: Enables DMA controller for large data transfers */ #define SERIAL_NOR_HOST_SUPPORT_DMA (1UL << 8) /** * @brief Enable automatic chip select control * @note Bit9: Hardware automatically controls CS pin state when enabled */ #define SERIAL_NOR_HOST_CS_CONTROL_AUTO (1UL << 9)
Enumerations
I/O operation modes (defined in
hpm_serial_nor_host.h):typedef enum { single_io_mode = 0, /**< Single-wire SPI mode */ dual_io_mode, /**< Dual-wire mode using MOSI as D0, MISO as D1 */ quad_io_mode /**< Quad-wire QSPI mode */ } hpm_serial_nor_seq_io_mode_t;
Address length modes (defined in
hpm_serial_nor_host.h):typedef enum { flash_addrlen_24bit = 0, /**< 24-bit address mode (3-byte) */ flash_addrlen_32bit /**< 32-bit address mode (4-byte) */ } hpm_serial_nor_seq_addr_bit_t;
Data transfer directions (defined in
hpm_serial_nor_host.h):typedef enum { write_direction = 0, /**< Write operation for programming/erasing */ read_direction /**< Read operation */ } hpm_serial_nor_seq_direction_t;
Structure Definitions
hpm_nor_host_dma_control_t: Host DMA control parameters structure. Implementation varies based on SERIAL_NOR_USE_DMA_MGR:
When SERIAL_NOR_USE_DMA_MGR=0: Manual DMA channel and base address configuration
When SERIAL_NOR_USE_DMA_MGR=1: DMA Manager auto-allocation
typedef struct { uint8_t rx_dma_req; /* RX DMA request line number (e.g. HPM_DMA_SRC_SPI2_RX) */ uint8_t tx_dma_req; /* TX DMA request line number (e.g. HPM_DMA_SRC_SPI2_TX) */ #if (SERIAL_NOR_USE_DMA_MGR == 0) uint8_t rx_dma_ch; /* Manually assigned RX DMA channel */ uint8_t tx_dma_ch; /* Manually assigned TX DMA channel */ void *dma_base; /* DMA controller base (e.g. HPM_DMA) */ void *dmamux_base; /* DMAMUX controller base (e.g. HPM_DMAMUX) */ #else dma_resource_t txdma_resource; /* TX DMA resource from DMA Manager */ dma_resource_t rxdma_resource; /* RX DMA resource from DMA Manager */ #endif } hpm_nor_host_dma_control_t;
hpm_nor_host_param_t: Host controller hardware configuration parameters
typedef struct { uint8_t pin_or_cs_index; /* Physical pin number or CS index */ hpm_nor_host_dma_control_t dma_control; /* DMA config (requires SERIAL_NOR_HOST_SUPPORT_DMA) */ uint32_t clock_name; /* Clock source name (e.g. clock_spi0) */ uint32_t frequency; /* Communication frequency (Hz) */ uint32_t transfer_max_size; /* Max single transfer size (bytes) */ void *host_base; /* Host controller base address */ /** * @brief CS signal control callback * @param cs_pin CS pin number * @param state Pin state (0: low, 1: high) */ void (*set_cs)(uint32_t cs_pin, uint8_t state); /** * @brief Frequency setup callback * @param host Host controller instance * @param freq Target frequency value */ void (*set_frequency)(void *host, uint32_t freq); } hpm_nor_host_param_t;
hpm_sfdp_read_para_t: Read operation timing parameters (supports different read modes)
typedef struct { uint8_t read_cmd; /* Base read command (e.g. 0x03: Normal, 0x6B: Quad Fast) */ uint8_t data_dummy_count; /* Dummy cycles before data phase (set per flash spec) */ hpm_serial_nor_seq_addr_bit_t addr_bit; /* Address length mode */ hpm_serial_nor_seq_io_mode_t data_phase_format; /* Data phase I/O mode */ hpm_serial_nor_seq_io_mode_t addr_phase_format; /* Address phase I/O mode */ } hpm_sfdp_read_para_t;
hpm_sfdp_program_para_t: Page programming parameters
typedef struct { bool has_4b_addressing_inst_table; /* Supports 4-byte addressing instructions (>128Mb) */ bool support_1_4_4_page_program; /* Supports 1-4-4 mode (1cmd +4addr +4data) */ bool support_1_1_4_page_program; /* Supports 1-1-4 mode (1cmd +1addr +4data) */ uint8_t page_program_cmd; /* Page program command (e.g. 0x02: Standard) */ } hpm_sfdp_program_para_t;
hpm_serial_nor_host_param_t: Host parameter container
typedef struct { uint32_t flags; /* Feature flags (SERIAL_NOR_HOST_SUPPORT_* macros) */ hpm_nor_host_param_t param; /* Hardware params (pins/DMA/clocks) */ void *user_data; /* User context pointer for callbacks */ } hpm_serial_nor_host_param_t;
hpm_serial_nor_transfer_seq_t: NOR flash operation sequence descriptor
typedef struct { uint8_t use_dma; /* DMA selector (0:disable 1:enable) */ /* Command phase */ struct { uint8_t cmd; /* Operation command (e.g. 0x03: Read) */ } cmd_phase; /* Address phase */ struct { bool enable; /* Enable address phase */ hpm_serial_nor_seq_addr_bit_t addr_bit; /* Address length */ hpm_serial_nor_seq_io_mode_t addr_io_mode; /* Address I/O mode */ uint32_t addr; /* Target address */ } addr_phase; /* Dummy phase */ struct { uint8_t dummy_count; /* Dummy cycles (per flash spec) */ } dummy_phase; /* Data phase */ struct { hpm_serial_nor_seq_direction_t direction; /* Data direction */ hpm_serial_nor_seq_io_mode_t data_io_mode; /* Data I/O mode */ uint32_t len; /* Data length (bytes) */ uint8_t *buf; /* Data buffer pointer */ } data_phase; } hpm_serial_nor_transfer_seq_t;
serial_nor_host_ops_t: Host controller operations
typedef struct { hpm_stat_t (*init)(void *host); hpm_stat_t (*transfer)(void *host, hpm_serial_nor_transfer_seq_t *seq); void (*set_cs)(uint32_t cs_pin, uint8_t state); void (*set_frequency)(void *host, uint32_t freq); void *user_data; } serial_nor_host_ops_t;
hpm_serial_nor_host_t: Complete host instance
typedef struct { hpm_serial_nor_host_param_t host_param; /* Host configuration */ serial_nor_host_ops_t host_ops; /* Hardware operations */ void *user_data; /* Extension pointer */ } hpm_serial_nor_host_t;
hpm_serial_nor_t: Full device descriptor
typedef struct { hpm_serial_nor_host_t host; /* Host driver instance */ hpm_sfdp_read_para_t nor_read_para; /* Read timing config */ hpm_sfdp_program_para_t nor_program_para; /* Program config */ hpm_serial_nor_info_t flash_info; /* Physical characteristics */ } hpm_serial_nor_t;
8.3. API Call Flow Introduction
8.3.1. Define Serial NOR Initialization Variables
Define a
hpm_serial_nor_tstruct variable. Example:
hpm_serial_nor_t nor_flash_dev;
8.3.2. Initialize Serial NOR Host Parameters
Main initialization for flash device’s host member:
#define APP_SPI_DATA_LEN_IN_BITS (8U) #define PORT_SPI_IO_MODE SERIAL_NOR_HOST_SUPPORT_DUAL_IO_MODE #define PORT_SPI_BASE HPM_SPI2 #define PORT_SPI_CLK_NAME clock_spi2 #define PORT_SPI_NOR_DMA HPM_HDMA #define PORT_SPI_NOR_DMAMUX HPM_DMAMUX #define PORT_SPI_RX_DMA_REQ HPM_DMA_SRC_SPI2_RX #define PORT_SPI_TX_DMA_REQ HPM_DMA_SRC_SPI2_TX #define PORT_SPI_RX_DMA_CH 0 #define PORT_SPI_TX_DMA_CH 1 #define PORT_SPI_CLK_FREQUENCY (40000000u) ATTR_WEAK hpm_stat_t serial_nor_get_board_host(hpm_serial_nor_host_t *host) { /* Host capability flags */ host->host_param.flags = PORT_SPI_IO_MODE | /* Dual I/O mode */ SERIAL_NOR_HOST_SUPPORT_DMA | /* Enable DMA */ SERIAL_NOR_HOST_SUPPORT_SPI_INTERFACE; /* SPI protocol */ /* Hardware parameters */ host->host_param.param.set_cs = board_write_spi_cs; /* CS control callback */ host->host_param.param.set_frequency = set_spi_clk_frequency; /* Clock config */ host->host_param.param.clock_name = PORT_SPI_CLK_NAME; /* Clock source */ host->host_param.param.pin_or_cs_index = BOARD_SPI_CS_PIN; /* CS pin/index */ host->host_param.param.host_base = PORT_SPI_BASE; /* SPI base address */ #if (SERIAL_NOR_USE_DMA_MGR == 0) /* Manual DMA resource configuration */ host->host_param.param.dma_control.dma_base = PORT_SPI_NOR_DMA; /* DMA ctrl base */ host->host_param.param.dma_control.dmamux_base = PORT_SPI_NOR_DMAMUX; /* DMAMUX */ host->host_param.param.dma_control.rx_dma_ch = PORT_SPI_RX_DMA_CH; /* RX channel */ host->host_param.param.dma_control.tx_dma_ch = PORT_SPI_TX_DMA_CH; /* TX channel */ #endif /* Common DMA request lines */ host->host_param.param.dma_control.rx_dma_req = PORT_SPI_RX_DMA_REQ; /* RX request */ host->host_param.param.dma_control.tx_dma_req = PORT_SPI_TX_DMA_REQ; /* TX request */ host->host_param.param.frequency = PORT_SPI_CLK_FREQUENCY; /* 40MHz clock */ host->host_param.param.transfer_max_size = SPI_SOC_TRANSFER_COUNT_MAX; /* Max transfer */ host->host_param.param.user_data = NULL; /* User context pointer */ return status_success; } serial_nor_get_board_host(&nor_flash_dev.host);
When the DMA Manager component is enabled, there is no need to manually configure the DMA channel; only the DMA request line needs to be configured.
The SPI clock source must be enabled, and the SPI-related pins must be initialized.
8.3.3. serial_nor Initialization
Call
hpm_serial_nor_initAPI to initialize serial_nor device. During this process, parameters fromnor_flash_devwill be applied to theflashparameter, and return NOR flash device information viahpm_serial_nor_info_t.hpm_serial_nor_initAPI prototype:hpm_stat_t hpm_serial_nor_init(hpm_serial_nor_t *flash, hpm_serial_nor_info_t *info);
Parameter description
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Pointer to NOR Flash device instance
info
hpm_serial_nor_info_t *[out] Output parameter for flash physical characteristics
Return value
status_success: Initialization successfulstatus_invalid_argument: Invalid parameterstatus_spi_nor_flash_not_identified: Flash chip not recognized
Core functionality:
- Hardware interface initialization:
Bind SPI host operation functions
Initialize SPI controller hardware
Configure initial communication frequency (10MHz for SFDP reading)
- Flash parameter identification:
Read SFDP parameter table (JEDEC standard)
Parse physical parameters: page/sector/block sizes
Get capacity info (24-bit/32-bit addressing)
- Operation mode configuration:
Auto-attempt quad mode enablement (QE bit setting)
Configure optimal read/write timing
Setup DMA transfer mode (if enabled)
- Information synchronization:
Output parsed flash parameters via info
Return initialization status (success/failure reason)
Example: Initialize serial_nor and retrieve flash info
hpm_stat_t stat; hpm_serial_nor_info_t flash_info; stat = hpm_serial_nor_init(&nor_flash_dev, &flash_info); if (stat != status_success) { printf("SPI NOR Flash initialization failed\n"); } else { printf("SPI NOR Flash initialized successfully\n"); if (hpm_serial_nor_get_info(&nor_flash_dev, &flash_info) == status_success) { printf("Flash SFDP version: %d\n", flash_info.sfdp_version); printf("Flash size: %d KB\n", flash_info.size_in_kbytes); printf("Page size: %d Bytes\n", flash_info.page_size); printf("Sector size: %d KB\n", flash_info.sector_size_kbytes); printf("Block size: %d KB\n", flash_info.block_size_kbytes); printf("Sector erase command: 0x%02x\n", flash_info.sector_erase_cmd); printf("Block erase command: 0x%02x\n", flash_info.block_erase_cmd); } }
8.3.4. serial_nor Check NOR Flash Busy Status
During NOR Flash operations (e.g. non-blocking erase/program), need to check device busy status.
Use
hpm_serial_nor_is_busyAPI to check if device is busy:API prototype:
hpm_stat_t hpm_serial_nor_is_busy(hpm_serial_nor_t *flash);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance pointer
Return values:
status_spi_nor_flash_is_busy: Device busy (erase/program in progress)status_success: Device readystatus_invalid_argument: Invalid parameter (NULL pointer)
Example:
/* Wait erase operation complete */ while(hpm_serial_nor_is_busy(&nor_flash_dev) == status_spi_nor_flash_is_busy) { hpm_spi_nor_udelay(100); /* Delay 100us */ } printf("Flash operation completed\n");
Important Notes
This API doesn’t implement retry mechanism internally, caller must implement polling logic
8.3.5. serial_nor Erase Operations
Includes both blocking and non-blocking interfaces. Non-blocking erase supports sector/block operations, while blocking erase supports sector/block/chip erase and address-range based erase.
8.3.5.1. Non-Blocking Erase Interfaces
8.3.5.1.1. Sector Erase
Use
hpm_serial_nor_erase_sector_nonblockingAPI for non-blocking sector erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_sector_nonblocking(hpm_serial_nor_t *flash, uint32_t sector_addr);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
sector_addr
uint32_t[in] Target sector address (must be sector-aligned)
Return values:
status_success: Erase command sent successfullystatus_invalid_argument: Invalid parameters (NULL pointer/address misaligned)status_spi_nor_flash_is_busy: Flash device busy
Example:
/* Erase sector starting at 0x8000 */ hpm_stat_t status = hpm_serial_nor_erase_sector_nonblocking(&nor_flash_dev, 0x8000); if (status == status_success) { /* Perform other tasks here */ while(hpm_serial_nor_is_busy(&nor_flash_dev) == status_spi_nor_flash_is_busy) { /* Wait for erase completion */ } printf("Sector erase completed\n"); } else { printf("Erase failed: 0x%08X\n", status); }
Important Notes
Must ensure sector_addr is integer multiple of sector size (flash_info.sector_size_kbytes)
Should check flash readiness via hpm_serial_nor_is_busy() before calling
8.3.5.1.2. Block Erase
Use
hpm_serial_nor_erase_block_nonblockingAPI for non-blocking block erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_block_nonblocking(hpm_serial_nor_t *flash, uint32_t block_addr);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance pointer
block_addr
uint32_t[in] Target block address (must be block-aligned, get block size via flash_info.block_size_kbytes)
- Return values:
status_success: Erase command sent successfullystatus_invalid_argument: Invalid parameters (NULL pointer/address misaligned)status_spi_nor_flash_is_busy: Flash device busy
Example:
/* Erase block starting at 0x10000 */ hpm_stat_t status = hpm_serial_nor_erase_block_nonblocking(&nor_flash_dev, 0x10000); if (status == status_success) { /* Perform other tasks here */ while(hpm_serial_nor_is_busy(&nor_flash_dev) == status_spi_nor_flash_is_busy) { /* Wait for erase completion */ } printf("Block erase completed\n"); } else { printf("Erase failed: 0x%08X\n", status); }
Important Notes
Must ensure block_addr is integer multiple of block size (flash_info.block_size_kbytes)
Should check flash readiness via hpm_serial_nor_is_busy() before calling
8.3.5.2. Blocking Erase Interfaces
8.3.5.2.1. Chip Erase
Use
hpm_serial_nor_erase_chipAPI for full chip erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_chip(hpm_serial_nor_t *flash);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
Return values:
status_success: Erase operation completedstatus_invalid_argument: Invalid parameters (NULL pointer)status_spi_nor_flash_is_busy: Device busy state timeout
Example:
/* Perform full chip erase */ hpm_stat_t status = hpm_serial_nor_erase_chip(&nor_flash_dev); if (status == status_success) { printf("Full chip erase succeeded\n"); } else { printf("Erase failed: 0x%08X\n", status); }
- Important Notes
This operation will erase ALL data on the chip - use with extreme caution!
Typical erase time reference: MX25L25635F takes ~150 seconds
8.3.5.2.2. Sector Erase
Use
hpm_serial_nor_erase_sector_blockingAPI for sector erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_sector_blocking(hpm_serial_nor_t *flash, uint32_t sector_addr);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
sector_addr
uint32_t[in] Target sector address (must be sector-aligned, get sector size via flash_info.sector_size_kbytes)
Return values:
status_success: Sector erase completedstatus_invalid_argument: Invalid parameters (NULL pointer/address misaligned)status_spi_nor_flash_is_busy: Flash device busy state timeout
Example:
/* Erase sector starting at 0x8000 */ hpm_stat_t status = hpm_serial_nor_erase_sector_blocking(&nor_flash_dev, 0x8000); if (status == status_success) { printf("Sector erase succeeded\n"); }
Important Notes
Must ensure sector_addr is integer multiple of sector size (flash_info.sector_size_kbytes)
8.3.5.2.3. Block Erase
Use
hpm_serial_nor_erase_block_blockingAPI for blocking block erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_block_blocking(hpm_serial_nor_t *flash, uint32_t block_addr);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance pointer
block_addr
uint32_t[in] Target block address (must be block-aligned)
Return values:
status_success: Block erase completedstatus_invalid_argument: Invalid parameters (NULL pointer/address misaligned)status_spi_nor_flash_is_busy: Flash device busy timeout
Example:
/* Erase block starting at 0x10000 */ hpm_stat_t status = hpm_serial_nor_erase_block_blocking(&nor_flash_dev, 0x10000); if (status == status_success) { printf("Block erase succeeded\n"); }
Important Notes
Ensure block_addr is integer multiple of block size (flash_info.block_size_kbytes)
This operation will erase ALL data in specified block - use with caution!
8.3.5.2.4. Address-Range Erase
Use
hpm_serial_nor_erase_blockingAPI for address-range erase:API prototype:
hpm_stat_t hpm_serial_nor_erase_blocking(hpm_serial_nor_t *flash, uint32_t start, uint32_t length);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
start
uint32_t[in] Start address
length
uint32_t[in] Erase length (bytes)
Return values:
status_success: Erase operation completedstatus_invalid_argument: Invalid parametersstatus_spi_nor_flash_is_busy: Flash busy timeout
Example:
/* Erase 1024 bytes starting at 0x20000 */ hpm_stat_t status = hpm_serial_nor_erase_blocking(&nor_flash_dev, 0x20000, 1024); if (status == status_success) { printf("Address-range erase succeeded\n"); } else { printf("Erase failed: 0x%08X\n", status); }
Important Notes
Auto-adapt erase granularity: Prefer block erase (64KB) → sector erase (4KB)
Actual erased range will expand to sector/block boundaries
8.3.6. serial_nor Program Operations
Includes both blocking and non-blocking interfaces. Non-blocking programming supports page-level operations, while blocking programming supports page/address-range based writes.
8.3.6.1. Non-Blocking Program Interface
Use
hpm_serial_nor_page_program_nonblockingAPI for non-blocking page programming:API prototype:
hpm_stat_t hpm_serial_nor_page_program_nonblocking(hpm_serial_nor_t *flash, uint8_t *buf, uint32_t data_len, uint32_t address);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
buf
uint8_t *[in] Data buffer to be programmed
data_len
uint32_t[in] Data length in bytes
address
uint32_t[in] Target programming address
Return values:
status_success: Program command sent successfullystatus_invalid_argument: Invalid parameters (NULL pointer/address misaligned/length exceeds limit)status_spi_nor_flash_is_busy: Device busy
Example:
uint8_t write_buf[256]; /* Fill data... */ /* Non-blocking program at 0x1000 */ hpm_stat_t status = hpm_serial_nor_page_program_nonblocking(&nor_flash_dev, write_buf, 256, 0x1000); if (status == status_success) { while(hpm_serial_nor_is_busy(&nor_flash_dev) == status_spi_nor_flash_is_busy) { /* Perform other tasks */ } printf("Page programming completed\n"); }
Important Notes
Must ensure address is integer multiple of page size (flash_info.page_size)
Should check device readiness via hpm_serial_nor_is_busy() before calling
Data length must not exceed page size
Requires sector to be pre-erased before programming
8.3.6.2. Blocking Program Interface
Call
hpm_serial_nor_program_blockingAPI to program data of arbitrary length to specified address:API prototype:
hpm_stat_t hpm_serial_nor_program_blocking(hpm_serial_nor_t *flash, uint8_t *buf, uint32_t data_len, uint32_t address);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
buf
uint8_t *[in] Data buffer to be programmed
data_len
uint32_t[in] Data length in bytes
address
uint32_t[in] Target programming address
Return values:
status_success: Data programming completedstatus_invalid_argument: Invalid parameters (NULL pointer/address out of range)status_spi_nor_flash_is_busy: Flash device busy timeout
Example:
uint8_t write_buf[256] = {0x01, 0x23, 0x45, 0x67}; hpm_stat_t status = hpm_serial_nor_program_blocking(&nor_flash_dev, write_buf, sizeof(write_buf), 0x8000); if (status == status_success) { printf("Data programmed successfully\n"); }
8.3.7. serial_nor Read Operations
Use
hpm_serial_nor_readAPI for data reading:API prototype:
hpm_stat_t hpm_serial_nor_read(hpm_serial_nor_t *flash, uint8_t *buf, uint16_t data_len, uint32_t address);
Parameters:
Parameter
Type
Description
flash
hpm_serial_nor_t *[in] Initialized NOR Flash device instance
buf
uint8_t *[in] Data buffer for read operation
data_len
uint16_t[in] Data length in bytes
address
uint32_t[in] Start address for reading
Return values:
status_success: Data read successfullystatus_invalid_argument: Invalid parameters (NULL pointer/address out of range)status_spi_nor_flash_is_busy: Flash device busy timeout
Example:
uint8_t read_buf[256]; hpm_stat_t status = hpm_serial_nor_read(&nor_flash_dev, read_buf, sizeof(read_buf), 0x8000); if (status == status_success) { printf("Data read successfully\n"); }
Important Notes
Actual read speed depends on SPI clock configuration
Recommend 4-byte aligned data_len for optimal performance
Supports cross-page continuous reading (limited only by buffer size)
No pre-erase required before reading
Automatically handles address alignment and boundary crossing
Note
When DMA manager is enabled, the DMA channel allocation is managed by DMA manager. Avoid channel conflicts between serial_nor and other SPI components.
To get TX DMA resource used by serial_nor component, call
hpm_serial_nor_get_tx_dma_mgr_resourceAPI:API prototype:
dma_resource_t *hpm_serial_nor_get_tx_dma_mgr_resource(hpm_serial_nor_t *flash);
To get RX DMA resource used by serial_nor component, call
hpm_serial_nor_get_rx_dma_mgr_resourceAPI:API prototype:
dma_resource_t *hpm_serial_nor_get_rx_dma_mgr_resource(hpm_serial_nor_t *flash);
Example: How to use DMA resource APIs and configure DMA channels
/* SPI initialization omitted... */ /* Get TX DMA resource */ dma_resource_t *tx_dma_resource = hpm_serial_nor_get_tx_dma_mgr_resource(&nor_flash_dev); if (tx_dma_resource != NULL) { printf("TX DMA channel resource obtained successfully.\n"); printf("TX DMA instance: %d, TX DMA channel: %d\n", tx_dma_resource->dma_instance, tx_dma_resource->dma_channel); /* Set TX DMA interrupt priority to 1 */ dma_mgr_enable_dma_irq_with_priority(tx_dma_resource, 1); } /* Get RX DMA resource */ dma_resource_t *rx_dma_resource = hpm_serial_nor_get_rx_dma_mgr_resource(&nor_flash_dev); if (rx_dma_resource != NULL) { printf("RX DMA channel resource obtained successfully.\n"); printf("RX DMA instance: %d, RX DMA channel: %d\n", rx_dma_resource->dma_instance, rx_dma_resource->dma_channel); /* Set RX DMA interrupt priority to 1 */ dma_mgr_enable_dma_irq_with_priority(rx_dma_resource, 1); }