1 /*
2  * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*******************************************************************************
8  * NOTICE
9  * The HAL is not public api, don't use in application code.
10  * See readme.md in hal/include/hal/readme.md
11  ******************************************************************************/
12 
13 // The HAL layer for SPI Flash (common part)
14 
15 #pragma once
16 
17 #include "hal/spi_flash_ll.h"
18 #include "hal/spi_types.h"
19 #include "hal/spi_flash_types.h"
20 #include "esp_assert.h"
21 
22 /* Hardware host-specific constants */
23 #define SPI_FLASH_HAL_MAX_WRITE_BYTES 64
24 #define SPI_FLASH_HAL_MAX_READ_BYTES 64
25 
26 /**
27  * Generic driver context structure for all chips using the SPI peripheral.
28  * Include this into the HEAD of the driver data for other driver
29  * implementations that also use the SPI peripheral.
30  */
31 typedef struct {
32     spi_flash_host_inst_t inst; ///< Host instance, containing host data and function pointer table. May update with the host (hardware version).
33     spi_dev_t *spi;             ///< Pointer to SPI peripheral registers (SP1, SPI2 or SPI3). Set before initialisation.
34     int cs_num;                 ///< Which cs pin is used, 0-2.
35     struct {
36         uint8_t extra_dummy;            ///< Pre-calculated extra dummy used for compensation
37         uint8_t cs_setup;               ///< (cycles-1) of prepare phase by spi clock.
38         uint8_t cs_hold;                ///< CS hold time config used by the host
39         uint8_t reserved2;              ///< Reserved, set to 0.
40     };
41     spi_flash_ll_clock_reg_t clock_conf;    ///< Pre-calculated clock configuration value
42     esp_flash_io_mode_t base_io_mode;       ///< Default IO mode mask for common commands
43     uint32_t flags;             ///< Flags for configurations with one set of driver code. (e.g. QPI mode, auto-suspend mode, 64-bit address mode, etc.)
44 #define SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND         BIT(0)  ///< When the auto-suspend is setup in configuration.
45 #define SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_RESUME          BIT(1)  ///< Setup auto-resume feature.
46 #define SPI_FLASH_HOST_CONTEXT_FLAG_OCTAL_MODE           BIT(2)  ///< Flash works under octal spi mode.
47     spi_flash_sus_cmd_conf sus_cfg;        ///< To store suspend command/mask information.
48     uint32_t slicer_flags;      /// Slicer flags for configuring how to slice data correctly while reading or writing.
49 #define SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR           BIT(0)  ///< Slice data according to DTR mode, the address and length must be even (A0=0).
50 } spi_flash_hal_context_t;
51 ESP_STATIC_ASSERT(sizeof(spi_flash_hal_context_t) == 40, "size of spi_flash_hal_context_t incorrect. Please check data compatibility with the ROM");
52 
53 /// This struct provide MSPI Flash necessary timing related config, should be consistent with that in union in `spi_flash_hal_config_t`.
54 typedef struct {
55     uint32_t extra_dummy;
56     uint32_t cs_hold;
57     uint8_t cs_setup;
58     spi_flash_ll_clock_reg_t clock_config;
59 } spi_flash_hal_timing_config_t;
60 
61 /// Configuration structure for the SPI driver.
62 typedef struct {
63     union {
64         struct {
65             uint32_t extra_dummy;   ///< extra dummy for timing compensation.
66             uint32_t cs_hold;       ///< CS hold time config used by the host
67             uint8_t cs_setup;       ///< (cycles-1) of prepare phase by spi clock
68             spi_flash_ll_clock_reg_t clock_config;  ///< (optional) Clock configuration for Octal flash.
69         };
70         spi_flash_hal_timing_config_t timing_reg;  ///< Reconfigure timing tuning regs.
71     };
72     bool iomux;             ///< Whether the IOMUX is used, used for timing compensation.
73     int input_delay_ns;     ///< Input delay on the MISO pin after the launch clock, used for timing compensation.
74     enum esp_flash_speed_s speed __attribute__((deprecated));      ///< SPI flash clock speed to work at. Replaced by freq_mhz
75     spi_host_device_t host_id;            ///< SPI peripheral ID.
76     int cs_num;             ///< Which cs pin is used, 0-(SOC_SPI_PERIPH_CS_NUM-1).
77     bool auto_sus_en;       ///< Auto suspend feature enable bit 1: enable, 0: disable.
78     bool octal_mode_en;     ///< Octal spi flash mode enable bit 1: enable, 0: disable.
79     bool using_timing_tuning;               ///< System exist SPI0/1 timing tuning, using value from system directely if set to 1.
80     esp_flash_io_mode_t default_io_mode;        ///< Default flash io mode.
81     int freq_mhz;         ///< SPI flash clock speed (MHZ).
82     int clock_src_freq;    ///< SPI flash clock source (MHZ).
83 } spi_flash_hal_config_t;
84 
85 /**
86  * Configure SPI flash hal settings.
87  *
88  * @param data Buffer to hold configured data, the buffer should be in DRAM to be available when cache disabled
89  * @param cfg Configurations to set
90  *
91  * @return
92  *      - ESP_OK: success
93  *      - ESP_ERR_INVALID_ARG: the data buffer is not in the DRAM.
94  */
95 esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_hal_config_t *cfg);
96 
97 /**
98  * Configure the device-related register before transactions.
99  *
100  * @param host The driver context.
101  *
102  * @return always return ESP_OK.
103  */
104 esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host);
105 
106 /**
107  * Send an user-defined spi transaction to the device.
108  *
109  * @note This is usually used when the memspi interface doesn't support some
110  *      particular commands. Since this function supports timing compensation, it is
111  *      also used to receive some data when the frequency is high.
112  *
113  * @param host The driver context.
114  * @param trans The transaction to send, also holds the received data.
115  *
116  * @return always return ESP_OK.
117  */
118 esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans);
119 
120 /**
121  * Erase whole flash chip by using the erase chip (C7h) command.
122  *
123  * @param host The driver context.
124  */
125 void spi_flash_hal_erase_chip(spi_flash_host_inst_t *host);
126 
127 /**
128  * Erase a specific sector by its start address through the sector erase (20h)
129  * command. For 24bit address only.
130  *
131  * @param host The driver context.
132  * @param start_address Start address of the sector to erase.
133  */
134 void spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address);
135 
136 /**
137  * Erase a specific 64KB block by its start address through the 64KB block
138  * erase (D8h) command. For 24bit address only.
139  *
140  * @param host The driver context.
141  * @param start_address Start address of the block to erase.
142  */
143 void spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address);
144 
145 /**
146  * Program a page of the flash using the page program (02h) command. For 24bit address only.
147  *
148  * @param host The driver context.
149  * @param address Address of the page to program
150  * @param buffer Data to program
151  * @param length Size of the buffer in bytes, no larger than ``SPI_FLASH_HAL_MAX_WRITE_BYTES`` (64) bytes.
152  */
153 void spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length);
154 
155 /**
156  * Read from the flash. Call ``spi_flash_hal_configure_host_read_mode`` to
157  * configure the read command before calling this function.
158  *
159  * @param host The driver context.
160  * @param buffer Buffer to store the read data
161  * @param address Address to read
162  * @param length Length to read, no larger than ``SPI_FLASH_HAL_MAX_READ_BYTES`` (64) bytes.
163  *
164  * @return always return ESP_OK.
165  */
166 esp_err_t spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len);
167 
168 /**
169  * @brief Send the write enable (06h) or write disable (04h) command to the flash chip.
170  *
171  * @param driver The driver context.
172  * @param wp true to enable the write protection, otherwise false.
173  *
174  * @return always return ESP_OK.
175  */
176 esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp);
177 
178 /**
179  * Check whether the SPI host is idle and can perform other operations.
180  *
181  * @param host The driver context.
182  *
183  * @return 0:busy, 1:idle, 2:suspended.
184  */
185 uint32_t spi_flash_hal_check_status(spi_flash_host_inst_t *host);
186 
187 /**
188  * @brief Configure the SPI host hardware registers for the specified io mode.
189  *
190  *  Note that calling this configures SPI host registers, so if running any
191  *  other commands as part of set_io_mode() then these must be run before
192  *  calling this function.
193  *
194  *  The command value, address length and dummy cycles are configured according
195  *  to the format of read commands:
196  *
197  *  - command: 8 bits, value set.
198  *  - address: 24 bits
199  *  - dummy: cycles to compensate the input delay
200  *  - out & in data: 0 bits.
201  *
202  *  The following commands still need to:
203  *
204  *  - Read data: set address value and data (length and contents), no need
205  *    to touch command and dummy phases.
206  *  - Common read: set command value, address value (or length to 0 if not used)
207  *  - Common write: set command value, address value (or length to 0 if not
208  *    used), disable dummy phase, and set output data.
209  *
210  * @param host The driver context
211  * @param io_mode The HW read mode to use
212  * @param addr_bitlen Length of the address phase, in bits
213  * @param dummy_cyclelen_base Base cycles of the dummy phase, some extra dummy cycles may be appended to compensate the timing.
214  * @param command  Actual reading command to send to flash chip on the bus.
215  *
216  * @return always return ESP_OK.
217  */
218 esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_inst_t *host, uint32_t command, uint32_t addr_bitlen,
219                                                int dummy_cyclelen_base, esp_flash_io_mode_t io_mode);
220 
221 /**
222  * Poll until the last operation is done.
223  *
224  * @param host The driver context.
225  */
226 void spi_flash_hal_poll_cmd_done(spi_flash_host_inst_t *host);
227 
228 /**
229  * 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
230  * regions that are accessible ith cache disabled. *
231  *
232  * @param host The driver context
233  * @param p The buffer holding data to send.
234  *
235  * @return True if the buffer can be used to send data, otherwise false.
236  */
237 bool spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p);
238 
239 /**
240  * 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
241  * regions that are accessible ith cache disabled. *
242  *
243  * @param host The driver context
244  * @param p The buffer to hold the received data.
245  *
246  * @return True if the buffer can be used to receive data, otherwise false.
247  */
248 bool spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p);
249 
250 /**
251  * @brief Resume flash chip status from suspend.
252  *
253  * @param host The driver context.
254  *
255  */
256 void spi_flash_hal_resume(spi_flash_host_inst_t *host);
257 
258 /**
259  * @brief Set the flash into suspend status manually.
260  *
261  * @param host The driver context.
262  *
263  */
264 void spi_flash_hal_suspend(spi_flash_host_inst_t *host);
265 
266 /**
267  * To setup for reading flash suspend status register
268  *
269  * @param host The driver context.
270  * @param sus_conf Flash chip suspend feature configuration, mainly for command config, may vary from chip to chip.
271  *
272  * @return Always ESP_OK
273  */
274 esp_err_t spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf);
275