Skip to content

Commit 79a5b0b

Browse files
committed
Merge branch 'feat/esp_flash_data_slicer' into 'master'
esp_flash: refactor to be compatible with the latest ROM Closes IDF-1664 and IDFGH-2074 See merge request espressif/esp-idf!8565
2 parents 81bfba0 + c796bd5 commit 79a5b0b

20 files changed

+600
-383
lines changed

components/soc/include/hal/spi_flash_hal.h

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@
3737
* implementations that also use the SPI peripheral.
3838
*/
3939
typedef struct {
40+
spi_flash_host_inst_t inst; ///< Host instance, containing host data and function pointer table. May update with the host (hardware version).
4041
spi_dev_t *spi; ///< Pointer to SPI peripheral registers (SP1, SPI2 or SPI3). Set before initialisation.
4142
int cs_num; ///< Which cs pin is used, 0-2.
42-
int extra_dummy;
43-
spi_flash_ll_clock_reg_t clock_conf;
44-
} spi_flash_memspi_data_t;
43+
int extra_dummy; ///< Pre-calculated extra dummy used for compensation
44+
spi_flash_ll_clock_reg_t clock_conf; ///< Pre-calculated clock configuration value
45+
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.)
46+
} spi_flash_hal_context_t;
4547

4648
/// Configuration structure for the SPI driver.
4749
typedef struct {
@@ -50,7 +52,7 @@ typedef struct {
5052
bool iomux; ///< Whether the IOMUX is used, used for timing compensation.
5153
int input_delay_ns; ///< Input delay on the MISO pin after the launch clock, used for timing compensation.
5254
esp_flash_speed_t speed;///< SPI flash clock speed to work at.
53-
} spi_flash_memspi_config_t;
55+
} spi_flash_hal_config_t;
5456

5557
/**
5658
* Configure SPI flash hal settings.
@@ -62,16 +64,16 @@ typedef struct {
6264
* - ESP_OK: success
6365
* - ESP_ERR_INVALID_ARG: the data buffer is not in the DRAM.
6466
*/
65-
esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_memspi_config_t *cfg);
67+
esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_hal_config_t *cfg);
6668

6769
/**
6870
* Configure the device-related register before transactions.
6971
*
70-
* @param driver The driver context.
72+
* @param host The driver context.
7173
*
7274
* @return always return ESP_OK.
7375
*/
74-
esp_err_t spi_flash_hal_device_config(spi_flash_host_driver_t *driver);
76+
esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host);
7577

7678
/**
7779
* 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);
8082
* particular commands. Since this function supports timing compensation, it is
8183
* also used to receive some data when the frequency is high.
8284
*
83-
* @param driver The driver context.
85+
* @param host The driver context.
8486
* @param trans The transaction to send, also holds the received data.
8587
*
8688
* @return always return ESP_OK.
8789
*/
88-
esp_err_t spi_flash_hal_common_command(spi_flash_host_driver_t *driver, spi_flash_trans_t *trans);
90+
esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
8991

9092
/**
9193
* Erase whole flash chip by using the erase chip (C7h) command.
9294
*
93-
* @param driver The driver context.
95+
* @param host The driver context.
9496
*/
95-
void spi_flash_hal_erase_chip(spi_flash_host_driver_t *driver);
97+
void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host);
9698

9799
/**
98100
* Erase a specific sector by its start address through the sector erase (20h)
99101
* command.
100102
*
101-
* @param driver The driver context.
103+
* @param host The driver context.
102104
* @param start_address Start address of the sector to erase.
103105
*/
104-
void spi_flash_hal_erase_sector(spi_flash_host_driver_t *driver, uint32_t start_address);
106+
void spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address);
105107

106108
/**
107109
* Erase a specific 64KB block by its start address through the 64KB block
108110
* erase (D8h) command.
109111
*
110-
* @param driver The driver context.
112+
* @param host The driver context.
111113
* @param start_address Start address of the block to erase.
112114
*/
113-
void spi_flash_hal_erase_block(spi_flash_host_driver_t *driver, uint32_t start_address);
115+
void spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address);
114116

