esp_flash: refactor to make host driver function a const table

This is also part of ESP32-S3 ROM changes
This commit is contained in:
Michael (XIAO Xufeng) 2020-05-07 14:46:41 +08:00
parent f99ba33920
commit c796bd5e63
13 changed files with 204 additions and 220 deletions

View File

@ -37,11 +37,13 @@
* implementations that also use the SPI peripheral.
*/
typedef struct {
spi_flash_host_inst_t inst; ///< Host instance, containing host data and function pointer table. May update with the host (hardware version).
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.
int extra_dummy;
spi_flash_ll_clock_reg_t clock_conf;
} spi_flash_memspi_data_t;
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;
/// Configuration structure for the SPI driver.
typedef struct {
@ -50,7 +52,7 @@ typedef struct {
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.
} spi_flash_memspi_config_t;
} spi_flash_hal_config_t;
/**
* Configure SPI flash hal settings.
@ -62,16 +64,16 @@ typedef struct {
* - ESP_OK: success
* - ESP_ERR_INVALID_ARG: the data buffer is not in the DRAM.
*/
esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_memspi_config_t *cfg);
esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_hal_config_t *cfg);
/**
* Configure the device-related register before transactions.
*
* @param driver The driver context.
* @param host The driver context.
*
* @return always return ESP_OK.
*/
esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *driver);
esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host);
/**
* Send an user-defined spi transaction to the device.
@ -80,60 +82,60 @@ esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *driver);
* particular commands. Since this function supports timing compensation, it is
* also used to receive some data when the frequency is high.
*
* @param driver The driver context.
* @param host The driver context.
* @param trans The transaction to send, also holds the received data.
*
* @return always return ESP_OK.
*/
esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *driver, spi_flash_trans_t *trans);
esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
/**
* Erase whole flash chip by using the erase chip (C7h) command.
*
* @param driver The driver context.
* @param host The driver context.
*/
void spi_flash_hal_erase_chip(spi_flash_host_driver_t *driver);
void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host);
/**
* Erase a specific sector by its start address through the sector erase (20h)
* command.
*
* @param driver The driver context.
* @param host The driver context.
* @param start_address Start address of the sector to erase.
*/
void spi_flash_hal_erase_sector(spi_flash_host_driver_t *driver, uint32_t start_address);
void spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Erase a specific 64KB block by its start address through the 64KB block
* erase (D8h) command.
*
* @param driver The driver context.
* @param host The driver context.
* @param start_address Start address of the block to erase.
*/
void spi_flash_hal_erase_block(spi_flash_host_driver_t *driver, uint32_t start_address);
void spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Program a page of the flash using the page program (02h) command.
*
* @param driver The driver context.
* @param host The driver context.
* @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.
*/
void spi_flash_hal_program_page(spi_flash_host_driver_t *driver, const void *buffer, uint32_t address, uint32_t length);
void spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
/**
* Read from the flash. Call ``spi_flash_hal_configure_host_read_mode`` to
* configure the read command before calling this function.
*
* @param driver The driver context.
* @param host The driver context.
* @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.
*/
esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *driver, void *buffer, uint32_t address, uint32_t read_len);
esp_err_t spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
/**
* @brief Send the write enable (06h) or write disable (04h) command to the flash chip.
@ -143,16 +145,16 @@ esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *driver, void *buffer, uint
*
* @return always return ESP_OK.
*/
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *chip_drv, bool wp);
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp);
/**
* Check whether the SPI host is idle and can perform other operations.
*
* @param driver The driver context.
* @param host The driver context.
*
* @return ture if idle, otherwise false.
*/
bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver);
bool spi_flash_hal_host_idle(spi_flash_host_inst_t *host);
/**
* @brief Configure the SPI host hardware registers for the specified io mode.
@ -177,7 +179,7 @@ bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver);
* - Common write: set command value, address value (or length to 0 if not
* used), disable dummy phase, and set output data.
*
* @param driver The driver context
* @param host The driver context
* @param io_mode The HW read mode to use
* @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.
@ -185,34 +187,34 @@ bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver);
*
* @return always return ESP_OK.
*/
esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_driver_t *driver, uint32_t command, uint32_t addr_bitlen,
esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_inst_t *host, uint32_t command, uint32_t addr_bitlen,
int dummy_cyclelen_base, esp_flash_io_mode_t io_mode);
/**
* Poll until the last operation is done.
*
* @param driver The driver context.
* @param host The driver context.
*/
void spi_flash_hal_poll_cmd_done(spi_flash_host_driver_t *driver);
void spi_flash_hal_poll_cmd_done(spi_flash_host_inst_t *host);
/**
* 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. *
*
* @param driver The driver context
* @param host The driver context
* @param p The buffer holding data to send.
*
* @return True if the buffer can be used to send data, otherwise false.
*/
bool spi_flash_hal_supports_direct_write(spi_flash_host_driver_t *driver, const void *p);
bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
/**
* 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. *
*
* @param driver The driver context
* @param host The driver context
* @param p The buffer to hold the received data.
*
* @return True if the buffer can be used to receive data, otherwise false.
*/
bool spi_flash_hal_supports_direct_read(spi_flash_host_driver_t *driver, const void *p);
bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p);

View File

