297 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			297 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
|  | /*
 | ||
|  |  * This file is part of the Serial Flash Universal Driver Library. | ||
|  |  * | ||
|  |  * Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com> | ||
|  |  * | ||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||
|  |  * a copy of this software and associated documentation files (the | ||
|  |  * 'Software'), to deal in the Software without restriction, including | ||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||
|  |  * the following conditions: | ||
|  |  * | ||
|  |  * The above copyright notice and this permission notice shall be | ||
|  |  * included in all copies or substantial portions of the Software. | ||
|  |  * | ||
|  |  * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
|  |  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
|  |  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
|  |  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
|  |  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|  |  * | ||
|  |  * Function: It is the macro definition head file for this library. | ||
|  |  * Created on: 2016-04-23 | ||
|  |  */ | ||
|  | 
 | ||
|  | #ifndef _SFUD_DEF_H_
 | ||
|  | #define _SFUD_DEF_H_
 | ||
|  | 
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <stdint.h>
 | ||
|  | #include <stdbool.h>
 | ||
|  | #include <sfud_cfg.h>
 | ||
|  | #include "sfud_flash_def.h"
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" { | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /* debug print function. Must be implement by user. */ | ||
|  | #ifdef SFUD_DEBUG_MODE
 | ||
|  | #ifndef SFUD_DEBUG
 | ||
|  | #define SFUD_DEBUG(...) sfud_log_debug(__FILE__, __LINE__, __VA_ARGS__)
 | ||
|  | #endif /* SFUD_DEBUG */
 | ||
|  | #else
 | ||
|  | #define SFUD_DEBUG(...)
 | ||
|  | #endif /* SFUD_DEBUG_MODE */
 | ||
|  | 
 | ||
|  | #ifndef SFUD_INFO
 | ||
|  | #define SFUD_INFO(...)  sfud_log_info(__VA_ARGS__)
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /* assert for developer. */ | ||
|  | #ifdef SFUD_DEBUG_MODE
 | ||
|  | #define SFUD_ASSERT(EXPR)                                                      \
 | ||
|  | if (!(EXPR))                                                                   \ | ||
|  | {                                                                              \ | ||
|  |     SFUD_DEBUG("(%s) has assert failed at %s.", #EXPR, __FUNCTION__);          \ | ||
|  |     while (1);                                                                 \ | ||
|  | } | ||
|  | #else
 | ||
|  | #define SFUD_ASSERT(EXPR)
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * retry process | ||
|  |  * | ||
|  |  * @param delay delay function for every retry. NULL will not delay for every retry. | ||
|  |  * @param retry retry counts | ||
|  |  * @param result SFUD_ERR_TIMEOUT: retry timeout | ||
|  |  */ | ||
|  | #define SFUD_RETRY_PROCESS(delay, retry, result)                               \
 | ||
|  |     void (*__delay_temp)(void) = (void (*)(void))delay;                        \ | ||
|  |     if (retry == 0) {result = SFUD_ERR_TIMEOUT;break;}                         \ | ||
|  |     else {if (__delay_temp) {__delay_temp();} retry --;} | ||
|  | 
 | ||
|  | /* software version number */ | ||
|  | #define SFUD_SW_VERSION                             "1.1.0"
 | ||
|  | /*
 | ||
|  |  * all defined supported command | ||
|  |  */ | ||
|  | #ifndef SFUD_CMD_WRITE_ENABLE
 | ||
|  | #define SFUD_CMD_WRITE_ENABLE                          0x06
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_WRITE_DISABLE
 | ||
|  | #define SFUD_CMD_WRITE_DISABLE                         0x04
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_READ_STATUS_REGISTER
 | ||
|  | #define SFUD_CMD_READ_STATUS_REGISTER                  0x05
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_VOLATILE_SR_WRITE_ENABLE
 | ||
|  | #define SFUD_VOLATILE_SR_WRITE_ENABLE                  0x50
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_WRITE_STATUS_REGISTER
 | ||
|  | #define SFUD_CMD_WRITE_STATUS_REGISTER                 0x01
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_PAGE_PROGRAM
 | ||
|  | #define SFUD_CMD_PAGE_PROGRAM                          0x02
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_AAI_WORD_PROGRAM
 | ||
|  | #define SFUD_CMD_AAI_WORD_PROGRAM                      0xAD
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_ERASE_CHIP
 | ||
|  | #define SFUD_CMD_ERASE_CHIP                            0xC7
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_READ_DATA
 | ||
|  | #define SFUD_CMD_READ_DATA                             0x03
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_DUAL_OUTPUT_READ_DATA
 | ||
|  | #define SFUD_CMD_DUAL_OUTPUT_READ_DATA                 0x3B
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_DUAL_IO_READ_DATA
 | ||
|  | #define SFUD_CMD_DUAL_IO_READ_DATA                     0xBB
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_QUAD_IO_READ_DATA
 | ||
|  | #define SFUD_CMD_QUAD_IO_READ_DATA                     0xEB
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_QUAD_OUTPUT_READ_DATA
 | ||
|  | #define SFUD_CMD_QUAD_OUTPUT_READ_DATA                 0x6B
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_MANUFACTURER_DEVICE_ID
 | ||
|  | #define SFUD_CMD_MANUFACTURER_DEVICE_ID                0x90
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_JEDEC_ID
 | ||
|  | #define SFUD_CMD_JEDEC_ID                              0x9F
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_READ_UNIQUE_ID
 | ||
|  | #define SFUD_CMD_READ_UNIQUE_ID                        0x4B
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_READ_SFDP_REGISTER
 | ||
|  | #define SFUD_CMD_READ_SFDP_REGISTER                    0x5A
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_ENABLE_RESET
 | ||
|  | #define SFUD_CMD_ENABLE_RESET                          0x66
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_RESET
 | ||
|  | #define SFUD_CMD_RESET                                 0x99
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_ENTER_4B_ADDRESS_MODE
 | ||
|  | #define SFUD_CMD_ENTER_4B_ADDRESS_MODE                 0xB7
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_CMD_EXIT_4B_ADDRESS_MODE
 | ||
|  | #define SFUD_CMD_EXIT_4B_ADDRESS_MODE                  0xE9
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef SFUD_WRITE_MAX_PAGE_SIZE
 | ||
|  | #define SFUD_WRITE_MAX_PAGE_SIZE                        256
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /* send dummy data for read data */ | ||
|  | #ifndef SFUD_DUMMY_DATA
 | ||
|  | #define SFUD_DUMMY_DATA                                0xFF
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /* maximum number of erase type support on JESD216 (V1.0) */ | ||
|  | #define SFUD_SFDP_ERASE_TYPE_MAX_NUM                      4
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * status register bits | ||
|  |  */ | ||
|  | enum { | ||
|  |     SFUD_STATUS_REGISTER_BUSY = (1 << 0),                  /**< busing */ | ||
|  |     SFUD_STATUS_REGISTER_WEL = (1 << 1),                   /**< write enable latch */ | ||
|  |     SFUD_STATUS_REGISTER_SRP = (1 << 7),                   /**< status register protect */ | ||
|  | }; | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * error code | ||
|  |  */ | ||
|  | typedef enum { | ||
|  |     SFUD_SUCCESS = 0,                                      /**< success */ | ||
|  |     SFUD_ERR_NOT_FOUND = 1,                                /**< not found or not supported */ | ||
|  |     SFUD_ERR_WRITE = 2,                                    /**< write error */ | ||
|  |     SFUD_ERR_READ = 3,                                     /**< read error */ | ||
|  |     SFUD_ERR_TIMEOUT = 4,                                  /**< timeout error */ | ||
|  |     SFUD_ERR_ADDR_OUT_OF_BOUND = 5,                        /**< address is out of flash bound */ | ||
|  | } sfud_err; | ||
|  | 
 | ||
|  | #ifdef SFUD_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; | ||
|  | } sfud_qspi_read_cmd_format; | ||
|  | #endif /* SFUD_USING_QSPI */
 | ||
