• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 /*******************************************************************************
16  * NOTICE
17  * The hal is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The LL layer for ESP32 SPI register operations
22 
23 #pragma once
24 
25 #include "hal/hal_defs.h"
26 #include "soc/spi_periph.h"
27 #include "esp32/rom/lldesc.h"
28 #include <string.h>
29 #include <esp_types.h>
30 #include <stdlib.h> //for abs()
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /// Registers to reset during initialization. Don't use in app.
37 #define SPI_LL_DMA_FIFO_RST_MASK (SPI_AHBM_RST | SPI_AHBM_FIFO_RST)
38 /// Interrupt not used. Don't use in app.
39 #define SPI_LL_UNUSED_INT_MASK  (SPI_INT_EN | SPI_SLV_WR_STA_DONE | SPI_SLV_RD_STA_DONE | SPI_SLV_WR_BUF_DONE | SPI_SLV_RD_BUF_DONE)
40 /// Swap the bit order to its correct place to send
41 #define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)data<<(32-len))
42 /// This is the expected clock frequency
43 #define SPI_LL_PERIPH_CLK_FREQ (80 * 1000000)
44 #define SPI_LL_GET_HW(ID) ((ID)==0? &SPI1:((ID)==1? &SPI2 : &SPI3))
45 
46 /**
47  * The data structure holding calculated clock configuration. Since the
48  * calculation needs long time, it should be calculated during initialization and
49  * stored somewhere to be quickly used.
50  */
51 typedef uint32_t spi_ll_clock_val_t;
52 
53 //On ESP32-S2 and earlier chips, DMA registers are part of SPI registers. So set the registers of SPI peripheral to control DMA.
54 typedef spi_dev_t spi_dma_dev_t;
55 
56 /** IO modes supported by the master. */
57 typedef enum {
58     SPI_LL_IO_MODE_NORMAL = 0,  ///< 1-bit mode for all phases
59     SPI_LL_IO_MODE_DIO,         ///< 2-bit mode for address and data phases, 1-bit mode for command phase
60     SPI_LL_IO_MODE_DUAL,        ///< 2-bit mode for data phases only, 1-bit mode for command and address phases
61     SPI_LL_IO_MODE_QIO,         ///< 4-bit mode for address and data phases, 1-bit mode for command phase
62     SPI_LL_IO_MODE_QUAD,        ///< 4-bit mode for data phases only, 1-bit mode for command and address phases
63 } spi_ll_io_mode_t;
64 
65 
66 /*------------------------------------------------------------------------------
67  * Control
68  *----------------------------------------------------------------------------*/
69 /**
70  * Initialize SPI peripheral (master).
71  *
72  * @param hw Beginning address of the peripheral registers.
73  */
spi_ll_master_init(spi_dev_t * hw)74 static inline void spi_ll_master_init(spi_dev_t *hw)
75 {
76     //Reset timing
77     hw->ctrl2.val = 0;
78 
79     //use all 64 bytes of the buffer
80     hw->user.usr_miso_highpart = 0;
81     hw->user.usr_mosi_highpart = 0;
82 
83     //Disable unneeded ints
84     hw->slave.val &= ~SPI_LL_UNUSED_INT_MASK;
85 }
86 
87 /**
88  * Initialize SPI peripheral (slave).
89  *
90  * @param hw Beginning address of the peripheral registers.
91  */
spi_ll_slave_init(spi_dev_t * hw)92 static inline void spi_ll_slave_init(spi_dev_t *hw)
93 {
94     //Configure slave
95     hw->clock.val = 0;
96     hw->user.val = 0;
97     hw->ctrl.val = 0;
98     hw->slave.wr_rd_buf_en = 1; //no sure if needed
99     hw->user.doutdin = 1; //we only support full duplex
100     hw->user.sio = 0;
101     hw->slave.slave_mode = 1;
102     hw->slave.sync_reset = 1;
103     hw->slave.sync_reset = 0;
104     //use all 64 bytes of the buffer
105     hw->user.usr_miso_highpart = 0;
106     hw->user.usr_mosi_highpart = 0;
107 
108     //Disable unneeded ints
109     hw->slave.val &= ~SPI_LL_UNUSED_INT_MASK;
110 }
111 
112 /**
113  * Check whether user-defined transaction is done.
114  *
115  * @param hw Beginning address of the peripheral registers.
116  *
117  * @return true if transaction is done, otherwise false.
118  */
spi_ll_usr_is_done(spi_dev_t * hw)119 static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
120 {
121     return hw->slave.trans_done;
122 }
123 
124 /**
125  * Trigger start of user-defined transaction for master.
126  *
127  * @param hw Beginning address of the peripheral registers.
128  */
spi_ll_master_user_start(spi_dev_t * hw)129 static inline void spi_ll_master_user_start(spi_dev_t *hw)
130 {
131     hw->cmd.usr = 1;
132 }
133 
134 /**
135  * Trigger start of user-defined transaction for slave.
136  *
137  * @param hw Beginning address of the peripheral registers.
138  */
spi_ll_slave_user_start(spi_dev_t * hw)139 static inline void spi_ll_slave_user_start(spi_dev_t *hw)
140 {
141     hw->cmd.usr = 1;
142 }
143 
144 /**
145  * Get current running command bit-mask. (Preview)
146  *
147  * @param hw Beginning address of the peripheral registers.
148  *
149  * @return Bitmask of running command, see ``SPI_CMD_REG``. 0 if no in-flight command.
150  */
spi_ll_get_running_cmd(spi_dev_t * hw)151 static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
152 {
153     return hw->cmd.val;
154 }
155 
156 /**
157  * Reset SPI CPU TX FIFO
158  *
159  * @param hw Beginning address of the peripheral registers.
160  */
spi_ll_cpu_tx_fifo_reset(spi_dev_t * hw)161 static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw)
162 {
163     //This is not used in esp32
164 }
165 
166 /**
167  * Reset SPI DMA FIFO
168  *
169  * @param hw Beginning address of the peripheral registers.
170  */
spi_ll_cpu_rx_fifo_reset(spi_dev_t * hw)171 static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw)
172 {
173     //This is not used in esp32
174 }
175 
176 /**
177  * Reset SPI DMA TX FIFO
178  *
179  * On ESP32, this function is not seperated
180  *
181  * @param hw Beginning address of the peripheral registers.
182  */
spi_ll_dma_tx_fifo_reset(spi_dev_t * hw)183 static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw)
184 {
185     hw->dma_conf.val |= SPI_LL_DMA_FIFO_RST_MASK;
186     hw->dma_conf.val &= ~SPI_LL_DMA_FIFO_RST_MASK;
187 }
188 
189 /**
190  * Reset SPI DMA RX FIFO
191  *
192  * On ESP32, this function is not seperated
193  *
194  * @param hw Beginning address of the peripheral registers.
195  */
spi_ll_dma_rx_fifo_reset(spi_dev_t * hw)196 static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw)
197 {
198     hw->dma_conf.val |= SPI_LL_DMA_FIFO_RST_MASK;
199     hw->dma_conf.val &= ~SPI_LL_DMA_FIFO_RST_MASK;
200 }
201 
202 /**
203  * Clear in fifo full error
204  *
205  * @param hw Beginning address of the peripheral registers.
206  */
spi_ll_infifo_full_clr(spi_dev_t * hw)207 static inline void spi_ll_infifo_full_clr(spi_dev_t *hw)
208 {
209     //This is not used in esp32
210 }
211 
212 /**
213  * Clear out fifo empty error
214  *
215  * @param hw Beginning address of the peripheral registers.
216  */
spi_ll_outfifo_empty_clr(spi_dev_t * hw)217 static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw)
218 {
219     //This is not used in esp32
220 }
221 
222 /*------------------------------------------------------------------------------
223  * SPI configuration for DMA
224  *----------------------------------------------------------------------------*/
225 
226 /**
227  * Enable/Disable RX DMA (Peripherals->DMA->RAM)
228  *
229  * @param hw     Beginning address of the peripheral registers.
230  * @param enable 1: enable; 2: disable
231  */
spi_ll_dma_rx_enable(spi_dev_t * hw,bool enable)232 static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable)
233 {
234     //This is not used in esp32
235 }
236 
237 /**
238  * Enable/Disable TX DMA (RAM->DMA->Peripherals)
239  *
240  * @param hw     Beginning address of the peripheral registers.
241  * @param enable 1: enable; 2: disable
242  */
spi_ll_dma_tx_enable(spi_dev_t * hw,bool enable)243 static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable)
244 {
245     //This is not used in esp32
246 }
247 
248 /**
249  * Configuration of RX DMA EOF interrupt generation way
250  *
251  * @param hw     Beginning address of the peripheral registers.
252  * @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.
253  */
spi_ll_dma_set_rx_eof_generation(spi_dev_t * hw,bool enable)254 static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable)
255 {
256     //This is not used in esp32
257 }
258 
259 /*------------------------------------------------------------------------------
260  * Buffer
261  *----------------------------------------------------------------------------*/
262 /**
263  * Write to SPI buffer.
264  *
265  * @param hw Beginning address of the peripheral registers.
266  * @param buffer_to_send Data address to copy to the buffer.
267  * @param bitlen Length to copy, in bits.
268  */
spi_ll_write_buffer(spi_dev_t * hw,const uint8_t * buffer_to_send,size_t bitlen)269 static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen)
270 {
271     for (size_t x = 0; x < bitlen; x += 32) {
272         //Use memcpy to get around alignment issues for txdata
273         uint32_t word;
274         memcpy(&word, &buffer_to_send[x / 8], 4);
275         hw->data_buf[(x / 32)] = word;
276     }
277 }
278 
279 /**
280  * Read from SPI buffer.
281  *
282  * @param hw Beginning address of the peripheral registers.
283  * @param buffer_to_rcv Address to copy buffer data to.
284  * @param bitlen Length to copy, in bits.
285  */
spi_ll_read_buffer(spi_dev_t * hw,uint8_t * buffer_to_rcv,size_t bitlen)286 static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen)
287 {
288     for (size_t x = 0; x < bitlen; x += 32) {
289         //Do a memcpy to get around possible alignment issues in rx_buffer
290         uint32_t word = hw->data_buf[x / 32];
291         int len = bitlen - x;
292         if (len > 32) {
293             len = 32;
294         }
295         memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8);
296     }
297 }
298 
299 /*------------------------------------------------------------------------------
300  * Configs: mode
301  *----------------------------------------------------------------------------*/
302 /**
303  * Enable/disable the postive-cs feature.
304  *
305  * @param hw Beginning address of the peripheral registers.
306  * @param cs One of the CS (0-2) to enable/disable the feature.
307  * @param pos_cs true to enable the feature, otherwise disable (default).
308  */
spi_ll_master_set_pos_cs(spi_dev_t * hw,int cs,uint32_t pos_cs)309 static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs)
310 {
311     if (pos_cs) {
312         hw->pin.master_cs_pol |= (1 << cs);
313     } else {
314         hw->pin.master_cs_pol &= ~(1 << cs);
315     }
316 }
317 
318 /**
319  * Enable/disable the LSBFIRST feature for TX data.
320  *
321  * @param hw Beginning address of the peripheral registers.
322  * @param lsbfirst true if LSB of TX data to be sent first, otherwise MSB is sent first (default).
323  */
spi_ll_set_tx_lsbfirst(spi_dev_t * hw,bool lsbfirst)324 static inline void spi_ll_set_tx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
325 {
326     hw->ctrl.wr_bit_order = lsbfirst;
327 }
328 
329 /**
330  * Enable/disable the LSBFIRST feature for RX data.
331  *
332  * @param hw Beginning address of the peripheral registers.
333  * @param lsbfirst true if first bit received as LSB, otherwise as MSB (default).
334  */
spi_ll_set_rx_lsbfirst(spi_dev_t * hw,bool lsbfirst)335 static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
336 {
337     hw->ctrl.rd_bit_order = lsbfirst;
338 }
339 
340 /**
341  * Set SPI mode for the peripheral as master.
342  *
343  * @param hw Beginning address of the peripheral registers.
344  * @param mode SPI mode to work at, 0-3.
345  */
spi_ll_master_set_mode(spi_dev_t * hw,uint8_t mode)346 static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode)
347 {
348     //Configure polarity
349     if (mode == 0) {
350         hw->pin.ck_idle_edge = 0;
351         hw->user.ck_out_edge = 0;
352     } else if (mode == 1) {
353         hw->pin.ck_idle_edge = 0;
354         hw->user.ck_out_edge = 1;
355     } else if (mode == 2) {
356         hw->pin.ck_idle_edge = 1;
357         hw->user.ck_out_edge = 1;
358     } else if (mode == 3) {
359         hw->pin.ck_idle_edge = 1;
360         hw->user.ck_out_edge = 0;
361     }
362 }
363 
364 /**
365  * Set SPI mode for the peripheral as slave.
366  *
367  * @param hw Beginning address of the peripheral registers.
368  * @param mode SPI mode to work at, 0-3.
369  */
spi_ll_slave_set_mode(spi_dev_t * hw,const int mode,bool dma_used)370 static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used)
371 {
372     if (mode == 0) {
373         //The timing needs to be fixed to meet the requirements of DMA
374         hw->pin.ck_idle_edge = 1;
375         hw->user.ck_i_edge = 0;
376         hw->ctrl2.miso_delay_mode = 0;
377         hw->ctrl2.miso_delay_num = 0;
378         hw->ctrl2.mosi_delay_mode = 2;
379         hw->ctrl2.mosi_delay_num = 2;
380     } else if (mode == 1) {
381         hw->pin.ck_idle_edge = 1;
382         hw->user.ck_i_edge = 1;
383         hw->ctrl2.miso_delay_mode = 2;
384         hw->ctrl2.miso_delay_num = 0;
385         hw->ctrl2.mosi_delay_mode = 0;
386         hw->ctrl2.mosi_delay_num = 0;
387     } else if (mode == 2) {
388         //The timing needs to be fixed to meet the requirements of DMA
389         hw->pin.ck_idle_edge = 0;
390         hw->user.ck_i_edge = 1;
391         hw->ctrl2.miso_delay_mode = 0;
392         hw->ctrl2.miso_delay_num = 0;
393         hw->ctrl2.mosi_delay_mode = 1;
394         hw->ctrl2.mosi_delay_num = 2;
395     } else if (mode == 3) {
396         hw->pin.ck_idle_edge = 0;
397         hw->user.ck_i_edge = 0;
398         hw->ctrl2.miso_delay_mode = 1;
399         hw->ctrl2.miso_delay_num = 0;
400         hw->ctrl2.mosi_delay_mode = 0;
401         hw->ctrl2.mosi_delay_num = 0;
402     }
403 
404     /* Silicon issues exists in mode 0 and 2 with DMA, change clock phase to
405      * avoid dma issue. This will cause slave output to appear at most half a
406      * spi clock before
407      */
408     if (dma_used) {
409         if (mode == 0) {
410             hw->pin.ck_idle_edge = 0;
411             hw->user.ck_i_edge = 1;
412             hw->ctrl2.miso_delay_mode = 0;
413             hw->ctrl2.miso_delay_num = 2;
414             hw->ctrl2.mosi_delay_mode = 0;
415             hw->ctrl2.mosi_delay_num = 3;
416         } else if (mode == 2) {
417             hw->pin.ck_idle_edge = 1;
418             hw->user.ck_i_edge = 0;
419             hw->ctrl2.miso_delay_mode = 0;
420             hw->ctrl2.miso_delay_num = 2;
421             hw->ctrl2.mosi_delay_mode = 0;
422             hw->ctrl2.mosi_delay_num = 3;
423         }
424     }
425 }
426 
427 /**
428  * Set SPI to work in full duplex or half duplex mode.
429  *
430  * @param hw Beginning address of the peripheral registers.
431  * @param half_duplex true to work in half duplex mode, otherwise in full duplex mode.
432  */
spi_ll_set_half_duplex(spi_dev_t * hw,bool half_duplex)433 static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex)
434 {
435     hw->user.doutdin = !half_duplex;
436 }
437 
438 /**
439  * Set SPI to work in SIO mode or not.
440  *
441  * SIO is a mode which MOSI and MISO share a line. The device MUST work in half-duplexmode.
442  *
443  * @param hw Beginning address of the peripheral registers.
444  * @param sio_mode true to work in SIO mode, otherwise false.
445  */
spi_ll_set_sio_mode(spi_dev_t * hw,int sio_mode)446 static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
447 {
448     hw->user.sio = sio_mode;
449 }
450 
451 /**
452  * Configure the io mode for the master to work at.
453  *
454  * @param hw Beginning address of the peripheral registers.
455  * @param io_mode IO mode to work at, see ``spi_ll_io_mode_t``.
456  */
spi_ll_master_set_io_mode(spi_dev_t * hw,spi_ll_io_mode_t io_mode)457 static inline void spi_ll_master_set_io_mode(spi_dev_t *hw, spi_ll_io_mode_t io_mode)
458 {
459     hw->ctrl.val &= ~(SPI_FREAD_DUAL | SPI_FREAD_QUAD | SPI_FREAD_DIO | SPI_FREAD_QIO);
460     hw->user.val &= ~(SPI_FWRITE_DUAL | SPI_FWRITE_QUAD | SPI_FWRITE_DIO | SPI_FWRITE_QIO);
461     switch (io_mode) {
462     case SPI_LL_IO_MODE_DIO:
463         hw->ctrl.fread_dio = 1;
464         hw->user.fwrite_dio = 1;
465         break;
466     case SPI_LL_IO_MODE_DUAL:
467         hw->ctrl.fread_dual = 1;
468         hw->user.fwrite_dual = 1;
469         break;
470     case SPI_LL_IO_MODE_QIO:
471         hw->ctrl.fread_qio = 1;
472         hw->user.fwrite_qio = 1;
473         break;
474     case SPI_LL_IO_MODE_QUAD:
475         hw->ctrl.fread_quad = 1;
476         hw->user.fwrite_quad = 1;
477         break;
478     default:
479         break;
480     };
481     if (io_mode != SPI_LL_IO_MODE_NORMAL) {
482         hw->ctrl.fastrd_mode = 1;
483     }
484 }
485 
486 /**
487  * Select one of the CS to use in current transaction.
488  *
489  * @param hw Beginning address of the peripheral registers.
490  * @param cs_id The cs to use, 0-2, otherwise none of them is used.
491  */
spi_ll_master_select_cs(spi_dev_t * hw,int cs_id)492 static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
493 {
494     hw->pin.cs0_dis = (cs_id == 0) ? 0 : 1;
495     hw->pin.cs1_dis = (cs_id == 1) ? 0 : 1;
496     hw->pin.cs2_dis = (cs_id == 2) ? 0 : 1;
497 }
498 
499 /*------------------------------------------------------------------------------
500  * Configs: parameters
501  *----------------------------------------------------------------------------*/
502 /**
503  * Set the clock for master by stored value.
504  *
505  * @param hw Beginning address of the peripheral registers.
506  * @param val stored clock configuration calculated before (by ``spi_ll_cal_clock``).
507  */
spi_ll_master_set_clock_by_reg(spi_dev_t * hw,const spi_ll_clock_val_t * val)508 static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_clock_val_t *val)
509 {
510     hw->clock.val = *(uint32_t *)val;
511 }
512 
513 /**
514  * Get the frequency of given dividers. Don't use in app.
515  *
516  * @param fapb APB clock of the system.
517  * @param pre Pre devider.
518  * @param n main divider.
519  *
520  * @return Frequency of given dividers.
521  */
spi_ll_freq_for_pre_n(int fapb,int pre,int n)522 static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
523 {
524     return (fapb / (pre * n));
525 }
526 
527 /**
528  * Calculate the nearest frequency avaliable for master.
529  *
530  * @param fapb APB clock of the system.
531  * @param hz Frequncy desired.
532  * @param duty_cycle Duty cycle desired.
533  * @param out_reg Output address to store the calculated clock configurations for the return frequency.
534  *
535  * @return Actual (nearest) frequency.
536  */
spi_ll_master_cal_clock(int fapb,int hz,int duty_cycle,spi_ll_clock_val_t * out_reg)537 static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
538 {
539     typeof(SPI1.clock) reg;
540     int eff_clk;
541 
542     //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
543     if (hz > ((fapb / 4) * 3)) {
544         //Using Fapb directly will give us the best result here.
545         reg.clkcnt_l = 0;
546         reg.clkcnt_h = 0;
547         reg.clkcnt_n = 0;
548         reg.clkdiv_pre = 0;
549         reg.clk_equ_sysclk = 1;
550         eff_clk = fapb;
551     } else {
552         //For best duty cycle resolution, we want n to be as close to 32 as possible, but
553         //we also need a pre/n combo that gets us as close as possible to the intended freq.
554         //To do this, we bruteforce n and calculate the best pre to go along with that.
555         //If there's a choice between pre/n combos that give the same result, use the one
556         //with the higher n.
557         int pre, n, h, l;
558         int bestn = -1;
559         int bestpre = -1;
560         int besterr = 0;
561         int errval;
562         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.
563             //Effectively, this does pre=round((fapb/n)/hz).
564             pre = ((fapb / n) + (hz / 2)) / hz;
565             if (pre <= 0) {
566                 pre = 1;
567             }
568             if (pre > 8192) {
569                 pre = 8192;
570             }
571             errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz);
572             if (bestn == -1 || errval <= besterr) {
573                 besterr = errval;
574                 bestn = n;
575                 bestpre = pre;
576             }
577         }
578 
579         n = bestn;
580         pre = bestpre;
581         l = n;
582         //This effectively does round((duty_cycle*n)/256)
583         h = (duty_cycle * n + 127) / 256;
584         if (h <= 0) {
585             h = 1;
586         }
587 
588         reg.clk_equ_sysclk = 0;
589         reg.clkcnt_n = n - 1;
590         reg.clkdiv_pre = pre - 1;
591         reg.clkcnt_h = h - 1;
592         reg.clkcnt_l = l - 1;
593         eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n);
594     }
595     if (out_reg != NULL) {
596         *(uint32_t *)out_reg = reg.val;
597     }
598     return eff_clk;
599 }
600 
601 /**
602  * Calculate and set clock for SPI master according to desired parameters.
603  *
604  * This takes long, suggest to calculate the configuration during
605  * initialization by ``spi_ll_master_cal_clock`` and store the result, then
606  * configure the clock by stored value when used by
607  * ``spi_ll_msater_set_clock_by_reg``.
608  *
609  * @param hw Beginning address of the peripheral registers.
610  * @param fapb APB clock of the system.
611  * @param hz Frequncy desired.
612  * @param duty_cycle Duty cycle desired.
613  *
614  * @return Actual frequency that is used.
615  */
spi_ll_master_set_clock(spi_dev_t * hw,int fapb,int hz,int duty_cycle)616 static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle)
617 {
618     spi_ll_clock_val_t reg_val;
619     int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, &reg_val);
620     spi_ll_master_set_clock_by_reg(hw, &reg_val);
621     return freq;
622 }
623 
624 /**
625  * Enable/disable the CK sel feature for a CS pin.
626  *
627  * CK sel is a feature to toggle the CS line along with the clock.
628  *
629  * @param hw Beginning address of the peripheral registers.
630  * @param cs CS pin to enable/disable the feature, 0-2.
631  * @param cksel true to enable the feature, otherwise false.
632  */
spi_ll_master_set_cksel(spi_dev_t * hw,int cs,uint32_t cksel)633 static inline void spi_ll_master_set_cksel(spi_dev_t *hw, int cs, uint32_t cksel)
634 {
635     if (cksel) {
636         hw->pin.master_ck_sel |= (1 << cs);
637     } else {
638         hw->pin.master_ck_sel &= ~(1 << cs);
639     }
640 }
641 
642 /**
643  * Set the mosi delay after the output edge to the signal. (Preview)
644  *
645  * The delay mode/num is a Espressif conception, may change in the new chips.
646  *
647  * @param hw Beginning address of the peripheral registers.
648  * @param delay_mode Delay mode, see TRM.
649  * @param delay_num APB clocks to delay.
650  */
spi_ll_set_mosi_delay(spi_dev_t * hw,int delay_mode,int delay_num)651 static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int delay_num)
652 {
653     hw->ctrl2.mosi_delay_mode = delay_mode;
654     hw->ctrl2.mosi_delay_num = delay_num;
655 }
656 
657 /**
658  * Set the miso delay applied to the input signal before the internal peripheral. (Preview)
659  *
660  * The delay mode/num is a Espressif conception, may change in the new chips.
661  *
662  * @param hw Beginning address of the peripheral registers.
663  * @param delay_mode Delay mode, see TRM.
664  * @param delay_num APB clocks to delay.
665  */
spi_ll_set_miso_delay(spi_dev_t * hw,int delay_mode,int delay_num)666 static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int delay_num)
667 {
668     hw->ctrl2.miso_delay_mode = delay_mode;
669     hw->ctrl2.miso_delay_num = delay_num;
670 }
671 
672 /**
673  * Set dummy clocks to output before RX phase (master), or clocks to skip
674  * before the data phase and after the address phase (slave).
675  *
676  * Note this phase is also used to compensate RX timing in half duplex mode.
677  *
678  * @param hw Beginning address of the peripheral registers.
679  * @param dummy_n Dummy cycles used. 0 to disable the dummy phase.
680  */
spi_ll_set_dummy(spi_dev_t * hw,int dummy_n)681 static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n)
682 {
683     hw->user.usr_dummy = dummy_n ? 1 : 0;
684     hw->user1.usr_dummy_cyclelen = dummy_n - 1;
685 }
686 
687 /**
688  * Set the delay of SPI clocks before the CS inactive edge after the last SPI clock.
689  *
690  * @param hw Beginning address of the peripheral registers.
691  * @param hold Delay of SPI clocks after the last clock, 0 to disable the hold phase.
692  */
spi_ll_master_set_cs_hold(spi_dev_t * hw,int hold)693 static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold)
694 {
695     hw->ctrl2.hold_time = hold;
696     hw->user.cs_hold = hold ? 1 : 0;
697 }
698 
699 /**
700  * Set the delay of SPI clocks before the first SPI clock after the CS active edge.
701  *
702  * Note ESP32 doesn't support to use this feature when command/address phases
703  * are used in full duplex mode.
704  *
705  * @param hw Beginning address of the peripheral registers.
706  * @param setup Delay of SPI clocks after the CS active edge, 0 to disable the setup phase.
707  */
spi_ll_master_set_cs_setup(spi_dev_t * hw,uint8_t setup)708 static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup)
709 {
710     hw->ctrl2.setup_time = setup - 1;
711     hw->user.cs_setup = setup ? 1 : 0;
712 }
713 
714 /*------------------------------------------------------------------------------
715  * Configs: data
716  *----------------------------------------------------------------------------*/
717 /**
718  * Set the input length (master).
719  *
720  * @param hw Beginning address of the peripheral registers.
721  * @param bitlen input length, in bits.
722  */
spi_ll_set_miso_bitlen(spi_dev_t * hw,size_t bitlen)723 static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen)
724 {
725     hw->miso_dlen.usr_miso_dbitlen = bitlen - 1;
726 }
727 
728 /**
729  * Set the output length (master).
730  *
731  * @param hw Beginning address of the peripheral registers.
732  * @param bitlen output length, in bits.
733  */
spi_ll_set_mosi_bitlen(spi_dev_t * hw,size_t bitlen)734 static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
735 {
736     hw->mosi_dlen.usr_mosi_dbitlen = bitlen - 1;
737 }
738 
739 /**
740  * Set the maximum input length (slave).
741  *
742  * @param hw Beginning address of the peripheral registers.
743  * @param bitlen input length, in bits.
744  */
spi_ll_slave_set_rx_bitlen(spi_dev_t * hw,size_t bitlen)745 static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
746 {
747     hw->slv_wrbuf_dlen.bit_len = bitlen - 1;
748 }
749 
750 /**
751  * Set the maximum output length (slave).
752  *
753  * @param hw Beginning address of the peripheral registers.
754  * @param bitlen output length, in bits.
755  */
spi_ll_slave_set_tx_bitlen(spi_dev_t * hw,size_t bitlen)756 static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
757 {
758     hw->slv_rdbuf_dlen.bit_len = bitlen - 1;
759 }
760 
761 /**
762  * Set the length of command phase.
763  *
764  * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
765  * command phases takes 4 cycles in 4-bit mode.
766  *
767  * @param hw Beginning address of the peripheral registers.
768  * @param bitlen Length of command phase, in bits. 0 to disable the command phase.
769  */
spi_ll_set_command_bitlen(spi_dev_t * hw,int bitlen)770 static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen)
771 {
772     hw->user2.usr_command_bitlen = bitlen - 1;
773     hw->user.usr_command = bitlen ? 1 : 0;
774 }
775 
776 /**
777  * Set the length of address phase.
778  *
779  * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit
780  * address phases takes 4 cycles in 4-bit mode.
781  *
782  * @param hw Beginning address of the peripheral registers.
783  * @param bitlen Length of address phase, in bits. 0 to disable the address phase.
784  */
spi_ll_set_addr_bitlen(spi_dev_t * hw,int bitlen)785 static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen)
786 {
787     hw->user1.usr_addr_bitlen = bitlen - 1;
788     hw->user.usr_addr = bitlen ? 1 : 0;
789 }
790 
791 /**
792  * Set the address value in an intuitive way.
793  *
794  * The length and lsbfirst is required to shift and swap the address to the right place.
795  *
796  * @param hw Beginning address of the peripheral registers.
797  * @param address Address to set
798  * @param addrlen Length of the address phase
799  * @param lsbfirst whether the LSB first feature is enabled.
800  */
spi_ll_set_address(spi_dev_t * hw,uint64_t addr,int addrlen,uint32_t lsbfirst)801 static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst)
802 {
803     if (lsbfirst) {
804         /* The output address start from the LSB of the highest byte, i.e.
805          * addr[24] -> addr[31]
806          * ...
807          * addr[0] -> addr[7]
808          * slv_wr_status[24] -> slv_wr_status[31]
809          * ...
810          * slv_wr_status[0] -> slv_wr_status[7]
811          * So swap the byte order to let the LSB sent first.
812          */
813         addr = HAL_SWAP64(addr);
814         hw->addr = addr >> 32;
815         hw->slv_wr_status = addr;
816     } else {
817         // shift the address to MSB of addr (and maybe slv_wr_status) register.
818         // output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
819         if (addrlen > 32) {
820             hw->addr = addr >> (addrlen - 32);
821             hw->slv_wr_status = addr << (64 - addrlen);
822         } else {
823             hw->addr = addr << (32 - addrlen);
824         }
825     }
826 }
827 
828 /**
829  * Set the command value in an intuitive way.
830  *
831  * The length and lsbfirst is required to shift and swap the command to the right place.
832  *
833  * @param hw Beginning command of the peripheral registers.
834  * @param command Command to set
835  * @param addrlen Length of the command phase
836  * @param lsbfirst whether the LSB first feature is enabled.
837  */
spi_ll_set_command(spi_dev_t * hw,uint16_t cmd,int cmdlen,bool lsbfirst)838 static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst)
839 {
840     if (lsbfirst) {
841         // The output command start from bit0 to bit 15, kept as is.
842         hw->user2.usr_command_value = cmd;
843     } else {
844         /* Output command will be sent from bit 7 to 0 of command_value, and
845          * then bit 15 to 8 of the same register field. Shift and swap to send
846          * more straightly.
847          */
848         hw->user2.usr_command_value = HAL_SPI_SWAP_DATA_TX(cmd, cmdlen);
849 
850     }
851 }
852 
853 /**
854  * Enable/disable the RX data phase.
855  *
856  * @param hw Beginning address of the peripheral registers.
857  * @param enable true if RX phase exist, otherwise false.
858  */
spi_ll_enable_miso(spi_dev_t * hw,int enable)859 static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable)
860 {
861     hw->user.usr_miso = enable;
862 }
863 
864 /**
865  * Enable/disable the TX data phase.
866  *
867  * @param hw Beginning address of the peripheral registers.
868  * @param enable true if TX phase exist, otherwise false.
869  */
spi_ll_enable_mosi(spi_dev_t * hw,int enable)870 static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
871 {
872     hw->user.usr_mosi = enable;
873 }
874 
875 /**
876  * Reset the slave peripheral before next transaction.
877  *
878  * @param hw Beginning address of the peripheral registers.
879  */
spi_ll_slave_reset(spi_dev_t * hw)880 static inline void spi_ll_slave_reset(spi_dev_t *hw)
881 {
882     hw->slave.sync_reset = 1;
883     hw->slave.sync_reset = 0;
884 }
885 
886 /**
887  * Get the received bit length of the slave.
888  *
889  * @param hw Beginning address of the peripheral registers.
890  *
891  * @return Received bits of the slave.
892  */
spi_ll_slave_get_rcv_bitlen(spi_dev_t * hw)893 static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
894 {
895     return hw->slv_rd_bit.slv_rdata_bit;
896 }
897 
898 /*------------------------------------------------------------------------------
899  * Interrupts
900  *----------------------------------------------------------------------------*/
901 /**
902  * Disable the trans_done interrupt.
903  *
904  * @param hw Beginning address of the peripheral registers.
905  */
spi_ll_disable_int(spi_dev_t * hw)906 static inline void spi_ll_disable_int(spi_dev_t *hw)
907 {
908     hw->slave.trans_inten = 0;
909 }
910 
911 /**
912  * Clear the trans_done interrupt.
913  *
914  * @param hw Beginning address of the peripheral registers.
915  */
spi_ll_clear_int_stat(spi_dev_t * hw)916 static inline void spi_ll_clear_int_stat(spi_dev_t *hw)
917 {
918     hw->slave.trans_done = 0;
919 }
920 
921 /**
922  * Set the trans_done interrupt.
923  *
924  * @param hw Beginning address of the peripheral registers.
925  */
spi_ll_set_int_stat(spi_dev_t * hw)926 static inline void spi_ll_set_int_stat(spi_dev_t *hw)
927 {
928     hw->slave.trans_done = 1;
929 }
930 
931 /**
932  * Enable the trans_done interrupt.
933  *
934  * @param hw Beginning address of the peripheral registers.
935  */
spi_ll_enable_int(spi_dev_t * hw)936 static inline void spi_ll_enable_int(spi_dev_t *hw)
937 {
938     hw->slave.trans_inten = 1;
939 }
940 
941 /*------------------------------------------------------------------------------
942  * DMA:
943  *      RX DMA (Peripherals->DMA->RAM)
944  *      TX DMA (RAM->DMA->Peripherals)
945  *----------------------------------------------------------------------------*/
946 /**
947  * Reset RX DMA which stores the data received from a peripheral into RAM.
948  *
949  * @param dma_in  Beginning address of the DMA peripheral registers which stores the data received from a peripheral into RAM.
950  * @param channel DMA channel, for chip version compatibility, not used.
951  */
spi_dma_ll_rx_reset(spi_dma_dev_t * dma_in,uint32_t channel)952 static inline void spi_dma_ll_rx_reset(spi_dma_dev_t *dma_in, uint32_t channel)
953 {
954     //Reset RX DMA peripheral
955     dma_in->dma_conf.in_rst = 1;
956     dma_in->dma_conf.in_rst = 0;
957 }
958 
959 /**
960  * Start RX DMA.
961  *
962  * @param dma_in  Beginning address of the DMA peripheral registers which stores the data received from a peripheral into RAM.
963  * @param channel DMA channel, for chip version compatibility, not used.
964  * @param addr    Address of the beginning DMA descriptor.
965  */
spi_dma_ll_rx_start(spi_dma_dev_t * dma_in,uint32_t channel,lldesc_t * addr)966 static inline void spi_dma_ll_rx_start(spi_dma_dev_t *dma_in, uint32_t channel, lldesc_t *addr)
967 {
968     dma_in->dma_in_link.addr = (int) addr & 0xFFFFF;
969     dma_in->dma_in_link.start = 1;
970 }
971 
972 /**
973  * Enable DMA RX channel burst for data
974  *
975  * @param dma_in  Beginning address of the DMA peripheral registers which stores the data received from a peripheral into RAM.
976  * @param channel DMA channel, for chip version compatibility, not used.
977  * @param enable  True to enable, false to disable
978  */
spi_dma_ll_rx_enable_burst_data(spi_dma_dev_t * dma_in,uint32_t channel,bool enable)979 static inline void spi_dma_ll_rx_enable_burst_data(spi_dma_dev_t *dma_in, uint32_t channel, bool enable)
980 {
981     //This is not supported in esp32
982 }
983 
984 /**
985  * Enable DMA RX channel burst for descriptor
986  *
987  * @param dma_in  Beginning address of the DMA peripheral registers which stores the data received from a peripheral into RAM.
988  * @param channel DMA channel, for chip version compatibility, not used.
989  * @param enable  True to enable, false to disable
990  */
spi_dma_ll_rx_enable_burst_desc(spi_dma_dev_t * dma_in,uint32_t channel,bool enable)991 static inline void spi_dma_ll_rx_enable_burst_desc(spi_dma_dev_t *dma_in, uint32_t channel, bool enable)
992 {
993     dma_in->dma_conf.indscr_burst_en = enable;
994 }
995 
996 /**
997  * Reset TX DMA which transmits the data from RAM to a peripheral.
998  *
999  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1000  * @param channel DMA channel, for chip version compatibility, not used.
1001  */
spi_dma_ll_tx_reset(spi_dma_dev_t * dma_out,uint32_t channel)1002 static inline void spi_dma_ll_tx_reset(spi_dma_dev_t *dma_out, uint32_t channel)
1003 {
1004     //Reset TX DMA peripheral
1005     dma_out->dma_conf.out_rst = 1;
1006     dma_out->dma_conf.out_rst = 0;
1007 }
1008 
1009 /**
1010  * Start TX DMA.
1011  *
1012  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1013  * @param channel DMA channel, for chip version compatibility, not used.
1014  * @param addr    Address of the beginning DMA descriptor.
1015  */
spi_dma_ll_tx_start(spi_dma_dev_t * dma_out,uint32_t channel,lldesc_t * addr)1016 static inline void spi_dma_ll_tx_start(spi_dma_dev_t *dma_out, uint32_t channel, lldesc_t *addr)
1017 {
1018     dma_out->dma_out_link.addr = (int) addr & 0xFFFFF;
1019     dma_out->dma_out_link.start = 1;
1020 }
1021 
1022 /**
1023  * Enable DMA TX channel burst for data
1024  *
1025  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1026  * @param channel DMA channel, for chip version compatibility, not used.
1027  * @param enable  True to enable, false to disable
1028  */
spi_dma_ll_tx_enable_burst_data(spi_dma_dev_t * dma_out,uint32_t channel,bool enable)1029 static inline void spi_dma_ll_tx_enable_burst_data(spi_dma_dev_t *dma_out, uint32_t channel, bool enable)
1030 {
1031     dma_out->dma_conf.out_data_burst_en = enable;
1032 }
1033 
1034 /**
1035  * Enable DMA TX channel burst for descriptor
1036  *
1037  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1038  * @param channel DMA channel, for chip version compatibility, not used.
1039  * @param enable  True to enable, false to disable
1040  */
spi_dma_ll_tx_enable_burst_desc(spi_dma_dev_t * dma_out,uint32_t channel,bool enable)1041 static inline void spi_dma_ll_tx_enable_burst_desc(spi_dma_dev_t *dma_out, uint32_t channel, bool enable)
1042 {
1043     dma_out->dma_conf.outdscr_burst_en = enable;
1044 }
1045 
1046 /**
1047  * Configuration of OUT EOF flag generation way
1048  *
1049  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1050  * @param channel DMA channel, for chip version compatibility, not used.
1051  * @param enable  1: when dma pop all data from fifo  0:when ahb push all data to fifo.
1052  */
spi_dma_ll_set_out_eof_generation(spi_dma_dev_t * dma_out,uint32_t channel,bool enable)1053 static inline void spi_dma_ll_set_out_eof_generation(spi_dma_dev_t *dma_out, uint32_t channel, bool enable)
1054 {
1055     dma_out->dma_conf.out_eof_mode = enable;
1056 }
1057 
1058 /**
1059  * Enable automatic outlink-writeback
1060  *
1061  * @param dma_out Beginning address of the DMA peripheral registers which transmits the data from RAM to a peripheral.
1062  * @param channel DMA channel, for chip version compatibility, not used.
1063  * @param enable  True to enable, false to disable
1064  */
spi_dma_ll_enable_out_auto_wrback(spi_dma_dev_t * dma_out,uint32_t channel,bool enable)1065 static inline void spi_dma_ll_enable_out_auto_wrback(spi_dma_dev_t *dma_out, uint32_t channel, bool enable)
1066 {
1067     //does not configure it in ESP32
1068 }
1069 
1070 #undef SPI_LL_RST_MASK
1071 #undef SPI_LL_UNUSED_INT_MASK
1072 
1073 #ifdef __cplusplus
1074 }
1075 #endif
1076