1 /*
2  * SPDX-FileCopyrightText: 2015-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 LL layer for ESP32-S3 SPI register operations
14 
15 #pragma once
16 
17 #include <stdlib.h> //for abs()
18 #include <string.h>
19 #include "esp_attr.h"
20 #include "esp_types.h"
21 #include "soc/spi_periph.h"
22 #include "soc/spi_struct.h"
23 #include "soc/lldesc.h"
24 #include "hal/assert.h"
25 #include "hal/misc.h"
26 #include "hal/spi_types.h"
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /// Interrupt not used. Don't use in app.
33 #define SPI_LL_UNUSED_INT_MASK  (SPI_TRANS_DONE_INT_ENA | SPI_SLV_WR_DMA_DONE_INT_ENA | SPI_SLV_RD_DMA_DONE_INT_ENA | SPI_SLV_WR_BUF_DONE_INT_ENA | SPI_SLV_RD_BUF_DONE_INT_ENA)
34 /// These 2 masks together will set SPI transaction to one line mode
35 #define SPI_LL_ONE_LINE_CTRL_MASK (SPI_FREAD_OCT | SPI_FREAD_QUAD | SPI_FREAD_DUAL | SPI_FCMD_OCT | \
36         SPI_FCMD_QUAD | SPI_FCMD_DUAL | SPI_FADDR_OCT | SPI_FADDR_QUAD | SPI_FADDR_DUAL)
37 #define SPI_LL_ONE_LINE_USER_MASK (SPI_FWRITE_OCT | SPI_FWRITE_QUAD | SPI_FWRITE_DUAL)
38 
39 /// Swap the bit order to its correct place to send
40 #define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len))
41 /// This is the expected clock frequency
42 #define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
43 #define SPI_LL_GET_HW(ID) ((ID)==0? ({abort();NULL;}):((ID)==1? &GPSPI2 : &GPSPI3))
44 
45 /**
46  * The data structure holding calculated clock configuration. Since the
47  * calculation needs long time, it should be calculated during initialization and
48  * stored somewhere to be quickly used.
49  */
50 typedef uint32_t spi_ll_clock_val_t;
51 typedef spi_dev_t spi_dma_dev_t;
52 
53 // Type definition of all supported interrupts
54 typedef enum {
55     SPI_LL_INTR_TRANS_DONE =    BIT(0),     ///< A transaction has done
56     SPI_LL_INTR_RDBUF =         BIT(6),     ///< Has received RDBUF command. Only available in slave HD.
57     SPI_LL_INTR_WRBUF =         BIT(7),     ///< Has received WRBUF command. Only available in slave HD.
58     SPI_LL_INTR_RDDMA =         BIT(8),     ///< Has received RDDMA command. Only available in slave HD.
59     SPI_LL_INTR_WRDMA =         BIT(9),     ///< Has received WRDMA command. Only available in slave HD.
60     SPI_LL_INTR_CMD7 =          BIT(10),    ///< Has received CMD7 command. Only available in slave HD.
61     SPI_LL_INTR_CMD8 =          BIT(11),    ///< Has received CMD8 command. Only available in slave HD.
62     SPI_LL_INTR_CMD9 =          BIT(12),    ///< Has received CMD9 command. Only available in slave HD.
63     SPI_LL_INTR_CMDA =          BIT(13),    ///< Has received CMDA command. Only available in slave HD.
64     SPI_LL_INTR_SEG_DONE =      BIT(14),
65 } spi_ll_intr_t;
66 FLAG_ATTR(spi_ll_intr_t)
67 
68 // Flags for conditions under which the transaction length should be recorded
69 typedef enum {
70     SPI_LL_TRANS_LEN_COND_WRBUF =   BIT(0), ///< WRBUF length will be recorded
71     SPI_LL_TRANS_LEN_COND_RDBUF =   BIT(1), ///< RDBUF length will be recorded
72     SPI_LL_TRANS_LEN_COND_WRDMA =   BIT(2), ///< WRDMA length will be recorded
73     SPI_LL_TRANS_LEN_COND_RDDMA =   BIT(3), ///< RDDMA length will be recorded
74 } spi_ll_trans_len_cond_t;
FLAG_ATTR(spi_ll_trans_len_cond_t)75 FLAG_ATTR(spi_ll_trans_len_cond_t)
76 
77 /*------------------------------------------------------------------------------
78  * Control
79  *----------------------------------------------------------------------------*/
80 /**
81  * Initialize SPI peripheral (master).
82  *
83  * @param hw Beginning address of the peripheral registers.
84  */
85 static inline void spi_ll_master_init(spi_dev_t *hw)
86 {
87     //Reset timing
88     hw->user1.cs_setup_time = 0;
89     hw->user1.cs_hold_time = 0;
90 
91     //use all 64 bytes of the buffer
92     hw->user.usr_miso_highpart = 0;
93     hw->user.usr_mosi_highpart = 0;
94 
95     //Disable unneeded ints
96     hw->slave.val = 0;
97     hw->user.val = 0;
98 
99     hw->clk_gate.clk_en = 1;
100     hw->clk_gate.mst_clk_active = 1;
101     hw->clk_gate.mst_clk_sel = 1;
102 
103     hw->dma_conf.val = 0;
104     hw->dma_conf.tx_seg_trans_clr_en = 1;
105     hw->dma_conf.rx_seg_trans_clr_en = 1;
106     hw->dma_conf.dma_seg_trans_en = 0;
107 }
108 
109 /**
110  * Initialize SPI peripheral (slave).
111  *
112  * @param hw Beginning address of the peripheral registers.
113  */
spi_ll_slave_init(spi_dev_t * hw)114 static inline void spi_ll_slave_init(spi_dev_t *hw)
115 {
116     //Configure slave
117     hw->clock.val = 0;
118     hw->user.val = 0;
119     hw->ctrl.val = 0;
120     hw->user.doutdin = 1; //we only support full duplex
121     hw->user.sio = 0;
122     hw->slave.slave_mode = 1;
123     hw->slave.soft_reset = 1;
124     hw->slave.soft_reset = 0;
125     //use all 64 bytes of the buffer
126     hw->user.usr_miso_highpart = 0;
127     hw->user.usr_mosi_highpart = 0;
128 
129     // Configure DMA In-Link to not be terminated when transaction bit counter exceeds
130     hw->dma_conf.rx_eof_en = 0;
131     hw->dma_conf.dma_seg_trans_en = 0;
132 
133     //Disable unneeded ints
134     hw->dma_int_ena.val &= ~SPI_LL_UNUSED_INT_MASK;
135 }
136 
137 /**
138  * Initialize SPI peripheral (slave half duplex mode)
139  *
140  * @param hw Beginning address of the peripheral registers.
141  */
spi_ll_slave_hd_init(spi_dev_t * hw)142 static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
143 {
144     hw->clock.val = 0;
145     hw->user.val = 0;
146     hw->ctrl.val = 0;
147     hw->user.doutdin = 0;
148     hw->user.sio = 0;
149 
150     hw->slave.soft_reset = 1;
151     hw->slave.soft_reset = 0;
152     hw->slave.slave_mode = 1;
153 }
154 
155 /**
156  * Check whether user-defined transaction is done.
157  *
158  * @param hw Beginning address of the peripheral registers.
159  *
160  * @return   True if transaction is done, otherwise false.
161  */
spi_ll_usr_is_done(spi_dev_t * hw)162 static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
163 {
164     return hw->dma_int_raw.trans_done;
165 }
166 
167 /**
168  * Trigger start of user-defined transaction for master.
169  * The synchronization between two clock domains is required in ESP32-S3
170  *
171  * @param hw Beginning address of the peripheral registers.
172  */
spi_ll_master_user_start(spi_dev_t * hw)173 static inline void spi_ll_master_user_start(spi_dev_t *hw)
174 {
175     hw->cmd.update = 1;
176     while (hw->cmd.update);
177     hw->cmd.usr = 1;
178 }
179 
180 /**
181  * Trigger start of user-defined transaction for slave.
182  *
183  * @param hw Beginning address of the peripheral registers.
184  */
spi_ll_slave_user_start(spi_dev_t * hw)185 static inline void spi_ll_slave_user_start(spi_dev_t *hw)
186 {
187     hw->cmd.usr = 1;
188 }
189 
190 /**
191  * Get current running command bit-mask. (Preview)
192  *
193  * @param hw Beginning address of the peripheral registers.
194  *
195  * @return   Bitmask of running command, see ``SPI_CMD_REG``. 0 if no in-flight command.
196  */
spi_ll_get_running_cmd(spi_dev_t * hw)197 static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
198 {
199     return hw->cmd.val;
200 }
201 
202 /**
203  * Reset the slave peripheral before next transaction.
204  *
205  * @param hw Beginning address of the peripheral registers.
206  */
spi_ll_slave_reset(spi_dev_t * hw)207 static inline void spi_ll_slave_reset(spi_dev_t *hw)
208 {
209     hw->slave.soft_reset = 1;
210     hw->slave.soft_reset = 0;
211 }
212 
213 /**
214  * Reset SPI CPU TX FIFO
215  *
216  * On ESP32S3, this function is not seperated
217  *
218  * @param hw Beginning address of the peripheral registers.
219  */
spi_ll_cpu_tx_fifo_reset(spi_dev_t * hw)220 static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw)
221 {
222     hw->dma_conf.buf_afifo_rst = 1;
223     hw->dma_conf.buf_afifo_rst = 0;
224 }
225 
226 /**
227  * Reset SPI CPU RX FIFO
228  *
229  * On ESP32S3, this function is not seperated
230  *
231  * @param hw Beginning address of the peripheral registers.
232  */
spi_ll_cpu_rx_fifo_reset(spi_dev_t * hw)233 static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw)
234 {
235     hw->dma_conf.rx_afifo_rst = 1;
236     hw->dma_conf.rx_afifo_rst = 0;
237 }
238 
239 /**
240  * Reset SPI DMA TX FIFO
241  *
242  * @param hw Beginning address of the peripheral registers.
243  */
spi_ll_dma_tx_fifo_reset(spi_dev_t * hw)244 static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw)
245 {
246     hw->dma_conf.dma_afifo_rst = 1;
247     hw->dma_conf.dma_afifo_rst = 0;
248 }
249 
250 /**
251  * Reset SPI DMA RX FIFO
252  *
253  * @param hw Beginning address of the peripheral registers.
254  */
spi_ll_dma_rx_fifo_reset(spi_dev_t * hw)255 static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw)
256 {
257     hw->dma_conf.rx_afifo_rst = 1;
258     hw->dma_conf.rx_afifo_rst = 0;
259 }
260 
261 /**
262  * Clear in fifo full error
263  *
264  * @param hw Beginning address of the peripheral registers.
265  */
spi_ll_infifo_full_clr(spi_dev_t * hw)266 static inline void spi_ll_infifo_full_clr(spi_dev_t *hw)
267 {
268     hw->dma_int_clr.infifo_full_err = 1;
269 }
270 
271 /**
272  * Clear out fifo empty error
273  *
274  * @param hw Beginning address of the peripheral registers.
275  */
spi_ll_outfifo_empty_clr(spi_dev_t * hw)276 static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw)
277 {
278     hw->dma_int_clr.outfifo_empty_err = 1;
279 }
280 
281 /*------------------------------------------------------------------------------
282  * DMA
283  *----------------------------------------------------------------------------*/
284 /**
285  * Enable/Disable RX DMA (Peripherals->DMA->RAM)
286  *
287  * @param hw     Beginning address of the peripheral registers.
288  * @param enable 1: enable; 2: disable
289  */
spi_ll_dma_rx_enable(spi_dev_t * hw,bool enable)290 static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable)
291 {
292     hw->dma_conf.dma_rx_ena = enable;
293 }
294 
295 /**
296  * Enable/Disable TX DMA (RAM->DMA->Peripherals)
297  *
298  * @param hw     Beginning address of the peripheral registers.
299  * @param enable 1: enable; 2: disable
300  */
spi_ll_dma_tx_enable(spi_dev_t * hw,bool enable)301 static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable)
302 {
303     hw->dma_conf.dma_tx_ena = enable;
304 }
305 
306 /**
307  * Configuration of RX DMA EOF interrupt generation way
308  *
309  * @param hw     Beginning address of the peripheral registers.
310  * @param enable 1: spi_dma_inlink_eof is set when the number of dma pushed data bytes is equal to the value of spi_slv/mst_dma_rd_bytelen[19:0] in spi dma transition.  0: spi_dma_inlink_eof is set by spi_trans_done in non-seg-trans or spi_dma_seg_trans_done in seg-trans.
311  */
spi_ll_dma_set_rx_eof_generation(spi_dev_t * hw,bool enable)312 static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable)
313 {
314     hw->dma_conf.rx_eof_en = enable;
315 }
316 
317 /*------------------------------------------------------------------------------
318  * Buffer
319  *----------------------------------------------------------------------------*/
320 /**
321  * Write to SPI hardware data buffer.
322  *
323  * @param hw             Beginning address of the peripheral registers.
324  * @param buffer_to_send Address of the data to be written to the hardware data buffer.
325  * @param bitlen         Length to write, in bits.
326  */
spi_ll_write_buffer(spi_dev_t * hw,const uint8_t * buffer_to_send,size_t bitlen)327 static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen)
328 {
329     for (size_t x = 0; x < bitlen; x += 32) {
330         //Use memcpy to get around alignment issues for txdata
331         uint32_t word;
332         memcpy(&word, &buffer_to_send[x / 8], 4);
333         hw->data_buf[(x / 32)] = word;
334     }
335 }
336 
337 /**
338  * Write to SPI hardware data buffer by buffer ID (address)
339  *
340  * @param hw      Beginning address of the peripheral registers
341  * @param byte_id Start ID (address) of the hardware buffer to be written
342  * @param data    Address of the data to be written to the hardware data buffer.
343  * @param len     Length to write, in bytes.
344  */
spi_ll_write_buffer_byte(spi_dev_t * hw,int byte_id,uint8_t * data,int len)345 static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
346 {
347     HAL_ASSERT(byte_id + len <= 64);
348     HAL_ASSERT(len > 0);
349     HAL_ASSERT(byte_id >= 0);
350 
351     while (len > 0) {
352         uint32_t word;
353         int offset = byte_id % 4;
354         int copy_len = 4 - offset;
355         if (copy_len > len) {
356             copy_len = len;
357         }
358 
359         //read-modify-write
360         if (copy_len != 4) {
361             word = hw->data_buf[byte_id / 4];    //read
362         }
363         memcpy(((uint8_t *)&word) + offset, data, copy_len);  //modify
364         hw->data_buf[byte_id / 4] = word;                     //write
365 
366         data += copy_len;
367         byte_id += copy_len;
368         len -= copy_len;
369     }
370 }
371 
372 /**
373  * Read from SPI hardware data buffer.
374  *
375  * @param hw            Beginning address of the peripheral registers.
376  * @param buffer_to_rcv Address of a buffer to read data from hardware data buffer
377  * @param bitlen        Length to read, in bits.
378  */
spi_ll_read_buffer(spi_dev_t * hw,uint8_t * buffer_to_rcv,size_t bitlen)379 static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen)
380 {
381     for (size_t x = 0; x < bitlen; x += 32) {
382         //Do a memcpy to get around possible alignment issues in rx_buffer
383         uint32_t word = hw->data_buf[x / 32];
384         int len = bitlen - x;
385         if (len > 32) {
386             len = 32;
387         }
388         memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8);
389     }
390 }
391 
392 /**
393  * Read from SPI hardware data buffer by buffer ID (address)
394  *
395  * @param hw      Beginning address of the peripheral registers
396  * @param byte_id Start ID (address) of the hardware buffer to be read
397  * @param data    Address of a buffer to read data from hardware data buffer
398  * @param len     Length to read, in bytes.
399  */
spi_ll_read_buffer_byte(spi_dev_t * hw,int byte_id,uint8_t * out_data,int len)400 static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *out_data, int len)
401 {
402     while (len > 0) {
403         uint32_t word = hw->data_buf[byte_id / 4];
404         int offset = byte_id % 4;
405         int copy_len = 4 - offset;
406         if (copy_len > len) {
407             copy_len = len;
408         }
409 
410         memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
411         byte_id += copy_len;
412         out_data += copy_len;
413         len -= copy_len;
414     }
415 }
416 
417 /*------------------------------------------------------------------------------
418  * Configs: mode
419  *----------------------------------------------------------------------------*/
420 /**
421  * Enable/disable the postive-cs feature.
422  *
423  * @param hw     Beginning address of the peripheral registers.
424  * @param cs     One of the CS (0-2) to enable/disable the feature.
425  * @param pos_cs True to enable the feature, otherwise disable (default).
426  */
spi_ll_master_set_pos_cs(spi_dev_t * hw,int cs,uint32_t pos_cs)427 static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs)
428 {
429     if (pos_cs) {
430         hw->misc.master_cs_pol |= (1 << cs);
431     } else {
432         hw->misc.master_cs_pol &= ~(1 << cs);
433     }
434 }
435 
436 /**
437  * Enable/disable the LSBFIRST feature for TX data.
438  *
439  * @param hw       Beginning address of the peripheral registers.
440  * @param lsbfirst True if LSB of TX data to be sent first, otherwise MSB is sent first (default).
441  */
spi_ll_set_tx_lsbfirst(spi_dev_t * hw,bool lsbfirst)442 static inline void spi_ll_set_tx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
443 {
444     hw->ctrl.wr_bit_order = lsbfirst;
445 }
446 
447 /**
448  * Enable/disable the LSBFIRST feature for RX data.
449  *
450  * @param hw       Beginning address of the peripheral registers.
451  * @param lsbfirst True if first bit received as LSB, otherwise as MSB (default).
452  */
spi_ll_set_rx_lsbfirst(spi_dev_t * hw,bool lsbfirst)453 static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
454 {
455     hw->ctrl.rd_bit_order = lsbfirst;
456 }
457 
458 /**
459  * Set SPI mode for the peripheral as master.
460  *
461  * @param hw   Beginning address of the peripheral registers.
462  * @param mode SPI mode to work at, 0-3.
463  */
spi_ll_master_set_mode(spi_dev_t * hw,uint8_t mode)464 static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode)
465 {
466     //Configure polarity
467     if (mode == 0) {
468         hw->misc.ck_idle_edge = 0;
469         hw->user.ck_out_edge = 0;
470     } else if (mode == 1) {
471         hw->misc.ck_idle_edge = 0;
472         hw->user.ck_out_edge = 1;
473     } else if (mode == 2) {
474         hw->misc.ck_idle_edge = 1;
475         hw->user.ck_out_edge = 1;
476     } else if (mode == 3) {
477         hw->misc.ck_idle_edge = 1;
478         hw->user.ck_out_edge = 0;
479     }
480 }
481 
482 /**
483  * Set SPI mode for the peripheral as slave.
484  *
485  * @param hw   Beginning address of the peripheral registers.
486  * @param mode SPI mode to work at, 0-3.
487  */
spi_ll_slave_set_mode(spi_dev_t * hw,const int mode,bool dma_used)488 static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used)
489 {
490     if (mode == 0) {
491         hw->misc.ck_idle_edge = 0;
492         hw->user.rsck_i_edge = 0;
493         hw->user.tsck_i_edge = 0;
494         hw->slave.clk_mode_13 = 0;
495     } else if (mode == 1) {
496         hw->misc.ck_idle_edge = 0;
497         hw->user.rsck_i_edge = 1;
498         hw->user.tsck_i_edge = 1;
499         hw->slave.clk_mode_13 = 1;
500     } else if (mode == 2) {
501         hw->misc.ck_idle_edge = 1;
502         hw->user.rsck_i_edge = 1;
503         hw->user.tsck_i_edge = 1;
504         hw->slave.clk_mode_13 = 0;
505     } else if (mode == 3) {
506         hw->misc.ck_idle_edge = 1;
507         hw->user.rsck_i_edge = 0;
508         hw->user.tsck_i_edge = 0;
509         hw->slave.clk_mode_13 = 1;
510     }
511     hw->slave.rsck_data_out = 0;
512 }
513 
514 /**
515  * Set SPI to work in full duplex or half duplex mode.
516  *
517  * @param hw          Beginning address of the peripheral registers.
518  * @param half_duplex True to work in half duplex mode, otherwise in full duplex mode.
519  */
spi_ll_set_half_duplex(spi_dev_t * hw,bool half_duplex)520 static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex)
521 {
522     hw->user.doutdin = !half_duplex;
523 }
524 
525 /**
526  * Set SPI to work in SIO mode or not.
527  *
528  * SIO is a mode which MOSI and MISO share a line. The device MUST work in half-duplexmode.
529  *
530  * @param hw       Beginning address of the peripheral registers.
531  * @param sio_mode True to work in SIO mode, otherwise false.
532  */
spi_ll_set_sio_mode(spi_dev_t * hw,int sio_mode)533 static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
534 {
535     hw->user.sio = sio_mode;
536 }
537 
538 /**
539  * Configure the SPI transaction line mode for the master to use.
540  *
541  * @param hw        Beginning address of the peripheral registers.
542  * @param line_mode SPI transaction line mode to use, see ``spi_line_mode_t``.
543  */
spi_ll_master_set_line_mode(spi_dev_t * hw,spi_line_mode_t line_mode)544 static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t line_mode)
545 {
546     hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK;
547     hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK;
548     hw->ctrl.fcmd_dual = (line_mode.cmd_lines == 2);
549     hw->ctrl.fcmd_quad = (line_mode.cmd_lines == 4);
550     hw->ctrl.fcmd_oct = (line_mode.cmd_lines == 8);
551     hw->ctrl.faddr_dual = (line_mode.addr_lines == 2);
552     hw->ctrl.faddr_quad = (line_mode.addr_lines == 4);
553     hw->ctrl.faddr_oct = (line_mode.addr_lines == 8);
554     hw->ctrl.fread_dual = (line_mode.data_lines == 2);
555     hw->user.fwrite_dual = (line_mode.data_lines == 2);
556     hw->ctrl.fread_quad = (line_mode.data_lines == 4);
557     hw->user.fwrite_quad = (line_mode.data_lines == 4);
558     hw->ctrl.fread_oct = (line_mode.data_lines == 8);
559     hw->user.fwrite_oct = (line_mode.data_lines == 8);
560 }
561 
562 /**
563  * Set the SPI slave to work in segment transaction mode
564  *
565  * @param hw        Beginning address of the peripheral registers.
566  * @param seg_trans True to work in seg mode, otherwise false.
567  */
spi_ll_slave_set_seg_mode(spi_dev_t * hw,bool seg_trans)568 static inline void spi_ll_slave_set_seg_mode(spi_dev_t *hw, bool seg_trans)
569 {
570     hw->dma_conf.dma_seg_trans_en = seg_trans;
571 }
572 
573 /**
574  * Select one of the CS to use in current transaction.
575  *
576  * @param hw    Beginning address of the peripheral registers.
577  * @param cs_id The cs to use, 0-2, otherwise none of them is used.
578  */
spi_ll_master_select_cs(spi_dev_t * hw,int cs_id)579 static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
580 {
581     if (hw == &GPSPI2) {
582         hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1;
583         hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1;
584         hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1;
585         hw->misc.cs3_dis = (cs_id == 3) ? 0 : 1;
586         hw->misc.cs4_dis = (cs_id == 4) ? 0 : 1;
587         hw->misc.cs5_dis = (cs_id == 5) ? 0 : 1;
588     }
589 
590     if (hw == &GPSPI3) {
591         hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1;
592         hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1;
593         hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1;
594     }
595 }
596 
597 /**
598  * Keep Chip Select activated after the current transaction.
599  *
600  * @param hw Beginning address of the peripheral registers.
601  * @param keep_active if 0 don't keep CS activated, else keep CS activated
602  */
spi_ll_master_keep_cs(spi_dev_t * hw,int keep_active)603 static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
604 {
605     hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0;
606 }
607 
608 /*------------------------------------------------------------------------------
609  * Configs: parameters
610  *----------------------------------------------------------------------------*/
611 /**
612  * Set the clock for master by stored value.
613  *
614  * @param hw  Beginning address of the peripheral registers.
615  * @param val Stored clock configuration calculated before (by ``spi_ll_cal_clock``).
616  */
spi_ll_master_set_clock_by_reg(spi_dev_t * hw,const spi_ll_clock_val_t * val)617 static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_clock_val_t *val)
618 {
619     hw->clock.val = *(uint32_t *)val;
620 }
621 
622 /**
623  * Get the frequency of given dividers. Don't use in app.
624  *
625  * @param fapb APB clock of the system.
626  * @param pre  Pre devider.
627  * @param n    Main divider.
628  *
629  * @return     Frequency of given dividers.
630  */
spi_ll_freq_for_pre_n(int fapb,int pre,int n)631 static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
632 {
633     return (fapb / (pre * n));
634 }
635 
636 /**
637  * Calculate the nearest frequency avaliable for master.
638  *
639  * @param fapb       APB clock of the system.
640  * @param hz         Frequncy desired.
641  * @param duty_cycle Duty cycle desired.
642  * @param out_reg    Output address to store the calculated clock configurations for the return frequency.
643  *
644  * @return           Actual (nearest) frequency.
645  */
spi_ll_master_cal_clock(int fapb,int hz,int duty_cycle,spi_ll_clock_val_t * out_reg)646 static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
647 {
648     __typeof__(GPSPI2.clock) reg;
649     int eff_clk;
650 
651     //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
652     if (hz > ((fapb / 4) * 3)) {
653         //Using Fapb directly will give us the best result here.
654         reg.clkcnt_l = 0;
655         reg.clkcnt_h = 0;
656         reg.clkcnt_n = 0;
657         reg.clkdiv_pre = 0;
658         reg.clk_equ_sysclk = 1;
659         eff_clk = fapb;
660     } else {
661         //For best duty cycle resolution, we want n to be as close to 32 as possible, but
662         //we also need a pre/n combo that gets us as close as possible to the intended freq.
663         //To do this, we bruteforce n and calculate the best pre to go along with that.
664         //If there's a choice between pre/n combos that give the same result, use the one
665         //with the higher n.
666         int pre, n, h, l;
667         int bestn = -1;
668         int bestpre = -1;
669         int besterr = 0;
670         int errval;
671         for (n = 2; n <= 64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse.
672             //Effectively, this does pre=round((fapb/n)/hz).
673             pre = ((fapb / n) + (hz / 2)) / hz;
674             if (pre <= 0) {
675                 pre = 1;
676             }
677             if (pre > 8192) {
678                 pre = 8192;
679             }
680             errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz);
681             if (bestn == -1 || errval <= besterr) {
682                 besterr = errval;
683                 bestn = n;
684                 bestpre = pre;
685             }
686         }
687 
688         n = bestn;
689         pre = bestpre;
690         l = n;
691         //This effectively does round((duty_cycle*n)/256)
692         h = (duty_cycle * n + 127) / 256;
693         if (h <= 0) {
694             h = 1;
695         }
696 
697         reg.clk_equ_sysclk = 0;
698         reg.clkcnt_n = n - 1;
699         reg.clkdiv_pre = pre - 1;
700         reg.clkcnt_h = h - 1;
701         reg.clkcnt_l = l - 1;
702         eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n);
703     }
704     if (out_reg != NULL) {
705         *(uint32_t *)out_reg = reg.val;
706     }
707     return eff_clk;
708 }
709 
710 /**
711  * Calculate and set clock for SPI master according to desired parameters.
712  *
713  * This takes long, suggest to calculate the configuration during
714  * initialization by ``spi_ll_master_cal_clock`` and store the result, then
715  * configure the clock by stored value when used by
716  * ``spi_ll_msater_set_clock_by_reg``.
717  *
718  * @param hw         Beginning address of the peripheral registers.
719  * @param fapb       APB clock of the system.
720  * @param hz         Frequncy desired.
721  * @param duty_cycle Duty cycle desired.
722  *
723  * @return           Actual frequency that is used.
724  */
spi_ll_master_set_clock(spi_dev_t * hw,int fapb,int hz,int duty_cycle)725 static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle)
726 {
727     spi_ll_clock_val_t reg_val;
728     int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, &reg_val);
729     spi_ll_master_set_clock_by_reg(hw, &reg_val);
730     return freq;
731 }
732 
733 /**
734  * Set the mosi delay after the output edge to the signal. (Preview)
735  *
736  * The delay mode/num is a Espressif conception, may change in the new chips.
737  *
738  * @param hw         Beginning address of the peripheral registers.
739  * @param delay_mode Delay mode, see TRM.
740  * @param delay_num  APB clocks to delay.
741  */
spi_ll_set_mosi_delay(spi_dev_t * hw,int delay_mode,int delay_num)742 static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int delay_num)
743 {
744 }
745 
746 /**
747  * Set the miso delay applied to the input signal before the internal peripheral. (Preview)
748  *
749  * The delay mode/num is a Espressif conception, may change in the new chips.
750  *
751  * @param hw         Beginning address of the peripheral registers.
752  * @param delay_mode Delay mode, see TRM.
753  * @param delay_num  APB clocks to delay.
754  */
spi_ll_set_miso_delay(spi_dev_t * hw,int delay_mode,int delay_num)755 static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int delay_num)
756 {
757 }
758 
759 /**
760  * Set the delay of SPI clocks before the CS inactive edge after the last SPI clock.
761  *
762  * @param hw   Beginning address of the peripheral registers.
763  * @param hold Delay of SPI clocks after the last clock, 0 to disable the hold phase.
764  */
spi_ll_master_set_cs_hold(spi_dev_t * hw,int hold)765 static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold)
766 {
767     hw->user1.cs_hold_time = hold;
768     hw->user.cs_hold = hold ? 1 : 0;
769 }
770 
771 /**
772  * Set the delay of SPI clocks before the first SPI clock after the CS active edge.
773  *
774  * Note ESP32 doesn't support to use this feature when command/address phases
775  * are used in full duplex mode.
776  *
777  * @param hw    Beginning address of the peripheral registers.
778  * @param setup Delay of SPI clocks after the CS active edge, 0 to disable the setup phase.
779  */
spi_ll_master_set_cs_setup(spi_dev_t * hw,uint8_t setup)780 static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup)
781 {
782     hw->user1.cs_setup_time = setup - 1;
783     hw->user.cs_setup = setup ? 1 : 0;
784 }
785 
786 /*------------------------------------------------------------------------------
787  * Configs: data
788  *----------------------------------------------------------------------------*/
789 /**
790  * Set the output length (master).
791  * This should be called before master setting MISO(input) length
792  *
793  * @param hw     Beginning address of the peripheral registers.
794  * @param bitlen output length, in bits.
795  */
spi_ll_set_mosi_bitlen(spi_dev_t * hw,size_t bitlen)796 static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
797 {
798     if (bitlen > 0) {
799         hw->ms_dlen.ms_data_bitlen = bitlen - 1;
800     }
801 }
802 
803 /**
804  * Set the input length (master).
805  *
806  * @param hw     Beginning address of the peripheral registers.
807  * @param bitlen input length, in bits.
808  */
spi_ll_set_miso_bitlen(spi_dev_t * hw,size_t bitlen)809 static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen)
810 {
811     if (bitlen > 0) {
812         hw->ms_dlen.ms_data_bitlen = bitlen - 1;
813     }
814 }
815 
816 /**
817  * Set the maximum input length (slave).
818  *
819  * @param hw     Beginning address of the peripheral registers.
820  * @param bitlen Input length, in bits.
821  */
spi_ll_slave_set_rx_bitlen(spi_dev_t * hw,size_t bitlen)822 static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
823 {
824     //This is not used in esp32s3
825 }
826 
827 /**
828  * Set the maximum output length (slave).
829  *
830  * @param hw     Beginning address of the peripheral registers.
831  * @param bitlen Output length, in bits.
832  */
spi_ll_slave_set_tx_bitlen(spi_dev_t * hw,size_t bitlen)833 static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
834 {
835     //This is not used in esp32s3
836 }
837 
838 /**
839  * Set the length of command phase.
840  *
841  * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
842  * command phases takes 4 cycles in 4-bit mode.
843  *
844  * @param hw     Beginning address of the peripheral registers.
845  * @param bitlen Length of command phase, in bits. 0 to disable the command phase.
846  */
spi_ll_set_command_bitlen(spi_dev_t * hw,int bitlen)847 static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen)
848 {
849     hw->user2.usr_command_bitlen = bitlen - 1;
850     hw->user.usr_command = bitlen ? 1 : 0;
851 }
852 
853 /**
854  * Set the length of address phase.
855  *
856  * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
857  * address phases takes 4 cycles in 4-bit mode.
858  *
859  * @param hw     Beginning address of the peripheral registers.
860  * @param bitlen Length of address phase, in bits. 0 to disable the address phase.
861  */
spi_ll_set_addr_bitlen(spi_dev_t * hw,int bitlen)862 static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen)
863 {
864     hw->user1.usr_addr_bitlen = bitlen - 1;
865     hw->user.usr_addr = bitlen ? 1 : 0;
866 }
867 
868 /**
869  * Set the address value in an intuitive way.
870  *
871  * The length and lsbfirst is required to shift and swap the address to the right place.
872  *
873  * @param hw       Beginning address of the peripheral registers.
874  * @param address  Address to set
875  * @param addrlen  Length of the address phase
876  * @param lsbfirst Whether the LSB first feature is enabled.
877  */
spi_ll_set_address(spi_dev_t * hw,uint64_t addr,int addrlen,uint32_t lsbfirst)878 static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst)
879 {
880     if (lsbfirst) {
881         /* The output address start from the LSB of the highest byte, i.e.
882         * addr[24] -> addr[31]
883         * ...
884         * addr[0] -> addr[7]
885         * So swap the byte order to let the LSB sent first.
886         */
887         addr = HAL_SWAP32(addr);
888         //otherwise only addr register is sent
889         hw->addr = addr;
890     } else {
891         // shift the address to MSB of addr register.
892         // output address will be sent from MSB to LSB of addr register
893         hw->addr = addr << (32 - addrlen);
894     }
895 }
896 
897 /**
898  * Set the command value in an intuitive way.
899  *
900  * The length and lsbfirst is required to shift and swap the command to the right place.
901  *
902  * @param hw       Beginning command of the peripheral registers.
903  * @param command  Command to set
904  * @param addrlen  Length of the command phase
905  * @param lsbfirst Whether the LSB first feature is enabled.
906  */
spi_ll_set_command(spi_dev_t * hw,uint16_t cmd,int cmdlen,bool lsbfirst)907 static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst)
908 {
909     if (lsbfirst) {
910         // The output command start from bit0 to bit 15, kept as is.
911         HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, cmd);
912     } else {
913         /* Output command will be sent from bit 7 to 0 of command_value, and
914          * then bit 15 to 8 of the same register field. Shift and swap to send
915          * more straightly.
916          */
917         HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen));
918 
919     }
920 }
921 
922 /**
923  * Set dummy clocks to output before RX phase (master), or clocks to skip
924  * before the data phase and after the address phase (slave).
925  *
926  * Note this phase is also used to compensate RX timing in half duplex mode.
927  *
928  * @param hw      Beginning address of the peripheral registers.
929  * @param dummy_n Dummy cycles used. 0 to disable the dummy phase.
930  */
spi_ll_set_dummy(spi_dev_t * hw,int dummy_n)931 static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n)
932 {
933     hw->user.usr_dummy = dummy_n ? 1 : 0;
934     HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user1, usr_dummy_cyclelen, dummy_n - 1);
935 }
936 
937 /**
938  * Enable/disable the RX data phase.
939  *
940  * @param hw     Beginning address of the peripheral registers.
941  * @param enable True if RX phase exist, otherwise false.
942  */
spi_ll_enable_miso(spi_dev_t * hw,int enable)943 static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable)
944 {
945     hw->user.usr_miso = enable;
946 }
947 
948 /**
949  * Enable/disable the TX data phase.
950  *
951  * @param hw     Beginning address of the peripheral registers.
952  * @param enable True if TX phase exist, otherwise false.
953  */
spi_ll_enable_mosi(spi_dev_t * hw,int enable)954 static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
955 {
956     hw->user.usr_mosi = enable;
957 }
958 
959 /**
960  * Get the received bit length of the slave.
961  *
962  * @param hw Beginning address of the peripheral registers.
963  *
964  * @return   Received bits of the slave.
965  */
spi_ll_slave_get_rcv_bitlen(spi_dev_t * hw)966 static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
967 {
968     return hw->slave1.data_bitlen;
969 }
970 
971 /*------------------------------------------------------------------------------
972  * Interrupts
973  *----------------------------------------------------------------------------*/
974 //helper macros to generate code for each interrupts
975 #define FOR_EACH_ITEM(op, list) do { list(op) } while(0)
976 #define INTR_LIST(item)    \
977     item(SPI_LL_INTR_TRANS_DONE,    dma_int_ena.trans_done,         dma_int_raw.trans_done,         dma_int_clr.trans_done,         dma_int_set.trans_done_int_set) \
978     item(SPI_LL_INTR_RDBUF,         dma_int_ena.rd_buf_done,        dma_int_raw.rd_buf_done,        dma_int_clr.rd_buf_done,        dma_int_set.rd_buf_done_int_set) \
979     item(SPI_LL_INTR_WRBUF,         dma_int_ena.wr_buf_done,        dma_int_raw.wr_buf_done,        dma_int_clr.wr_buf_done,        dma_int_set.wr_buf_done_int_set) \
980     item(SPI_LL_INTR_RDDMA,         dma_int_ena.rd_dma_done,        dma_int_raw.rd_dma_done,        dma_int_clr.rd_dma_done,        dma_int_set.rd_dma_done_int_set) \
981     item(SPI_LL_INTR_WRDMA,         dma_int_ena.wr_dma_done,        dma_int_raw.wr_dma_done,        dma_int_clr.wr_dma_done,        dma_int_set.wr_dma_done_int_set) \
982     item(SPI_LL_INTR_SEG_DONE,      dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done, dma_int_set.dma_seg_trans_done_int_set) \
983     item(SPI_LL_INTR_CMD7,          dma_int_ena.cmd7,               dma_int_raw.cmd7,               dma_int_clr.cmd7,               dma_int_set.cmd7_int_set) \
984     item(SPI_LL_INTR_CMD8,          dma_int_ena.cmd8,               dma_int_raw.cmd8,               dma_int_clr.cmd8,               dma_int_set.cmd8_int_set) \
985     item(SPI_LL_INTR_CMD9,          dma_int_ena.cmd9,               dma_int_raw.cmd9,               dma_int_clr.cmd9,               dma_int_set.cmd9_int_set) \
986     item(SPI_LL_INTR_CMDA,          dma_int_ena.cmda,               dma_int_raw.cmda,               dma_int_clr.cmda,               dma_int_set.cmda_int_set)
987 
988 
spi_ll_enable_intr(spi_dev_t * hw,spi_ll_intr_t intr_mask)989 static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
990 {
991 #define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1;
992     FOR_EACH_ITEM(ENA_INTR, INTR_LIST);
993 #undef ENA_INTR
994 }
995 
spi_ll_disable_intr(spi_dev_t * hw,spi_ll_intr_t intr_mask)996 static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
997 {
998 #define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0;
999     FOR_EACH_ITEM(DIS_INTR, INTR_LIST);
1000 #undef DIS_INTR
1001 }
1002 
spi_ll_set_intr(spi_dev_t * hw,spi_ll_intr_t intr_mask)1003 static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
1004 {
1005 #define SET_INTR(intr_bit, _, __, ___, set_reg) if (intr_mask & (intr_bit)) hw->set_reg = 1;
1006     FOR_EACH_ITEM(SET_INTR, INTR_LIST);
1007 #undef SET_INTR
1008 }
1009 
spi_ll_clear_intr(spi_dev_t * hw,spi_ll_intr_t intr_mask)1010 static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
1011 {
1012 #define CLR_INTR(intr_bit, _, __, clr_reg, ...) if (intr_mask & (intr_bit)) hw->clr_reg = 1;
1013     FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
1014 #undef CLR_INTR
1015 }
1016 
spi_ll_get_intr(spi_dev_t * hw,spi_ll_intr_t intr_mask)1017 static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
1018 {
1019 #define GET_INTR(intr_bit, _, raw_reg, ...) if (intr_mask & (intr_bit) && hw->raw_reg) return true;
1020     FOR_EACH_ITEM(GET_INTR, INTR_LIST);
1021     return false;
1022 #undef GET_INTR
1023 }
1024 
1025 #undef FOR_EACH_ITEM
1026 #undef INTR_LIST
1027 
1028 /**
1029  * Disable the trans_done interrupt.
1030  *
1031  * @param hw Beginning address of the peripheral registers.
1032  */
spi_ll_disable_int(spi_dev_t * hw)1033 static inline void spi_ll_disable_int(spi_dev_t *hw)
1034 {
1035     hw->dma_int_ena.trans_done = 0;
1036 }
1037 
1038 /**
1039  * Clear the trans_done interrupt.
1040  *
1041  * @param hw Beginning address of the peripheral registers.
1042  */
spi_ll_clear_int_stat(spi_dev_t * hw)1043 static inline void spi_ll_clear_int_stat(spi_dev_t *hw)
1044 {
1045     hw->dma_int_clr.trans_done = 1;
1046 }
1047 
1048 /**
1049  * Set the trans_done interrupt.
1050  *
1051  * @param hw Beginning address of the peripheral registers.
1052  */
spi_ll_set_int_stat(spi_dev_t * hw)1053 static inline void spi_ll_set_int_stat(spi_dev_t *hw)
1054 {
1055     hw->dma_int_set.trans_done_int_set = 1;
1056 }
1057 
1058 /**
1059  * Enable the trans_done interrupt.
1060  *
1061  * @param hw Beginning address of the peripheral registers.
1062  */
spi_ll_enable_int(spi_dev_t * hw)1063 static inline void spi_ll_enable_int(spi_dev_t *hw)
1064 {
1065     hw->dma_int_ena.trans_done = 1;
1066 }
1067 
1068 /*------------------------------------------------------------------------------
1069  * Slave HD
1070  *----------------------------------------------------------------------------*/
spi_ll_slave_hd_set_len_cond(spi_dev_t * hw,spi_ll_trans_len_cond_t cond_mask)1071 static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
1072 {
1073     hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
1074     hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
1075     hw->slave.rddma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDDMA) ? 1 : 0;
1076     hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
1077 }
1078 
spi_ll_slave_get_rx_byte_len(spi_dev_t * hw)1079 static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
1080 {
1081     return hw->slave1.data_bitlen / 8;
1082 }
1083 
spi_ll_slave_hd_get_last_addr(spi_dev_t * hw)1084 static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
1085 {
1086     return hw->slave1.last_addr;
1087 }
1088 
1089 #undef SPI_LL_RST_MASK
1090 #undef SPI_LL_UNUSED_INT_MASK
1091 
1092 #ifdef __cplusplus
1093 }
1094 #endif
1095