• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 #include "plat_addr_map.h"
16 #include "cmsis.h"
17 #include "hal_cmu.h"
18 #include "hal_dma.h"
19 #include "hal_location.h"
20 #include "hal_sleep.h"
21 #include "hal_spi.h"
22 #include "hal_trace.h"
23 #include "reg_spi.h"
24 #include "string.h"
25 
26 // TODO:
27 // 1) Add transfer timeout control
28 
29 #ifdef SPI_ROM_ONLY
30 #define SPI_ASSERT(c, ...)                  ASSERT_NODUMP(c)
31 #else
32 #define SPI_ASSERT(c, ...)                  ASSERT(c, ##__VA_ARGS__)
33 #endif
34 
35 #if defined(CHIP_BEST2000) || defined(CHIP_BEST2001) || defined(CHIP_BEST2300) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2300P)
36 // ISPI operations are required during deep sleep (to enable/disable PLLs)
37 #define ISPI_API_LOC                        BOOT_TEXT_SRAM_LOC
38 #else
39 #define ISPI_API_LOC
40 #endif
41 
42 #if (CHIP_SPI_VER >= 5)
43 #define ISPI_CS_QTY                         15
44 #else
45 #define ISPI_CS_QTY                         HAL_SPI_CS_QTY
46 #endif
47 
48 enum HAL_SPI_ID_T {
49     HAL_SPI_ID_INTERNAL,
50 #ifdef CHIP_HAS_SPI
51     HAL_SPI_ID_0,
52 #endif
53 #ifdef CHIP_HAS_SPILCD
54     HAL_SPI_ID_SLCD,
55 #endif
56 #ifdef CHIP_HAS_SPIPHY
57     HAL_SPI_ID_PHY,
58 #endif
59 #ifdef CHIP_HAS_SPIDPD
60     HAL_SPI_ID_DPD,
61 #endif
62 
63     HAL_SPI_ID_QTY
64 };
65 
66 enum HAL_SPI_CS_T {
67     HAL_SPI_CS_0,
68 #if (CHIP_SPI_VER >= 2)
69     HAL_SPI_CS_1,
70     HAL_SPI_CS_2,
71 #if (CHIP_SPI_VER >= 3)
72     HAL_SPI_CS_3,
73 #if (CHIP_SPI_VER >= 4)
74     //HAL_SPI_CS_4,
75 #endif
76 #endif
77 #endif
78 
79     HAL_SPI_CS_QTY
80 };
81 
82 enum HAL_SPI_XFER_TYPE_T {
83     HAL_SPI_XFER_TYPE_SEND,
84     HAL_SPI_XFER_TYPE_RECV,
85 
86     HAL_SPI_XFER_TYPE_QTY
87 };
88 
89 struct HAL_SPI_MOD_NAME_T {
90     enum HAL_CMU_MOD_ID_T mod;
91     enum HAL_CMU_MOD_ID_T apb;
92 };
93 
94 static struct SPI_T * const spi[HAL_SPI_ID_QTY] = {
95     (struct SPI_T *)ISPI_BASE,
96 #ifdef CHIP_HAS_SPI
97     (struct SPI_T *)SPI_BASE,
98 #endif
99 #ifdef CHIP_HAS_SPILCD
100     (struct SPI_T *)SPILCD_BASE,
101 #endif
102 #ifdef CHIP_HAS_SPIPHY
103     (struct SPI_T *)SPIPHY_BASE,
104 #endif
105 #ifdef CHIP_HAS_SPIDPD
106     (struct SPI_T *)SPIDPD_BASE,
107 #endif
108 };
109 
110 static const struct HAL_SPI_MOD_NAME_T spi_mod[HAL_SPI_ID_QTY] = {
111     {
112         .mod = HAL_CMU_MOD_O_SPI_ITN,
113         .apb = HAL_CMU_MOD_P_SPI_ITN,
114     },
115 #ifdef CHIP_HAS_SPI
116     {
117         .mod = HAL_CMU_MOD_O_SPI,
118         .apb = HAL_CMU_MOD_P_SPI,
119     },
120 #endif
121 #ifdef CHIP_HAS_SPILCD
122     {
123         .mod = HAL_CMU_MOD_O_SLCD,
124         .apb = HAL_CMU_MOD_P_SLCD,
125     },
126 #endif
127 #ifdef CHIP_HAS_SPIPHY
128     {
129         .mod = HAL_CMU_MOD_O_SPI_PHY,
130         .apb = HAL_CMU_MOD_P_SPI_PHY,
131     },
132 #endif
133 #ifdef CHIP_HAS_SPIDPD
134     {
135         .mod = HAL_CMU_MOD_O_SPI_DPD,
136         .apb = HAL_CMU_MOD_P_SPI_DPD,
137     },
138 #endif
139 };
140 
141 //static BOOT_BSS_LOC struct HAL_SPI_CTRL_T ispi_ctrl;
142 #ifdef CHIP_HAS_SPIPHY
143 //static BOOT_BSS_LOC struct HAL_SPI_CTRL_T spiphy_ctrl;
144 #endif
145 
146 #ifndef SPI_ROM_ONLY
147 #ifdef CHIP_HAS_SPI
148 static struct HAL_SPI_CTRL_T spi0_ctrl[HAL_SPI_CS_QTY];
149 #if (CHIP_SPI_VER >= 2)
150 static enum HAL_SPI_CS_T spi0_cs = HAL_SPI_CS_0;
151 #else
152 static const enum HAL_SPI_CS_T spi0_cs = HAL_SPI_CS_0;
153 #endif
154 #endif
155 #ifdef CHIP_HAS_SPILCD
156 static struct HAL_SPI_CTRL_T spilcd_ctrl[HAL_SPI_CS_QTY];
157 #if (CHIP_SPI_VER >= 2)
158 static enum HAL_SPI_CS_T spilcd_cs = HAL_SPI_CS_0;
159 #else
160 static const enum HAL_SPI_CS_T spilcd_cs = HAL_SPI_CS_0;
161 #endif
162 #endif
163 #ifdef CHIP_HAS_SPIDPD
164 static struct HAL_SPI_CTRL_T spidpd_ctrl;
165 #endif
166 
167 #ifdef CORE_SLEEP_POWER_DOWN
168 static SRAM_BSS_LOC struct SAVED_SPI_REGS_T saved_spi_regs[HAL_SPI_ID_QTY];
169 #endif
170 
171 static uint8_t BOOT_BSS_LOC spi_cs_map[HAL_SPI_ID_QTY];
172 STATIC_ASSERT(sizeof(spi_cs_map[0]) * 8 >= HAL_SPI_CS_QTY, "spi_cs_map size too small");
173 
174 static bool BOOT_BSS_LOC in_use[HAL_SPI_ID_QTY] = { false, };
175 
176 static HAL_SPI_DMA_HANDLER_T BOOT_BSS_LOC spi_txdma_handler[HAL_SPI_ID_QTY];
177 static HAL_SPI_DMA_HANDLER_T BOOT_BSS_LOC spi_rxdma_handler[HAL_SPI_ID_QTY];
178 static uint8_t BOOT_BSS_LOC spi_txdma_chan[HAL_SPI_ID_QTY];
179 static uint8_t BOOT_BSS_LOC spi_rxdma_chan[HAL_SPI_ID_QTY];
180 
181 static enum HAL_SPI_MOD_CLK_SEL_T BOOT_BSS_LOC clk_sel[HAL_SPI_ID_QTY];
182 
183 static bool BOOT_BSS_LOC spi_init_done = false;
184 
185 static int hal_spi_activate_cs_id(enum HAL_SPI_ID_T id, uint32_t cs);
186 #endif
187 
188 #ifdef CHIP_HAS_SPILCD
189 static enum SPI_RX_DMA_MODE_T spi_slave_recv_dma_mode[HAL_SPI_ID_QTY];
190 static uint32_t spi_slave_recv_dma_size[HAL_SPI_ID_QTY];
191 #endif
192 
193 //static const char *invalid_id = "Invalid SPI ID: %d";
194 
get_frame_bytes(enum HAL_SPI_ID_T id)195 static inline uint8_t get_frame_bytes(enum HAL_SPI_ID_T id)
196 {
197     uint8_t bits, cnt;
198 
199     bits = GET_BITFIELD(spi[id]->SSPCR0, SPI_SSPCR0_DSS) + 1;
200     if (bits <= 8) {
201         cnt = 1;
202     } else if (bits <= 16) {
203         cnt = 2;
204     } else {
205         cnt = 4;
206     }
207 
208     return cnt;
209 }
210 
copy_frame_from_bytes(uint32_t * val,const uint8_t * data,uint8_t cnt)211 static inline void copy_frame_from_bytes(uint32_t *val, const uint8_t *data, uint8_t cnt)
212 {
213 #ifdef UNALIGNED_ACCESS
214     if (cnt == 1) {
215         *val = *(const uint8_t *)data;
216     } else if (cnt == 2) {
217         *val = *(const uint16_t *)data;
218     } else {
219         *val = *(const uint32_t *)data;
220     }
221 #else
222     if (cnt == 1) {
223         *val = data[0];
224     } else if (cnt == 2) {
225         *val = data[0] | (data[1] << 8);
226     } else {
227         *val = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
228     }
229 #endif
230 }
231 
copy_bytes_from_frame(uint8_t * data,uint32_t val,uint8_t cnt)232 static inline void copy_bytes_from_frame(uint8_t *data, uint32_t val, uint8_t cnt)
233 {
234 #ifdef UNALIGNED_ACCESS
235     if (cnt == 1) {
236         *(uint8_t *)data = (uint8_t)val;
237     } else if (cnt == 2) {
238         *(uint16_t *)data = (uint16_t)val;
239     } else {
240         *(uint32_t *)data = (uint32_t)val;
241     }
242 #else
243     data[0] = (uint8_t)val;
244     if (cnt == 1) {
245         return;
246     } else if (cnt == 2) {
247         data[1] = (uint8_t)(val >> 8);
248     } else {
249         data[1] = (uint8_t)(val >> 8);
250         data[2] = (uint8_t)(val >> 16);
251         data[3] = (uint8_t)(val >> 24);
252     }
253 #endif
254 }
255 
hal_spi_init_ctrl(const struct HAL_SPI_CFG_T * cfg,struct HAL_SPI_CTRL_T * ctrl)256 int hal_spi_init_ctrl(const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl)
257 {
258     uint32_t div;
259     uint16_t cpsdvsr, scr;
260     uint32_t mod_clk;
261 
262 #ifdef SPI_ROM_ONLY
263     // Assume default crystal -- Never access global versatile data to ensure reentrance
264     mod_clk = HAL_CMU_DEFAULT_CRYSTAL_FREQ;
265 #else // !SPI_ROM_ONLY
266     mod_clk = 0;
267 #ifdef PERIPH_PLL_FREQ
268     if (PERIPH_PLL_FREQ / 2 > 2 * hal_cmu_get_crystal_freq()) {
269         // Init to OSC_X2
270         mod_clk = 2 * hal_cmu_get_crystal_freq();
271         if (cfg->rate * 2 > mod_clk) {
272             mod_clk = PERIPH_PLL_FREQ / 2;
273             ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_PLL;
274         } else {
275             mod_clk = 0;
276         }
277     }
278 #endif
279     if (mod_clk == 0) {
280         // Init to OSC
281         mod_clk = hal_cmu_get_crystal_freq();
282         if (cfg->rate * 2 > mod_clk) {
283             mod_clk *= 2;
284             ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_OSC_X2;
285         } else {
286             ctrl->clk_sel = HAL_SPI_MOD_CLK_SEL_OSC;
287         }
288     }
289 #endif // !SPI_ROM_ONLY
290 
291 #ifdef SPI_SLAVE
292     SPI_ASSERT(cfg->rate <= mod_clk*2 / (MIN_CPSDVSR * (1 + MIN_SCR)), "SPI rate too large: %u", cfg->rate);
293 #else
294     SPI_ASSERT(cfg->rate <= mod_clk / (MIN_CPSDVSR * (1 + MIN_SCR)), "SPI rate too large: %u", cfg->rate);
295 #endif
296     SPI_ASSERT(cfg->rate >= mod_clk / (MAX_CPSDVSR * (1 + MAX_SCR)), "SPI rate too small: %u", cfg->rate);
297     SPI_ASSERT(cfg->tx_bits <= MAX_DATA_BITS && cfg->tx_bits >= MIN_DATA_BITS, "Invalid SPI TX bits: %d", cfg->tx_bits);
298     SPI_ASSERT(cfg->rx_bits <= MAX_DATA_BITS && cfg->rx_bits >= MIN_DATA_BITS, "Invalid SPI RX bits: %d", cfg->rx_bits);
299     SPI_ASSERT(cfg->rx_frame_bits <= MAX_DATA_BITS && (cfg->rx_frame_bits == 0 || cfg->rx_frame_bits > cfg->rx_bits),
300         "Invalid SPI RX FRAME bits: %d", cfg->rx_frame_bits);
301     SPI_ASSERT(cfg->cs < HAL_SPI_CS_QTY, "SPI cs bad: %d", cfg->cs);
302 
303     div = (mod_clk + cfg->rate - 1) / cfg->rate;
304     cpsdvsr = (div + MAX_SCR) / (MAX_SCR + 1);
305     if (cpsdvsr < 2) {
306         cpsdvsr = 2;
307     } else {
308         if (cpsdvsr & 0x1) {
309             cpsdvsr += 1;
310         }
311         if (cpsdvsr > MAX_CPSDVSR) {
312             cpsdvsr = MAX_CPSDVSR;
313         }
314     }
315     scr = (div + cpsdvsr - 1) / cpsdvsr;
316     if (scr > 0) {
317         scr -= 1;
318     }
319     if (scr > MAX_SCR) {
320         scr = MAX_SCR;
321     }
322 
323     ctrl->sspcr0_tx = SPI_SSPCR0_SCR(scr) |
324                      (cfg->clk_delay_half ? SPI_SSPCR0_SPH : 0) |
325                      (cfg->clk_polarity ? SPI_SSPCR0_SPO : 0) |
326                      SPI_SSPCR0_FRF(0) | // Only support Motorola SPI frame format
327                      SPI_SSPCR0_DSS(cfg->tx_bits - 1);
328     ctrl->sspcr1 = (cfg->rx_sep_line ? SPI_RX_SEL_EN : 0) |
329                    SPI_SLAVE_ID(cfg->cs) |
330                    SPI_SSPCR1_SOD |
331                    (cfg->slave ? SPI_SSPCR1_MS : 0) |
332                    SPI_SSPCR1_SSE;
333     ctrl->sspcpsr = SPI_SSPCPSR_CPSDVSR(cpsdvsr);
334     ctrl->sspdmacr = (cfg->dma_tx ? SPI_SSPDMACR_TXDMAE : 0) |
335                      (cfg->dma_rx ? SPI_SSPDMACR_RXDMAE : 0);
336     ctrl->ssprxcr_tx = 0;
337     if (cfg->rx_frame_bits > 0) {
338         ctrl->sspcr0_rx = SET_BITFIELD(ctrl->sspcr0_tx, SPI_SSPCR0_DSS, cfg->rx_frame_bits - 1);
339         ctrl->ssprxcr_rx = SPI_SSPRXCR_EN | SPI_SSPRXCR_OEN_POLARITY | SPI_SSPRXCR_RXBITS(cfg->rx_bits - 1);
340     } else {
341         ctrl->sspcr0_rx = SET_BITFIELD(ctrl->sspcr0_tx, SPI_SSPCR0_DSS, cfg->rx_bits - 1);
342         ctrl->ssprxcr_rx = 0;
343     }
344 
345     return 0;
346 }
347 
hal_spi_set_xfer_type_id(enum HAL_SPI_ID_T id,const struct HAL_SPI_CTRL_T * ctrl,enum HAL_SPI_XFER_TYPE_T type)348 static void NOINLINE POSSIBLY_UNUSED hal_spi_set_xfer_type_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, enum HAL_SPI_XFER_TYPE_T type)
349 {
350     uint32_t sspcr0;
351     uint32_t ssprxcr;
352 
353     if (type == HAL_SPI_XFER_TYPE_SEND) {
354         sspcr0 = ctrl->sspcr0_tx;
355         ssprxcr = ctrl->ssprxcr_tx;
356     } else {
357         sspcr0 = ctrl->sspcr0_rx;
358         ssprxcr = ctrl->ssprxcr_rx;
359     }
360 
361     spi[id]->SSPCR0 = sspcr0;
362     spi[id]->SSPRXCR = ssprxcr;
363 }
364 
hal_spi_enable_id(enum HAL_SPI_ID_T id,const struct HAL_SPI_CTRL_T * ctrl,enum HAL_SPI_XFER_TYPE_T type)365 static void NOINLINE hal_spi_enable_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, enum HAL_SPI_XFER_TYPE_T type)
366 {
367     hal_spi_set_xfer_type_id(id, ctrl, type);
368 
369     spi[id]->SSPCR1 = ctrl->sspcr1;
370     spi[id]->SSPCPSR = ctrl->sspcpsr;
371     spi[id]->SSPDMACR = ctrl->sspdmacr;
372 
373 #ifdef SPI_ROM_ONLY
374     if (id == HAL_SPI_ID_INTERNAL) {
375         hal_cmu_ispi_set_freq(HAL_CMU_PERIPH_FREQ_26M);
376 #ifdef CHIP_HAS_SPI
377     } else if (id == HAL_SPI_ID_0) {
378         hal_cmu_spi_set_freq(HAL_CMU_PERIPH_FREQ_26M);
379 #endif
380 #ifdef CHIP_HAS_SPILCD
381     } else if (id == HAL_SPI_ID_SLCD) {
382         hal_cmu_slcd_set_freq(HAL_CMU_PERIPH_FREQ_26M);
383 #endif
384     }
385 #else // !SPI_ROM_ONLY
386     if (clk_sel[id] != ctrl->clk_sel) {
387         clk_sel[id] = ctrl->clk_sel;
388         if (ctrl->clk_sel == HAL_SPI_MOD_CLK_SEL_PLL) {
389 #ifdef PERIPH_PLL_FREQ
390             if (0) {
391 #ifdef CHIP_HAS_SPI
392             } else if (id == HAL_SPI_ID_0) {
393                 hal_cmu_spi_set_div(2);
394 #endif
395 #ifdef CHIP_HAS_SPILCD
396             } else if (id == HAL_SPI_ID_SLCD) {
397                 hal_cmu_slcd_set_div(2);
398 #endif
399             }
400             // ISPI cannot use PLL clock
401 #endif
402         } else {
403             enum HAL_CMU_PERIPH_FREQ_T periph_freq;
404 
405             if (ctrl->clk_sel == HAL_SPI_MOD_CLK_SEL_OSC_X2) {
406                 periph_freq = HAL_CMU_PERIPH_FREQ_52M;
407             } else {
408                 periph_freq = HAL_CMU_PERIPH_FREQ_26M;
409             }
410 
411             if (id == HAL_SPI_ID_INTERNAL) {
412                 hal_cmu_ispi_set_freq(periph_freq);
413 #ifdef CHIP_HAS_SPI
414             } else if (id == HAL_SPI_ID_0) {
415                 hal_cmu_spi_set_freq(periph_freq);
416 #endif
417 #ifdef CHIP_HAS_SPILCD
418             } else if (id == HAL_SPI_ID_SLCD) {
419                 hal_cmu_slcd_set_freq(periph_freq);
420 #endif
421             }
422         }
423     }
424 #endif // !SPI_ROM_ONLY
425 }
426 
hal_spi_disable_id(enum HAL_SPI_ID_T id)427 static void hal_spi_disable_id(enum HAL_SPI_ID_T id)
428 {
429     spi[id]->SSPCR1 &= ~SPI_SSPCR1_SSE;
430 }
431 
hal_spi_get_ctrl_id(enum HAL_SPI_ID_T id,struct HAL_SPI_CTRL_T * ctrl)432 static void POSSIBLY_UNUSED hal_spi_get_ctrl_id(enum HAL_SPI_ID_T id, struct HAL_SPI_CTRL_T *ctrl)
433 {
434     ctrl->sspcr0_tx = spi[id]->SSPCR0;
435     ctrl->sspcr1 = spi[id]->SSPCR1;
436     ctrl->sspcpsr = spi[id]->SSPCPSR;
437     ctrl->sspdmacr = spi[id]->SSPDMACR;
438     ctrl->ssprxcr_tx = spi[id]->SSPRXCR;
439 }
440 
hal_spi_open_id(enum HAL_SPI_ID_T id,const struct HAL_SPI_CFG_T * cfg,struct HAL_SPI_CTRL_T * ctrl)441 static int NOINLINE hal_spi_open_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl)
442 {
443     int ret;
444     struct HAL_SPI_CTRL_T ctrl_regs;
445     bool cfg_clk = true;
446 
447     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
448 
449     if (ctrl == NULL) {
450         ctrl = &ctrl_regs;
451     }
452 
453     ret = hal_spi_init_ctrl(cfg, ctrl);
454     if (ret) {
455         return ret;
456     }
457 
458 #ifndef SPI_ROM_ONLY
459     if (!spi_init_done) {
460         spi_init_done = true;
461         for (int i = HAL_SPI_ID_INTERNAL; i < HAL_SPI_ID_QTY; i++) {
462             spi_txdma_chan[i] = HAL_DMA_CHAN_NONE;
463             spi_rxdma_chan[i] = HAL_DMA_CHAN_NONE;
464         }
465     }
466 
467     if (spi_cs_map[id]) {
468         cfg_clk = false;
469     }
470     spi_cs_map[id] |= (1 << cfg->cs);
471 #endif
472 
473     if (cfg_clk) {
474         hal_cmu_clock_enable(spi_mod[id].mod);
475         hal_cmu_clock_enable(spi_mod[id].apb);
476         hal_cmu_reset_clear(spi_mod[id].mod);
477         hal_cmu_reset_clear(spi_mod[id].apb);
478     }
479 
480     hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
481 
482     return 0;
483 }
484 
hal_spi_close_id(enum HAL_SPI_ID_T id,uint32_t cs)485 static int POSSIBLY_UNUSED hal_spi_close_id(enum HAL_SPI_ID_T id, uint32_t cs)
486 {
487     int ret = 0;
488     bool cfg_clk = true;
489 
490 #ifndef SPI_ROM_ONLY
491     if (spi_cs_map[id] & (1 << cs)) {
492         spi_cs_map[id] &= ~(1 << cs);
493 #if (CHIP_SPI_VER >= 2)
494         if (spi_cs_map[id]) {
495             cfg_clk = false;
496         }
497 #endif
498     } else {
499         ret = 1;
500         cfg_clk = false;
501     }
502 #endif
503 
504     if (cfg_clk) {
505         hal_spi_disable_id(id);
506 
507         hal_cmu_reset_set(spi_mod[id].apb);
508         hal_cmu_reset_set(spi_mod[id].mod);
509         hal_cmu_clock_disable(spi_mod[id].apb);
510         hal_cmu_clock_disable(spi_mod[id].mod);
511     }
512 
513     return ret;
514 }
515 
hal_spi_set_cs_id(enum HAL_SPI_ID_T id,uint32_t cs)516 static void POSSIBLY_UNUSED ISPI_API_LOC hal_spi_set_cs_id(enum HAL_SPI_ID_T id, uint32_t cs)
517 {
518     spi[id]->SSPCR1 = SET_BITFIELD(spi[id]->SSPCR1, SPI_SLAVE_ID, cs);
519 }
520 
hal_spi_busy_id(enum HAL_SPI_ID_T id)521 static bool ISPI_API_LOC hal_spi_busy_id(enum HAL_SPI_ID_T id)
522 {
523     return ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && (spi[id]->SSPSR & SPI_SSPSR_BSY));
524 }
525 
hal_spi_enable_slave_output_id(enum HAL_SPI_ID_T id)526 static void ISPI_API_LOC hal_spi_enable_slave_output_id(enum HAL_SPI_ID_T id)
527 {
528     if (spi[id]->SSPCR1 & SPI_SSPCR1_MS) {
529         spi[id]->SSPCR1 &= ~SPI_SSPCR1_SOD;
530     }
531 }
532 
hal_spi_disable_slave_output_id(enum HAL_SPI_ID_T id)533 static void ISPI_API_LOC hal_spi_disable_slave_output_id(enum HAL_SPI_ID_T id)
534 {
535     if (spi[id]->SSPCR1 & SPI_SSPCR1_MS) {
536         spi[id]->SSPCR1 |= SPI_SSPCR1_SOD;
537     }
538 }
539 
hal_spi_send_id(enum HAL_SPI_ID_T id,const void * data,uint32_t len)540 static int ISPI_API_LOC hal_spi_send_id(enum HAL_SPI_ID_T id, const void *data, uint32_t len)
541 {
542     uint8_t cnt;
543     uint32_t sent, value;
544     int ret;
545 
546     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
547     SPI_ASSERT((spi[id]->SSPDMACR & SPI_SSPDMACR_TXDMAE) == 0, "TX-DMA configured on SPI %d", id);
548 
549     cnt = get_frame_bytes(id);
550 
551     if (len == 0 || (len & (cnt - 1)) != 0) {
552         return -1;
553     }
554 
555     sent = 0;
556 
557     hal_spi_enable_slave_output_id(id);
558 
559     while (sent < len) {
560         if ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) == 0) {
561             break;
562         }
563         if (spi[id]->SSPSR & SPI_SSPSR_TNF) {
564             value = 0;
565             copy_frame_from_bytes(&value, (uint8_t *)data + sent, cnt);
566             spi[id]->SSPDR = value;
567             sent += cnt;
568         }
569     }
570 
571     if (sent >= len) {
572         ret = 0;
573     } else {
574         ret = 1;
575     }
576 
577     while (hal_spi_busy_id(id));
578     hal_spi_disable_slave_output_id(id);
579 
580     return ret;
581 }
582 
hal_spi_recv_id(enum HAL_SPI_ID_T id,const void * cmd,void * data,uint32_t len)583 static int ISPI_API_LOC hal_spi_recv_id(enum HAL_SPI_ID_T id, const void *cmd, void *data, uint32_t len)
584 {
585     uint8_t cnt;
586     uint32_t sent, recv, value;
587     int ret;
588 
589     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
590     SPI_ASSERT((spi[id]->SSPDMACR & (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE)) == 0, "RX/TX-DMA configured on SPI %d", id);
591 
592     cnt = get_frame_bytes(id);
593 
594     if (len == 0 || (len & (cnt - 1)) != 0) {
595         return -1;
596     }
597 
598     // Rx transaction should start from idle state
599     if (spi[id]->SSPSR & SPI_SSPSR_BSY) {
600         return -11;
601     }
602 
603     sent = 0;
604     recv = 0;
605 
606     // Flush the RX FIFO by reset or CPU read
607     while (spi[id]->SSPSR & SPI_SSPSR_RNE) {
608         spi[id]->SSPDR;
609     }
610     spi[id]->SSPICR = ~0UL;
611 
612     hal_spi_enable_slave_output_id(id);
613 
614     while (recv < len || sent < len) {
615         if ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) == 0) {
616             break;
617         }
618         if (sent < len && (spi[id]->SSPSR & SPI_SSPSR_TNF)) {
619             value = 0;
620             copy_frame_from_bytes(&value, (uint8_t *)cmd + sent, cnt);
621             spi[id]->SSPDR = value;
622             sent += cnt;
623         }
624         if (recv < len && (spi[id]->SSPSR & SPI_SSPSR_RNE)) {
625             value = spi[id]->SSPDR;
626             copy_bytes_from_frame((uint8_t *)data + recv, value, cnt);
627             recv += cnt;
628         }
629     }
630 
631     if (recv >= len && sent >= len) {
632         ret = 0;
633     } else {
634         ret = 1;
635     }
636 
637     while (hal_spi_busy_id(id));
638     hal_spi_disable_slave_output_id(id);
639 
640     return ret;
641 }
642 
643 #ifdef SPI_ROM_ONLY
644 
645 //------------------------------------------------------------
646 // ISPI ROM functions
647 //------------------------------------------------------------
648 
hal_ispi_rom_open(const struct HAL_SPI_CFG_T * cfg)649 int hal_ispi_rom_open(const struct HAL_SPI_CFG_T *cfg)
650 {
651     SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "ISPI_ROM: Bad bits cfg");
652 
653     return hal_spi_open_id(HAL_SPI_ID_INTERNAL, cfg, NULL);
654 }
655 
hal_ispi_rom_activate_cs(uint32_t cs)656 void hal_ispi_rom_activate_cs(uint32_t cs)
657 {
658     SPI_ASSERT(cs < ISPI_CS_QTY, "ISPI_ROM: SPI cs bad: %d", cs);
659 
660     hal_spi_set_cs_id(HAL_SPI_ID_INTERNAL, cs);
661 }
662 
hal_ispi_rom_busy(void)663 int hal_ispi_rom_busy(void)
664 {
665     return hal_spi_busy_id(HAL_SPI_ID_INTERNAL);
666 }
667 
hal_ispi_rom_send(const void * data,uint32_t len)668 int hal_ispi_rom_send(const void *data, uint32_t len)
669 {
670     int ret;
671 
672     ret = hal_spi_send_id(HAL_SPI_ID_INTERNAL, data, len);
673 
674     return ret;
675 }
676 
hal_ispi_rom_recv(const void * cmd,void * data,uint32_t len)677 int hal_ispi_rom_recv(const void *cmd, void *data, uint32_t len)
678 {
679     int ret;
680 
681     ret = hal_spi_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len);
682 
683     return ret;
684 }
685 
686 #ifdef CHIP_HAS_SPIPHY
687 //------------------------------------------------------------
688 // SPI PHY ROM functions
689 //------------------------------------------------------------
690 
hal_spiphy_rom_open(const struct HAL_SPI_CFG_T * cfg)691 int hal_spiphy_rom_open(const struct HAL_SPI_CFG_T *cfg)
692 {
693     SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "SPIPHY_ROM: Bad bits cfg");
694 
695     return hal_spi_open_id(HAL_SPI_ID_PHY, cfg, NULL);
696 }
697 
hal_spiphy_rom_busy(void)698 int hal_spiphy_rom_busy(void)
699 {
700     return hal_spi_busy_id(HAL_SPI_ID_PHY);
701 }
702 
hal_spiphy_rom_send(const void * data,uint32_t len)703 int hal_spiphy_rom_send(const void *data, uint32_t len)
704 {
705     int ret;
706 
707     ret = hal_spi_send_id(HAL_SPI_ID_PHY, data, len);
708 
709     return ret;
710 }
711 
hal_spiphy_rom_recv(const void * cmd,void * data,uint32_t len)712 int hal_spiphy_rom_recv(const void *cmd, void *data, uint32_t len)
713 {
714     int ret;
715 
716     ret = hal_spi_recv_id(HAL_SPI_ID_PHY, cmd, data, len);
717 
718     return ret;
719 }
720 #endif
721 
722 #else // !SPI_ROM_ONLY
723 
724 POSSIBLY_UNUSED
hal_spi_activate_cs_id(enum HAL_SPI_ID_T id,uint32_t cs)725 static int hal_spi_activate_cs_id(enum HAL_SPI_ID_T id, uint32_t cs)
726 {
727     struct HAL_SPI_CTRL_T *ctrl = NULL;
728 
729     SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPI cs bad: %d", cs);
730     SPI_ASSERT(spi_cs_map[id] & (1 << cs), "SPI cs not opened: %d", cs);
731 
732 #if (CHIP_SPI_VER >= 2)
733     if (0) {
734 #ifdef CHIP_HAS_SPI
735     } else if (id == HAL_SPI_ID_0) {
736         spi0_cs = cs;
737 #endif
738 #ifdef CHIP_HAS_SPILCD
739     } else if (id == HAL_SPI_ID_SLCD) {
740         spilcd_cs = cs;
741 #endif
742     }
743 #endif
744 
745     if (0) {
746 #ifdef CHIP_HAS_SPI
747     } else if (id == HAL_SPI_ID_0) {
748         ctrl = &spi0_ctrl[spi0_cs];
749 #endif
750 #ifdef CHIP_HAS_SPILCD
751     } else if (id == HAL_SPI_ID_SLCD) {
752         ctrl = &spilcd_ctrl[spilcd_cs];
753 #endif
754     }
755     if (ctrl) {
756         hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
757     }
758 
759     return 0;
760 }
761 
hal_spi_enable_and_send_id(enum HAL_SPI_ID_T id,const struct HAL_SPI_CTRL_T * ctrl,const void * data,uint32_t len)762 static int POSSIBLY_UNUSED hal_spi_enable_and_send_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len)
763 {
764     int ret;
765     struct HAL_SPI_CTRL_T saved;
766 
767     if (set_bool_flag(&in_use[id])) {
768         return -31;
769     }
770 
771     hal_spi_get_ctrl_id(id, &saved);
772     hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
773     ret = hal_spi_send_id(id, data, len);
774     hal_spi_enable_id(id, &saved, HAL_SPI_XFER_TYPE_SEND);
775 
776     clear_bool_flag(&in_use[id]);
777 
778     return ret;
779 }
780 
hal_spi_enable_and_recv_id(enum HAL_SPI_ID_T id,const struct HAL_SPI_CTRL_T * ctrl,const void * cmd,void * data,uint32_t len)781 static int POSSIBLY_UNUSED hal_spi_enable_and_recv_id(enum HAL_SPI_ID_T id, const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len)
782 {
783     int ret;
784     struct HAL_SPI_CTRL_T saved;
785 
786     if (set_bool_flag(&in_use[id])) {
787         return -31;
788     }
789 
790     hal_spi_get_ctrl_id(id, &saved);
791     hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_RECV);
792     ret = hal_spi_recv_id(id, cmd, data, len);
793     hal_spi_enable_id(id, &saved, HAL_SPI_XFER_TYPE_SEND);
794 
795     clear_bool_flag(&in_use[id]);
796 
797     return ret;
798 }
799 
hal_spi_txdma_handler(uint8_t chan,uint32_t remains,uint32_t error,struct HAL_DMA_DESC_T * lli)800 static void hal_spi_txdma_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli)
801 {
802     enum HAL_SPI_ID_T id;
803     uint32_t lock;
804 
805     lock = int_lock();
806     for (id = HAL_SPI_ID_INTERNAL; id < HAL_SPI_ID_QTY; id++) {
807         if (spi_txdma_chan[id] == chan) {
808             spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
809             break;
810         }
811     }
812     int_unlock(lock);
813 
814     if (id >= HAL_SPI_ID_QTY) {
815         return;
816     }
817 
818     hal_gpdma_free_chan(chan);
819 
820     clear_bool_flag(&in_use[id]);
821 
822     if (spi_txdma_handler[id]) {
823         spi_txdma_handler[id](error);
824     }
825 }
826 
hal_spi_dma_send_id(enum HAL_SPI_ID_T id,const void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)827 static int hal_spi_dma_send_id(enum HAL_SPI_ID_T id, const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
828 {
829     uint8_t cnt;
830     enum HAL_DMA_RET_T ret;
831     struct HAL_DMA_CH_CFG_T dma_cfg;
832     enum HAL_DMA_WDITH_T dma_width;
833     uint32_t lock;
834     enum HAL_DMA_PERIPH_T dst_periph;
835 
836     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
837     SPI_ASSERT((spi[id]->SSPDMACR & SPI_SSPDMACR_TXDMAE), "TX-DMA not configured on SPI %d", id);
838 
839     spi_txdma_handler[id] = handler;
840 
841     cnt = get_frame_bytes(id);
842 
843     if ((len & (cnt - 1)) != 0) {
844         return -1;
845     }
846     if (((uint32_t)data & (cnt - 1)) != 0) {
847         return -2;
848     }
849 
850     // Tx transaction should start from idle state for SPI mode 1 and 3 (SPH=1)
851     if ((spi[id]->SSPCR0 & SPI_SSPCR0_SPH) && (spi[id]->SSPSR & SPI_SSPSR_BSY)) {
852         return -11;
853     }
854 
855     if (id == HAL_SPI_ID_INTERNAL) {
856         dst_periph = HAL_GPDMA_ISPI_TX;
857 #ifdef CHIP_HAS_SPI
858     } else if (id == HAL_SPI_ID_0) {
859         dst_periph = HAL_GPDMA_SPI_TX;
860 #endif
861 #ifdef CHIP_HAS_SPILCD
862     } else if (id == HAL_SPI_ID_SLCD) {
863         dst_periph = HAL_GPDMA_SPILCD_TX;
864 #endif
865     } else {
866         return -12;
867     }
868 
869     lock = int_lock();
870     if (spi_txdma_chan[id] != HAL_DMA_CHAN_NONE) {
871         int_unlock(lock);
872         return -3;
873     }
874     spi_txdma_chan[id] = hal_gpdma_get_chan(dst_periph, HAL_DMA_HIGH_PRIO);
875     if (spi_txdma_chan[id] == HAL_DMA_CHAN_NONE) {
876         int_unlock(lock);
877         return -4;
878     }
879     int_unlock(lock);
880 
881     if (cnt == 1) {
882         dma_width = HAL_DMA_WIDTH_BYTE;
883     } else if (cnt == 2) {
884         dma_width = HAL_DMA_WIDTH_HALFWORD;
885     } else {
886         dma_width = HAL_DMA_WIDTH_WORD;
887     }
888 
889     memset(&dma_cfg, 0, sizeof(dma_cfg));
890     dma_cfg.ch = spi_txdma_chan[id];
891     dma_cfg.dst = 0; // useless
892     dma_cfg.dst_bsize = HAL_DMA_BSIZE_4;
893     dma_cfg.dst_periph = dst_periph;
894     dma_cfg.dst_width = dma_width;
895     dma_cfg.handler = handler ? hal_spi_txdma_handler : NULL;
896     dma_cfg.src = (uint32_t)data;
897     dma_cfg.src_bsize = HAL_DMA_BSIZE_16;
898     //dma_cfg.src_periph = HAL_GPDMA_PERIPH_QTY; // useless
899     dma_cfg.src_tsize = len / cnt;
900     dma_cfg.src_width = dma_width;
901     dma_cfg.try_burst = 0;
902     dma_cfg.type = HAL_DMA_FLOW_M2P_DMA;
903 
904     hal_spi_enable_slave_output_id(id);
905 
906     ret = hal_gpdma_start(&dma_cfg);
907     if (ret != HAL_DMA_OK) {
908         hal_spi_disable_slave_output_id(id);
909         return -5;
910     }
911 
912     if (handler == NULL) {
913         while ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && hal_gpdma_chan_busy(spi_txdma_chan[id]));
914         hal_gpdma_free_chan(spi_txdma_chan[id]);
915         spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
916         while (hal_spi_busy_id(id));
917         hal_spi_disable_slave_output_id(id);
918     }
919 
920     return 0;
921 }
922 
hal_spi_stop_dma_send_id(enum HAL_SPI_ID_T id)923 static void hal_spi_stop_dma_send_id(enum HAL_SPI_ID_T id)
924 {
925     uint32_t lock;
926     uint8_t tx_chan;
927 
928     lock = int_lock();
929     tx_chan = spi_txdma_chan[id];
930     spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
931     int_unlock(lock);
932 
933     if (tx_chan != HAL_DMA_CHAN_NONE) {
934         hal_gpdma_cancel(tx_chan);
935         hal_gpdma_free_chan(tx_chan);
936     }
937 
938     clear_bool_flag(&in_use[id]);
939 }
940 
hal_spi_rxdma_handler(uint8_t chan,uint32_t remains,uint32_t error,struct HAL_DMA_DESC_T * lli)941 static void hal_spi_rxdma_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli)
942 {
943     enum HAL_SPI_ID_T id;
944     uint32_t lock;
945     uint8_t tx_chan = HAL_DMA_CHAN_NONE;
946     struct HAL_SPI_CTRL_T *ctrl = NULL;
947 
948     lock = int_lock();
949     for (id = HAL_SPI_ID_INTERNAL; id < HAL_SPI_ID_QTY; id++) {
950         if (spi_rxdma_chan[id] == chan) {
951             tx_chan = spi_txdma_chan[id];
952             spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE;
953             spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
954             break;
955         }
956     }
957     int_unlock(lock);
958 
959     if (id >= HAL_SPI_ID_QTY) {
960         return;
961     }
962 
963     hal_gpdma_free_chan(chan);
964     hal_gpdma_cancel(tx_chan);
965     hal_gpdma_free_chan(tx_chan);
966 
967     if (0) {
968 #ifdef CHIP_HAS_SPI
969     } else if (id == HAL_SPI_ID_0) {
970         ctrl = &spi0_ctrl[spi0_cs];
971 #endif
972 #ifdef CHIP_HAS_SPILCD
973     } else if (id == HAL_SPI_ID_SLCD) {
974         ctrl = &spilcd_ctrl[spilcd_cs];
975 #endif
976     }
977     if (ctrl) {
978         hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
979     }
980     clear_bool_flag(&in_use[id]);
981 
982     if (spi_rxdma_handler[id]) {
983         spi_rxdma_handler[id](error);
984     }
985 }
986 
987 #ifdef CHIP_HAS_SPILCD
hal_spi_slave_rxdma_handler(uint8_t chan,uint32_t remains,uint32_t error,struct HAL_DMA_DESC_T * lli)988 static void hal_spi_slave_rxdma_handler(uint8_t chan, uint32_t remains, uint32_t error, struct HAL_DMA_DESC_T *lli)
989 {
990     enum HAL_SPI_ID_T id;
991     uint32_t lock;
992     uint32_t xfer;
993 
994     lock = int_lock();
995     for (id = HAL_SPI_ID_INTERNAL; id < HAL_SPI_ID_QTY; id++) {
996         if (spi_rxdma_chan[id] == chan) {
997             if (spi_slave_recv_dma_mode[id] == SPI_RX_DMA_MODE_NORMAL) {
998                 spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE;
999             }
1000             break;
1001         }
1002     }
1003     int_unlock(lock);
1004 
1005     if (id >= HAL_SPI_ID_QTY) {
1006         return;
1007     }
1008     if (spi_slave_recv_dma_mode[id] == SPI_RX_DMA_MODE_NORMAL) {
1009         // Get remain xfer size
1010         xfer = hal_gpdma_get_sg_remain_size(chan);
1011         hal_gpdma_free_chan(chan);
1012     } else {
1013         xfer = 0;
1014     }
1015     if (spi_rxdma_handler[id]) {
1016         if (spi_slave_recv_dma_mode[id] == SPI_RX_DMA_MODE_NORMAL) {
1017             // Already get xfer size
1018             if (spi_slave_recv_dma_size[id] > xfer) {
1019                 xfer = spi_slave_recv_dma_size[id] - xfer;
1020             } else {
1021                 xfer = 0;
1022             }
1023         } else if (spi_slave_recv_dma_mode[id] == SPI_RX_DMA_MODE_PINGPANG) {
1024             xfer = spi_slave_recv_dma_size[id] / 2;
1025         }
1026         spi_rxdma_handler[id](error);
1027     }
1028 }
1029 #endif
1030 
hal_spi_dma_recv_id(enum HAL_SPI_ID_T id,const void * cmd,void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1031 static int hal_spi_dma_recv_id(enum HAL_SPI_ID_T id, const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1032 {
1033     uint8_t cnt;
1034     enum HAL_DMA_RET_T ret;
1035     struct HAL_DMA_CH_CFG_T dma_cfg;
1036     enum HAL_DMA_WDITH_T dma_width;
1037     uint32_t lock;
1038     int result;
1039     enum HAL_DMA_PERIPH_T dst_periph, src_periph;
1040     struct HAL_SPI_CTRL_T *ctrl = NULL;
1041 
1042     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
1043     SPI_ASSERT((spi[id]->SSPDMACR & (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE)) ==
1044         (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE), "RX/TX-DMA not configured on SPI %d", id);
1045 
1046     spi_rxdma_handler[id] = handler;
1047 
1048     result = 0;
1049 
1050     cnt = get_frame_bytes(id);
1051 
1052     if ((len & (cnt - 1)) != 0) {
1053         return -1;
1054     }
1055     if (((uint32_t)data & (cnt - 1)) != 0) {
1056         return -2;
1057     }
1058 
1059     // Rx transaction should start from idle state
1060     if (spi[id]->SSPSR & SPI_SSPSR_BSY) {
1061         return -11;
1062     }
1063 
1064     if (id == HAL_SPI_ID_INTERNAL) {
1065         src_periph = HAL_GPDMA_ISPI_RX;
1066         dst_periph = HAL_GPDMA_ISPI_TX;
1067 #ifdef CHIP_HAS_SPI
1068     } else if (id == HAL_SPI_ID_0) {
1069         src_periph = HAL_GPDMA_SPI_RX;
1070         dst_periph = HAL_GPDMA_SPI_TX;
1071 #endif
1072 #ifdef CHIP_HAS_SPILCD
1073     } else if (id == HAL_SPI_ID_SLCD) {
1074         src_periph = HAL_GPDMA_SPILCD_RX;
1075         dst_periph = HAL_GPDMA_SPILCD_TX;
1076 #endif
1077     } else {
1078         return -12;
1079     }
1080 
1081     lock = int_lock();
1082     if (spi_txdma_chan[id] != HAL_DMA_CHAN_NONE || spi_rxdma_chan[id] != HAL_DMA_CHAN_NONE) {
1083         int_unlock(lock);
1084         return -3;
1085     }
1086     spi_txdma_chan[id] = hal_gpdma_get_chan(dst_periph, HAL_DMA_HIGH_PRIO);
1087     if (spi_txdma_chan[id] == HAL_DMA_CHAN_NONE) {
1088         int_unlock(lock);
1089         return -4;
1090     }
1091     spi_rxdma_chan[id] = hal_gpdma_get_chan(src_periph, HAL_DMA_HIGH_PRIO);
1092     if (spi_rxdma_chan[id] == HAL_DMA_CHAN_NONE) {
1093         hal_gpdma_free_chan(spi_txdma_chan[id]);
1094         spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
1095         int_unlock(lock);
1096         return -5;
1097     }
1098     int_unlock(lock);
1099 
1100     if (cnt == 1) {
1101         dma_width = HAL_DMA_WIDTH_BYTE;
1102     } else if (cnt == 2) {
1103         dma_width = HAL_DMA_WIDTH_HALFWORD;
1104     } else {
1105         dma_width = HAL_DMA_WIDTH_WORD;
1106     }
1107 
1108     memset(&dma_cfg, 0, sizeof(dma_cfg));
1109     dma_cfg.ch = spi_rxdma_chan[id];
1110     dma_cfg.dst = (uint32_t)data;
1111     dma_cfg.dst_bsize = HAL_DMA_BSIZE_16;
1112     //dma_cfg.dst_periph = HAL_GPDMA_PERIPH_QTY; // useless
1113     dma_cfg.dst_width = dma_width;
1114     dma_cfg.handler = handler ? hal_spi_rxdma_handler : NULL;
1115     dma_cfg.src = 0; // useless
1116     dma_cfg.src_periph = src_periph;
1117     dma_cfg.src_bsize = HAL_DMA_BSIZE_4;
1118     dma_cfg.src_tsize = len / cnt;
1119     dma_cfg.src_width = dma_width;
1120     dma_cfg.try_burst = 0;
1121     dma_cfg.type = HAL_DMA_FLOW_P2M_DMA;
1122 
1123     // Flush the RX FIFO by reset or DMA read (CPU read is forbidden when DMA is enabled)
1124     if (spi[id]->SSPSR & SPI_SSPSR_RNE) {
1125         // Reset SPI MODULE might cause the increment of the FIFO pointer
1126         hal_cmu_reset_pulse(spi_mod[id].mod);
1127         // Reset SPI APB will reset the FIFO pointer
1128         hal_cmu_reset_pulse(spi_mod[id].apb);
1129         if (0) {
1130 #ifdef CHIP_HAS_SPI
1131         } else if (id == HAL_SPI_ID_0) {
1132             ctrl = &spi0_ctrl[spi0_cs];
1133 #endif
1134 #ifdef CHIP_HAS_SPILCD
1135         } else if (id == HAL_SPI_ID_SLCD) {
1136             ctrl = &spilcd_ctrl[spilcd_cs];
1137 #endif
1138         }
1139         if (ctrl) {
1140             // hal_spi_set_xfer_type_id() is not enough, for all the registers have been reset by APB reset
1141             hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_RECV);
1142         }
1143     }
1144     spi[id]->SSPICR = ~0UL;
1145 
1146     ret = hal_gpdma_start(&dma_cfg);
1147     if (ret != HAL_DMA_OK) {
1148         result = -8;
1149         goto _exit;
1150     }
1151 
1152     dma_cfg.ch = spi_txdma_chan[id];
1153     dma_cfg.dst = 0; // useless
1154     dma_cfg.dst_bsize = HAL_DMA_BSIZE_4;
1155     dma_cfg.dst_periph = dst_periph;
1156     dma_cfg.dst_width = dma_width;
1157     dma_cfg.handler = NULL;
1158     dma_cfg.src = (uint32_t)cmd;
1159     dma_cfg.src_bsize = HAL_DMA_BSIZE_16;
1160     //dma_cfg.src_periph = HAL_GPDMA_PERIPH_QTY; // useless
1161     dma_cfg.src_tsize = len / cnt;
1162     dma_cfg.src_width = dma_width;
1163     dma_cfg.try_burst = 0;
1164     dma_cfg.type = HAL_DMA_FLOW_M2P_DMA;
1165 
1166     hal_spi_enable_slave_output_id(id);
1167 
1168     ret = hal_gpdma_start(&dma_cfg);
1169     if (ret != HAL_DMA_OK) {
1170         result = -9;
1171         goto _exit;
1172     }
1173 
1174     if (handler == NULL) {
1175         while ((spi[id]->SSPCR1 & SPI_SSPCR1_SSE) && hal_gpdma_chan_busy(spi_rxdma_chan[id]));
1176     }
1177 
1178 _exit:
1179     if (result || handler == NULL) {
1180         hal_gpdma_cancel(spi_txdma_chan[id]);
1181         hal_gpdma_free_chan(spi_txdma_chan[id]);
1182         spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
1183 
1184         while (hal_spi_busy_id(id));
1185         hal_spi_disable_slave_output_id(id);
1186 
1187         hal_gpdma_cancel(spi_rxdma_chan[id]);
1188         hal_gpdma_free_chan(spi_rxdma_chan[id]);
1189         spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE;
1190 
1191         if (ctrl) {
1192             hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
1193         }
1194     }
1195 
1196     return 0;
1197 }
1198 
1199 #ifdef CHIP_HAS_SPILCD
spi_slave_fill_dma_desc(struct HAL_DMA_DESC_T * desc,uint32_t cnt,uint32_t cnt_mode,struct HAL_DMA_CH_CFG_T * cfg,uint32_t len,enum SPI_RX_DMA_MODE_T mode,uint32_t step)1200 static int spi_slave_fill_dma_desc(struct HAL_DMA_DESC_T *desc, uint32_t cnt, uint32_t cnt_mode, struct HAL_DMA_CH_CFG_T *cfg,
1201                              uint32_t len, enum SPI_RX_DMA_MODE_T mode, uint32_t step)
1202 {
1203     enum HAL_DMA_RET_T ret;
1204     struct HAL_DMA_DESC_T *last_desc;
1205     int tc_irq;
1206     int i;
1207 
1208     for (i = 0; i < cnt_mode - 1; i++) {
1209         cfg->src_tsize = step/cnt;
1210         tc_irq = 0;
1211         if (mode == SPI_RX_DMA_MODE_PINGPANG) {
1212             tc_irq = (i == cnt_mode / 2 - 1) ? 1 : 0;
1213         } else if (mode == SPI_RX_DMA_MODE_STREAM) {
1214             tc_irq = 1;
1215         }
1216         ret = hal_gpdma_init_desc(&desc[i], cfg, &desc[i + 1], tc_irq);
1217         if (ret != HAL_DMA_OK) {
1218             return 1;
1219         }
1220         cfg->dst += step;
1221     }
1222 
1223     cfg->src_tsize = (len - (step * i))/cnt;
1224     last_desc = NULL;
1225     if (mode == SPI_RX_DMA_MODE_PINGPANG || mode == SPI_RX_DMA_MODE_STREAM) {
1226         last_desc = &desc[0];
1227     }
1228     ret = hal_gpdma_init_desc(&desc[i], cfg, last_desc, 1);
1229     if (ret != HAL_DMA_OK) {
1230         return 1;
1231     }
1232 
1233     return 0;
1234 }
1235 #endif
1236 
hal_spi_slave_dma_recv(void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,enum SPI_RX_DMA_MODE_T mode,uint32_t step)1237 int hal_spi_slave_dma_recv(void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler,
1238                               struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,enum SPI_RX_DMA_MODE_T mode, uint32_t step)
1239 {
1240 #ifdef CHIP_HAS_SPILCD
1241     uint8_t cnt;
1242     uint32_t cnt_mode;
1243     enum HAL_DMA_RET_T ret;
1244     struct HAL_DMA_CH_CFG_T dma_cfg;
1245     enum HAL_DMA_WDITH_T dma_width;
1246     uint32_t lock;
1247     enum HAL_DMA_PERIPH_T src_periph;
1248     struct HAL_SPI_CTRL_T *ctrl = NULL;
1249     struct HAL_DMA_DESC_T desc_c1;
1250 
1251     enum HAL_SPI_ID_T id = HAL_SPI_ID_SLCD;
1252     //SPI_ASSERT(id < HAL_SPI_ID_QTY, invalid_id, id);
1253     SPI_ASSERT((spi[id]->SSPDMACR & (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE)) ==
1254         (SPI_SSPDMACR_TXDMAE | SPI_SSPDMACR_RXDMAE), "RX/TX-DMA not configured on SPI %d", id);
1255 
1256     hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_RECV);
1257     spi_rxdma_handler[id] = handler;
1258     cnt = get_frame_bytes(id);
1259 
1260     if ((len & (cnt - 1)) != 0) {
1261         return -1;
1262     }
1263     if (((uint32_t)data & (cnt - 1)) != 0) {
1264         return -2;
1265     }
1266 
1267     if (0) {
1268     } else if (mode == SPI_RX_DMA_MODE_NORMAL) {
1269         cnt_mode = (len + step - 1) / step;
1270     } else if (mode == SPI_RX_DMA_MODE_PINGPANG) {
1271         cnt_mode = ((len / 2 + step - 1) / step) * 2;
1272         step = len / cnt_mode;
1273         if (len % cnt_mode != 0) {
1274             return -11;
1275         }
1276         if (step == 0) {
1277             return -12;
1278         }
1279     } else if (mode == SPI_RX_DMA_MODE_STREAM) {
1280         cnt_mode = (len + step - 1) / step;
1281         if (cnt_mode == 1) {
1282             // cnt should >= 2
1283             cnt_mode++;
1284         }
1285         step = (len + cnt_mode - 1) / cnt_mode;
1286         if (step == 0) {
1287             return -13;
1288         }
1289     } else {
1290         return -10;
1291     }
1292 
1293     if (desc == NULL && desc_cnt) {
1294         *desc_cnt = (cnt == 1) ? 0 : cnt;
1295         return 0;
1296     }
1297 
1298     if (cnt_mode > 1) {
1299         if (desc == NULL || desc_cnt == NULL) {
1300             return -1;
1301         }
1302         if (*desc_cnt < cnt_mode) {
1303             return -2;
1304         }
1305     } else {
1306         // Use desc in current stack
1307         desc = &desc_c1;
1308     }
1309     if (desc_cnt) {
1310         *desc_cnt = (cnt_mode == 1) ? 0 : cnt_mode;
1311     }
1312 
1313     // Rx transaction should start from idle state
1314     if (spi[id]->SSPSR & SPI_SSPSR_BSY) {
1315         return -11;
1316     }
1317 
1318     if (id == HAL_SPI_ID_INTERNAL) {
1319         src_periph = HAL_GPDMA_ISPI_RX;
1320 #ifdef CHIP_HAS_SPI
1321     } else if (id == HAL_SPI_ID_0) {
1322         src_periph = HAL_GPDMA_SPI_RX;
1323 #endif
1324 #ifdef CHIP_HAS_SPILCD
1325     } else if (id == HAL_SPI_ID_SLCD) {
1326         src_periph = HAL_GPDMA_SPILCD_RX;
1327 #endif
1328     } else {
1329         return -12;
1330     }
1331 
1332     lock = int_lock();
1333     spi_rxdma_chan[id] = hal_gpdma_get_chan(src_periph, HAL_DMA_HIGH_PRIO);
1334     if (spi_rxdma_chan[id] == HAL_DMA_CHAN_NONE) {
1335         int_unlock(lock);
1336         return -5;
1337     }
1338     int_unlock(lock);
1339 
1340     if (cnt == 1) {
1341         dma_width = HAL_DMA_WIDTH_BYTE;
1342     } else if (cnt == 2) {
1343         dma_width = HAL_DMA_WIDTH_HALFWORD;
1344     } else {
1345         dma_width = HAL_DMA_WIDTH_WORD;
1346     }
1347 
1348     memset(&dma_cfg, 0, sizeof(dma_cfg));
1349     dma_cfg.ch = spi_rxdma_chan[id];
1350     dma_cfg.dst = (uint32_t)data;
1351     dma_cfg.dst_bsize = HAL_DMA_BSIZE_16;
1352     //dma_cfg.dst_periph = HAL_GPDMA_PERIPH_QTY; // useless
1353     dma_cfg.dst_width = dma_width;
1354     dma_cfg.handler = handler ? hal_spi_slave_rxdma_handler : NULL;
1355     dma_cfg.src = 0; // useless
1356     dma_cfg.src_periph = src_periph;
1357     dma_cfg.src_bsize = HAL_DMA_BSIZE_8;
1358     dma_cfg.src_tsize = len;
1359     dma_cfg.src_width = dma_width;
1360     dma_cfg.try_burst = 0;
1361     dma_cfg.type = HAL_DMA_FLOW_P2M_DMA;
1362 
1363     // Flush the RX FIFO by reset or DMA read (CPU read is forbidden when DMA is enabled)
1364     if (spi[id]->SSPSR & SPI_SSPSR_RNE) {
1365         // Reset SPI MODULE might cause the increment of the FIFO pointer
1366         hal_cmu_reset_pulse(spi_mod[id].mod);
1367         // Reset SPI APB will reset the FIFO pointer
1368         hal_cmu_reset_pulse(spi_mod[id].apb);
1369         if (0) {
1370 #ifdef CHIP_HAS_SPI
1371         } else if (id == HAL_SPI_ID_0) {
1372             ctrl = &spi0_ctrl[spi0_cs];
1373 #endif
1374 #ifdef CHIP_HAS_SPILCD
1375         } else if (id == HAL_SPI_ID_SLCD) {
1376             ctrl = &spilcd_ctrl[spilcd_cs];
1377 #endif
1378         }
1379         if (ctrl) {
1380             // hal_spi_set_xfer_type_id() is not enough, for all the registers have been reset by APB reset
1381             hal_spi_enable_id(id, ctrl, HAL_SPI_XFER_TYPE_RECV);
1382         }
1383     }
1384     spi[id]->SSPICR = ~0UL;
1385 
1386     if (cnt_mode == 1) {
1387         ret = hal_dma_init_desc(desc, &dma_cfg, NULL, 1);
1388         if (ret != HAL_DMA_OK) {
1389             ret = 1;
1390         }
1391     } else {
1392         ret = spi_slave_fill_dma_desc(desc, cnt, cnt_mode, &dma_cfg, len, mode, step);
1393     }
1394     if (ret) {
1395         return 2;
1396     }
1397 
1398     spi_slave_recv_dma_mode[id] = mode;
1399     spi_slave_recv_dma_size[id] = len;
1400 
1401     ret = hal_gpdma_sg_start(desc, &dma_cfg);
1402     if (ret == HAL_DMA_OK) {
1403         ret = 0;
1404     } else {
1405         hal_gpdma_free_chan(spi_rxdma_chan[id]);
1406         spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE;
1407         ret = 5;
1408     }
1409 #else
1410     SPI_ASSERT(0,"Wrong case");
1411 #endif
1412     return 0;
1413 }
1414 
hal_spi_stop_dma_recv_id(enum HAL_SPI_ID_T id)1415 void hal_spi_stop_dma_recv_id(enum HAL_SPI_ID_T id)
1416 {
1417     uint32_t lock;
1418     uint8_t rx_chan, tx_chan;
1419     struct HAL_SPI_CTRL_T *ctrl = NULL;
1420 
1421     lock = int_lock();
1422     rx_chan = spi_rxdma_chan[id];
1423     spi_rxdma_chan[id] = HAL_DMA_CHAN_NONE;
1424     tx_chan = spi_txdma_chan[id];
1425     spi_txdma_chan[id] = HAL_DMA_CHAN_NONE;
1426     int_unlock(lock);
1427 
1428     if (rx_chan == HAL_DMA_CHAN_NONE && tx_chan == HAL_DMA_CHAN_NONE) {
1429         return;
1430     }
1431 
1432     if (rx_chan != HAL_DMA_CHAN_NONE) {
1433         hal_gpdma_cancel(rx_chan);
1434         hal_gpdma_free_chan(rx_chan);
1435     }
1436     if (tx_chan != HAL_DMA_CHAN_NONE) {
1437         hal_gpdma_cancel(tx_chan);
1438         hal_gpdma_free_chan(tx_chan);
1439     }
1440 
1441     if (0) {
1442 #ifdef CHIP_HAS_SPI
1443     } else if (id == HAL_SPI_ID_0) {
1444         ctrl = &spi0_ctrl[spi0_cs];
1445 #endif
1446 #ifdef CHIP_HAS_SPILCD
1447     } else if (id == HAL_SPI_ID_SLCD) {
1448         ctrl = &spilcd_ctrl[spilcd_cs];
1449 #endif
1450     }
1451     if (ctrl) {
1452         hal_spi_set_xfer_type_id(id, ctrl, HAL_SPI_XFER_TYPE_SEND);
1453     }
1454     clear_bool_flag(&in_use[id]);
1455 }
1456 
1457 //------------------------------------------------------------
1458 // ISPI functions
1459 //------------------------------------------------------------
1460 
hal_ispi_open(const struct HAL_SPI_CFG_T * cfg)1461 int BOOT_TEXT_FLASH_LOC hal_ispi_open(const struct HAL_SPI_CFG_T *cfg)
1462 {
1463     SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "ISPI: Bad bits cfg");
1464 
1465     return hal_spi_open_id(HAL_SPI_ID_INTERNAL, cfg, NULL);
1466 }
1467 
hal_ispi_close(uint32_t cs)1468 int hal_ispi_close(uint32_t cs)
1469 {
1470     return hal_spi_close_id(HAL_SPI_ID_INTERNAL, cs);
1471 }
1472 
hal_ispi_activate_cs(uint32_t cs)1473 void ISPI_API_LOC hal_ispi_activate_cs(uint32_t cs)
1474 {
1475     SPI_ASSERT(cs < ISPI_CS_QTY, "ISPI: SPI cs bad: %d", cs);
1476 
1477     hal_spi_set_cs_id(HAL_SPI_ID_INTERNAL, cs);
1478 }
1479 
hal_ispi_busy(void)1480 int hal_ispi_busy(void)
1481 {
1482     return hal_spi_busy_id(HAL_SPI_ID_INTERNAL);
1483 }
1484 
hal_ispi_send(const void * data,uint32_t len)1485 int ISPI_API_LOC hal_ispi_send(const void *data, uint32_t len)
1486 {
1487     int ret;
1488 
1489     if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) {
1490         return -31;
1491     }
1492 
1493     ret = hal_spi_send_id(HAL_SPI_ID_INTERNAL, data, len);
1494 
1495     clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]);
1496 
1497     return ret;
1498 }
1499 
hal_ispi_recv(const void * cmd,void * data,uint32_t len)1500 int ISPI_API_LOC hal_ispi_recv(const void *cmd, void *data, uint32_t len)
1501 {
1502     int ret;
1503 
1504     if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) {
1505         return -31;
1506     }
1507 
1508     ret = hal_spi_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len);
1509 
1510     clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]);
1511 
1512     return ret;
1513 }
1514 
hal_ispi_dma_send(const void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1515 int hal_ispi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1516 {
1517     int ret;
1518 
1519     if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) {
1520         return -31;
1521     }
1522 
1523     ret = hal_spi_dma_send_id(HAL_SPI_ID_INTERNAL, data, len, handler);
1524 
1525     if (ret || handler == NULL) {
1526         clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]);
1527     }
1528 
1529     return ret;
1530 }
1531 
hal_ispi_dma_recv(const void * cmd,void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1532 int hal_ispi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1533 {
1534     int ret;
1535 
1536     if (set_bool_flag(&in_use[HAL_SPI_ID_INTERNAL])) {
1537         return -31;
1538     }
1539 
1540     ret = hal_spi_dma_recv_id(HAL_SPI_ID_INTERNAL, cmd, data, len, handler);
1541 
1542     if (ret || handler == NULL) {
1543         clear_bool_flag(&in_use[HAL_SPI_ID_INTERNAL]);
1544     }
1545 
1546     return ret;
1547 }
1548 
hal_ispi_stop_dma_send(void)1549 void hal_ispi_stop_dma_send(void)
1550 {
1551     hal_spi_stop_dma_send_id(HAL_SPI_ID_INTERNAL);
1552 }
1553 
hal_ispi_stop_dma_recv(void)1554 void hal_ispi_stop_dma_recv(void)
1555 {
1556     hal_spi_stop_dma_recv_id(HAL_SPI_ID_INTERNAL);
1557 }
1558 
1559 #ifdef CHIP_HAS_SPI
1560 //------------------------------------------------------------
1561 // SPI peripheral functions
1562 //------------------------------------------------------------
1563 
hal_spi_open(const struct HAL_SPI_CFG_T * cfg)1564 int hal_spi_open(const struct HAL_SPI_CFG_T *cfg)
1565 {
1566     int ret;
1567     uint32_t lock;
1568 
1569     if (cfg->cs >= HAL_SPI_CS_QTY) {
1570         return -1;
1571     }
1572 
1573     lock = int_lock();
1574 
1575     ret = hal_spi_open_id(HAL_SPI_ID_0, cfg, &spi0_ctrl[cfg->cs]);
1576 
1577 #if (CHIP_SPI_VER >= 2)
1578     if (ret == 0) {
1579         spi0_cs = cfg->cs;
1580     }
1581 #endif
1582 
1583     int_unlock(lock);
1584 
1585     return ret;
1586 }
1587 
hal_spi_close(uint32_t cs)1588 int hal_spi_close(uint32_t cs)
1589 {
1590     int ret;
1591     uint32_t lock;
1592 
1593     lock = int_lock();
1594 
1595     ret = hal_spi_close_id(HAL_SPI_ID_0, cs);
1596 
1597 #if (CHIP_SPI_VER >= 2)
1598     if (ret == 0 && spi0_cs == cs) {
1599         uint32_t lowest_cs;
1600 
1601         lowest_cs = __CLZ(__RBIT(spi_cs_map[HAL_SPI_ID_0]));
1602         if (lowest_cs < HAL_SPI_CS_QTY) {
1603             hal_spi_activate_cs_id(HAL_SPI_ID_0, lowest_cs);
1604         } else {
1605             lowest_cs = HAL_SPI_CS_0;
1606         }
1607         spi0_cs = lowest_cs;
1608     }
1609 #endif
1610 
1611     int_unlock(lock);
1612 
1613     return ret;
1614 }
1615 
hal_spi_activate_cs(uint32_t cs)1616 int hal_spi_activate_cs(uint32_t cs)
1617 {
1618     return hal_spi_activate_cs_id(HAL_SPI_ID_0, cs);
1619 }
1620 
hal_spi_busy(void)1621 int hal_spi_busy(void)
1622 {
1623     return hal_spi_busy_id(HAL_SPI_ID_0);
1624 }
1625 
hal_spi_send(const void * data,uint32_t len)1626 int hal_spi_send(const void *data, uint32_t len)
1627 {
1628     int ret;
1629 
1630     if (set_bool_flag(&in_use[HAL_SPI_ID_0])) {
1631         return -31;
1632     }
1633 
1634     ret =  hal_spi_send_id(HAL_SPI_ID_0, data, len);
1635 
1636     clear_bool_flag(&in_use[HAL_SPI_ID_0]);
1637 
1638     return ret;
1639 }
1640 
hal_spi_recv(const void * cmd,void * data,uint32_t len)1641 int hal_spi_recv(const void *cmd, void *data, uint32_t len)
1642 {
1643     int ret;
1644 
1645     if (set_bool_flag(&in_use[HAL_SPI_ID_0])) {
1646         return -31;
1647     }
1648 
1649     hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_RECV);
1650     ret = hal_spi_recv_id(HAL_SPI_ID_0, cmd, data, len);
1651     hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_SEND);
1652 
1653     clear_bool_flag(&in_use[HAL_SPI_ID_0]);
1654 
1655     return ret;
1656 }
1657 
hal_spi_dma_send(const void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1658 int hal_spi_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1659 {
1660     int ret;
1661 
1662     if (set_bool_flag(&in_use[HAL_SPI_ID_0])) {
1663         return -31;
1664     }
1665 
1666     ret = hal_spi_dma_send_id(HAL_SPI_ID_0, data, len, handler);
1667 
1668     if (ret || handler == NULL) {
1669         clear_bool_flag(&in_use[HAL_SPI_ID_0]);
1670     }
1671 
1672     return ret;
1673 }
1674 
hal_spi_dma_recv(const void * cmd,void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1675 int hal_spi_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1676 {
1677     int ret;
1678 
1679     if (set_bool_flag(&in_use[HAL_SPI_ID_0])) {
1680         return -31;
1681     }
1682 
1683     hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_RECV);
1684 
1685     ret = hal_spi_dma_recv_id(HAL_SPI_ID_0, cmd, data, len, handler);
1686 
1687     if (ret || handler == NULL) {
1688         hal_spi_set_xfer_type_id(HAL_SPI_ID_0, &spi0_ctrl[spi0_cs], HAL_SPI_XFER_TYPE_SEND);
1689 
1690         clear_bool_flag(&in_use[HAL_SPI_ID_0]);
1691     }
1692 
1693     return ret;
1694 }
1695 
hal_spi_stop_dma_send(void)1696 void hal_spi_stop_dma_send(void)
1697 {
1698     hal_spi_stop_dma_send_id(HAL_SPI_ID_0);
1699 }
1700 
hal_spi_stop_dma_recv(void)1701 void hal_spi_stop_dma_recv(void)
1702 {
1703     hal_spi_stop_dma_recv_id(HAL_SPI_ID_0);
1704 }
1705 
hal_spi_enable_and_send(const struct HAL_SPI_CTRL_T * ctrl,const void * data,uint32_t len)1706 int hal_spi_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len)
1707 {
1708     return hal_spi_enable_and_send_id(HAL_SPI_ID_0, ctrl, data, len);
1709 }
1710 
hal_spi_enable_and_recv(const struct HAL_SPI_CTRL_T * ctrl,const void * cmd,void * data,uint32_t len)1711 int hal_spi_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len)
1712 {
1713     return hal_spi_enable_and_recv_id(HAL_SPI_ID_0, ctrl, cmd, data, len);
1714 }
1715 #endif // CHIP_HAS_SPI
1716 
1717 #ifdef CHIP_HAS_SPILCD
1718 //------------------------------------------------------------
1719 // SPI LCD functions
1720 //------------------------------------------------------------
1721 
hal_spilcd_open(const struct HAL_SPI_CFG_T * cfg)1722 int hal_spilcd_open(const struct HAL_SPI_CFG_T *cfg)
1723 {
1724     int ret;
1725     uint32_t lock;
1726 
1727     if (cfg->cs >= HAL_SPI_CS_QTY) {
1728         return -1;
1729     }
1730 
1731     lock = int_lock();
1732 
1733     ret = hal_spi_open_id(HAL_SPI_ID_SLCD, cfg, &spilcd_ctrl[cfg->cs]);
1734 
1735 #if (CHIP_SPI_VER >= 2)
1736     if (ret == 0) {
1737         spilcd_cs = cfg->cs;
1738     }
1739 #endif
1740 
1741     int_unlock(lock);
1742 
1743     return ret;
1744 }
1745 
hal_spilcd_close(uint32_t cs)1746 int hal_spilcd_close(uint32_t cs)
1747 {
1748     int ret;
1749     uint32_t lock;
1750 
1751     lock = int_lock();
1752 
1753     ret = hal_spi_close_id(HAL_SPI_ID_SLCD, cs);
1754 
1755 #if (CHIP_SPI_VER >= 2)
1756     if (ret == 0 && spilcd_cs == cs) {
1757         uint32_t lowest_cs;
1758 
1759         lowest_cs = __CLZ(__RBIT(spi_cs_map[HAL_SPI_ID_SLCD]));
1760         if (lowest_cs < HAL_SPI_CS_QTY) {
1761             hal_spi_activate_cs_id(HAL_SPI_ID_SLCD, lowest_cs);
1762         } else {
1763             lowest_cs = HAL_SPI_CS_0;
1764         }
1765         spilcd_cs = lowest_cs;
1766     }
1767 #endif
1768 
1769     int_unlock(lock);
1770 
1771     return ret;
1772 }
1773 
hal_spilcd_activate_cs(uint32_t cs)1774 int hal_spilcd_activate_cs(uint32_t cs)
1775 {
1776     return hal_spi_activate_cs_id(HAL_SPI_ID_SLCD, cs);
1777 }
1778 
hal_spilcd_busy(void)1779 int hal_spilcd_busy(void)
1780 {
1781     return hal_spi_busy_id(HAL_SPI_ID_SLCD);
1782 }
1783 
hal_spilcd_send(const void * data,uint32_t len)1784 int hal_spilcd_send(const void *data, uint32_t len)
1785 {
1786     int ret;
1787 
1788     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1789         return -31;
1790     }
1791 
1792     ret =  hal_spi_send_id(HAL_SPI_ID_SLCD, data, len);
1793 
1794     clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1795 
1796     return ret;
1797 }
1798 
hal_spilcd_recv(const void * cmd,void * data,uint32_t len)1799 int hal_spilcd_recv(const void *cmd, void *data, uint32_t len)
1800 {
1801     int ret;
1802 
1803     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1804         return -31;
1805     }
1806 
1807     hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_RECV);
1808     ret = hal_spi_recv_id(HAL_SPI_ID_SLCD, cmd, data, len);
1809     hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_SEND);
1810 
1811     clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1812 
1813     return ret;
1814 }
1815 
hal_spilcd_dma_send(const void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1816 int hal_spilcd_dma_send(const void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1817 {
1818     int ret;
1819 
1820     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1821         return -31;
1822     }
1823 
1824     ret = hal_spi_dma_send_id(HAL_SPI_ID_SLCD, data, len, handler);
1825 
1826     if (ret || handler == NULL) {
1827         clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1828     }
1829 
1830     return ret;
1831 }
1832 
hal_spilcd_dma_recv(const void * cmd,void * data,uint32_t len,HAL_SPI_DMA_HANDLER_T handler)1833 int hal_spilcd_dma_recv(const void *cmd, void *data, uint32_t len, HAL_SPI_DMA_HANDLER_T handler)
1834 {
1835     int ret;
1836 
1837     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1838         return -31;
1839     }
1840 
1841     hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_RECV);
1842 
1843     ret = hal_spi_dma_recv_id(HAL_SPI_ID_SLCD, cmd, data, len, handler);
1844 
1845     if (ret || handler == NULL) {
1846         hal_spi_set_xfer_type_id(HAL_SPI_ID_SLCD, &spilcd_ctrl[spilcd_cs], HAL_SPI_XFER_TYPE_SEND);
1847 
1848         clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1849     }
1850 
1851     return ret;
1852 }
1853 
hal_spilcd_stop_dma_send(void)1854 void hal_spilcd_stop_dma_send(void)
1855 {
1856     hal_spi_stop_dma_send_id(HAL_SPI_ID_SLCD);
1857 }
1858 
hal_spilcd_stop_dma_recv(void)1859 void hal_spilcd_stop_dma_recv(void)
1860 {
1861     hal_spi_stop_dma_recv_id(HAL_SPI_ID_SLCD);
1862 }
1863 
hal_spilcd_set_data_mode(void)1864 int hal_spilcd_set_data_mode(void)
1865 {
1866     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1867         return -31;
1868     }
1869 
1870     spi[HAL_SPI_ID_SLCD]->SSPCR1 |= SPI_LCD_DC_DATA;
1871 
1872     clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1873     return 0;
1874 }
1875 
hal_spilcd_set_cmd_mode(void)1876 int hal_spilcd_set_cmd_mode(void)
1877 {
1878     if (set_bool_flag(&in_use[HAL_SPI_ID_SLCD])) {
1879         return -31;
1880     }
1881 
1882     spi[HAL_SPI_ID_SLCD]->SSPCR1 &= ~SPI_LCD_DC_DATA;
1883 
1884     clear_bool_flag(&in_use[HAL_SPI_ID_SLCD]);
1885     return 0;
1886 }
1887 
hal_spilcd_enable_and_send(const struct HAL_SPI_CTRL_T * ctrl,const void * data,uint32_t len)1888 int hal_spilcd_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len)
1889 {
1890     return hal_spi_enable_and_send_id(HAL_SPI_ID_SLCD, ctrl, data, len);
1891 }
1892 
hal_spilcd_enable_and_recv(const struct HAL_SPI_CTRL_T * ctrl,const void * cmd,void * data,uint32_t len)1893 int hal_spilcd_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len)
1894 {
1895     return hal_spi_enable_and_recv_id(HAL_SPI_ID_SLCD, ctrl, cmd, data, len);
1896 }
1897 #endif // CHIP_HAS_SPILCD
1898 
1899 #ifdef CHIP_HAS_SPIPHY
1900 //------------------------------------------------------------
1901 // SPI PHY functions
1902 //------------------------------------------------------------
1903 
hal_spiphy_open(const struct HAL_SPI_CFG_T * cfg)1904 int hal_spiphy_open(const struct HAL_SPI_CFG_T *cfg)
1905 {
1906     SPI_ASSERT(cfg->tx_bits == cfg->rx_bits && cfg->rx_frame_bits == 0, "SPIPHY: Bad bits cfg");
1907 
1908     return hal_spi_open_id(HAL_SPI_ID_PHY, cfg, NULL);
1909 }
1910 
hal_spiphy_close(uint32_t cs)1911 int hal_spiphy_close(uint32_t cs)
1912 {
1913     return hal_spi_close_id(HAL_SPI_ID_PHY, cs);
1914 }
1915 
hal_spiphy_activate_cs(uint32_t cs)1916 void hal_spiphy_activate_cs(uint32_t cs)
1917 {
1918     SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPIPHY: SPI cs bad: %d", cs);
1919 
1920     hal_spi_set_cs_id(HAL_SPI_ID_PHY, cs);
1921 }
1922 
hal_spiphy_busy(void)1923 int hal_spiphy_busy(void)
1924 {
1925     return hal_spi_busy_id(HAL_SPI_ID_PHY);
1926 }
1927 
hal_spiphy_send(const void * data,uint32_t len)1928 int hal_spiphy_send(const void *data, uint32_t len)
1929 {
1930     int ret;
1931 
1932     if (set_bool_flag(&in_use[HAL_SPI_ID_PHY])) {
1933         return -31;
1934     }
1935 
1936     ret =  hal_spi_send_id(HAL_SPI_ID_PHY, data, len);
1937 
1938     clear_bool_flag(&in_use[HAL_SPI_ID_PHY]);
1939 
1940     return ret;
1941 }
1942 
hal_spiphy_recv(const void * cmd,void * data,uint32_t len)1943 int hal_spiphy_recv(const void *cmd, void *data, uint32_t len)
1944 {
1945     int ret;
1946 
1947     if (set_bool_flag(&in_use[HAL_SPI_ID_PHY])) {
1948         return -31;
1949     }
1950 
1951     ret = hal_spi_recv_id(HAL_SPI_ID_PHY, cmd, data, len);
1952 
1953     clear_bool_flag(&in_use[HAL_SPI_ID_PHY]);
1954 
1955     return ret;
1956 }
1957 #endif // CHIP_HAS_SPIPHY
1958 
1959 #ifdef CHIP_HAS_SPIDPD
1960 //------------------------------------------------------------
1961 // SPI DPD functions
1962 //------------------------------------------------------------
1963 
hal_spidpd_open(const struct HAL_SPI_CFG_T * cfg)1964 int hal_spidpd_open(const struct HAL_SPI_CFG_T *cfg)
1965 {
1966     SPI_ASSERT(cfg->rx_frame_bits == 0, "SPIDPD: Bad bits cfg");
1967 
1968     return hal_spi_open_id(HAL_SPI_ID_DPD, cfg, &spidpd_ctrl);
1969 }
1970 
hal_spidpd_close(uint32_t cs)1971 int hal_spidpd_close(uint32_t cs)
1972 {
1973     return hal_spi_close_id(HAL_SPI_ID_DPD, cs);
1974 }
1975 
hal_spidpd_activate_cs(uint32_t cs)1976 void hal_spidpd_activate_cs(uint32_t cs)
1977 {
1978     SPI_ASSERT(cs < HAL_SPI_CS_QTY, "SPIDPD: SPI cs bad: %d", cs);
1979 
1980     hal_spi_set_cs_id(HAL_SPI_ID_DPD, cs);
1981 }
1982 
hal_spidpd_busy(void)1983 int hal_spidpd_busy(void)
1984 {
1985     return hal_spi_busy_id(HAL_SPI_ID_DPD);
1986 }
1987 
hal_spidpd_send(const void * data,uint32_t len)1988 int hal_spidpd_send(const void *data, uint32_t len)
1989 {
1990     int ret;
1991 
1992     if (set_bool_flag(&in_use[HAL_SPI_ID_DPD])) {
1993         return -31;
1994     }
1995 
1996     ret =  hal_spi_send_id(HAL_SPI_ID_DPD, data, len);
1997 
1998     clear_bool_flag(&in_use[HAL_SPI_ID_DPD]);
1999 
2000     return ret;
2001 }
2002 
hal_spidpd_recv(const void * cmd,void * data,uint32_t len)2003 int hal_spidpd_recv(const void *cmd, void *data, uint32_t len)
2004 {
2005     int ret;
2006 
2007     if (set_bool_flag(&in_use[HAL_SPI_ID_DPD])) {
2008         return -31;
2009     }
2010 
2011     hal_spi_set_xfer_type_id(HAL_SPI_ID_DPD, &spidpd_ctrl, HAL_SPI_XFER_TYPE_RECV);
2012     ret = hal_spi_recv_id(HAL_SPI_ID_DPD, cmd, data, len);
2013     hal_spi_set_xfer_type_id(HAL_SPI_ID_DPD, &spidpd_ctrl, HAL_SPI_XFER_TYPE_SEND);
2014 
2015     clear_bool_flag(&in_use[HAL_SPI_ID_DPD]);
2016 
2017     return ret;
2018 }
2019 #endif // CHIP_HAS_SPIDPD
2020 
2021 #ifdef CORE_SLEEP_POWER_DOWN
hal_spi_sleep(void)2022 void SRAM_TEXT_LOC hal_spi_sleep(void)
2023 {
2024     enum HAL_SPI_ID_T id;
2025 
2026     for (id = 0; id < HAL_SPI_ID_QTY; id++) {
2027         if (spi_cs_map[id]) {
2028             saved_spi_regs[id].SSPCR0   = spi[id]->SSPCR0;
2029             saved_spi_regs[id].SSPCR1   = spi[id]->SSPCR1;
2030             saved_spi_regs[id].SSPCPSR  = spi[id]->SSPCPSR;
2031             saved_spi_regs[id].SSPDMACR = spi[id]->SSPDMACR;
2032             saved_spi_regs[id].SSPRXCR  = spi[id]->SSPRXCR;
2033         }
2034     }
2035 }
2036 
hal_spi_wakeup(void)2037 void SRAM_TEXT_LOC hal_spi_wakeup(void)
2038 {
2039     enum HAL_SPI_ID_T id;
2040 
2041     for (id = 0; id < HAL_SPI_ID_QTY; id++) {
2042         if (spi_cs_map[id]) {
2043             spi[id]->SSPCR0     = saved_spi_regs[id].SSPCR0;
2044             spi[id]->SSPCR1     = saved_spi_regs[id].SSPCR1;
2045             spi[id]->SSPCPSR    = saved_spi_regs[id].SSPCPSR;
2046             spi[id]->SSPDMACR   = saved_spi_regs[id].SSPDMACR;
2047             spi[id]->SSPRXCR    = saved_spi_regs[id].SSPRXCR;
2048         }
2049     }
2050 }
2051 #endif
2052 
2053 #endif // !SPI_ROM_ONLY
2054 
2055