mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
parent
f99ba33920
commit
c796bd5e63
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user