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