115117
/**
116118
* Program a page of the flash using the page program (02h) command.
117119
*
118-
* @param driver The driver context.
120+
* @param host The driver context.
119121
* @param address Address of the page to program
120122
* @param buffer Data to program
121123
* @param length Size of the buffer in bytes, no larger than ``SPI_FLASH_HAL_MAX_WRITE_BYTES`` (64) bytes.
122124
*/
123-
void spi_flash_hal_program_page(spi_flash_host_driver_t *driver, const void *buffer, uint32_t address, uint32_t length);
125+
void spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
124126

125127
/**
126128
* Read from the flash. Call ``spi_flash_hal_configure_host_read_mode`` to
127129
* configure the read command before calling this function.
128130
*
129-
* @param driver The driver context.
131+
* @param host The driver context.
130132
* @param buffer Buffer to store the read data
131133
* @param address Address to read
132134
* @param length Length to read, no larger than ``SPI_FLASH_HAL_MAX_READ_BYTES`` (64) bytes.
133135
*
134136
* @return always return ESP_OK.
135137
*/
136-
esp_err_t spi_flash_hal_read(spi_flash_host_driver_t *driver, void *buffer, uint32_t address, uint32_t read_len);
138+
esp_err_t spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
137139

138140
/**
139141
* @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
143145
*
144146
* @return always return ESP_OK.
145147
*/
146-
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_driver_t *chip_drv, bool wp);
148+
esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp);
147149

148150
/**
149151
* Check whether the SPI host is idle and can perform other operations.
150152
*
151-
* @param driver The driver context.
153+
* @param host The driver context.
152154
*
153155
* @return ture if idle, otherwise false.
154156
*/
155-
bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver);
157+
bool spi_flash_hal_host_idle(spi_flash_host_inst_t *host);
156158

157159
/**
158160
* @brief Configure the SPI host hardware registers for the specified io mode.
@@ -177,42 +179,42 @@ bool spi_flash_hal_host_idle(spi_flash_host_driver_t *driver);
177179
* - Common write: set command value, address value (or length to 0 if not
178180
* used), disable dummy phase, and set output data.
179181
*
180-
* @param driver The driver context
182+
* @param host The driver context
181183
* @param io_mode The HW read mode to use
182184
* @param addr_bitlen Length of the address phase, in bits
183185
* @param dummy_cyclelen_base Base cycles of the dummy phase, some extra dummy cycles may be appended to compensate the timing.
184186
* @param command Actual reading command to send to flash chip on the bus.
185187
*
186188
* @return always return ESP_OK.
187189
*/
188-
esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_driver_t *driver, uint32_t command, uint32_t addr_bitlen,
190+
esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_inst_t *host, uint32_t command, uint32_t addr_bitlen,
189191
int dummy_cyclelen_base, esp_flash_io_mode_t io_mode);
190192

191193
/**
192194
* Poll until the last operation is done.
193195
*
194-
* @param driver The driver context.
196+
* @param host The driver context.
195197
*/
196-
void spi_flash_hal_poll_cmd_done(spi_flash_host_driver_t *driver);
198+
void spi_flash_hal_poll_cmd_done(spi_flash_host_inst_t *host);
197199

198200
/**
199201
* 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
200202
* regions that are accessible ith cache disabled. *
201203
*
202-
* @param driver The driver context
204+
* @param host The driver context
203205
* @param p The buffer holding data to send.
204206
*
205207
* @return True if the buffer can be used to send data, otherwise false.
206208
*/
207-
bool spi_flash_hal_supports_direct_write(spi_flash_host_driver_t *driver, const void *p);
209+
bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
208210

209211
/**
210212
* 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
211213
* regions that are accessible ith cache disabled. *
212214
*
213-
* @param driver The driver context
215+
* @param host The driver context
214216
* @param p The buffer to hold the received data.
215217
*
216218
* @return True if the buffer can be used to receive data, otherwise false.
217219
*/
218-
bool spi_flash_hal_supports_direct_read(spi_flash_host_driver_t *driver, const void *p);
220+
bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p);