@ -68,55 +68,57 @@ typedef enum {
///Slowest io mode supported by ESP32, currently SlowRd
#define SPI_FLASH_READ_MODE_MIN SPI_FLASH_SLOWRD
struct spi_flash_host_driver_t;
typedef struct spi_flash_host_driver_t spi_flash_host_driver_t;
struct spi_flash_host_driver_s;
typedef struct spi_flash_host_driver_s spi_flash_host_driver_t;
/** SPI Flash Host driver instance */
typedef struct {
const struct spi_flash_host_driver_s* driver; ///< Pointer to the implementation function table
// Implementations can wrap this structure into their own ones, and append other data here
} spi_flash_host_inst_t ;
/** Host driver configuration and context structure. */
struct spi_flash_host_driver_t {
/**
* Configuration and static data used by the specific host driver. The type
* is determined by the host driver.
*/
void *driver_data;
struct spi_flash_host_driver_s {
/**
* Configure the device-related register before transactions. This saves
* some time to re-configure those registers when we send continuously
*/
esp_err_t (*dev_config)(spi_flash_host_driver_t *driver);
esp_err_t (*dev_config)(spi_flash_host_inst_t *host);
/**
* Send an user-defined spi transaction to the device.
*/
esp_err_t (*common_command)(spi_flash_host_driver_t *driver, spi_flash_trans_t *t);
esp_err_t (*common_command)(spi_flash_host_inst_t *host, spi_flash_trans_t *t);
/**
* Read flash ID.
*/
esp_err_t (*read_id)(spi_flash_host_driver_t *driver, uint32_t *id);
esp_err_t (*read_id)(spi_flash_host_inst_t *host, uint32_t *id);
/**
* Erase whole flash chip.
*/
void (*erase_chip)(spi_flash_host_driver_t *driver);
void (*erase_chip)(spi_flash_host_inst_t *host);
/**
* Erase a specific sector by its start address.
*/
void (*erase_sector)(spi_flash_host_driver_t *driver, uint32_t start_address);
void (*erase_sector)(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Erase a specific block by its start address.
*/
void (*erase_block)(spi_flash_host_driver_t *driver, uint32_t start_address);
void (*erase_block)(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Read the status of the flash chip.
*/
esp_err_t (*read_status)(spi_flash_host_driver_t *driver, uint8_t *out_sr);
esp_err_t (*read_status)(spi_flash_host_inst_t *host, uint8_t *out_sr);
/**
* Disable write protection.
*/
esp_err_t (*set_write_protect)(spi_flash_host_driver_t *driver, bool wp);
esp_err_t (*set_write_protect)(spi_flash_host_inst_t *host, bool wp);
/**
* Program a page of the flash. Check ``max_write_bytes`` for the maximum allowed writing length.
*/
void (*program_page)(spi_flash_host_driver_t *driver, const void *buffer, uint32_t address, uint32_t length);
void (*program_page)(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
/** Check whether given buffer can be directly used to write */
bool (*supports_direct_write)(spi_flash_host_driver_t *driver, const void *p);
bool (*supports_direct_write)(spi_flash_host_inst_t *host, const void *p);
/**
* Slicer for write data. The `program_page` should be called iteratively with the return value
* of this function.
@ -127,13 +129,14 @@ struct spi_flash_host_driver_t {
* @param page_size Physical page size of the flash chip
* @return Length that can be actually written in one `program_page` call
*/
int (*write_data_slicer)(uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size);
int (*write_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr,
uint32_t page_size);
/**
* Read data from the flash. Check ``max_read_bytes`` for the maximum allowed reading length.
*/
esp_err_t (*read)(spi_flash_host_driver_t *driver, void *buffer, uint32_t address, uint32_t read_len);
esp_err_t (*read)(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
/** Check whether given buffer can be directly used to read */
bool (*supports_direct_read)(spi_flash_host_driver_t *driver, const void *p);
bool (*supports_direct_read)(spi_flash_host_inst_t *host, const void *p);
/**
* Slicer for read data. The `read` should be called iteratively with the return value
* of this function.
@ -144,26 +147,26 @@ struct spi_flash_host_driver_t {
* @param page_size Physical page size of the flash chip
* @return Length that can be actually read in one `read` call
*/
int (*read_data_slicer)(uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size);
int (*read_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size);
/**
* Check whether the host is idle to perform new operations.
*/
bool (*host_idle)(spi_flash_host_driver_t *driver);
bool (*host_idle)(spi_flash_host_inst_t *host);
/**
* Configure the host to work at different read mode. Responsible to compensate the timing and set IO mode.
*/
esp_err_t (*configure_host_io_mode)(spi_flash_host_driver_t *driver, uint32_t command,
esp_err_t (*configure_host_io_mode)(spi_flash_host_inst_t *host, uint32_t command,
uint32_t addr_bitlen, int dummy_bitlen_base,
esp_flash_io_mode_t io_mode);
/**
* Internal use, poll the HW until the last operation is done.
*/
void (*poll_cmd_done)(spi_flash_host_driver_t *driver);
void (*poll_cmd_done)(spi_flash_host_inst_t *host);
/**
* For some host (SPI1), they are shared with a cache. When the data is
* modified, the cache needs to be flushed. Left NULL if not supported.
*/
esp_err_t (*flush_cache)(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size);
esp_err_t (*flush_cache)(spi_flash_host_inst_t* host, uint32_t addr, uint32_t size);
};
#ifdef __cplusplus

View File

@ -63,7 +63,7 @@ static inline int get_dummy_n(bool gpio_is_used, int input_delay_ns, int eff_clk
return apb_period_n / apbclk_n;
}
esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_memspi_config_t *cfg)
esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_hal_config_t *cfg)
{
if (!esp_ptr_internal(data_out)) {
return ESP_ERR_INVALID_ARG;
@ -77,7 +77,8 @@ esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_
}
#endif
*data_out = (spi_flash_memspi_data_t) {
*data_out = (spi_flash_hal_context_t) {
.inst = data_out->inst, // Keeps the function pointer table
.spi = spi_flash_ll_get_hw(cfg->host_id),
.cs_num = cfg->cs_num,
.extra_dummy = get_dummy_n(!cfg->iomux, cfg->input_delay_ns, clock_cfg.freq),
@ -88,18 +89,18 @@ esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_
return ESP_OK;
}
bool spi_flash_hal_supports_direct_write(spi_flash_host_driver_t *host, const void *p)
bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
{
bool direct_write = ( ((spi_flash_memspi_data_t *)host->driver_data)->spi != spi_flash_ll_get_hw(SPI_HOST)
bool direct_write = ( ((spi_flash_hal_context_t *)host)->spi != spi_flash_ll_get_hw(SPI_HOST)
|| esp_ptr_in_dram(p) );
return direct_write;
}
bool spi_flash_hal_supports_direct_read(spi_flash_host_driver_t *host, const void *p)
bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
{
//currently the host doesn't support to read through dma, no word-aligned requirements
bool direct_read = ( ((spi_flash_memspi_data_t *)host->driver_data)->spi != spi_flash_ll_get_hw(SPI_HOST)
bool direct_read = ( ((spi_flash_hal_context_t *)host)->spi != spi_flash_ll_get_hw(SPI_HOST)
|| esp_ptr_in_dram(p) );
return direct_read;
}

View File

@ -19,32 +19,31 @@
#include "sdkconfig.h"
#define ADDRESS_MASK_24BIT 0xFFFFFF
#define COMPUTE_DUMMY_CYCLELEN(host, base) ((base) + ((spi_flash_memspi_data_t *)(host)->driver_data)->extra_dummy)
#define COMPUTE_DUMMY_CYCLELEN(host, base) ((base) + ((spi_flash_hal_context_t*)host)->extra_dummy)
static inline spi_dev_t *get_spi_dev(spi_flash_host_driver_t *host)
static inline spi_dev_t *get_spi_dev(spi_flash_host_inst_t *host)
{
return ((spi_flash_memspi_data_t *)host->driver_data)->spi;
return ((spi_flash_hal_context_t*)host)->spi;
}
void spi_flash_hal_poll_cmd_done(spi_flash_host_driver_t *host)
void spi_flash_hal_poll_cmd_done(spi_flash_host_inst_t *host)
{
while (!spi_flash_ll_cmd_is_done(get_spi_dev(host))) {
//nop
}
}
esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *host)
esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host)
{
spi_flash_memspi_data_t *drv_data = (spi_flash_memspi_data_t *)host->driver_data;
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_reset(dev);
spi_flash_ll_set_cs_pin(dev, drv_data->cs_num);
spi_flash_ll_set_clock(dev, &drv_data->clock_conf);
spi_flash_ll_set_cs_pin(dev, ((spi_flash_hal_context_t*)host)->cs_num);
spi_flash_ll_set_clock(dev, &((spi_flash_hal_context_t*)host)->clock_conf);
return ESP_OK;
}
esp_err_t spi_flash_hal_configure_host_io_mode(
spi_flash_host_driver_t *host,
spi_flash_host_inst_t *host,
uint32_t command,
uint32_t addr_bitlen,
int dummy_cyclelen_base,
@ -89,9 +88,9 @@ esp_err_t spi_flash_hal_configure_host_io_mode(
return ESP_OK;
}
esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *host, spi_flash_trans_t *trans)
esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
{
host->configure_host_io_mode(host, trans->command, trans->address_bitlen, 0, SPI_FLASH_FASTRD);
host->driver->configure_host_io_mode(host, trans->command, trans->address_bitlen, 0, SPI_FLASH_FASTRD);
spi_dev_t *dev = get_spi_dev(host);
@ -106,19 +105,19 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *host, spi_flash_
spi_flash_ll_set_miso_bitlen(dev, trans->miso_len * 8);
spi_flash_ll_user_start(dev);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
spi_flash_ll_get_buffer_data(dev, trans->miso_data, trans->miso_len);
return ESP_OK;
}
esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *host, void *buffer, uint32_t address, uint32_t read_len)
esp_err_t spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
{
spi_dev_t *dev = get_spi_dev(host);
int bitlen = spi_flash_ll_get_addr_bitlen(dev);
spi_flash_ll_set_usr_address(dev, address << (bitlen - 24), bitlen);
spi_flash_ll_set_miso_bitlen(dev, read_len * 8);
spi_flash_ll_user_start(dev);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
spi_flash_ll_get_buffer_data(dev, buffer, read_len);
return ESP_OK;
}

View File

@ -22,18 +22,18 @@
#include "spi_flash_hal_common.inc"
bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_driver_t *host, const void *p)
bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
{
return true;
}
bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_driver_t *host, const void *p)
bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
{
return true;
}
bool spi_flash_hal_gpspi_host_idle(spi_flash_host_driver_t *chip_drv)
bool spi_flash_hal_gpspi_host_idle(spi_flash_host_inst_t *host)
{
spi_dev_t *dev = get_spi_dev(chip_drv);
spi_dev_t *dev = get_spi_dev(host);
return spi_flash_ll_host_idle(dev);
}

View File

@ -14,51 +14,51 @@
#include "spi_flash_hal_common.inc"
void spi_flash_hal_erase_chip(spi_flash_host_driver_t *host)
void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
{
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_erase_chip(dev);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
}
void spi_flash_hal_erase_sector(spi_flash_host_driver_t *host, uint32_t start_address)
void spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
{
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_set_addr_bitlen(dev, 24);
spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT);
spi_flash_ll_erase_sector(dev);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
}
void spi_flash_hal_erase_block(spi_flash_host_driver_t *host, uint32_t start_address)
void spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
{
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_set_addr_bitlen(dev, 24);
spi_flash_ll_set_address(dev, start_address & ADDRESS_MASK_24BIT);
spi_flash_ll_erase_block(dev);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
}
void spi_flash_hal_program_page(spi_flash_host_driver_t *host, const void *buffer, uint32_t address, uint32_t length)
void spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
{
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_set_addr_bitlen(dev, 24);
spi_flash_ll_set_address(dev, (address & ADDRESS_MASK_24BIT) | (length << 24));
spi_flash_ll_program_page(dev, buffer, length);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
}
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *host, bool wp)
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
{
spi_dev_t *dev = get_spi_dev(host);
spi_flash_ll_set_write_protect(dev, wp);
host->poll_cmd_done(host);
host->driver->poll_cmd_done(host);
return ESP_OK;
}
bool spi_flash_hal_host_idle(spi_flash_host_driver_t *chip_drv)
bool spi_flash_hal_host_idle(spi_flash_host_inst_t *host)
{
spi_dev_t *dev = get_spi_dev(chip_drv);
spi_dev_t *dev = get_spi_dev(host);
bool idle = spi_flash_ll_host_idle(dev);
// Not clear if this is necessary, or only necessary if

View File

@ -103,7 +103,7 @@ static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip)
return err;
}
}
chip->host->dev_config(chip->host);
chip->host->driver->dev_config(chip->host);
return ESP_OK;
}
@ -151,8 +151,8 @@ bool esp_flash_chip_driver_initialized(const esp_flash_t *chip)
esp_err_t IRAM_ATTR esp_flash_init(esp_flash_t *chip)
{
esp_err_t err = ESP_OK;
if (chip == NULL || chip->host == NULL || chip->host->driver_data == NULL ||
((memspi_host_data_t*)chip->host->driver_data)->spi == NULL) {
if (chip == NULL || chip->host == NULL || chip->host->driver == NULL ||
((memspi_host_inst_t*)chip->host)->spi == NULL) {
return ESP_ERR_INVALID_ARG;
}
@ -212,11 +212,11 @@ esp_err_t IRAM_ATTR esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id
// Send generic RDID command twice, check for a matching result and retry in case we just powered on (inner
// function fails if it sees all-ones or all-zeroes.)
err = chip->host->read_id(chip->host, flash_id);
err = chip->host->driver->read_id(chip->host, flash_id);
if (err == ESP_OK) { // check we see the same ID twice, in case of transient power-on errors
uint32_t new_id;
err = chip->host->read_id(chip->host, &new_id);
err = chip->host->driver->read_id(chip->host, &new_id);
if (err == ESP_OK && (new_id != *flash_id)) {
err = ESP_ERR_FLASH_NOT_INITIALISED;
}
@ -284,7 +284,7 @@ esp_err_t IRAM_ATTR esp_flash_read_id(esp_flash_t *chip, uint32_t *out_id)
return err;
}
err = chip->host->read_id(chip->host, out_id);
err = chip->host->driver->read_id(chip->host, out_id);
return rom_spiflash_api_funcs->end(chip, err);
}
@ -553,7 +553,7 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add
}
//when the cache is disabled, only the DRAM can be read, check whether we need to receive in another buffer in DRAM.
bool direct_read = chip->host->supports_direct_read(chip->host, buffer);
bool direct_read = chip->host->driver->supports_direct_read(chip->host, buffer);
uint8_t* temp_buffer = NULL;
//each time, we at most read this length
@ -617,7 +617,7 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3
}
//when the cache is disabled, only the DRAM can be read, check whether we need to copy the data first
bool direct_write = chip->host->supports_direct_write(chip->host, buffer);
bool direct_write = chip->host->driver->supports_direct_write(chip->host, buffer);
err = ESP_OK;
/* Write output in chunks, either by buffering on stack or

View File

@ -116,8 +116,7 @@ esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_d
return ESP_ERR_INVALID_ARG;
}
esp_flash_t *chip = NULL;
spi_flash_host_driver_t *host = NULL;
memspi_host_data_t *host_data = NULL;
memspi_host_inst_t *host = NULL;
esp_err_t ret = ESP_OK;
uint32_t caps = MALLOC_CAP_DEFAULT;
@ -129,23 +128,16 @@ esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_d
goto fail;
}
host = (spi_flash_host_driver_t*)heap_caps_malloc(sizeof(spi_flash_host_driver_t), caps);
host = (memspi_host_inst_t*)heap_caps_malloc(sizeof(memspi_host_inst_t), caps);
*chip = (esp_flash_t) {
.read_mode = config->io_mode,
.host = host,
.host = (spi_flash_host_inst_t*)host,
};
if (!host) {
ret = ESP_ERR_NO_MEM;
goto fail;
}
host_data = (memspi_host_data_t*)heap_caps_malloc(sizeof(memspi_host_data_t), caps);
host->driver_data = host_data;
if (!host_data) {
ret = ESP_ERR_NO_MEM;
goto fail;
}
int dev_id = -1;
esp_err_t err = esp_flash_init_os_functions(chip, config->host_id, &dev_id);
if (err == ESP_ERR_NOT_SUPPORTED) {
@ -173,7 +165,7 @@ esp_err_t spi_bus_add_flash_device(esp_flash_t **out_chip, const esp_flash_spi_d
.input_delay_ns = config->input_delay_ns,
.speed = config->speed,
};
err = memspi_host_init_pointers(host, host_data, &host_cfg);
err = memspi_host_init_pointers(host, &host_cfg);
if (err != ESP_OK) {
ret = err;
goto fail;
@ -195,10 +187,7 @@ esp_err_t spi_bus_remove_flash_device(esp_flash_t *chip)
return ESP_ERR_INVALID_ARG;
}
esp_flash_deinit_os_functions(chip);
if (chip->host) {
free(chip->host->driver_data);
free(chip->host);
}
free(chip->host);
free(chip);
return ESP_OK;
}
@ -209,13 +198,11 @@ extern const esp_flash_os_functions_t esp_flash_noos_functions;
#ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL
static DRAM_ATTR memspi_host_data_t default_driver_data;
static DRAM_ATTR spi_flash_host_driver_t esp_flash_default_host_drv = ESP_FLASH_DEFAULT_HOST_DRIVER();
static DRAM_ATTR memspi_host_inst_t esp_flash_default_host;
static DRAM_ATTR esp_flash_t default_chip = {
.read_mode = DEFAULT_FLASH_MODE,
.host = &esp_flash_default_host_drv,
.host = (spi_flash_host_inst_t*)&esp_flash_default_host,
.os_func = &esp_flash_noos_functions,
};
@ -229,12 +216,14 @@ esp_err_t esp_flash_init_default_chip(void)
#endif
//the host is already initialized, only do init for the data and load it to the host
spi_flash_hal_init(&default_driver_data, &cfg);
default_chip.host->driver_data = &default_driver_data;
esp_err_t err = memspi_host_init_pointers(&esp_flash_default_host, &cfg);
if (err != ESP_OK) {
return err;
}
// ROM TODO: account for non-standard default pins in efuse
// ROM TODO: to account for chips which are slow to power on, maybe keep probing in a loop here
esp_err_t err = esp_flash_init(&default_chip);
err = esp_flash_init(&default_chip);
if (err != ESP_OK) {
return err;
}

View File

@ -80,7 +80,7 @@ typedef struct {
risk.
*/
struct esp_flash_t {
spi_flash_host_driver_t *host; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used.
spi_flash_host_inst_t* host; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used.
const spi_flash_chip_t *chip_drv; ///< Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation.
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.

View File

@ -38,20 +38,19 @@
}
/// configuration for the memspi host
typedef spi_flash_memspi_config_t memspi_host_config_t;
typedef spi_flash_hal_config_t memspi_host_config_t;
/// context for the memspi host
typedef spi_flash_memspi_data_t memspi_host_data_t;
typedef spi_flash_hal_context_t memspi_host_inst_t;
/**
* Initialize the memory SPI host.
*
* @param host Pointer to the host structure.
* @param data Pointer to allocated space to hold the context of host driver.
* @param cfg Pointer to configuration structure
*
* @return always return ESP_OK
*/
esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_data_t *data, const memspi_host_config_t *cfg);
esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_config_t *cfg);
/*******************************************************************************
* NOTICE
@ -66,7 +65,7 @@ esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_d
* High speed implementation of RDID through memspi interface relying on the
* ``common_command``.
*
* @param driver The driver context.
* @param host The driver context.
* @param id Output of the read ID from the slave.
*
* @return
@ -74,82 +73,82 @@ esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_d
* - ESP_ERR_FLASH_NO_RESPONSE: if no response from chip
* - or other cases from ``spi_hal_common_command``
*/
esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *driver, uint32_t *id);
esp_err_t memspi_host_read_id_hs(spi_flash_host_inst_t *host, uint32_t *id);
/**
* High speed implementation of RDSR through memspi interface relying on the
* ``common_command``.
*
* @param driver The driver context.
* @param host The driver context.
* @param id Output of the read ID from the slave.
*
* @return
* - ESP_OK: if success
* - or other cases from ``spi_hal_common_command``
*/
esp_err_t memspi_host_read_status_hs(spi_flash_host_driver_t *driver, uint8_t *out_sr);
esp_err_t memspi_host_read_status_hs(spi_flash_host_inst_t *host, uint8_t *out_sr);
/**
* Flush the cache (if needed) after the contents are modified.
*
* @param driver The driver context.
* @param host The driver context.
* @param addr Start address of the modified region
* @param size Size of the region modified.
*
* @return always ESP_OK.
*/
esp_err_t memspi_host_flush_cache(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size);
esp_err_t memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size);
/**
* Erase contents of entire chip.
*
* @param driver The driver context.
* @param host The driver context.
*/
void memspi_host_erase_chip(spi_flash_host_driver_t *driver);
void memspi_host_erase_chip(spi_flash_host_inst_t *host);
/**
* Erase a sector starting from a given address.
*
* @param driver The driver context.
* @param host The driver context.
* @param start_address Starting address of the sector.
*/
void memspi_host_erase_sector(spi_flash_host_driver_t *driver, uint32_t start_address);
void memspi_host_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Erase a block starting from a given address.
*
* @param driver The driver context.
* @param host The driver context.
* @param start_address Starting address of the block.
*/
void memspi_host_erase_block(spi_flash_host_driver_t *driver, uint32_t start_address);
void memspi_host_erase_block(spi_flash_host_inst_t *host, uint32_t start_address);
/**
* Program a page with contents of a buffer.
*
* @param driver The driver context.
* @param host The driver context.
* @param buffer Buffer which contains the data to be flashed.
* @param address Starting address of where to flash the data.
* @param length The number of bytes to flash.
*/
void memspi_host_program_page(spi_flash_host_driver_t *driver, const void *buffer, uint32_t address, uint32_t length);
void memspi_host_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
/**
* Set ability to write to chip.
*
* @param driver The driver context.
* @param host The driver context.
* @param wp Enable or disable write protect (true - enable, false - disable).
*/
esp_err_t memspi_host_set_write_protect(spi_flash_host_driver_t *driver, bool wp);
esp_err_t memspi_host_set_write_protect(spi_flash_host_inst_t *host, bool wp);
/**
* Read data to buffer.
*
* @param driver The driver context.
* @param host The driver context.
* @param buffer Buffer which contains the data to be read.
* @param address Starting address of where to read the data.
* @param length The number of bytes to read.
*/
esp_err_t memspi_host_read(spi_flash_host_driver_t *driver, void *buffer, uint32_t address, uint32_t read_len);
esp_err_t memspi_host_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
/**
* @brief Slicer for read data used in non-encrypted regions. This slicer does nothing but
@ -162,7 +161,7 @@ esp_err_t memspi_host_read(spi_flash_host_driver_t *driver, void *buffer, uint32
*
* @return Length that can actually be read in one `read` call in `spi_flash_host_driver_t`.
*/
int memspi_host_read_data_slicer(uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
/**
* @brief Slicer for write data used in non-encrypted regions. This slicer limit the length to the
@ -176,4 +175,4 @@ int memspi_host_read_data_slicer(uint32_t address, uint32_t len, uint32_t *align
*
* @return Length that can actually be written in one `program_page` call in `spi_flash_host_driver_t`.
*/
int memspi_host_write_data_slicer(uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);
int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size);

