1 /* 2 * Copyright (C) 2017-2020 Alibaba Group Holding Limited 3 */ 4 5 /****************************************************************************** 6 * @file drv/spiflash.h 7 * @brief Header File for SPIFLASH Driver 8 * @version V1.0 9 * @date 02. June 2020 10 * @model spiflash 11 ******************************************************************************/ 12 #ifndef _DRV_SPIFLASH_H_ 13 #define _DRV_SPIFLASH_H_ 14 15 #include <stdint.h> 16 #include <drv/gpio.h> 17 #include <drv/spi.h> 18 #include <drv/qspi.h> 19 #include <drv/common.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /** 26 * \brief Build a flash ID 27 * \param [in] vendor_id Vendor id(8bit) 28 * \param [in] device_id Flash device id (ID15~ID0) 16bit 29 * \return 24bit flash id 30 */ 31 #define FLASH_ID_BUILD(VENDOR_ID,DEVICE_ID) 32 33 /** 34 * \struct csi_spiflash_lock_info_t 35 * \ flash use status register 1 to protect data in memory array 36 * \ different flash vendor support different protect region (top/bottom/none) 37 * also support different protect number 38 * status1 register bif field show as follow 39 * 7 |6 |5 |4 |3 |2 |1 |0 40 * --------------------------------------------------------------------- 41 * vensor def | vendor def | vendor def | BP2 | BP1 | BP0 | WEL | BUSY 42 * \ Protect type 43 * \ Protect block size : Vendor define ,user should check flash datasheet of vendor 44 * : Use w25q64fw as example , min protect block size is 128 KB 45 * \ TOP : Protect address from flash top address 46 * \ BOTTOM : Protect address from flash bottom address 47 * \ SEC : Protect addres base on sector unit and protect region only must not exceed one block 48 * \ BPx : Protect start addres base on TOP/BOTTOM feature,and BPx value denote protect number 49 * \ BP[x..0]'s value : 2^(n-1) protect block unit, ex, BP[x..0] = 5, protect block number = 2^(5-1) = 16 50 * \ If BP[x..0] = 0 denote protect none 51 * \ If BP[x..0]'s all bis is 1 ,denote protect all flash 52 * \ 53 * \ NOTE: 54 * \ only support SEC = 0 55 * \ only support CMP = 0 56 * \ 57 * 58 * Sample table portion for 8MB flash (Winbond w25q64fw): 59 * 60 * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion 61 * -------------------------------------------------------------------------- 62 * X | X | 0 | 0 | 0 | NONE | NONE 63 * 0 | 0 | 0 | 0 | 1 | 128 KB | Upper 1/64 64 * 0 | 0 | 0 | 1 | 0 | 256 KB | Upper 1/32 65 * 0 | 0 | 0 | 1 | 1 | 512 KB | Upper 1/16 66 * 0 | 0 | 1 | 0 | 0 | 1 MB | Upper 1/8 67 * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4 68 * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2 69 * X | X | 1 | 1 | 1 | 8 MB | ALL 70 * ------|-------|-------|-------|-------|---------------|------------------- 71 * 0 | 1 | 0 | 0 | 1 | 128 KB | Lower 1/64 72 * 0 | 1 | 0 | 1 | 0 | 256 KB | Lower 1/32 73 * 0 | 1 | 0 | 1 | 1 | 512 KB | Lower 1/16 74 * 0 | 1 | 1 | 0 | 0 | 1 MB | Lower 1/8 75 * 0 | 1 | 1 | 0 | 1 | 2 MB | Lower 1/4 76 * 0 | 1 | 1 | 1 | 0 | 4 MB | Lower 1/2 77 * 78 */ 79 typedef enum { 80 LOCK_TP_NONE, 81 LOCK_TP_TOP, 82 LOCK_TP_BOTTOM, 83 LOCK_TP_DUAL 84 } csi_spiflash_lock_region_t; 85 typedef enum { 86 SPIFLASH_DATA_1_LINE = 1, 87 SPIFLASH_DATA_2_LINES = 2, 88 SPIFLASH_DATA_4_LINES = 4 89 } csi_spiflash_data_line_t; 90 typedef union { 91 csi_spi_t spi; 92 csi_qspi_t qspi; 93 } csi_spi_qspi_t; 94 95 /** 96 \brief Flash information 97 */ 98 typedef struct { 99 char *flash_name; ///< Name string of spiflash 100 uint32_t flash_id; ///< JEDEC ID = manufature ID <<16 | device ID (ID15~ID0) 101 uint32_t flash_size; ///< Flash chip size 102 uint32_t xip_addr; ///< If use qspi controler to access flash ,code can be ececuted on flash ,the addr is xip addr 103 uint32_t sector_size; ///< Sector size 104 uint32_t page_size; ///< Page size for read or program 105 } csi_spiflash_info_t; 106 107 typedef struct{ 108 struct{ 109 uint8_t buswidth; ///< cmd buswidth 110 }cmd; 111 struct { 112 uint8_t buswidth; ///< addr buswidth 113 }addr; 114 struct { 115 uint8_t nbytes; ///< dummy bytes 116 }dummy; 117 struct { 118 uint8_t buswidth; ///< data buswidth 119 }data; 120 } csi_spiflash_cmd_t; 121 122 /** 123 \brief Flash control block 124 */ 125 typedef struct { 126 csi_spi_qspi_t spi_qspi; ///< Spi/qspi handle 127 void (*spi_cs_callback)(csi_gpio_pin_state_t value); 128 void *flash_prv_info; ///< Point to vendor private feature struct 129 int32_t (*spi_send)(void *spi, uint8_t cmd, uint32_t addr, uint32_t addr_size, const void *data, uint32_t size); 130 int32_t (*spi_receive)(void *spi, uint8_t cmd, uint32_t addr, uint32_t addr_size, void *data, uint32_t size); 131 csi_error_t (*set_cmd)(void *spi, csi_spiflash_cmd_t *cmd); 132 void *priv; ///< User private param 133 } csi_spiflash_t; 134 135 /** 136 \brief Initialize SPIFLASH with spi controler and probe flash device 137 \param[in] spiflash SPIFLASH handle 138 \param[in] spi_idx SPI controler index 139 \param[in] spi_cs GPIO info for chip select,if NULL, not use gpio cs 140 \return Error code 141 */ 142 csi_error_t csi_spiflash_spi_init(csi_spiflash_t *spiflash, uint32_t spi_idx, void *spi_cs_callback); 143 144 /** 145 \brief Initialize SPIFLASH with qspi controler and probe flash device 146 \param[in] spiflash SPIFLASH handle 147 \param[in] qspi_idx QSPI controler index 148 \return Error code 149 */ 150 csi_error_t csi_spiflash_qspi_init(csi_spiflash_t *spiflash, uint32_t qspi_idx, void *qspi_cs_callback); 151 152 /** 153 \brief De-initialize SPIFLASH Interface based on spi controler. stops operation and releases the software resources used by the interface 154 \param[in] spiflash SPIFLASH handle to operate 155 \return Error code 156 */ 157 void csi_spiflash_spi_uninit(csi_spiflash_t *spiflash); 158 159 /** 160 \brief De-initialize SPIFLASH Interface based on qspi controler. stops operation and releases the software resources used by the interface 161 \param[in] spiflash SPIFLASH handle to operate 162 \return Error code 163 */ 164 void csi_spiflash_qspi_uninit(csi_spiflash_t *spiflash); 165 166 167 /** 168 \brief Get flash device infomation 169 \param[in] spiflash SPIFLASH handle to operate 170 \param[in] flash_info User storage to get flash vendor info after flash init 171 \return spiflash_info_t 172 */ 173 csi_error_t csi_spiflash_get_flash_info(csi_spiflash_t *spiflash, csi_spiflash_info_t *flash_info); 174 175 176 /** 177 \brief Read data from Flash 178 \param[in] spiflash SPIFLASH handle to operate 179 \param[in] offset Data address, offset address relative to zero 180 \param[out] data Pointer to a buffer storing the data read from Flash 181 \param[in] size Number of data items to read 182 \return If receive successful, this function shall return the num of data witch is received successful 183 otherwise, the function shall return Error code 184 */ 185 int32_t csi_spiflash_read(csi_spiflash_t *spiflash, uint32_t offset, void *data, uint32_t size); 186 187 /** 188 \brief Program data to Flash 189 \param[in] spiflash SPIFLASH handle to operate 190 \param[in] offset Data address, offset address relative to zero 191 \param[in] data Pointer to a buffer containing the data to be programmed to Flash. 192 \param[in] size Number of data items to program 193 \return If program successful, this function shall return the num of data witch is program successful, 194 otherwise, the function shall return Error code 195 */ 196 int32_t csi_spiflash_program(csi_spiflash_t *spiflash, uint32_t offset, const void *data, uint32_t size); 197 198 /** 199 \brief Erase Flash Sector 200 \param[in] spiflash SPIFLASH handle to operate 201 \param[in] offset Data address, offset address relative to zero 202 \param[in] size Length to be erased 203 \return Error code 204 */ 205 csi_error_t csi_spiflash_erase(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); 206 207 /** 208 \brief Read flash status register 209 \param[in] spiflash SPIFLASH handle to operate 210 \param[in] cmd_code Cmd code 211 \param[out] data Data buf to save flash status register 212 \param[in] size Register length in byte 213 \return Error code 214 */ 215 csi_error_t csi_spiflash_read_reg(csi_spiflash_t *spiflash, uint8_t cmd_code, uint8_t *data, uint32_t size); 216 217 /** 218 \brief Write status register 219 \param[in] spiflash SPIFLASH handle to operate 220 \param[in] cmd Cmd code 221 \param[out] data Data buf to save flash status register 222 \param[in] size Register length in byte 223 \return Error code 224 */ 225 csi_error_t csi_spiflash_write_reg(csi_spiflash_t *spiflash, uint8_t cmd_code, uint8_t *data, uint32_t size); 226 227 228 /** 229 \brief Enable spiflash write protection 230 \param[in] spiflash SPIFLASH handle to operate 231 \param[in] offset Protect flash offset,offset need protect block size aligned 232 \param[in] size Lock size(byte) 233 \return Error code 234 */ 235 csi_error_t csi_spiflash_lock(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); 236 237 /** 238 \brief Enable spiflash write protection 239 \param[in] spiflash SPIFLASH handle to operate 240 \param[in] offset Protect flash offset,offset need protect block size aligned 241 \param[in] size Unlock size(byte) 242 \return Error code 243 */ 244 csi_error_t csi_spiflash_unlock(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); 245 246 /** 247 \brief check flash is locked(write protect) 248 \param[in] spiflash SPIFLASH handle to operate 249 \param[in] offset Protect flash offset,offset need protect block size aligned 250 \param[in] size Locked size(byte) 251 \return 0:unlocked if query region overlay with locked region 1: locked if query reigon is fully in locked region 252 */ 253 int csi_spiflash_is_locked(csi_spiflash_t *spiflash, uint32_t offset, uint32_t size); 254 255 /** 256 \brief Set QSPI data line 257 \param[in] spiflash SPIFLASH handle to operate 258 \param[in] line SPIFLASH data line mode 259 \return Error code 260 */ 261 csi_error_t csi_spiflash_config_data_line(csi_spiflash_t *spiflash, csi_spiflash_data_line_t line); 262 263 /** 264 \brief Set QSPI frequence 265 \param[in] spiflash SPIFLASH handle to operate 266 \param[in] hz SPIFLASH frequence 267 \return The actual config frequency 268 */ 269 uint32_t csi_spiflash_frequence(csi_spiflash_t *spiflash, uint32_t hz); 270 271 /** 272 \brief Flash power down. 273 \param[in] spiflash SPIFLASH handle to operate. 274 \return error code 275 */ 276 csi_error_t csi_spiflash_release_power_down(csi_spiflash_t *spiflash); 277 278 /** 279 \brief Flash power release. 280 \param[in] spiflash SPIFLASH handle to operate. 281 \return none 282 */ 283 void csi_spiflash_power_down(csi_spiflash_t *spiflash); 284 285 #ifdef __cplusplus 286 } 287 #endif 288 289 #endif /* _DRV_SPIFLASH_H_ */ 290