// // Created by lydxh on 24-11-27. // #ifndef HW_LIB_FLASH_DEF_H #define HW_LIB_FLASH_DEF_H #include #include #ifdef __cplusplus extern "C" { #endif /** * flash program(write) data mode */ enum flash_write_mode { FLASH_WM_PAGE_256B = 1 << 0, /**< write 1 to 256 bytes per page */ FLASH_WM_BYTE = 1 << 1, /**< byte write */ FLASH_WM_AAI = 1 << 2, /**< auto address increment */ FLASH_WM_DUAL_BUFFER = 1 << 3, /**< dual-buffer write, like AT45DB series */ }; /* manufacturer information */ typedef struct { char *name; uint8_t id; } flash_mf; /* flash chip information */ typedef struct { char *name; /**< flash chip name */ uint8_t mf_id; /**< manufacturer ID */ uint8_t type_id; /**< memory type ID */ uint8_t capacity_id; /**< capacity ID */ uint32_t capacity; /**< flash capacity (bytes) */ uint16_t write_mode; /**< write mode @see flash_write_mode */ uint32_t erase_gran; /**< erase granularity (bytes) */ uint8_t erase_gran_cmd; /**< erase granularity size block command */ } flash_chip; #ifdef FLASH_USING_QSPI /* QSPI flash chip's extended information compared with SPI flash */ typedef struct { uint8_t mf_id; /**< manufacturer ID */ uint8_t type_id; /**< memory type ID */ uint8_t capacity_id; /**< capacity ID */ uint8_t read_mode; /**< supported read mode on this qspi flash chip */ } flash_qspi_flash_ext_info; #endif /* FLASH support manufacturer JEDEC ID */ #define FLASH_MF_ID_CYPRESS 0x01 #define FLASH_MF_ID_FUJITSU 0x04 #define FLASH_MF_ID_EON 0x1C #define FLASH_MF_ID_ATMEL 0x1F #define FLASH_MF_ID_MICRON 0x20 #define FLASH_MF_ID_AMIC 0x37 #define FLASH_MF_ID_NOR_MEM 0x52 #define FLASH_MF_ID_SANYO 0x62 #define FLASH_MF_ID_INTEL 0x89 #define FLASH_MF_ID_ESMT 0x8C #define FLASH_MF_ID_FUDAN 0xA1 #define FLASH_MF_ID_HYUNDAI 0xAD #define FLASH_MF_ID_SST 0xBF #define FLASH_MF_ID_MACRONIX 0xC2 #define FLASH_MF_ID_GIGADEVICE 0xC8 #define FLASH_MF_ID_ISSI 0xD5 #define FLASH_MF_ID_WINBOND 0xEF #define FLASH_MF_ID_PUYA 0x85 /* FLASH supported manufacturer information table */ #define FLASH_MF_TABLE \ { \ {"Cypress", FLASH_MF_ID_CYPRESS}, \ {"Fujitsu", FLASH_MF_ID_FUJITSU}, \ {"EON", FLASH_MF_ID_EON}, \ {"Atmel", FLASH_MF_ID_ATMEL}, \ {"Micron", FLASH_MF_ID_MICRON}, \ {"AMIC", FLASH_MF_ID_AMIC}, \ {"Sanyo", FLASH_MF_ID_SANYO}, \ {"Intel", FLASH_MF_ID_INTEL}, \ {"ESMT", FLASH_MF_ID_ESMT}, \ {"Fudan", FLASH_MF_ID_FUDAN}, \ {"Hyundai", FLASH_MF_ID_HYUNDAI}, \ {"SST", FLASH_MF_ID_SST}, \ {"GigaDevice", FLASH_MF_ID_GIGADEVICE}, \ {"ISSI", FLASH_MF_ID_ISSI}, \ {"Winbond", FLASH_MF_ID_WINBOND}, \ {"Macronix", FLASH_MF_ID_MACRONIX}, \ {"NOR-MEM", FLASH_MF_ID_NOR_MEM}, \ {"PUYA", FLASH_MF_ID_PUYA}, \ } #ifdef FLASH_USING_FLASH_INFO_TABLE /* FLASH supported flash chip information table. If the flash not support JEDEC JESD216 standard, * then the FLASH will find the flash chip information by this table. You can add other flash to here then * notice me for update it. The configuration information name and index reference the flash_flash_chip structure. * | name | mf_id | type_id | capacity_id | capacity | write_mode | erase_gran | erase_gran_cmd | */ #define FLASH_FLASH_CHIP_TABLE \ { \ {"AT45DB161E", FLASH_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, FLASH_WM_BYTE|FLASH_WM_DUAL_BUFFER, 512, 0x81}, \ {"W25Q40BV", FLASH_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25X40CL", FLASH_MF_ID_WINBOND, 0x30, 0x13, 512L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25X16AV", FLASH_MF_ID_WINBOND, 0x30, 0x15, 2L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q16BV", FLASH_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q32BV", FLASH_MF_ID_WINBOND, 0x40, 0x16, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q64CV", FLASH_MF_ID_WINBOND, 0x40, 0x17, 8L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q64DW", FLASH_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q128BV", FLASH_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"W25Q256FV", FLASH_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"SST25VF080B", FLASH_MF_ID_SST, 0x25, 0x8E, 1L*1024L*1024L, FLASH_WM_BYTE|FLASH_WM_AAI, 4096, 0x20}, \ {"SST25VF016B", FLASH_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, FLASH_WM_BYTE|FLASH_WM_AAI, 4096, 0x20}, \ {"M25P32", FLASH_MF_ID_MICRON, 0x20, 0x16, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 64L*1024L, 0xD8}, \ {"M25P80", FLASH_MF_ID_MICRON, 0x20, 0x14, 1L*1024L*1024L, FLASH_WM_PAGE_256B, 64L*1024L, 0xD8}, \ {"M25P40", FLASH_MF_ID_MICRON, 0x20, 0x13, 512L*1024L, FLASH_WM_PAGE_256B, 64L*1024L, 0xD8}, \ {"EN25Q32B", FLASH_MF_ID_EON, 0x30, 0x16, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"GD25Q64B", FLASH_MF_ID_GIGADEVICE, 0x40, 0x17, 8L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"GD25Q16B", FLASH_MF_ID_GIGADEVICE, 0x40, 0x15, 2L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"GD25Q32C", FLASH_MF_ID_GIGADEVICE, 0x40, 0x16, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"S25FL216K", FLASH_MF_ID_CYPRESS, 0x40, 0x15, 2L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"S25FL032P", FLASH_MF_ID_CYPRESS, 0x02, 0x15, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"A25L080", FLASH_MF_ID_AMIC, 0x30, 0x14, 1L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"F25L004", FLASH_MF_ID_ESMT, 0x20, 0x13, 512L*1024L, FLASH_WM_BYTE|FLASH_WM_AAI, 4096, 0x20}, \ {"PCT25VF016B", FLASH_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, FLASH_WM_BYTE|FLASH_WM_AAI, 4096, 0x20}, \ {"NM25Q128EVB", FLASH_MF_ID_NOR_MEM, 0x21, 0x18, 16L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"P25D05H", FLASH_MF_ID_PUYA, 0x60, 0x13, 5L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"P25D10H", FLASH_MF_ID_PUYA, 0x60, 0x12, 1L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"P25D20H", FLASH_MF_ID_PUYA, 0x60, 0x11, 2L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"P25D40H", FLASH_MF_ID_PUYA, 0x60, 0x10, 4L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ {"P25Q80H", FLASH_MF_ID_PUYA, 0x30, 0x14, 8L*1024L*1024L, FLASH_WM_PAGE_256B, 4096, 0x20}, \ } #endif /* FLASH_USING_FLASH_INFO_TABLE */ #ifdef FLASH_USING_QSPI /* This table saves flash read-fast instructions in QSPI mode, * FLASH can use this table to select the most appropriate read instruction for flash. * | mf_id | type_id | capacity_id | qspi_read_mode | */ #define FLASH_FLASH_EXT_INFO_TABLE \ { \ /* W25Q40BV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x13, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* W25Q80JV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* W25Q16BV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* W25Q32BV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_OUTPUT|QUAD_IO}, \ /* W25Q64JV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ /* W25Q128JV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x18, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ /* W25Q256FV */ \ {FLASH_MF_ID_WINBOND, 0x40, 0x19, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ /* EN25Q32B */ \ {FLASH_MF_ID_EON, 0x30, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_IO}, \ /* S25FL216K */ \ {FLASH_MF_ID_CYPRESS, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* A25L080 */ \ {FLASH_MF_ID_AMIC, 0x30, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO}, \ /* A25LQ64 */ \ {FLASH_MF_ID_AMIC, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_IO}, \ /* MX25L3206E and KH25L3206E */ \ {FLASH_MF_ID_MACRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* MX25L51245G */ \ {FLASH_MF_ID_MACRONIX, 0x20, 0x1A, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ /* GD25Q64B */ \ {FLASH_MF_ID_GIGADEVICE, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT}, \ /* NM25Q128EVB */ \ {FLASH_MF_ID_NOR_MEM, 0x21, 0x18, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ } #endif /* FLASH_USING_QSPI */ /** * retry process * * @param delay delay function for every retry. NULL will not delay for every retry. * @param retry retry counts * @param result FLASH_ERR_TIMEOUT: retry timeout */ #define FLASH_RETRY_PROCESS(delay, retry, result) \ void (*__delay_temp)(void) = (void (*)(void))delay; \ if (retry == 0) {result = FLASH_ERR_TIMEOUT;break;} \ else {if (__delay_temp) {__delay_temp();} retry --;} /* software version number */ #define FLASH_SW_VERSION "1.1.0" /* * all defined supported command */ #ifndef FLASH_CMD_WRITE_ENABLE #define FLASH_CMD_WRITE_ENABLE 0x06 #endif #ifndef FLASH_CMD_WRITE_DISABLE #define FLASH_CMD_WRITE_DISABLE 0x04 #endif #ifndef FLASH_CMD_READ_STATUS_REGISTER #define FLASH_CMD_READ_STATUS_REGISTER 0x05 #endif #ifndef FLASH_VOLATILE_SR_WRITE_ENABLE #define FLASH_VOLATILE_SR_WRITE_ENABLE 0x50 #endif #ifndef FLASH_CMD_WRITE_STATUS_REGISTER #define FLASH_CMD_WRITE_STATUS_REGISTER 0x01 #endif #ifndef FLASH_CMD_PAGE_PROGRAM #define FLASH_CMD_PAGE_PROGRAM 0x02 #endif #ifndef FLASH_CMD_AAI_WORD_PROGRAM #define FLASH_CMD_AAI_WORD_PROGRAM 0xAD #endif #ifndef FLASH_CMD_ERASE_CHIP #define FLASH_CMD_ERASE_CHIP 0xC7 #endif #ifndef FLASH_CMD_READ_DATA #define FLASH_CMD_READ_DATA 0x03 #endif #ifndef FLASH_CMD_FAST_READ_DATA #define FLASH_CMD_FAST_READ_DATA 0x0B #endif #ifndef FLASH_CMD_DUAL_OUTPUT_READ_DATA #define FLASH_CMD_DUAL_OUTPUT_READ_DATA 0x3B #endif #ifndef FLASH_CMD_DUAL_IO_READ_DATA #define FLASH_CMD_DUAL_IO_READ_DATA 0xBB #endif #ifndef FLASH_CMD_QUAD_IO_READ_DATA #define FLASH_CMD_QUAD_IO_READ_DATA 0xEB #endif #ifndef FLASH_CMD_QUAD_OUTPUT_READ_DATA #define FLASH_CMD_QUAD_OUTPUT_READ_DATA 0x6B #endif #ifndef FLASH_CMD_MANUFACTURER_DEVICE_ID #define FLASH_CMD_MANUFACTURER_DEVICE_ID 0x90 #endif #ifndef FLASH_CMD_JEDEC_ID #define FLASH_CMD_JEDEC_ID 0x9F #endif #ifndef FLASH_CMD_READ_UNIQUE_ID #define FLASH_CMD_READ_UNIQUE_ID 0x4B #endif #ifndef FLASH_CMD_READ_SFDP_REGISTER #define FLASH_CMD_READ_SFDP_REGISTER 0x5A #endif #ifndef FLASH_CMD_ENABLE_RESET #define FLASH_CMD_ENABLE_RESET 0x66 #endif #ifndef FLASH_CMD_RESET #define FLASH_CMD_RESET 0x99 #endif #ifndef FLASH_CMD_ENTER_4B_ADDRESS_MODE #define FLASH_CMD_ENTER_4B_ADDRESS_MODE 0xB7 #endif #ifndef FLASH_CMD_EXIT_4B_ADDRESS_MODE #define FLASH_CMD_EXIT_4B_ADDRESS_MODE 0xE9 #endif #ifndef FLASH_WRITE_MAX_PAGE_SIZE #define FLASH_WRITE_MAX_PAGE_SIZE 256 #endif /* send dummy data for read data */ #ifndef FLASH_DUMMY_DATA #define FLASH_DUMMY_DATA 0xFF #endif /* dummy data count for fast read data and etc */ #ifndef FLASH_READ_DUMMY_BYTE_CNT #ifdef FLASH_USING_FAST_READ #define FLASH_READ_DUMMY_BYTE_CNT 1 #else #define FLASH_READ_DUMMY_BYTE_CNT 0 #endif #endif /* maximum number of erase type support on JESD216 (V1.0) */ #define FLASH_SFDP_ERASE_TYPE_MAX_NUM 4 /** * status register bits */ enum { FLASH_STATUS_REGISTER_BUSY = (1 << 0), /**< busing */ FLASH_STATUS_REGISTER_WEL = (1 << 1), /**< write enable latch */ FLASH_STATUS_REGISTER_SRP = (1 << 7), /**< status register protect */ }; /** * error code */ typedef enum { FLASH_SUCCESS = 0, /**< success */ FLASH_ERR_NOT_FOUND = 1, /**< not found or not supported */ FLASH_ERR_WRITE = 2, /**< write error */ FLASH_ERR_READ = 3, /**< read error */ FLASH_ERR_TIMEOUT = 4, /**< timeout error */ FLASH_ERR_ADDR_OUT_OF_BOUND = 5, /**< address is out of flash bound */ } flash_err; #ifdef FLASH_USING_QSPI /** * QSPI flash read cmd format */ typedef struct { uint8_t instruction; uint8_t instruction_lines; uint8_t address_size; uint8_t address_lines; uint8_t alternate_bytes_lines; uint8_t dummy_cycles; uint8_t data_lines; } flash_qspi_read_cmd_format; #endif /* FLASH_USING_QSPI */ /* SPI bus write read data function type */ typedef flash_err (*spi_write_read_func)(const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size); #ifdef FLASH_USING_SFDP /** * the SFDP (Serial Flash Discoverable Parameters) parameter info which used on this library */ typedef struct { bool available; /**< available when read SFDP OK */ uint8_t major_rev; /**< SFDP Major Revision */ uint8_t minor_rev; /**< SFDP Minor Revision */ uint16_t write_gran; /**< write granularity (bytes) */ uint8_t erase_4k; /**< 4 kilobyte erase is supported throughout the device */ uint8_t erase_4k_cmd; /**< 4 Kilobyte erase command */ bool sr_is_non_vola; /**< status register is supports non-volatile */ uint8_t vola_sr_we_cmd; /**< volatile status register write enable command */ bool addr_3_byte; /**< supports 3-Byte addressing */ bool addr_4_byte; /**< supports 4-Byte addressing */ uint32_t capacity; /**< flash capacity (bytes) */ struct { uint32_t size; /**< erase sector size (bytes). 0x00: not available */ uint8_t cmd; /**< erase command */ } eraser[FLASH_SFDP_ERASE_TYPE_MAX_NUM]; /**< supported eraser types table */ //TODO lots of fast read-related stuff (like modes supported and number of wait states/dummy cycles needed in each) } flash_sfdp, *flash_sfdp_t; #endif /** * SPI device */ typedef struct __flash_spi { /* SPI device name */ char *name; /* SPI bus write read data function */ flash_err (*wr)(const struct __flash_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size); #ifdef FLASH_USING_QSPI /* QSPI fast read function */ flash_err (*qspi_read)(const struct __flash_spi *spi, uint32_t addr, flash_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size); #endif /* lock SPI bus */ void (*lock)(const struct __flash_spi *spi); /* unlock SPI bus */ void (*unlock)(const struct __flash_spi *spi); /* some user data */ void *user_data; } flash_spi, *flash_spi_t; #ifdef __cplusplus } #endif #endif //HW_LIB_FLASH_DEF_H