|  | 
 | ||
|  | /* SPI bus write read data function type */ | ||
|  | typedef sfud_err (*spi_write_read_func)(const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size); | ||
|  | 
 | ||
|  | #ifdef SFUD_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[SFUD_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)
 | ||
|  | } sfud_sfdp, *sfud_sfdp_t; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * SPI device | ||
|  |  */ | ||
|  | typedef struct __sfud_spi { | ||
|  |     /* SPI device name */ | ||
|  |     char *name; | ||
|  |     /* SPI bus write read data function */ | ||
|  |     sfud_err (*wr)(const struct __sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, | ||
|  |                    size_t read_size); | ||
|  | #ifdef SFUD_USING_QSPI
 | ||
|  |     /* QSPI fast read function */ | ||
|  |     sfud_err (*qspi_read)(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, | ||
|  |                           uint8_t *read_buf, size_t read_size); | ||
|  | #endif
 | ||
|  |     /* lock SPI bus */ | ||
|  |     void (*lock)(const struct __sfud_spi *spi); | ||
|  |     /* unlock SPI bus */ | ||
|  |     void (*unlock)(const struct __sfud_spi *spi); | ||
|  |     /* some user data */ | ||
|  |     void *user_data; | ||
|  | } sfud_spi, *sfud_spi_t; | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * serial flash device | ||
|  |  */ | ||
|  | typedef struct { | ||
|  |     char *name;                                  /**< serial flash name */ | ||
|  |     size_t index;                                /**< index of flash device information table  @see flash_table */ | ||
|  |     sfud_flash_chip chip;                        /**< flash chip information */ | ||
|  |     sfud_spi spi;                                /**< SPI device */ | ||
|  |     bool init_ok;                                /**< initialize OK flag */ | ||
|  |     bool addr_in_4_byte;                         /**< flash is in 4-Byte addressing */ | ||
|  |     struct { | ||
|  |         void (*delay)(void);                     /**< every retry's delay */ | ||
|  |         size_t times;                            /**< default times for error retry */ | ||
|  |     } retry; | ||
|  |     void *user_data;                             /**< some user data */ | ||
|  | 
 | ||
|  | #ifdef SFUD_USING_QSPI
 | ||
|  |     sfud_qspi_read_cmd_format read_cmd_format;   /**< fast read cmd format */ | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifdef SFUD_USING_SFDP
 | ||
|  |     sfud_sfdp sfdp;                              /**< serial flash discoverable parameters by JEDEC standard */ | ||
|  | #endif
 | ||
|  | 
 | ||
|  | } sfud_flash, *sfud_flash_t; | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif /* _SFUD_DEF_H_ */
 |