components/soc/include/hal/spi_flash_types.h

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -68,84 +68,105 @@ typedef enum {
6868
///Slowest io mode supported by ESP32, currently SlowRd
6969
#define SPI_FLASH_READ_MODE_MIN SPI_FLASH_SLOWRD
7070

71-
struct spi_flash_host_driver_t;
72-
typedef struct spi_flash_host_driver_t spi_flash_host_driver_t;
71+
struct spi_flash_host_driver_s;
72+
typedef struct spi_flash_host_driver_s spi_flash_host_driver_t;
73+
74+
/** SPI Flash Host driver instance */
75+
typedef struct {
76+
const struct spi_flash_host_driver_s* driver; ///< Pointer to the implementation function table
77+
// Implementations can wrap this structure into their own ones, and append other data here
78+
} spi_flash_host_inst_t ;
79+
7380

7481
/** Host driver configuration and context structure. */
75-
struct spi_flash_host_driver_t {
76-
/**
77-
* Configuration and static data used by the specific host driver. The type
78-
* is determined by the host driver.
79-
*/
80-
void *driver_data;
82+
struct spi_flash_host_driver_s {
8183
/**
8284
* Configure the device-related register before transactions. This saves
8385
* some time to re-configure those registers when we send continuously
8486
*/
85-
esp_err_t (*dev_config)(spi_flash_host_driver_t *driver);
87+
esp_err_t (*dev_config)(spi_flash_host_inst_t *host);
8688
/**
8789
* Send an user-defined spi transaction to the device.
8890
*/
89-
esp_err_t (*common_command)(spi_flash_host_driver_t *driver, spi_flash_trans_t *t);
91+
esp_err_t (*common_command)(spi_flash_host_inst_t *host, spi_flash_trans_t *t);
9092
/**
9193
* Read flash ID.
9294
*/
93-
esp_err_t (*read_id)(spi_flash_host_driver_t *driver, uint32_t *id);
95+
esp_err_t (*read_id)(spi_flash_host_inst_t *host, uint32_t *id);
9496
/**
9597
* Erase whole flash chip.
9698
*/
97-
void (*erase_chip)(spi_flash_host_driver_t *driver);
99+
void (*erase_chip)(spi_flash_host_inst_t *host);
98100
/**
99101
* Erase a specific sector by its start address.
100102
*/
101-
void (*erase_sector)(spi_flash_host_driver_t *driver, uint32_t start_address);
103+
void (*erase_sector)(spi_flash_host_inst_t *host, uint32_t start_address);
102104
/**
103105
* Erase a specific block by its start address.
104106
*/
105-
void (*erase_block)(spi_flash_host_driver_t *driver, uint32_t start_address);
107+
void (*erase_block)(spi_flash_host_inst_t *host, uint32_t start_address);
106108
/**
107109
* Read the status of the flash chip.
108110
*/
109-
esp_err_t (*read_status)(spi_flash_host_driver_t *driver, uint8_t *out_sr);
111+
esp_err_t (*read_status)(spi_flash_host_inst_t *host, uint8_t *out_sr);
110112
/**
111113
* Disable write protection.
112114
*/
113-
esp_err_t (*set_write_protect)(spi_flash_host_driver_t *driver, bool wp);
115+
esp_err_t (*set_write_protect)(spi_flash_host_inst_t *host, bool wp);
114116
/**
115117
* Program a page of the flash. Check ``max_write_bytes`` for the maximum allowed writing length.
116118
*/
117-
void (*program_page)(spi_flash_host_driver_t *driver, const void *buffer, uint32_t address, uint32_t length);
118-
/** Check whether need to allocate new buffer to write */
119-
bool (*supports_direct_write)(spi_flash_host_driver_t *driver, const void *p);
120-
/** Check whether need to allocate new buffer to read */
121-
bool (*supports_direct_read)(spi_flash_host_driver_t *driver, const void *p);
122-
/** maximum length of program_page */
123-
int max_write_bytes;
119+
void (*program_page)(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
120+
/** Check whether given buffer can be directly used to write */
121+
bool (*supports_direct_write)(spi_flash_host_inst_t *host, const void *p);
122+
/**
123+
* Slicer for write data. The `program_page` should be called iteratively with the return value
124+
* of this function.
125+
*
126+
* @param address Beginning flash address to write
127+
* @param len Length request to write
128+
* @param align_addr Output of the aligned address to write to
129+
* @param page_size Physical page size of the flash chip
130+
* @return Length that can be actually written in one `program_page` call
131+
*/
132+
int (*write_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr,
133+
uint32_t page_size);
124134
/**
125135
* Read data from the flash. Check ``max_read_bytes`` for the maximum allowed reading length.
126136
*/
127-
esp_err_t (*read)(spi_flash_host_driver_t *driver, void *buffer, uint32_t address, uint32_t read_len);
128-
/** maximum length of read */
129-
int max_read_bytes;
137+
esp_err_t (*read)(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
138+
/** Check whether given buffer can be directly used to read */
139+
bool (*supports_direct_read)(spi_flash_host_inst_t *host, const void *p);
140+
/**
141+
* Slicer for read data. The `read` should be called iteratively with the return value
142+
* of this function.
143+
*
144+
* @param address Beginning flash address to read
145+
* @param len Length request to read
146+
* @param align_addr Output of the aligned address to read
147+
* @param page_size Physical page size of the flash chip
148+
* @return Length that can be actually read in one `read` call
149+
*/
150+
int (*read_data_slicer)(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_addr, uint32_t page_size);
130151
/**
131152
* Check whether the host is idle to perform new operations.
132153
*/
133-
bool (*host_idle)(spi_flash_host_driver_t *driver);
154+
bool (*host_idle)(spi_flash_host_inst_t *host);
134155
/**
135156
* Configure the host to work at different read mode. Responsible to compensate the timing and set IO mode.
136157
*/
137-
esp_err_t (*configure_host_io_mode)(spi_flash_host_driver_t *driver, uint32_t command,
158+
esp_err_t (*configure_host_io_mode)(spi_flash_host_inst_t *host, uint32_t command,
138159
uint32_t addr_bitlen, int dummy_bitlen_base,
139160
esp_flash_io_mode_t io_mode);
140161
/**
141162
* Internal use, poll the HW until the last operation is done.
142163
*/
143-
void (*poll_cmd_done)(spi_flash_host_driver_t *driver);
164+
void (*poll_cmd_done)(spi_flash_host_inst_t *host);
144165
/**
145166
* For some host (SPI1), they are shared with a cache. When the data is
146167
* modified, the cache needs to be flushed. Left NULL if not supported.
147168
*/
148-
esp_err_t (*flush_cache)(spi_flash_host_driver_t* driver, uint32_t addr, uint32_t size);
169+
esp_err_t (*flush_cache)(spi_flash_host_inst_t* host, uint32_t addr, uint32_t size);
149170
};
150171

151172
#ifdef __cplusplus

components/soc/src/hal/spi_flash_hal.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static inline int get_dummy_n(bool gpio_is_used, int input_delay_ns, int eff_clk
6363
return apb_period_n / apbclk_n;
6464
}
6565

66-
esp_err_t spi_flash_hal_init(spi_flash_memspi_data_t *data_out, const spi_flash_memspi_config_t *cfg)
66+
esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_hal_config_t *cfg)
6767
{
6868
if (!esp_ptr_internal(data_out)) {
6969
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_
7777
}
7878
#endif
7979

80-
*data_out = (spi_flash_memspi_data_t) {
80+
*data_out = (spi_flash_hal_context_t) {
81+
.inst = data_out->inst, // Keeps the function pointer table
8182
.spi = spi_flash_ll_get_hw(cfg->host_id),
8283
.cs_num = cfg->cs_num,
8384
.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_
8889
return ESP_OK;
8990
}
9091

91-
bool spi_flash_hal_supports_direct_write(spi_flash_host_driver_t *host, const void *p)
92+
bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
9293
{
93-
bool direct_write = ( ((spi_flash_memspi_data_t *)host->driver_data)->spi != spi_flash_ll_get_hw(SPI_HOST)
94+
bool direct_write = ( ((spi_flash_hal_context_t *)host)->spi != spi_flash_ll_get_hw(SPI_HOST)
9495
|| esp_ptr_in_dram(p) );
9596
return direct_write;
9697
}
9798

9899

99-
bool spi_flash_hal_supports_direct_read(spi_flash_host_driver_t *host, const void *p)
100+
bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
100101
{
101102
//currently the host doesn't support to read through dma, no word-aligned requirements
102-
bool direct_read = ( ((spi_flash_memspi_data_t *)host->driver_data)->spi != spi_flash_ll_get_hw(SPI_HOST)
103+
bool direct_read = ( ((spi_flash_hal_context_t *)host)->spi != spi_flash_ll_get_hw(SPI_HOST)
103104
|| esp_ptr_in_dram(p) );
104105
return direct_read;
105106
}

0 commit comments

Comments
 (0)