2019-01-08 05:29:25 -05:00
// Copyright 2010-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.
/*******************************************************************************
* NOTICE
* The HAL is not public api , don ' t use in application code .
* See readme . md in soc / include / hal / readme . md
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// The HAL layer for SPI Flash (common part)
# pragma once
# include "hal/spi_flash_ll.h"
2019-06-24 00:56:39 -04:00
# include "hal/spi_types.h"
2019-06-19 04:37:55 -04:00
# include "hal/spi_flash_types.h"
2019-01-08 05:29:25 -05:00
# include "soc/soc_memory_layout.h"
/* Hardware host-specific constants */
# define SPI_FLASH_HAL_MAX_WRITE_BYTES 64
# define SPI_FLASH_HAL_MAX_READ_BYTES 64
/**
* Generic driver context structure for all chips using the SPI peripheral .
* Include this into the HEAD of the driver data for other driver
* implementations that also use the SPI peripheral .
*/
typedef struct {
2020-05-07 02:46:41 -04:00
spi_flash_host_inst_t inst ; ///< Host instance, containing host data and function pointer table. May update with the host (hardware version).
2019-01-08 05:29:25 -05:00
spi_dev_t * spi ; ///< Pointer to SPI peripheral registers (SP1, SPI2 or SPI3). Set before initialisation.
int cs_num ; ///< Which cs pin is used, 0-2.
2020-05-07 02:46:41 -04:00
int extra_dummy ; ///< Pre-calculated extra dummy used for compensation
spi_flash_ll_clock_reg_t clock_conf ; ///< Pre-calculated clock configuration value
uint32_t reserved_config [ 2 ] ; ///< The ROM has reserved some memory for configurations with one set of driver code. (e.g. QPI mode, 64-bit address mode, etc.)
} spi_flash_hal_context_t ;
2019-01-08 05:29:25 -05:00
/// Configuration structure for the SPI driver.
typedef struct {
2019-06-24 00:56:39 -04:00
spi_host_device_t host_id ; ///< SPI peripheral ID.
2020-04-07 10:58:26 -04:00
int cs_num ; ///< Which cs pin is used, 0-(SOC_SPI_PERIPH_CS_NUM-1).
2019-01-08 05:29:25 -05:00
bool iomux ; ///< Whether the IOMUX is used, used for timing compensation.
int input_delay_ns ; ///< Input delay on the MISO pin after the launch clock, used for timing compensation.
esp_flash_speed_t speed ; ///< SPI flash clock speed to work at.
2020-05-07 02:46:41 -04:00
} spi_flash_hal_config_t ;
2019-01-08 05:29:25 -05:00
/**
* Configure SPI flash hal settings .
*
* @ param data Buffer to hold configured data , the buffer should be in DRAM to be available when cache disabled
* @ param cfg Configurations to set
*
* @ return
* - ESP_OK : success
* - ESP_ERR_INVALID_ARG : the data buffer is not in the DRAM .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_init ( spi_flash_hal_context_t * data_out , const spi_flash_hal_config_t * cfg ) ;
2019-01-08 05:29:25 -05:00
/**
* Configure the device - related register before transactions .
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
*
* @ return always return ESP_OK .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_device_config ( spi_flash_host_inst_t * host ) ;
2019-01-08 05:29:25 -05:00
/**
* Send an user - defined spi transaction to the device .
*
* @ note This is usually used when the memspi interface doesn ' t support some
* particular commands . Since this function supports timing compensation , it is
* also used to receive some data when the frequency is high .
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
* @ param trans The transaction to send , also holds the received data .
*
* @ return always return ESP_OK .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_common_command ( spi_flash_host_inst_t * host , spi_flash_trans_t * trans ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* Erase whole flash chip by using the erase chip ( C7h ) command .
2019-01-08 05:29:25 -05:00
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
*/
2020-05-07 02:46:41 -04:00
void spi_flash_hal_erase_chip ( spi_flash_host_inst_t * host ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* Erase a specific sector by its start address through the sector erase ( 20 h )
* command .
2019-01-08 05:29:25 -05:00
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
* @ param start_address Start address of the sector to erase .
*/
2020-05-07 02:46:41 -04:00
void spi_flash_hal_erase_sector ( spi_flash_host_inst_t * host , uint32_t start_address ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* Erase a specific 64 KB block by its start address through the 64 KB block
* erase ( D8h ) command .
2019-01-08 05:29:25 -05:00
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
* @ param start_address Start address of the block to erase .
*/
2020-05-07 02:46:41 -04:00
void spi_flash_hal_erase_block ( spi_flash_host_inst_t * host , uint32_t start_address ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* Program a page of the flash using the page program ( 02 h ) command .
2019-01-08 05:29:25 -05:00
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
* @ param address Address of the page to program
* @ param buffer Data to program
* @ param length Size of the buffer in bytes , no larger than ` ` SPI_FLASH_HAL_MAX_WRITE_BYTES ` ` ( 64 ) bytes .
*/
2020-05-07 02:46:41 -04:00
void spi_flash_hal_program_page ( spi_flash_host_inst_t * host , const void * buffer , uint32_t address , uint32_t length ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* Read from the flash . Call ` ` spi_flash_hal_configure_host_read_mode ` ` to
* configure the read command before calling this function .
2019-01-08 05:29:25 -05:00
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
* @ param buffer Buffer to store the read data
* @ param address Address to read
* @ param length Length to read , no larger than ` ` SPI_FLASH_HAL_MAX_READ_BYTES ` ` ( 64 ) bytes .
*
* @ return always return ESP_OK .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_read ( spi_flash_host_inst_t * host , void * buffer , uint32_t address , uint32_t read_len ) ;
2019-01-08 05:29:25 -05:00
/**
2019-08-02 21:59:10 -04:00
* @ brief Send the write enable ( 06 h ) or write disable ( 04 h ) command to the flash chip .
2019-01-08 05:29:25 -05:00
*
* @ param driver The driver context .
* @ param wp true to enable the write protection , otherwise false .
*
* @ return always return ESP_OK .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_set_write_protect ( spi_flash_host_inst_t * host , bool wp ) ;
2019-01-08 05:29:25 -05:00
/**
* Check whether the SPI host is idle and can perform other operations .
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
*
* @ return ture if idle , otherwise false .
*/
2020-05-07 02:46:41 -04:00
bool spi_flash_hal_host_idle ( spi_flash_host_inst_t * host ) ;
2019-01-08 05:29:25 -05:00
/**
2019-09-05 01:11:36 -04:00
* @ brief Configure the SPI host hardware registers for the specified io mode .
2019-01-08 05:29:25 -05:00
*
* Note that calling this configures SPI host registers , so if running any
2019-09-05 01:11:36 -04:00
* other commands as part of set_io_mode ( ) then these must be run before
2019-01-08 05:29:25 -05:00
* calling this function .
*
2019-09-05 01:11:36 -04:00
* The command value , address length and dummy cycles are configured according
* to the format of read commands :
*
* - command : 8 bits , value set .
* - address : 24 bits
* - dummy : cycles to compensate the input delay
* - out & in data : 0 bits .
*
* The following commands still need to :
*
* - Read data : set address value and data ( length and contents ) , no need
* to touch command and dummy phases .
* - Common read : set command value , address value ( or length to 0 if not used )
* - Common write : set command value , address value ( or length to 0 if not
* used ) , disable dummy phase , and set output data .
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context
2019-09-05 01:11:36 -04:00
* @ param io_mode The HW read mode to use
2019-01-08 05:29:25 -05:00
* @ param addr_bitlen Length of the address phase , in bits
* @ param dummy_cyclelen_base Base cycles of the dummy phase , some extra dummy cycles may be appended to compensate the timing .
2019-09-05 01:11:36 -04:00
* @ param command Actual reading command to send to flash chip on the bus .
2019-01-08 05:29:25 -05:00
*
* @ return always return ESP_OK .
*/
2020-05-07 02:46:41 -04:00
esp_err_t spi_flash_hal_configure_host_io_mode ( spi_flash_host_inst_t * host , uint32_t command , uint32_t addr_bitlen ,
2019-09-05 01:11:36 -04:00
int dummy_cyclelen_base , esp_flash_io_mode_t io_mode ) ;
2019-01-08 05:29:25 -05:00
/**
* Poll until the last operation is done .
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context .
2019-01-08 05:29:25 -05:00
*/
2020-05-07 02:46:41 -04:00
void spi_flash_hal_poll_cmd_done ( spi_flash_host_inst_t * host ) ;
2019-01-08 05:29:25 -05:00
/**
* Check whether the given buffer can be used as the write buffer directly . If ' chip ' is connected to the main SPI bus , we can only write directly from
* regions that are accessible ith cache disabled . *
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context
2019-01-08 05:29:25 -05:00
* @ param p The buffer holding data to send .
*
* @ return True if the buffer can be used to send data , otherwise false .
*/
2020-05-07 02:46:41 -04:00
bool spi_flash_hal_supports_direct_write ( spi_flash_host_inst_t * host , const void * p ) ;
2019-01-08 05:29:25 -05:00
/**
* Check whether the given buffer can be used as the read buffer directly . If ' chip ' is connected to the main SPI bus , we can only read directly from
* regions that are accessible ith cache disabled . *
*
2020-05-07 02:46:41 -04:00
* @ param host The driver context
2019-01-08 05:29:25 -05:00
* @ param p The buffer to hold the received data .
*
* @ return True if the buffer can be used to receive data , otherwise false .
*/
2020-05-07 02:46:41 -04:00
bool spi_flash_hal_supports_direct_read ( spi_flash_host_inst_t * host , const void * p ) ;