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