2019-01-08 05:29:25 -05:00
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2017-05-23 22:35:12 -04:00
# pragma once
2019-01-08 05:29:25 -05:00
# include "esp_err.h"
2017-05-23 22:35:12 -04:00
# include <stdint.h>
# include <stdbool.h>
2019-06-19 04:37:55 -04:00
# include "hal/spi_flash_types.h"
2017-05-23 22:35:12 -04:00
2019-06-19 04:37:11 -04:00
# ifdef __cplusplus
extern " C " {
# endif
2019-01-08 05:29:25 -05:00
struct spi_flash_chip_t ;
typedef struct spi_flash_chip_t spi_flash_chip_t ;
2017-05-23 22:35:12 -04:00
2019-01-08 05:29:25 -05:00
typedef struct esp_flash_t esp_flash_t ;
2017-05-23 22:35:12 -04:00
/** @brief Structure for describing a region of flash */
typedef struct {
2019-06-19 08:35:55 -04:00
uint32_t offset ; ///< Start address of this region
uint32_t size ; ///< Size of the region
2017-05-23 22:35:12 -04:00
} esp_flash_region_t ;
2019-06-19 08:35:55 -04:00
/** OS-level integration hooks for accessing flash chips inside a running OS */
2017-05-23 22:35:12 -04:00
typedef struct {
2019-01-08 05:29:25 -05:00
/**
* Called before commencing any flash operation . Does not need to be
* recursive ( ie is called at most once for each call to ' end ' ) .
*/
esp_err_t ( * start ) ( void * arg ) ;
/** Called after completing any flash operation. */
esp_err_t ( * end ) ( void * arg ) ;
2019-09-11 14:41:00 -04:00
/** Called before any erase/write operations to check whether the region is limited by the OS */
esp_err_t ( * region_protected ) ( void * arg , size_t start_addr , size_t size ) ;
2019-01-08 05:29:25 -05:00
/** Delay for at least 'ms' milliseconds. Called in between 'start' and 'end'. */
esp_err_t ( * delay_ms ) ( void * arg , unsigned ms ) ;
} esp_flash_os_functions_t ;
2017-05-23 22:35:12 -04:00
/** @brief Structure to describe a SPI flash chip connected to the system.
2019-06-19 08:35:55 -04:00
Structure must be initialized before use ( passed to esp_flash_init ( ) ) .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
struct esp_flash_t {
2019-06-19 08:35:55 -04:00
spi_flash_host_driver_t * host ; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used.
2019-06-19 04:37:11 -04:00
const spi_flash_chip_t * chip_drv ; ///< Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation.
2019-01-08 05:29:25 -05:00
2019-06-19 08:35:55 -04:00
const esp_flash_os_functions_t * os_func ; ///< Pointer to os-specific hook structure. Call ``esp_flash_init_os_functions()`` to setup this field, after the host is properly initialized.
void * os_func_data ; ///< Pointer to argument for os-specific hooks. Left NULL and will be initialized with ``os_func``.
2019-01-08 05:29:25 -05:00
2019-09-05 01:11:36 -04:00
esp_flash_io_mode_t read_mode ; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called.
2017-05-23 22:35:12 -04:00
uint32_t size ; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation.
2019-09-09 12:56:46 -04:00
uint32_t chip_id ; ///< Detected chip id.
2019-01-08 05:29:25 -05:00
} ;
2017-05-23 22:35:12 -04:00
/** @brief Initialise SPI flash chip interface.
2019-01-08 05:29:25 -05:00
*
2017-05-23 22:35:12 -04:00
* This function must be called before any other API functions are called for this chip .
*
2019-06-19 08:35:55 -04:00
* @ note Only the ` ` host ` ` and ` ` read_mode ` ` fields of the chip structure must
* be initialised before this function is called . Other fields may be
* auto - detected if left set to zero or NULL .
2017-05-23 22:35:12 -04:00
*
2019-06-19 08:35:55 -04:00
* @ note If the chip - > drv pointer is NULL , chip chip_drv will be auto - detected
* based on its manufacturer & product IDs . See
* ` ` esp_flash_registered_flash_drivers ` ` pointer for details of this process .
2017-05-23 22:35:12 -04:00
*
* @ param chip Pointer to SPI flash chip to use . If NULL , esp_flash_default_chip is substituted .
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if initialisation fails .
*/
esp_err_t esp_flash_init ( esp_flash_t * chip ) ;
/**
* Check if appropriate chip driver is set .
*
* @ param chip Pointer to SPI flash chip to use . If NULL , esp_flash_default_chip is substituted .
*
* @ return true if set , otherwise false .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
bool esp_flash_chip_driver_initialized ( const esp_flash_t * chip ) ;
2017-05-23 22:35:12 -04:00
/** @brief Read flash ID via the common "RDID" SPI flash command.
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
2019-06-19 08:35:55 -04:00
* @ param [ out ] out_id Pointer to receive ID value .
2017-05-23 22:35:12 -04:00
*
* ID is a 24 - bit value . Lower 16 bits of ' id ' are the chip ID , upper 8 bits are the manufacturer ID .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 08:35:55 -04:00
esp_err_t esp_flash_read_id ( esp_flash_t * chip , uint32_t * out_id ) ;
2017-05-23 22:35:12 -04:00
/** @brief Detect flash size based on flash ID.
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
2019-06-19 08:35:55 -04:00
* @ param [ out ] out_size Detected size in bytes .
2017-05-23 22:35:12 -04:00
*
* @ note Most flash chips use a common format for flash ID , where the lower 4 bits specify the size as a power of 2. If
* the manufacturer doesn ' t follow this convention , the size may be incorrectly detected .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 08:35:55 -04:00
esp_err_t esp_flash_get_size ( esp_flash_t * chip , uint32_t * out_size ) ;
2017-05-23 22:35:12 -04:00
/** @brief Erase flash chip contents
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
*
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_erase_chip ( esp_flash_t * chip ) ;
2017-05-23 22:35:12 -04:00
/** @brief Erase a region of the flash chip
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
* @ param start Address to start erasing flash . Must be sector aligned .
* @ param len Length of region to erase . Must also be sector aligned .
*
2019-01-08 05:29:25 -05:00
* Sector size is specifyed in chip - > drv - > sector_size field ( typically 4096 bytes . ) ESP_ERR_INVALID_ARG will be
2017-05-23 22:35:12 -04:00
* returned if the start & length are not a multiple of this size .
*
* Erase is performed using block ( multi - sector ) erases where possible ( block size is specified in
* chip - > drv - > block_erase_size field , typically 65536 bytes ) . Remaining sectors are erased using individual sector erase
* commands .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_erase_region ( esp_flash_t * chip , uint32_t start , uint32_t len ) ;
2017-05-23 22:35:12 -04:00
/** @brief Read if the entire chip is write protected
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
* @ param [ out ] write_protected Pointer to boolean , set to the value of the write protect flag .
*
2019-01-08 05:29:25 -05:00
* @ note A correct result for this flag depends on the SPI flash chip model and chip_drv in use ( via the ' chip - > drv '
2017-05-23 22:35:12 -04:00
* field ) .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_get_chip_write_protect ( esp_flash_t * chip , bool * write_protected ) ;
2017-05-23 22:35:12 -04:00
/** @brief Set write protection for the SPI flash chip
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
2019-06-19 08:35:55 -04:00
* @ param write_protect Boolean value for the write protect flag
2017-05-23 22:35:12 -04:00
*
2019-01-08 05:29:25 -05:00
* @ note Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use ( via the ' chip - > drv '
2017-05-23 22:35:12 -04:00
* field ) .
*
* Some SPI flash chips may require a power cycle before write protect status can be cleared . Otherwise ,
* write protection can be removed via a follow - up call to this function .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 08:35:55 -04:00
esp_err_t esp_flash_set_chip_write_protect ( esp_flash_t * chip , bool write_protect ) ;
2017-05-23 22:35:12 -04:00
/** @brief Read the list of individually protectable regions of this SPI flash chip.
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
2019-06-19 08:35:55 -04:00
* @ param [ out ] out_regions Pointer to receive a pointer to the array of protectable regions of the chip .
* @ param [ out ] out_num_regions Pointer to an integer receiving the count of protectable regions in the array returned in ' regions ' .
2017-05-23 22:35:12 -04:00
*
2019-01-08 05:29:25 -05:00
* @ note Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use ( via the ' chip - > drv '
2017-05-23 22:35:12 -04:00
* field ) .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 08:35:55 -04:00
esp_err_t esp_flash_get_protectable_regions ( const esp_flash_t * chip , const esp_flash_region_t * * out_regions , uint32_t * out_num_regions ) ;
2017-05-23 22:35:12 -04:00
/** @brief Detect if a region of the SPI flash chip is protected
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
* @ param region Pointer to a struct describing a protected region . This must match one of the regions returned from esp_flash_get_protectable_regions ( . . . ) .
2019-06-19 04:37:11 -04:00
* @ param [ out ] out_protected Pointer to a flag which is set based on the protected status for this region .
2017-05-23 22:35:12 -04:00
*
* @ note It is possible for this result to be false and write operations to still fail , if protection is enabled for the entire chip .
*
2019-01-08 05:29:25 -05:00
* @ note Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use ( via the ' chip - > drv '
2017-05-23 22:35:12 -04:00
* field ) .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 04:37:11 -04:00
esp_err_t esp_flash_get_protected_region ( esp_flash_t * chip , const esp_flash_region_t * region , bool * out_protected ) ;
2017-05-23 22:35:12 -04:00
/** @brief Update the protected status for a region of the SPI flash chip
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
* @ param region Pointer to a struct describing a protected region . This must match one of the regions returned from esp_flash_get_protectable_regions ( . . . ) .
2019-06-19 04:37:11 -04:00
* @ param protect Write protection flag to set .
2017-05-23 22:35:12 -04:00
*
* @ note It is possible for the region protection flag to be cleared and write operations to still fail , if protection is enabled for the entire chip .
*
2019-01-08 05:29:25 -05:00
* @ note Correct behaviour of this function depends on the SPI flash chip model and chip_drv in use ( via the ' chip - > drv '
2017-05-23 22:35:12 -04:00
* field ) .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-06-19 04:37:11 -04:00
esp_err_t esp_flash_set_protected_region ( esp_flash_t * chip , const esp_flash_region_t * region , bool protect ) ;
2017-05-23 22:35:12 -04:00
/** @brief Read data from the SPI flash chip
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
2019-01-08 05:29:25 -05:00
* @ param buffer Pointer to a buffer where the data will be read . To get better performance , this should be in the DRAM and word aligned .
2017-05-23 22:35:12 -04:00
* @ param address Address on flash to read from . Must be less than chip - > size field .
* @ param length Length ( in bytes ) of data to read .
*
* There are no alignment constraints on buffer , address or length .
*
* @ note If on - chip flash encryption is used , this function returns raw ( ie encrypted ) data . Use the flash cache
* to transparently decrypt data .
*
2019-01-08 05:29:25 -05:00
* @ return
* - ESP_OK : success
2020-02-24 22:56:13 -05:00
* - ESP_ERR_NO_MEM : Buffer is in external PSRAM which cannot be concurrently accessed , and a temporary internal buffer could not be allocated .
2019-01-08 05:29:25 -05:00
* - or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_read ( esp_flash_t * chip , void * buffer , uint32_t address , uint32_t length ) ;
2017-05-23 22:35:12 -04:00
/** @brief Write data to the SPI flash chip
*
* @ param chip Pointer to identify flash chip . Must have been successfully initialised via esp_flash_init ( )
* @ param address Address on flash to write to . Must be previously erased ( SPI NOR flash can only write bits 1 - > 0 ) .
2019-01-08 05:29:25 -05:00
* @ param buffer Pointer to a buffer with the data to write . To get better performance , this should be in the DRAM and word aligned .
2017-05-23 22:35:12 -04:00
* @ param length Length ( in bytes ) of data to write .
*
* There are no alignment constraints on buffer , address or length .
*
2019-01-08 05:29:25 -05:00
* @ return ESP_OK on success , or a flash error code if operation failed .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_write ( esp_flash_t * chip , const void * buffer , uint32_t address , uint32_t length ) ;
2017-05-23 22:35:12 -04:00
/** @brief Encrypted and write data to the SPI flash chip using on-chip hardware flash encryption
*
2019-09-05 06:45:45 -04:00
* @ param chip Pointer to identify flash chip . Must be NULL ( the main flash chip ) . For other chips , encrypted write is not supported .
2017-05-23 22:35:12 -04:00
* @ param address Address on flash to write to . 16 byte aligned . Must be previously erased ( SPI NOR flash can only write bits 1 - > 0 ) .
* @ param buffer Pointer to a buffer with the data to write .
* @ param length Length ( in bytes ) of data to write . 16 byte aligned .
*
* @ note Both address & length must be 16 byte aligned , as this is the encryption block size
*
2019-09-05 06:45:45 -04:00
* @ return
* - ESP_OK : on success
* - ESP_ERR_NOT_SUPPORTED : encrypted write not supported for this chip .
* - ESP_ERR_INVALID_ARG : Either the address , buffer or length is invalid .
* - or other flash error code from spi_flash_write_encrypted ( ) .
2017-05-23 22:35:12 -04:00
*/
2019-01-08 05:29:25 -05:00
esp_err_t esp_flash_write_encrypted ( esp_flash_t * chip , uint32_t address , const void * buffer , uint32_t length ) ;
2019-09-05 06:45:45 -04:00
/** @brief Read and decrypt data from the SPI flash chip using on-chip hardware flash encryption
*
* @ param chip Pointer to identify flash chip . Must be NULL ( the main flash chip ) . For other chips , encrypted read is not supported .
* @ param address Address on flash to read from .
* @ param out_buffer Pointer to a buffer for the data to read to .
* @ param length Length ( in bytes ) of data to read .
*
* @ return
* - ESP_OK : on success
* - ESP_ERR_NOT_SUPPORTED : encrypted read not supported for this chip .
* - or other flash error code from spi_flash_read_encrypted ( ) .
*/
esp_err_t esp_flash_read_encrypted ( esp_flash_t * chip , uint32_t address , void * out_buffer , uint32_t length ) ;
2017-05-23 22:35:12 -04:00
/** @brief Pointer to the "default" SPI flash chip, ie the main chip attached to the MCU.
This chip is used if the ' chip ' argument pass to esp_flash_xxx API functions is ever NULL .
*/
2019-01-08 05:29:25 -05:00
extern esp_flash_t * esp_flash_default_chip ;
2017-05-23 22:35:12 -04:00
2019-06-19 04:37:11 -04:00
2019-09-05 01:11:36 -04:00
/*******************************************************************************
* Utility Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ brief Returns true if chip is configured for Quad I / O or Quad Fast Read .
*
* @ param chip Pointer to SPI flash chip to use . If NULL , esp_flash_default_chip is substituted .
*
* @ return true if flash works in quad mode , otherwise false
*/
static inline bool esp_flash_is_quad_mode ( const esp_flash_t * chip )
{
return ( chip - > read_mode = = SPI_FLASH_QIO ) | | ( chip - > read_mode = = SPI_FLASH_QOUT ) ;
}
2019-06-19 04:37:11 -04:00
# ifdef __cplusplus
}
# endif