346 lines
11 KiB
C
346 lines
11 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#ifndef __SFC_H
|
|
#define __SFC_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define SPI_FLASH_GD25Q80C 0
|
|
#define SPI_FLASH_GD25LQ80C 1
|
|
#define SPI_FLASH_P25Q80H 2
|
|
#define SPI_FLASH_P25Q80L 3
|
|
#define SFC_DEFUALT_FLASH SPI_FLASH_GD25Q80C
|
|
|
|
#define SFC_MAX_SUPPORT_DEV 4
|
|
|
|
/* write en(0x06) or write dis(0x04) */
|
|
#define WRITE_EN_CMD_MODE 0x200
|
|
#define WRITE_EN_CMD_CYCLE 0x08000000
|
|
#define WRITE_DIS_CMD_MODE 0x200
|
|
#define WRITE_DIS_CMD_CYCLE 0x08000000
|
|
/* 0x50 */
|
|
#define VOLATILE_SR_WR_EN_CMD_MODE 0x200
|
|
#define VOLATILE_SR_WR_EN_CMD_CYCLE 0x08000000
|
|
/* read status reg1 (0x35) reg2(0x15) reg3(0x15) */
|
|
#define READ_STS_REG_CMD_MODE 0x100
|
|
#define READ_STS_REG_CMD_CYCLE 0x08000000
|
|
/* write status reg1(0x01) reg2(0x31) reg3(0x11) */
|
|
#define WRITE_STS_REG_CMD_MODE 0x200
|
|
#define WRITE_STS_REG_CMD_CYCLE 0x08000000
|
|
/* read data */
|
|
/* read(0x03) */
|
|
#define READ_DATA_CMD_MODE 0x100
|
|
#define READ_DATA_CMD_CYCLE 0x08180000
|
|
/* fast read(0x0B) */
|
|
#define FAST_READ_CMD_MODE 0x100
|
|
#define FAST_READ_CMD_CYCLE 0x08180008
|
|
/* dual output fast read(0x3B) */
|
|
#define DUAL_OUTPUT_FAST_RD_CMD_MODE 0x102
|
|
#define DUAL_OUTPUT_FAST_RD_CMD_CYCLE 0x08180008
|
|
/* dual io fast read(0xBB) */
|
|
#define DUAL_IO_FAST_RD_CMD_MODE 0x12a
|
|
#define DUAL_IO_FAST_RD_CMD_CYCLE 0x080c0400
|
|
/* quad output fast read(0x6B) */
|
|
#define QUAD_OUTPUT_FAST_RD_CMD_MODE 0x101
|
|
#define QUAD_OUTPUT_FAST_RD_CMD_CYCLE 0x08180008
|
|
/* quad output fast read(0xEB) */
|
|
#define QUAD_IO_FAST_RD_CMD_MODE 0x115
|
|
#define QUAD_IO_FAST_RD_CMD_CYCLE 0x08060204
|
|
/* page program (0x02) quad page program(0x32) */
|
|
#define PAGE_PROGRAM_CMD_MODE 0x200
|
|
#define PAGE_PROGRAM_CMD_CYCLE 0x08180000
|
|
#define QUAD_PAGE_PROGRAM_CMD_MODE 0x201
|
|
#define QUAD_PAGE_PROGRAM_CMD_CYCLE 0x08180000
|
|
/* erase page(0x81 only puyan) sector(0x20) block_64k(0xD8) chip(0xC7) */
|
|
#define SECTOR_ERASE_CMD_MODE 0x200
|
|
#define SECTOR_ERASE_CMD_CYCLE 0x08180000
|
|
//#define BLOCK_ERASE_32K_CMD_MODE 0x200
|
|
//#define BLOCK_ERASE_32K_CMD_CYCLE 0x08180000
|
|
#define BLOCK_ERASE_64K_CMD_MODE 0x200
|
|
#define BLOCK_ERASE_64K_CMD_CYCLE 0x08180000
|
|
#define CHIP_ERASE_CMD_MODE 0x200
|
|
#define CHIP_ERASE_CMD_CYCLE 0x08000000
|
|
/* rst_en(0x66) && rst(0x99) */
|
|
#define RESET_EN_CMD_MODE 0x200
|
|
#define RESET_EN_CMD_CYCLE 0x08000000
|
|
#define RESET_CMD_MODE 0x200
|
|
#define RESET_CMD_CYCLE 0x08000000
|
|
/* suspend(0x75) && resume(0x7A) */
|
|
#define PE_SUSPEND_CMD_MODE 0x200
|
|
#define PE_SUSPEND_CMD_CYCLE 0x08000000
|
|
#define PE_RESUME_CMD_MODE 0x200
|
|
#define PE_RESUME_CMD_CYCLE 0x08000000
|
|
/* Manufacture ID && Device ID (0x90 0x92 0x94) */
|
|
#define MANU_DEV_ID_CMD_MODE 0x100
|
|
#define MANU_DEV_ID_CMD_CYCLE 0x08180000
|
|
#define MANU_DEV_ID_DUAL_IO_CMD_MODE 0x12a
|
|
#define MANU_DEV_ID_DUAL_IO_CMD_CYCLE 0x080c0400
|
|
#define MANU_DEV_ID_QUAD_IO_CMD_MODE 0x115
|
|
#define MANU_DEV_ID_QUAD_IO_CMD_CYCLE 0x08060204
|
|
/* Read Identification((0x9F)) */
|
|
#define READ_ID_CMD_MODE 0x100
|
|
#define READ_ID_CMD_CYCLE 0x08000000
|
|
/* sfdp(0x5A) */
|
|
#define READ_SFDP_CMD_MODE 0x100
|
|
#define READ_SFDP_CMD_CYCLE 0x08180008
|
|
/* unique id(0x4B) */
|
|
#define READ_UNIQ_ID_CMD_MODE 0x100
|
|
#define READ_UNIQ_ID_CMD_CYCLE 0x08180008
|
|
|
|
#define TEST_MODE_CMD_MODE 0x100
|
|
#define TEST_MODE_CMD_CYCLE 0x08000000
|
|
|
|
#define PROGRAM_OTP_CMD 0x42
|
|
#define ERASE_OTP_CMD 0x44
|
|
#define READ_OTP_CMD 0x48
|
|
|
|
#define HAL_QPSI_TIMEOUT_DEFAULT_VALUE ((uint32_t)5000U)/* 5 s */
|
|
|
|
#define ADDR_MAPPING_SIZE_64K (1024 * 64)
|
|
#define ADDR_MAPPING_SIZE_128K (1024 * 128)
|
|
|
|
#define SFC_POWER_VOL_1P8V 0
|
|
#define SFC_POWER_VOL_3P3V 1
|
|
|
|
#define SFC_MAP_VALUE_INIT 0x03020100
|
|
#define SFC_MAP_VALUE_EX 0x0a090100
|
|
|
|
#define FLASH_VENDOR_ID_GD 0xc8
|
|
#define FLASH_VENDOR_ID_PUYA 0x85
|
|
#define FLASH_VENDOR_ID_ZBIT 0x5e
|
|
#define FLASH_VENDOR_ID_WINBOND 0xef
|
|
|
|
#define FLASH_SIZE_1MB 0x13
|
|
#define FLASH_SIZE_2MB 0x14
|
|
#define FLASH_SIZE_4MB 0x15
|
|
#define FLASH_SIZE_8MB 0x16
|
|
#define FLASH_SIZE_16MB 0x17
|
|
#define FLASH_SIZE_MAX 0x18
|
|
|
|
#define SFC_CHIP_UID_LEN_MAX 16
|
|
|
|
#define STS_LB1_BIT_S11 0x08
|
|
#define STS_LB2_BIT_S12 0x10
|
|
#define STS_LB3_BIT_S13 0x20
|
|
|
|
typedef enum {
|
|
MOD_SFC_PROG_WTIME = 0x00U,
|
|
MOD_SFC_ERASE_WTIME = 0x01U,
|
|
} sfc_pe_type_t;
|
|
|
|
typedef enum {
|
|
MOD_SFC_AMAP_64K = 0x00U,
|
|
MOD_SFC_AMAP_128K = 0x01U,
|
|
} sfc_addr_map_type_t;
|
|
|
|
typedef enum {
|
|
QSPI_OK = 0x00U,
|
|
QSPI_ERROR = 0x01U,
|
|
QSPI_BUSY = 0x02U,
|
|
QSPI_TIMEOUT = 0x03U,
|
|
QSPI_NOT_SUPPORTED = 0x04U
|
|
} sfc_sts_type_t;
|
|
|
|
typedef enum {
|
|
MOD_SFC_OP_PRM = 0x00U,
|
|
MOD_SFC_OP_ERASE = 0x01U,
|
|
MOD_SFC_OP_TRANS = 0x02U,
|
|
MOD_SFC_OP_REG_WR = 0x03U
|
|
} sfc_operation_mode_t;
|
|
|
|
typedef enum {
|
|
MOD_SFC_PROG_MIN = 0x00U,
|
|
MOD_SFC_PROG_STAND = 0x00U,
|
|
MOD_SFC_PROG_QUAD = 0x01U,
|
|
MOD_SFC_PROG_FAST = 0x02U,
|
|
MOD_SFC_PROG_MAX,
|
|
} sfc_page_prog_mode_t;
|
|
|
|
typedef enum {
|
|
MOD_SFC_SERIAL = 0x00U,
|
|
MOD_SFC_DUAL = 0x01U,
|
|
MOD_SFC_QUAD = 0x02U
|
|
} sfc_spi_mode_t;
|
|
|
|
typedef enum {
|
|
SFC_REG_ACCESS = 0x00U,
|
|
SFC_BUF_ACCESS = 0x01U
|
|
} sfc_access_type_t;
|
|
|
|
typedef enum {
|
|
SFC_READ_MIN = 0x00U,
|
|
SFC_READ_BYTE = 0x00U,
|
|
SFC_READ_HIGH_SPD = 0x01U,
|
|
SFC_READ_DUAL_FAST = 0x02U,
|
|
SFC_READ_QUAD_FAST = 0x03U,
|
|
SFC_READ_DUAL_IO_FAST = 0x04U,
|
|
SFC_READ_QUAD_IO_FAST = 0x05U,
|
|
SFC_READ_QUAD_IO_WORD_FAST = 0x06U,
|
|
SFC_READ_MAX,
|
|
} sfc_read_mode_t;
|
|
|
|
typedef enum {
|
|
SFC_ENDIAN_BIG = 0,
|
|
SFC_ENDIAN_LITTLE,
|
|
} sfc_endian_mode_t;
|
|
|
|
typedef enum {
|
|
MOD_SW_MODE_DIS = 0x00U,
|
|
MOD_SW_MODE_ENA = 0x01U,
|
|
} flash_sw_mode_t;
|
|
|
|
typedef enum _qe_cfg_mode {
|
|
QE_CFG_REG_01H = 0, /* command sequence: 01h+2bytes register value */
|
|
QE_CFG_REG_31H = 1, /* command sequence: 31h+1byte register value */
|
|
} qe_cfg_mode_t;
|
|
|
|
/**
|
|
* @brief flash otp region id.
|
|
*
|
|
*/
|
|
typedef enum {
|
|
FLASH_OTP_REGION0,
|
|
FLASH_OTP_REGION1,
|
|
FLASH_OTP_REGION2,
|
|
IOT_FLASH_OTP_REGION_MAX,
|
|
} FLASH_OTP_REGION_ID;
|
|
|
|
typedef struct sfc_cmd {
|
|
uint8_t cmd;
|
|
uint32_t addr;
|
|
uint8_t op_mode;
|
|
uint32_t swm_mode;
|
|
uint32_t swm_cycle;
|
|
uint32_t wtime;
|
|
} sfc_cmd_t;
|
|
|
|
typedef struct _flash_dev_info {
|
|
uint8_t dev_id;
|
|
uint8_t size;
|
|
uint8_t qe_cfg_mode;
|
|
} flash_dev_info_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t sfc_cmode; /* Operation Mode */
|
|
uint8_t sfc_mode; /* spi continus mode byte */
|
|
uint8_t cache_rd_mode; /* read mode */
|
|
uint8_t cmd; /* Specifies the Instruction to be sent */
|
|
uint32_t sfc_dlen; /* spi trans data length, unit is byte */
|
|
uint32_t addr; /* Specifies the Address to be sent */
|
|
uint32_t pe_wait_time; /* program or erase wait time,
|
|
unit is clock cycle num */
|
|
uint32_t sfc_rd_sts; /* status */
|
|
uint32_t sfc_wr_sts; /* status */
|
|
} sfc_op_t;
|
|
|
|
typedef struct _sfc_ctrl {
|
|
int is_quad;
|
|
int is_use_sus_resume;
|
|
int (*erase_page)(uint32_t page_addr, uint8_t sw_mode);
|
|
int (*erase_block)(uint32_t block_addr, uint8_t sw_mode);
|
|
int (*erase_sector)(uint32_t sector_addr, uint8_t sw_mode);
|
|
int (*erase_chip)(void);
|
|
int (*get_dev_id)(uint8_t *data);
|
|
int (*get_chip_id)(uint8_t *p_uid, uint32_t dlen);
|
|
int (*get_sts_reg)(uint8_t *data, uint8_t reg_num);
|
|
int (*set_quad_mode)(uint8_t qe_cfg_mode);
|
|
int (*cache_mode_cfg)(uint8_t cache_mode);
|
|
int (*addr_mapping)(uint32_t offset1, uint32_t offset2, uint32_t size);
|
|
int (*mapping_sts)();
|
|
int (*query_wip_sts)(uint8_t *wip);
|
|
int (*read)(uint8_t *data, uint32_t raddr, uint32_t size, uint8_t mode);
|
|
int (*write)(uint8_t *data, uint32_t waddr, uint32_t size,
|
|
uint8_t quad, uint8_t sw_mode);
|
|
int (*suspend_resume_ena)(void);
|
|
int (*read_otp)(uint8_t *data, uint32_t raddr, uint32_t size);
|
|
int (*write_otp)(uint8_t *data, uint32_t waddr,uint32_t size);
|
|
int (*erase_otp)(uint32_t addr);
|
|
void (*lock_otp)(FLASH_OTP_REGION_ID id);
|
|
int (*init)(void);
|
|
flash_dev_info_t *device_info;
|
|
} sfc_ctrl_t;
|
|
|
|
uint8_t hal_qspi_read_reg(uint8_t cmd);
|
|
|
|
uint8_t hal_qspi_write_reg(uint8_t cmd, uint32_t data, uint8_t len);
|
|
|
|
sfc_sts_type_t qspi_set_edge(uint8_t rx, uint8_t tx, uint8_t div);
|
|
|
|
sfc_sts_type_t qspi_cmd_swm_sel(uint32_t mode, uint32_t cycle);
|
|
|
|
sfc_sts_type_t qspi_cmd_cache_sel(uint8_t cmd);
|
|
|
|
sfc_sts_type_t qspi_cmd_wip_sel(uint8_t cmd);
|
|
|
|
sfc_sts_type_t qspi_cmd_resume_sel(uint8_t cmd);
|
|
|
|
sfc_sts_type_t sfc_pe_suspend();
|
|
|
|
sfc_sts_type_t sfc_pe_resume();
|
|
|
|
sfc_sts_type_t sfc_write_en(void);
|
|
|
|
sfc_sts_type_t sfc_write_disable(void);
|
|
|
|
sfc_sts_type_t sfc_write_en_volatile();
|
|
|
|
sfc_sts_type_t sfc_rst_ena_and_rst();
|
|
|
|
sfc_sts_type_t sfc_qspi_get_id_mult(uint8_t *data, uint8_t mode);
|
|
|
|
sfc_sts_type_t sfc_read_sfdp(uint8_t *data, uint32_t raddr, uint32_t size);
|
|
|
|
int sfc_query_wip_sts(uint8_t *wip);
|
|
|
|
int sfc_get_dev_id(uint8_t *data);
|
|
|
|
void sfc_clk_div_set(uint8_t div);
|
|
|
|
uint8_t sfc_clk_div_get();
|
|
|
|
sfc_sts_type_t hal_qspi_cfg_sfc_clk_out(int enable);
|
|
|
|
void sfc_set_edge(uint8_t rx, uint8_t tx);
|
|
|
|
void sfc_set_endian_mode(sfc_endian_mode_t endian);
|
|
|
|
void sfc_set_suspend_resume_param(void);
|
|
|
|
uint32_t sfc_get_pe_mode();
|
|
|
|
int sfc_enter_test_mode();
|
|
|
|
int sfc_test_mode_write(uint8_t *data, uint32_t waddr,uint32_t size);
|
|
|
|
void sfc_set_io_map(uint32_t map);
|
|
|
|
int sfc_read(uint8_t *data, uint32_t raddr, uint32_t size, uint8_t mode);
|
|
|
|
#define SFC_PARAM_CHECK(a) \
|
|
if (!(a)) { \
|
|
return -1; \
|
|
} \
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|