1 /*
2  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*******************************************************************************
8  * NOTICE
9  * The ll is not public api, don't use in application code.
10  * See readme.md in hal/include/hal/readme.md
11  ******************************************************************************/
12 
13 #pragma once
14 
15 #include <stdint.h>
16 #include <stdbool.h>
17 #include <sys/param.h>
18 #include "esp_bit_defs.h"
19 #include "hal/assert.h"
20 #include "soc/soc.h"
21 #include "soc/spi_mem_reg.h"
22 #include "soc/io_mux_reg.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #undef ARRAY_SIZE
29 #define ARRAY_SIZE(arr) (sizeof((arr))/sizeof(*(arr)))
30 #define MSPI_TIMING_LL_FLASH_OCT_MASK                 (SPI_MEM_FCMD_OCT | SPI_MEM_FADDR_OCT | SPI_MEM_FDIN_OCT | SPI_MEM_FDOUT_OCT)
31 #define MSPI_TIMING_LL_FLASH_QUAD_MASK                (SPI_MEM_FASTRD_MODE | SPI_MEM_FREAD_DUAL | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_QIO)
32 #define MSPI_TIMING_LL_FLASH_QIO_MODE_MASK            (SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE)
33 #define MSPI_TIMING_LL_FLASH_QUAD_MODE_MASK           (SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE)
34 #define MSPI_TIMING_LL_FLASH_DIO_MODE_MASK            (SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE)
35 #define MSPI_TIMING_LL_FLASH_DUAL_MODE_MASK           (SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE)
36 #define MSPI_TIMING_LL_FLASH_FAST_MODE_MASK           (SPI_MEM_FASTRD_MODE)
37 #define MSPI_TIMING_LL_FLASH_SLOW_MODE_MASK           0
38 
39 typedef enum {
40     MSPI_TIMING_LL_FLASH_OPI_MODE = BIT(0),
41     MSPI_TIMING_LL_FLASH_QIO_MODE = BIT(1),
42     MSPI_TIMING_LL_FLASH_QUAD_MODE = BIT(2),
43     MSPI_TIMING_LL_FLASH_DIO_MODE = BIT(3),
44     MSPI_TIMING_LL_FLASH_DUAL_MODE = BIT(4),
45     MSPI_TIMING_LL_FLASH_FAST_MODE = BIT(5),
46     MSPI_TIMING_LL_FLASH_SLOW_MODE = BIT(6),
47 } mspi_timing_ll_flash_mode_t;
48 
49 /**
50  * Set all MSPI pin drive strength
51  *
52  * @param spi_num  SPI0 / SPI1
53  * @param val      Pin drive strength
54  */
55 __attribute__((always_inline))
mspi_timing_ll_set_all_pin_drive(uint8_t spi_num,uint32_t val)56 static inline void mspi_timing_ll_set_all_pin_drive(uint8_t spi_num, uint32_t val)
57 {
58     SET_PERI_REG_MASK(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPICLK_PAD_DRV_CTL_EN);
59     REG_SET_FIELD(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, val);
60     REG_SET_FIELD(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, val);
61 
62     uint32_t regs[] = {IO_MUX_GPIO27_REG, IO_MUX_GPIO28_REG,
63                        IO_MUX_GPIO31_REG, IO_MUX_GPIO32_REG,
64                        IO_MUX_GPIO33_REG, IO_MUX_GPIO34_REG,
65                        IO_MUX_GPIO35_REG, IO_MUX_GPIO36_REG,
66                        IO_MUX_GPIO37_REG};
67     for (int i = 0; i < ARRAY_SIZE(regs); i++) {
68         PIN_SET_DRV(regs[i], val);
69     }
70 }
71 
72 /**
73  * Set all MSPI Flash clock pin drive strength
74  *
75  * @param spi_num  SPI0 / SPI1
76  * @param val      Pin drive strength
77  */
78 __attribute__((always_inline))
mspi_timing_ll_set_flash_clock_pin_drive(uint8_t spi_num,uint32_t val)79 static inline void mspi_timing_ll_set_flash_clock_pin_drive(uint8_t spi_num, uint32_t val)
80 {
81     bool clk_pin_drive_control = GET_PERI_REG_MASK(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPICLK_PAD_DRV_CTL_EN);
82     //You should never call this function, while `mspi_timing_ll_set_all_pin_drive()` isn't called
83     HAL_ASSERT(clk_pin_drive_control);
84     REG_SET_FIELD(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPI_FMEM_SPICLK_FUN_DRV, val);
85 }
86 
87 /**
88  * Set all MSPI PSRAM clock pin drive strength
89  *
90  * @param spi_num  SPI0 / SPI1
91  * @param val      Pin drive strength
92  */
93 __attribute__((always_inline))
mspi_timing_ll_set_psram_clock_pin_drive(uint8_t spi_num,uint32_t val)94 static inline void mspi_timing_ll_set_psram_clock_pin_drive(uint8_t spi_num, uint32_t val)
95 {
96     bool clk_pin_drive_control = GET_PERI_REG_MASK(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPICLK_PAD_DRV_CTL_EN);
97     //You should never call this function, while `mspi_timing_ll_set_all_pin_drive()` isn't called
98     HAL_ASSERT(clk_pin_drive_control);
99     REG_SET_FIELD(SPI_MEM_DATE_REG(spi_num), SPI_MEM_SPI_SMEM_SPICLK_FUN_DRV, val);
100 }
101 
102 /**
103  * Enable Flash HCLK
104  *
105  * @param spi_num  SPI0 / SPI1
106  */
107 __attribute__((always_inline))
mspi_timinng_ll_enable_flash_hclk(uint8_t spi_num)108 static inline void mspi_timinng_ll_enable_flash_hclk(uint8_t spi_num)
109 {
110     REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CLK_ENA);
111 }
112 
113 /**
114  * Enable PSRAM HCLK
115  *
116  * @param spi_num  SPI0 / SPI1
117  */
118 __attribute__((always_inline))
mspi_timinng_ll_enable_psram_hclk(uint8_t spi_num)119 static inline void mspi_timinng_ll_enable_psram_hclk(uint8_t spi_num)
120 {
121     REG_SET_BIT(SPI_MEM_SPI_SMEM_TIMING_CALI_REG(spi_num), SPI_MEM_SPI_SMEM_TIMING_CLK_ENA);
122 }
123 
124 /**
125  * Enable/Disable Flash variable dummy
126  *
127  * @param spi_num  SPI0 / SPI1
128  * @param enable   Enable / Disable
129  */
130 __attribute__((always_inline))
mspi_timing_ll_enable_flash_variable_dummy(uint8_t spi_num,bool enable)131 static inline void mspi_timing_ll_enable_flash_variable_dummy(uint8_t spi_num, bool enable)
132 {
133     REG_SET_FIELD(SPI_MEM_DDR_REG(1), SPI_MEM_SPI_FMEM_VAR_DUMMY, enable);
134 }
135 
136 /**
137  * Set MSPI core clock divider
138  *
139  * @param spi_num  SPI0 / SPI1
140  * @param val      Divider value
141  */
142 __attribute__((always_inline))
mspi_timing_ll_set_core_clock_divider(uint8_t spi_num,uint32_t val)143 static inline void mspi_timing_ll_set_core_clock_divider(uint8_t spi_num, uint32_t val)
144 {
145     REG_SET_FIELD(SPI_MEM_CORE_CLK_SEL_REG(spi_num), SPI_MEM_CORE_CLK_SEL, val);
146 }
147 
148 /**
149  * Set MSPI Flash clock
150  *
151  * @param spi_num  SPI0 / SPI1
152  * @param freqdiv  Divider value
153  */
154 __attribute__((always_inline))
mspi_timing_ll_set_flash_clock(uint8_t spi_num,uint32_t freqdiv)155 static inline void mspi_timing_ll_set_flash_clock(uint8_t spi_num, uint32_t freqdiv)
156 {
157     if (freqdiv == 1) {
158         WRITE_PERI_REG(SPI_MEM_CLOCK_REG(spi_num), SPI_MEM_CLK_EQU_SYSCLK);
159     } else {
160         uint32_t freqbits = (((freqdiv - 1) << SPI_MEM_CLKCNT_N_S)) | (((freqdiv / 2 - 1) << SPI_MEM_CLKCNT_H_S)) | ((freqdiv - 1) << SPI_MEM_CLKCNT_L_S);
161         WRITE_PERI_REG(SPI_MEM_CLOCK_REG(spi_num), freqbits);
162     }
163 }
164 
165 /**
166  * Set MSPI PSRAM clock
167  *
168  * @param spi_num  SPI0 / SPI1
169  * @param freqdiv  Divider value
170  */
171 __attribute__((always_inline))
mspi_timing_ll_set_psram_clock(uint8_t spi_num,uint32_t freqdiv)172 static inline void mspi_timing_ll_set_psram_clock(uint8_t spi_num, uint32_t freqdiv)
173 {
174     if (freqdiv == 1) {
175         WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), SPI_MEM_SCLK_EQU_SYSCLK);
176     } else {
177         uint32_t freqbits = (((freqdiv-1)<<SPI_MEM_SCLKCNT_N_S)) | (((freqdiv/2-1)<<SPI_MEM_SCLKCNT_H_S)) | ((freqdiv-1)<<SPI_MEM_SCLKCNT_L_S);
178         WRITE_PERI_REG(SPI_MEM_SRAM_CLK_REG(spi_num), freqbits);
179     }
180 }
181 
182 /**
183  * Set MSPI Flash din mode
184  *
185  * @param spi_num   SPI0 / SPI1
186  * @param din_mode  Din mode value
187  */
188 __attribute__((always_inline))
mspi_timing_ll_set_flash_din_mode(uint8_t spi_num,uint8_t din_mode)189 static inline void mspi_timing_ll_set_flash_din_mode(uint8_t spi_num, uint8_t din_mode)
190 {
191     uint32_t reg_val = (REG_READ(SPI_MEM_DIN_MODE_REG(spi_num)) & (~(SPI_MEM_DIN0_MODE_M | SPI_MEM_DIN1_MODE_M | SPI_MEM_DIN2_MODE_M | SPI_MEM_DIN3_MODE_M | SPI_MEM_DIN4_MODE_M | SPI_MEM_DIN5_MODE_M | SPI_MEM_DIN6_MODE_M | SPI_MEM_DIN7_MODE_M | SPI_MEM_DINS_MODE_M)))
192         | (din_mode << SPI_MEM_DIN0_MODE_S) | (din_mode << SPI_MEM_DIN1_MODE_S) | (din_mode << SPI_MEM_DIN2_MODE_S) | (din_mode << SPI_MEM_DIN3_MODE_S)
193         | (din_mode << SPI_MEM_DIN4_MODE_S) | (din_mode << SPI_MEM_DIN5_MODE_S) | (din_mode << SPI_MEM_DIN6_MODE_S) | (din_mode << SPI_MEM_DIN7_MODE_S) | (din_mode << SPI_MEM_DINS_MODE_S);
194     REG_WRITE(SPI_MEM_DIN_MODE_REG(spi_num), reg_val);
195 }
196 
197 /**
198  * Set MSPI Flash din num
199  *
200  * @param spi_num   SPI0 / SPI1
201  * @param din_num  Din num value
202  */
203 __attribute__((always_inline))
mspi_timing_ll_set_flash_din_num(uint8_t spi_num,uint8_t din_num)204 static inline void mspi_timing_ll_set_flash_din_num(uint8_t spi_num, uint8_t din_num)
205 {
206     uint32_t reg_val = (REG_READ(SPI_MEM_DIN_NUM_REG(spi_num)) & (~(SPI_MEM_DIN0_NUM_M | SPI_MEM_DIN1_NUM_M | SPI_MEM_DIN2_NUM_M | SPI_MEM_DIN3_NUM_M | SPI_MEM_DIN4_NUM_M | SPI_MEM_DIN5_NUM_M | SPI_MEM_DIN6_NUM_M | SPI_MEM_DIN7_NUM_M | SPI_MEM_DINS_NUM_M)))
207         | (din_num << SPI_MEM_DIN0_NUM_S) | (din_num << SPI_MEM_DIN1_NUM_S) | (din_num << SPI_MEM_DIN2_NUM_S) | (din_num << SPI_MEM_DIN3_NUM_S)
208         | (din_num << SPI_MEM_DIN4_NUM_S) | (din_num << SPI_MEM_DIN5_NUM_S) | (din_num << SPI_MEM_DIN6_NUM_S) | (din_num << SPI_MEM_DIN7_NUM_S) | (din_num << SPI_MEM_DINS_NUM_S);
209     REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val);
210 }
211 
212 /**
213  * Get MSPI Flash mode
214  *
215  * @param spi_num   SPI0 / SPI1
216  *
217  * @return Flash mode
218  */
219 __attribute__((always_inline))
mspi_timing_ll_get_flash_mode(uint8_t spi_num)220 static inline mspi_timing_ll_flash_mode_t mspi_timing_ll_get_flash_mode(uint8_t spi_num)
221 {
222     uint32_t ctrl_reg = READ_PERI_REG(SPI_MEM_CTRL_REG(0));
223     if (ctrl_reg & MSPI_TIMING_LL_FLASH_OCT_MASK) {
224         return MSPI_TIMING_LL_FLASH_OPI_MODE;
225     }
226 
227     switch (ctrl_reg & MSPI_TIMING_LL_FLASH_QUAD_MASK) {
228         case MSPI_TIMING_LL_FLASH_QIO_MODE_MASK:
229             return MSPI_TIMING_LL_FLASH_QIO_MODE;
230         case MSPI_TIMING_LL_FLASH_QUAD_MODE_MASK:
231             return MSPI_TIMING_LL_FLASH_QUAD_MODE;
232         case MSPI_TIMING_LL_FLASH_DIO_MODE_MASK:
233             return MSPI_TIMING_LL_FLASH_DIO_MODE;
234         case MSPI_TIMING_LL_FLASH_DUAL_MODE_MASK:
235             return MSPI_TIMING_LL_FLASH_DUAL_MODE;
236         case MSPI_TIMING_LL_FLASH_FAST_MODE_MASK:
237             return MSPI_TIMING_LL_FLASH_FAST_MODE;
238         case MSPI_TIMING_LL_FLASH_SLOW_MODE_MASK:
239             return MSPI_TIMING_LL_FLASH_SLOW_MODE;
240         default:
241             HAL_ASSERT(false);
242             return 0;
243     }
244 
245 }
246 
247 /**
248  * Set MSPI Octal Flash extra dummy
249  *
250  * @param spi_num      SPI0 / SPI1
251  * @param extra_dummy  Extra dummy
252  */
253 __attribute__((always_inline))
mspi_timing_ll_set_octal_flash_extra_dummy(uint8_t spi_num,uint8_t extra_dummy)254 static inline void mspi_timing_ll_set_octal_flash_extra_dummy(uint8_t spi_num, uint8_t extra_dummy)
255 {
256     if (extra_dummy > 0) {
257         SET_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M);
258         SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy,
259             SPI_MEM_EXTRA_DUMMY_CYCLELEN_S);
260     } else {
261         CLEAR_PERI_REG_MASK(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_M);
262         SET_PERI_REG_BITS(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_EXTRA_DUMMY_CYCLELEN_V, 0,
263             SPI_MEM_EXTRA_DUMMY_CYCLELEN_S);
264     }
265 }
266 
267 /**
268  * Set MSPI Quad Flash dummy
269  *
270  * @param spi_num    SPI0 / SPI1
271  * @param dummy      dummy
272  */
273 __attribute__((always_inline))
mspi_timing_ll_set_quad_flash_dummy(uint8_t spi_num,uint8_t dummy)274 static inline void mspi_timing_ll_set_quad_flash_dummy(uint8_t spi_num, uint8_t dummy)
275 {
276     //HW workaround: Use normal dummy register to set extra dummy, the calibration dedicated extra dummy register doesn't work for quad mode
277     SET_PERI_REG_MASK(SPI_MEM_USER_REG(spi_num), SPI_MEM_USR_DUMMY);
278     SET_PERI_REG_BITS(SPI_MEM_USER1_REG(spi_num), SPI_MEM_USR_DUMMY_CYCLELEN_V, dummy, SPI_MEM_USR_DUMMY_CYCLELEN_S);
279 }
280 
281 /**
282  * Set MSPI PSRAM din mode
283  *
284  * @param spi_num   SPI0 / SPI1
285  * @param din_mode  Din mode value
286  */
287 __attribute__((always_inline))
mspi_timing_ll_set_psram_din_mode(uint8_t spi_num,uint8_t din_mode)288 static inline void mspi_timing_ll_set_psram_din_mode(uint8_t spi_num, uint8_t din_mode)
289 {
290     uint32_t reg_val = (REG_READ(SPI_MEM_SPI_SMEM_DIN_MODE_REG(spi_num)) & (~(SPI_MEM_SPI_SMEM_DIN0_MODE_M | SPI_MEM_SPI_SMEM_DIN1_MODE_M | SPI_MEM_SPI_SMEM_DIN2_MODE_M | SPI_MEM_SPI_SMEM_DIN3_MODE_M | SPI_MEM_SPI_SMEM_DIN4_MODE_M | SPI_MEM_SPI_SMEM_DIN5_MODE_M | SPI_MEM_SPI_SMEM_DIN6_MODE_M | SPI_MEM_SPI_SMEM_DIN7_MODE_M | SPI_MEM_SPI_SMEM_DINS_MODE_M)))
291         | (din_mode << SPI_MEM_SPI_SMEM_DIN0_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN1_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN2_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN3_MODE_S)
292         | (din_mode << SPI_MEM_SPI_SMEM_DIN4_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN5_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN6_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DIN7_MODE_S) | (din_mode << SPI_MEM_SPI_SMEM_DINS_MODE_S);
293     REG_WRITE(SPI_MEM_SPI_SMEM_DIN_MODE_REG(spi_num), reg_val);
294 }
295 
296 /**
297  * Set MSPI PSRAM din num
298  *
299  * @param spi_num   SPI0 / SPI1
300  * @param din_num  Din num value
301  */
302 __attribute__((always_inline))
mspi_timing_ll_set_psram_din_num(uint8_t spi_num,uint8_t din_num)303 static inline void mspi_timing_ll_set_psram_din_num(uint8_t spi_num, uint8_t din_num)
304 {
305     uint32_t reg_val = (REG_READ(SPI_MEM_SPI_SMEM_DIN_NUM_REG(spi_num)) & (~(SPI_MEM_SPI_SMEM_DIN0_NUM_M | SPI_MEM_SPI_SMEM_DIN1_NUM_M | SPI_MEM_SPI_SMEM_DIN2_NUM_M | SPI_MEM_SPI_SMEM_DIN3_NUM_M | SPI_MEM_SPI_SMEM_DIN4_NUM_M | SPI_MEM_SPI_SMEM_DIN5_NUM_M | SPI_MEM_SPI_SMEM_DIN6_NUM_M | SPI_MEM_SPI_SMEM_DIN7_NUM_M | SPI_MEM_SPI_SMEM_DINS_NUM_M)))
306         | (din_num << SPI_MEM_SPI_SMEM_DIN0_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN1_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN2_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN3_NUM_S)
307         | (din_num << SPI_MEM_SPI_SMEM_DIN4_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN5_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN6_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DIN7_NUM_S) | (din_num << SPI_MEM_SPI_SMEM_DINS_NUM_S);
308     REG_WRITE(SPI_MEM_SPI_SMEM_DIN_NUM_REG(spi_num), reg_val);
309 }
310 
311 /**
312  * Set MSPI Octal PSRAM extra dummy
313  *
314  * @param spi_num      SPI0 / SPI1
315  * @param extra_dummy  Extra dummy
316  */
317 __attribute__((always_inline))
mspi_timing_ll_set_octal_psram_extra_dummy(uint8_t spi_num,uint8_t extra_dummy)318 static inline void mspi_timing_ll_set_octal_psram_extra_dummy(uint8_t spi_num, uint8_t extra_dummy)
319 {
320     if (extra_dummy > 0) {
321         SET_PERI_REG_MASK(SPI_MEM_SPI_SMEM_TIMING_CALI_REG(spi_num), SPI_MEM_SPI_SMEM_TIMING_CALI_M);
322         SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_TIMING_CALI_REG(spi_num), SPI_MEM_SPI_SMEM_EXTRA_DUMMY_CYCLELEN_V, extra_dummy,
323             SPI_MEM_SPI_SMEM_EXTRA_DUMMY_CYCLELEN_S);
324     } else {
325         CLEAR_PERI_REG_MASK(SPI_MEM_SPI_SMEM_TIMING_CALI_REG(spi_num), SPI_MEM_SPI_SMEM_TIMING_CALI_M);
326         SET_PERI_REG_BITS(SPI_MEM_SPI_SMEM_TIMING_CALI_REG(spi_num), SPI_MEM_SPI_SMEM_EXTRA_DUMMY_CYCLELEN_V, 0,
327             SPI_MEM_SPI_SMEM_EXTRA_DUMMY_CYCLELEN_S);
328     }
329 }
330 
331 /**
332  * Set MSPI Octal PSRAM dummy
333  *
334  * @param spi_num    SPI0 / SPI1
335  * @param dummy      dummy
336  */
337 __attribute__((always_inline))
mspi_timing_ll_set_quad_psram_dummy(uint8_t spi_num,uint8_t dummy)338 static inline void mspi_timing_ll_set_quad_psram_dummy(uint8_t spi_num, uint8_t dummy)
339 {
340     //HW workaround: Use normal dummy register to set extra dummy, the calibration dedicated extra dummy register doesn't work for quad mode
341     SET_PERI_REG_MASK(SPI_MEM_CACHE_SCTRL_REG(spi_num), SPI_MEM_USR_RD_SRAM_DUMMY_M);
342     SET_PERI_REG_BITS(SPI_MEM_CACHE_SCTRL_REG(spi_num), SPI_MEM_SRAM_RDUMMY_CYCLELEN_V, dummy, SPI_MEM_SRAM_RDUMMY_CYCLELEN_S);
343 }
344 
345 /**
346  * Clear MSPI hw fifo
347  *
348  * @param spi_num    SPI0 / SPI1
349  */
350 __attribute__((always_inline))
mspi_timing_ll_clear_fifo(uint8_t spi_num)351 static inline void mspi_timing_ll_clear_fifo(uint8_t spi_num)
352 {
353     for (int i = 0; i < 16; i++) {
354         REG_WRITE(SPI_MEM_W0_REG(spi_num) + i*4, 0);
355     }
356 }
357 
358 /**
359  * Get if cs setup is enabled or not
360  *
361  * @param spi_num    SPI0 / SPI1
362  *
363  * @return
364  *        true: enabled; false: disabled
365  */
366 __attribute__((always_inline))
mspi_timing_ll_is_cs_setup_enabled(uint8_t spi_num)367 static inline bool mspi_timing_ll_is_cs_setup_enabled(uint8_t spi_num)
368 {
369     return REG_GET_BIT(SPI_MEM_USER_REG(spi_num), SPI_MEM_CS_SETUP);
370 }
371 
372 /**
373  * Get cs setup val
374  *
375  * @param spi_num    SPI0 / SPI1
376  *
377  * @return
378  *        cs setup reg val
379  */
mspi_timing_ll_get_cs_setup_val(uint8_t spi_num)380 static inline uint32_t mspi_timing_ll_get_cs_setup_val(uint8_t spi_num)
381 {
382     return REG_GET_FIELD(SPI_MEM_CTRL2_REG(spi_num), SPI_MEM_CS_SETUP_TIME);
383 }
384 
385 /**
386  * Get if cs hold is enabled or not
387  *
388  * @param spi_num    SPI0 / SPI1
389  *
390  * @return
391  *        true: enabled; false: disabled
392  */
393 __attribute__((always_inline))
mspi_timing_ll_is_cs_hold_enabled(uint8_t spi_num)394 static inline bool mspi_timing_ll_is_cs_hold_enabled(uint8_t spi_num)
395 {
396     return REG_GET_BIT(SPI_MEM_USER_REG(spi_num), SPI_MEM_CS_HOLD);
397 }
398 
399 /**
400  * Get cs hold val
401  *
402  * @param spi_num    SPI0 / SPI1
403  *
404  * @return
405  *        cs hold reg val
406  */
mspi_timing_ll_get_cs_hold_val(uint8_t spi_num)407 static inline uint32_t mspi_timing_ll_get_cs_hold_val(uint8_t spi_num)
408 {
409     return REG_GET_FIELD(SPI_MEM_CTRL2_REG(spi_num), SPI_MEM_CS_HOLD_TIME);
410 }
411 
412 /**
413  * Get clock reg val
414  *
415  * @param spi_num    SPI0 / SPI1
416  *
417  * @return
418  *        clock reg val
419  */
420 __attribute__((always_inline))
mspi_timing_ll_get_clock_reg(uint8_t spi_num)421 static inline uint32_t mspi_timing_ll_get_clock_reg(uint8_t spi_num)
422 {
423     return READ_PERI_REG(SPI_MEM_CLOCK_REG(spi_num));
424 }
425 
426 #ifdef __cplusplus
427 }
428 #endif
429