View File

@ -23,22 +23,22 @@
#define SPI_FLASH_HAL_MAX_READ_BYTES 64
static const char TAG[] = "memspi";
static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER();
DRAM_ATTR static const spi_flash_host_driver_t esp_flash_default_host = ESP_FLASH_DEFAULT_HOST_DRIVER();
#ifdef CONFIG_IDF_TARGET_ESP32S2
extern void spi_flash_hal_gpspi_poll_cmd_done(spi_flash_host_driver_t *driver);
extern esp_err_t spi_flash_hal_gpspi_device_config(spi_flash_host_driver_t *driver);
extern void spi_flash_hal_gpspi_poll_cmd_done(spi_flash_host_inst_t *host);
extern esp_err_t spi_flash_hal_gpspi_device_config(spi_flash_host_inst_t *host);
esp_err_t spi_flash_hal_gpspi_configure_host_io_mode(
spi_flash_host_driver_t *host,
spi_flash_host_inst_t *host,
uint32_t command,
uint32_t addr_bitlen,
int dummy_cyclelen_base,
esp_flash_io_mode_t io_mode);
extern esp_err_t spi_flash_hal_gpspi_common_command(spi_flash_host_driver_t *chip_drv, spi_flash_trans_t *trans);
extern esp_err_t spi_flash_hal_gpspi_read(spi_flash_host_driver_t *chip_drv, void *buffer, uint32_t address, uint32_t read_len);
extern bool spi_flash_hal_gpspi_host_idle(spi_flash_host_driver_t *chip_drv);
extern bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_driver_t *driver, const void *p);
extern bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_driver_t *driver, const void *p);
extern esp_err_t spi_flash_hal_gpspi_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
extern esp_err_t spi_flash_hal_gpspi_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
extern bool spi_flash_hal_gpspi_host_idle(spi_flash_host_inst_t *host);
extern bool spi_flash_hal_gpspi_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
extern bool spi_flash_hal_gpspi_supports_direct_read(spi_flash_host_inst_t *host, const void *p);
/** Default configuration for GPSPI */
static const spi_flash_host_driver_t esp_flash_gpspi_host = {
@ -63,32 +63,23 @@ static const spi_flash_host_driver_t esp_flash_gpspi_host = {
};
#endif
esp_err_t memspi_host_init_pointers(spi_flash_host_driver_t *host, memspi_host_data_t *data, const memspi_host_config_t *cfg)
esp_err_t memspi_host_init_pointers(memspi_host_inst_t *host, const memspi_host_config_t *cfg)
{
#ifdef CONFIG_IDF_TARGET_ESP32
memcpy(host, &esp_flash_default_host, sizeof(spi_flash_host_driver_t));
host->inst.driver = &esp_flash_default_host;
#elif CONFIG_IDF_TARGET_ESP32S2
if (cfg->host_id == SPI_HOST)
memcpy(host, &esp_flash_default_host, sizeof(spi_flash_host_driver_t));
host->inst.driver = &esp_flash_default_host;
else {
memcpy(host, &esp_flash_gpspi_host, sizeof(spi_flash_host_driver_t));
host->inst.driver = &esp_flash_gpspi_host;
}
#endif
esp_err_t err = spi_flash_hal_init(data, cfg);
if (err != ESP_OK) {
return err;
}
host->driver_data = data;
//some functions are not required if not SPI1
if ((void*)data->spi != (void*)spi_flash_ll_get_hw(SPI_HOST)) {
host->flush_cache = NULL;
}
return ESP_OK;
esp_err_t err = spi_flash_hal_init(host, cfg);
return err;
}
esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *host, uint32_t *id)
esp_err_t memspi_host_read_id_hs(spi_flash_host_inst_t *host, uint32_t *id)
{
uint32_t id_buf = 0;
spi_flash_trans_t t = {
@ -96,7 +87,7 @@ esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *host, uint32_t *id)
.miso_len = 3,
.miso_data = ((uint8_t*) &id_buf),
};
host->common_command(host, &t);
host->driver->common_command(host, &t);
uint32_t raw_flash_id = id_buf;
ESP_EARLY_LOGV(TAG, "raw_chip_id: %X\n", raw_flash_id);
@ -112,7 +103,7 @@ esp_err_t memspi_host_read_id_hs(spi_flash_host_driver_t *host, uint32_t *id)
return ESP_OK;
}
esp_err_t memspi_host_read_status_hs(spi_flash_host_driver_t *driver, uint8_t *out_sr)
esp_err_t memspi_host_read_status_hs(spi_flash_host_inst_t *host, uint8_t *out_sr)
{
//NOTE: we do have a read id function, however it doesn't work in high freq
uint32_t stat_buf = 0;
@ -121,7 +112,7 @@ esp_err_t memspi_host_read_status_hs(spi_flash_host_driver_t *driver, uint8_t *o
.miso_data = ((uint8_t*) &stat_buf),
.miso_len = 1
};
esp_err_t err = driver->common_command(driver, &t);
esp_err_t err = host->driver->common_command(host, &t);
if (err != ESP_OK) {
return err;
}
@ -129,42 +120,42 @@ esp_err_t memspi_host_read_status_hs(spi_flash_host_driver_t *driver, uint8_t *o
return ESP_OK;
}
esp_err_t memspi_host_flush_cache(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size)
esp_err_t memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
{
if ((void*)((memspi_host_data_t*)(driver->driver_data))->spi == (void*) spi_flash_ll_get_hw(SPI_HOST)) {
if ((void*)((memspi_host_inst_t*)host)->spi == (void*) spi_flash_ll_get_hw(SPI_HOST)) {
spi_flash_check_and_flush_cache(addr, size);
}
return ESP_OK;
}
void memspi_host_erase_chip(spi_flash_host_driver_t *chip_drv)
void memspi_host_erase_chip(spi_flash_host_inst_t *host)
{
spi_flash_trans_t t = { 0 };
t.command = CMD_CHIP_ERASE;
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
}
void memspi_host_erase_sector(spi_flash_host_driver_t *chip_drv, uint32_t start_address)
void memspi_host_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
{
spi_flash_trans_t t = {
.command = CMD_SECTOR_ERASE,
.address_bitlen = 24,
.address = start_address
};
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
}
void memspi_host_erase_block(spi_flash_host_driver_t *chip_drv, uint32_t start_address)
void memspi_host_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
{
spi_flash_trans_t t = {
.command = CMD_LARGE_BLOCK_ERASE,
.address_bitlen = 24,
.address = start_address,
};
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
}
void memspi_host_program_page(spi_flash_host_driver_t *chip_drv, const void *buffer, uint32_t address, uint32_t length)
void memspi_host_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
{
spi_flash_trans_t t = {
.command = CMD_PROGRAM_PAGE,
@ -173,10 +164,10 @@ void memspi_host_program_page(spi_flash_host_driver_t *chip_drv, const void *buf
.mosi_len = length,
.mosi_data = buffer
};
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
}
esp_err_t memspi_host_read(spi_flash_host_driver_t *chip_drv, void *buffer, uint32_t address, uint32_t read_len)
esp_err_t memspi_host_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
{
spi_flash_trans_t t = {
.command = CMD_READ,
@ -185,22 +176,22 @@ esp_err_t memspi_host_read(spi_flash_host_driver_t *chip_drv, void *buffer, uint
.miso_len = read_len,
.miso_data = buffer
};
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
return ESP_OK;
}
esp_err_t memspi_host_set_write_protect(spi_flash_host_driver_t *chip_drv, bool wp)
esp_err_t memspi_host_set_write_protect(spi_flash_host_inst_t *host, bool wp)
{
spi_flash_trans_t t = {
.command = wp ? CMD_WRDI : CMD_WREN
};
chip_drv->common_command(chip_drv, &t);
host->driver->common_command(host, &t);
return ESP_OK;
}
// When encryption is enabled, etc. the data slicer may be complicated
// This is the simple case where the hardware has no other requirements than the size and page boundary
int memspi_host_write_data_slicer(uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
{
uint32_t align_addr = address;
uint32_t end_bound = (align_addr/page_size + 1) * page_size;
@ -210,7 +201,7 @@ int memspi_host_write_data_slicer(uint32_t address, uint32_t len, uint32_t *alig
return MIN(max_len, len);
}
int memspi_host_read_data_slicer(uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size)
{
// Shouldn't read longer than SPI_FLASH_HAL_MAX_READ_BYTES
uint32_t max_len = SPI_FLASH_HAL_MAX_READ_BYTES;

View File

@ -76,7 +76,7 @@ esp_err_t spi_flash_chip_generic_reset(esp_flash_t *chip)
t = (spi_flash_trans_t) {
.command = CMD_RST_EN,
};
esp_err_t err = chip->host->common_command(chip->host, &t);
esp_err_t err = chip->host->driver->common_command(chip->host, &t);
if (err != ESP_OK) {
return err;
}
@ -84,7 +84,7 @@ esp_err_t spi_flash_chip_generic_reset(esp_flash_t *chip)
t = (spi_flash_trans_t) {
.command = CMD_RST_DEV,
};
err = chip->host->common_command(chip->host, &t);
err = chip->host->driver->common_command(chip->host, &t);
if (err != ESP_OK) {
return err;
}
@ -118,10 +118,10 @@ esp_err_t spi_flash_chip_generic_erase_chip(esp_flash_t *chip)
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->idle_timeout);
}
if (err == ESP_OK) {
chip->host->erase_chip(chip->host);
chip->host->driver->erase_chip(chip->host);
//to save time, flush cache here
if (chip->host->flush_cache) {
err = chip->host->flush_cache(chip->host, 0, chip->size);
if (chip->host->driver->flush_cache) {
err = chip->host->driver->flush_cache(chip->host, 0, chip->size);
if (err != ESP_OK) {
return err;
}
@ -138,10 +138,10 @@ esp_err_t spi_flash_chip_generic_erase_sector(esp_flash_t *chip, uint32_t start_
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->idle_timeout);
}
if (err == ESP_OK) {
chip->host->erase_sector(chip->host, start_address);
chip->host->driver->erase_sector(chip->host, start_address);
//to save time, flush cache here
if (chip->host->flush_cache) {
err = chip->host->flush_cache(chip->host, start_address, chip->chip_drv->sector_size);
if (chip->host->driver->flush_cache) {
err = chip->host->driver->flush_cache(chip->host, start_address, chip->chip_drv->sector_size);
if (err != ESP_OK) {
return err;
}
@ -158,10 +158,10 @@ esp_err_t spi_flash_chip_generic_erase_block(esp_flash_t *chip, uint32_t start_a
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->idle_timeout);
}
if (err == ESP_OK) {
chip->host->erase_block(chip->host, start_address);
chip->host->driver->erase_block(chip->host, start_address);
//to save time, flush cache here
if (chip->host->flush_cache) {
err = chip->host->flush_cache(chip->host, start_address, chip->chip_drv->block_erase_size);
if (chip->host->driver->flush_cache) {
err = chip->host->driver->flush_cache(chip->host, start_address, chip->chip_drv->block_erase_size);
if (err != ESP_OK) {
return err;
}
@ -188,10 +188,10 @@ esp_err_t spi_flash_chip_generic_read(esp_flash_t *chip, void *buffer, uint32_t
while (err == ESP_OK && length > 0) {
memset(temp_buffer, 0xFF, sizeof(temp_buffer));
uint32_t read_len = chip->host->read_data_slicer(address, length, &align_address, page_size);
uint32_t read_len = chip->host->driver->read_data_slicer(chip->host, address, length, &align_address, page_size);
uint32_t left_off = address - align_address;
uint32_t data_len = MIN(align_address + read_len, address + length) - address;
err = chip->host->read(chip->host, temp_buffer, align_address, read_len);
err = chip->host->driver->read(chip->host, temp_buffer, align_address, read_len);
memcpy(buffer, temp_buffer + left_off, data_len);
@ -211,7 +211,7 @@ esp_err_t spi_flash_chip_generic_page_program(esp_flash_t *chip, const void *buf
if (err == ESP_OK) {
// Perform the actual Page Program command
chip->host->program_page(chip->host, buffer, address, length);
chip->host->driver->program_page(chip->host, buffer, address, length);
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->page_program_timeout);
}
@ -227,7 +227,7 @@ esp_err_t spi_flash_chip_generic_write(esp_flash_t *chip, const void *buffer, ui
while (err == ESP_OK && length > 0) {
memset(temp_buffer, 0xFF, sizeof(temp_buffer));
uint32_t page_len = chip->host->write_data_slicer(address, length, &align_address, page_size);
uint32_t page_len = chip->host->driver->write_data_slicer(chip->host, address, length, &align_address, page_size);
uint32_t left_off = address - align_address;
uint32_t write_len = MIN(align_address + page_len, address + length) - address;
memcpy(temp_buffer + left_off, buffer, write_len);
@ -241,8 +241,8 @@ esp_err_t spi_flash_chip_generic_write(esp_flash_t *chip, const void *buffer, ui
length -= write_len;
}
}
if (err == ESP_OK && chip->host->flush_cache) {
err = chip->host->flush_cache(chip->host, address, length);
if (err == ESP_OK && chip->host->driver->flush_cache) {
err = chip->host->driver->flush_cache(chip->host, address, length);
}
return err;
}
@ -259,7 +259,7 @@ esp_err_t spi_flash_chip_generic_set_write_protect(esp_flash_t *chip, bool write
err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->idle_timeout);
if (err == ESP_OK) {
chip->host->set_write_protect(chip->host, write_protect);
chip->host->driver->set_write_protect(chip->host, write_protect);
}
bool wp_read;
@ -276,7 +276,7 @@ esp_err_t spi_flash_chip_generic_get_write_protect(esp_flash_t *chip, bool *out_
esp_err_t err = ESP_OK;
uint8_t status;
assert(out_write_protect!=NULL);
err = chip->host->read_status(chip->host, &status);
err = chip->host->driver->read_status(chip->host, &status);
if (err != ESP_OK) {
return err;
}
@ -287,7 +287,7 @@ esp_err_t spi_flash_chip_generic_get_write_protect(esp_flash_t *chip, bool *out_
esp_err_t spi_flash_generic_wait_host_idle(esp_flash_t *chip, uint32_t *timeout_us)
{
while (chip->host->host_idle(chip->host) && *timeout_us > 0) {
while (chip->host->driver->host_idle(chip->host) && *timeout_us > 0) {
#if HOST_DELAY_INTERVAL_US > 0
if (*timeout_us > 1) {
int delay = MIN(HOST_DELAY_INTERVAL_US, *timeout_us);
@ -314,7 +314,7 @@ esp_err_t spi_flash_chip_generic_wait_idle(esp_flash_t *chip, uint32_t timeout_u
return err;
}
err = chip->host->read_status(chip->host, &status);
err = chip->host->driver->read_status(chip->host, &status);
if (err != ESP_OK) {
return err;
}
@ -374,7 +374,7 @@ esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip)
return ESP_ERR_FLASH_NOT_INITIALISED;
}
return chip->host->configure_host_io_mode(chip->host, read_command, addr_bitlen, dummy_cyclelen_base,
return chip->host->driver->configure_host_io_mode(chip->host, read_command, addr_bitlen, dummy_cyclelen_base,
chip->read_mode);
}
@ -451,7 +451,7 @@ static esp_err_t spi_flash_common_read_qe_sr(esp_flash_t *chip, uint8_t qe_rdsr_
.miso_data = (uint8_t*) &sr_buf,
.miso_len = qe_sr_bitwidth / 8,
};
esp_err_t ret = chip->host->common_command(chip->host, &t);
esp_err_t ret = chip->host->driver->common_command(chip->host, &t);
*sr = sr_buf;
return ret;
}
@ -464,7 +464,7 @@ static esp_err_t spi_flash_common_write_qe_sr(esp_flash_t *chip, uint8_t qe_wrsr
.mosi_len = qe_sr_bitwidth / 8,
.miso_len = 0,
};
return chip->host->common_command(chip->host, &t);
return chip->host->driver->common_command(chip->host, &t);
}
esp_err_t spi_flash_common_read_status_16b_rdsr_rdsr2(esp_flash_t* chip, uint32_t* out_sr)

View File

@ -8,6 +8,7 @@
#include "esp_flash.h"
#include "driver/spi_common_internal.h"
#include "esp_flash_spi_init.h"
#include "memspi_host_driver.h"
#include <esp_attr.h>
#include "esp_log.h"
@ -18,7 +19,6 @@
#include "soc/io_mux_reg.h"
#include "sdkconfig.h"
#include "hal/spi_flash_hal.h"
#include "ccomp_timer.h"
#include "esp_rom_gpio.h"
@ -175,9 +175,9 @@ static void get_chip_host(esp_flash_t* chip, spi_host_device_t* out_host_id, int
host_id = SPI_HOST;
cs_id = 0;
} else {
spi_flash_memspi_data_t* driver_data = (spi_flash_memspi_data_t*)chip->host->driver_data;
host_id = spi_flash_ll_hw_get_id(driver_data->spi);
cs_id = driver_data->cs_num;
spi_flash_hal_context_t* host_data = (spi_flash_hal_context_t*)chip->host;
host_id = spi_flash_ll_hw_get_id(host_data->spi);
cs_id = host_data->cs_num;
}
if (out_host_id) {
*out_host_id = host_id;