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 #ifdef CHIP_HAS_UART
16
17 #include "plat_addr_map.h"
18 #include "hal_uart.h"
19 #include "reg_uart.h"
20 #include "cmsis_nvic.h"
21 #include "hal_bootmode.h"
22 #include "hal_cache.h"
23 #include "hal_cmu.h"
24 #include "hal_dma.h"
25 #include "hal_iomux.h"
26 #include "hal_timer.h"
27 #include "hal_trace.h"
28 #include "string.h"
29
30 #define UART_FLUSH_DELAY_DEFAULT 2
31
32 enum UART_RX_DMA_MODE_T {
33 UART_RX_DMA_MODE_NORMAL,
34 UART_RX_DMA_MODE_PINGPANG,
35 UART_RX_DMA_MODE_STREAM,
36 UART_RX_DMA_MODE_BUF_LIST,
37 };
38
39 struct HAL_UART_HW_DESC_T {
40 struct UART_T *base;
41 IRQn_Type irq;
42 enum HAL_CMU_MOD_ID_T mod;
43 enum HAL_CMU_MOD_ID_T apb;
44 enum HAL_DMA_PERIPH_T rx_periph;
45 enum HAL_DMA_PERIPH_T tx_periph;
46 };
47
48 static const struct HAL_UART_HW_DESC_T uart[HAL_UART_ID_QTY] = {
49 {
50 .base = (struct UART_T *)UART0_BASE,
51 .irq = UART0_IRQn,
52 .mod = HAL_CMU_MOD_O_UART0,
53 .apb = HAL_CMU_MOD_P_UART0,
54 .rx_periph = HAL_GPDMA_UART0_RX,
55 .tx_periph = HAL_GPDMA_UART0_TX,
56 },
57 #if (CHIP_HAS_UART >= 2)
58 {
59 .base = (struct UART_T *)UART1_BASE,
60 .irq = UART1_IRQn,
61 .mod = HAL_CMU_MOD_O_UART1,
62 .apb = HAL_CMU_MOD_P_UART1,
63 .rx_periph = HAL_GPDMA_UART1_RX,
64 .tx_periph = HAL_GPDMA_UART1_TX,
65 },
66 #endif
67 #if (CHIP_HAS_UART >= 3)
68 {
69 .base = (struct UART_T *)UART2_BASE,
70 .irq = UART2_IRQn,
71 .mod = HAL_CMU_MOD_O_UART2,
72 .apb = HAL_CMU_MOD_P_UART2,
73 .rx_periph = HAL_GPDMA_UART2_RX,
74 .tx_periph = HAL_GPDMA_UART2_TX,
75 },
76 #endif
77 #if (CHIP_HAS_UART >= 4)
78 {
79 .base = (struct UART_T *)UART3_BASE,
80 .irq = UART3_IRQn,
81 .mod = HAL_CMU_MOD_O_UART3,
82 .apb = HAL_CMU_MOD_P_UART3,
83 .rx_periph = HAL_GPDMA_UART3_RX,
84 .tx_periph = HAL_GPDMA_UART3_TX,
85 },
86 #endif
87 #ifdef BT_UART
88 {
89 .base = (struct UART_T *)BT_UART_BASE,
90 .irq = INVALID_IRQn,
91 .mod = HAL_CMU_MOD_QTY,
92 .apb = HAL_CMU_MOD_QTY,
93 .rx_periph = HAL_DMA_PERIPH_NULL,
94 .tx_periph = HAL_DMA_PERIPH_NULL,
95 },
96 #endif
97 };
98
99 static bool init_done = false;
100
101 static HAL_UART_IRQ_HANDLER_T irq_handler[HAL_UART_ID_QTY] = { NULL };
102
103 static HAL_UART_IRQ_RXDMA_HANDLER_T rxdma_handler[HAL_UART_ID_QTY] = { NULL };
104 static HAL_UART_IRQ_TXDMA_HANDLER_T txdma_handler[HAL_UART_ID_QTY] = { NULL };
105
106 static uint8_t recv_dma_chan[HAL_UART_ID_QTY];
107 static uint8_t send_dma_chan[HAL_UART_ID_QTY];
108
109 static uint32_t recv_dma_size[HAL_UART_ID_QTY];
110 static uint32_t send_dma_size[HAL_UART_ID_QTY];
111
112 static union HAL_UART_IRQ_T recv_mask[HAL_UART_ID_QTY];
113
114 static enum UART_RX_DMA_MODE_T recv_dma_mode[HAL_UART_ID_QTY];
115
116 #ifdef CORE_SLEEP_POWER_DOWN
117 static bool uart_opened[HAL_UART_ID_QTY];
118 static struct SAVED_UART_REGS_T saved_uart_regs[HAL_UART_ID_QTY];
119 #endif
120
121 static const char * const err_invalid_id = "Invalid UART ID: %d";
122 static const char * const err_recv_dma_api = "%s: Set RT irq in hal_uart_dma_recv_mask... to avoid data lost";
123
124 static const struct HAL_UART_CFG_T default_cfg = {
125 .parity = HAL_UART_PARITY_NONE,
126 .stop = HAL_UART_STOP_BITS_1,
127 .data = HAL_UART_DATA_BITS_8,
128 .flow = HAL_UART_FLOW_CONTROL_RTSCTS,
129 .tx_level = HAL_UART_FIFO_LEVEL_1_2,
130 .rx_level = HAL_UART_FIFO_LEVEL_1_4,
131 .baud = 921600,
132 .dma_rx = false,
133 .dma_tx = false,
134 .dma_rx_stop_on_err = false,
135 };
136
137 static void hal_uart_irq_handler(void);
138
set_baud_rate(enum HAL_UART_ID_T id,uint32_t rate)139 static void set_baud_rate(enum HAL_UART_ID_T id, uint32_t rate)
140 {
141 uint32_t mod_clk;
142 uint32_t ibrd, fbrd;
143 uint32_t div;
144 uint32_t over_sample_ratio;
145
146 #ifdef UART_CLK_DIV_4
147 over_sample_ratio = 4;
148
149 uart[id].base->UARTOVSAMP = SET_BITFIELD(uart[id].base->UARTOVSAMP, UARTOVSAMP_RATIO, (over_sample_ratio - 1));
150 uart[id].base->UARTOVSAMPST = SET_BITFIELD(uart[id].base->UARTOVSAMPST, UARTOVSAMPST_START, 1);
151 #else
152 over_sample_ratio = 16;
153 // over sample start is 8
154 #endif
155
156 mod_clk = 0;
157 #ifdef PERIPH_PLL_FREQ
158 if (PERIPH_PLL_FREQ / 2 > 2 * hal_cmu_get_crystal_freq()) {
159 // Init to OSC_X2
160 mod_clk = 2 * hal_cmu_get_crystal_freq() / over_sample_ratio;
161 if (rate > mod_clk) {
162 mod_clk = PERIPH_PLL_FREQ / 2 / over_sample_ratio;
163
164 if (id == HAL_UART_ID_0) {
165 hal_cmu_uart0_set_div(2);
166 #if (CHIP_HAS_UART >= 2)
167 } else if (id == HAL_UART_ID_1) {
168 hal_cmu_uart1_set_div(2);
169 #endif
170 #if (CHIP_HAS_UART >= 3)
171 } else if (id == HAL_UART_ID_2) {
172 hal_cmu_uart2_set_div(2);
173 #endif
174 #if (CHIP_HAS_UART >= 4)
175 } else if (id == HAL_UART_ID_3) {
176 hal_cmu_uart3_set_div(2);
177 #endif
178 }
179 } else {
180 mod_clk = 0;
181 }
182 }
183 #endif
184 if (mod_clk == 0) {
185 enum HAL_CMU_PERIPH_FREQ_T periph_freq;
186
187 // Init to OSC
188 mod_clk = hal_cmu_get_crystal_freq() / over_sample_ratio;
189 if (rate > mod_clk) {
190 mod_clk *= 2;
191 periph_freq = HAL_CMU_PERIPH_FREQ_52M;
192 } else {
193 periph_freq = HAL_CMU_PERIPH_FREQ_26M;
194 }
195
196 if (id == HAL_UART_ID_0) {
197 hal_cmu_uart0_set_freq(periph_freq);
198 #if (CHIP_HAS_UART >= 2)
199 } else if (id == HAL_UART_ID_1) {
200 hal_cmu_uart1_set_freq(periph_freq);
201 #endif
202 #if (CHIP_HAS_UART >= 3)
203 } else if (id == HAL_UART_ID_2) {
204 hal_cmu_uart2_set_freq(periph_freq);
205 #endif
206 #if (CHIP_HAS_UART >= 4)
207 } else if (id == HAL_UART_ID_3) {
208 hal_cmu_uart3_set_freq(periph_freq);
209 #endif
210 }
211 }
212
213 div = (mod_clk * 64 + rate / 2) / rate;
214 ibrd = div / 64;
215 fbrd = div % 64;
216 if (ibrd == 0 || ibrd >= 65535) {
217 ASSERT(false, "Invalid baud param: %d", rate);
218 }
219
220 uart[id].base->UARTIBRD = ibrd;
221 uart[id].base->UARTFBRD = fbrd;
222
223 return;
224 }
225
hal_uart_open(enum HAL_UART_ID_T id,const struct HAL_UART_CFG_T * cfg)226 int hal_uart_open(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg)
227 {
228 uint32_t cr, lcr, dmacr;
229 int i;
230
231 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
232
233 if (!init_done) {
234 init_done = true;
235 for (i = HAL_UART_ID_0; i < HAL_UART_ID_QTY; i++) {
236 recv_dma_chan[i] = HAL_DMA_CHAN_NONE;
237 send_dma_chan[i] = HAL_DMA_CHAN_NONE;
238 }
239 }
240
241 if (hal_uart_opened(id)) {
242 hal_uart_close(id);
243 }
244
245 if (cfg == NULL) {
246 cfg = &default_cfg;
247 }
248
249 #ifdef CORE_SLEEP_POWER_DOWN
250 uart_opened[id] = true;
251 #endif
252
253 hal_cmu_clock_enable(uart[id].mod);
254 hal_cmu_clock_enable(uart[id].apb);
255 hal_cmu_reset_clear(uart[id].mod);
256 hal_cmu_reset_clear(uart[id].apb);
257
258 lcr = UARTLCR_H_FEN | UARTLCR_H_DMA_RT_CNT(9);
259
260 switch (cfg->parity) {
261 case HAL_UART_PARITY_NONE:
262 break;
263 case HAL_UART_PARITY_ODD:
264 lcr |= UARTLCR_H_PEN;
265 break;
266 case HAL_UART_PARITY_EVEN:
267 lcr |= UARTLCR_H_PEN
268 | UARTLCR_H_EPS;
269 break;
270 case HAL_UART_PARITY_FORCE1:
271 lcr |= UARTLCR_H_PEN
272 | UARTLCR_H_SPS;
273 break;
274 case HAL_UART_PARITY_FORCE0:
275 lcr |= UARTLCR_H_PEN
276 | UARTLCR_H_EPS
277 | UARTLCR_H_SPS;
278 break;
279 default:
280 ASSERT(false, "Invalid parity param: %d", cfg->parity);
281 break;
282 }
283
284 if (cfg->stop == HAL_UART_STOP_BITS_2) {
285 lcr |= UARTLCR_H_STP2;
286 } else if (cfg->stop != HAL_UART_STOP_BITS_1) {
287 ASSERT(false, "Invalid stop bits param: %d", cfg->stop);
288 }
289
290 switch (cfg->data) {
291 case HAL_UART_DATA_BITS_5:
292 lcr |= UARTLCR_H_WLEN_5;
293 break;
294 case HAL_UART_DATA_BITS_6:
295 lcr |= UARTLCR_H_WLEN_6;
296 break;
297 case HAL_UART_DATA_BITS_7:
298 lcr |= UARTLCR_H_WLEN_7;
299 break;
300 case HAL_UART_DATA_BITS_8:
301 lcr |= UARTLCR_H_WLEN_8;
302 break;
303 default:
304 ASSERT(false, "Invalid data bits param: %d", cfg->data);
305 break;
306 }
307
308
309 cr = UARTCR_UARTEN | UARTCR_TXE | UARTCR_RXE;
310
311 switch (cfg->flow) {
312 case HAL_UART_FLOW_CONTROL_NONE:
313 break;
314 case HAL_UART_FLOW_CONTROL_RTS:
315 cr |= UARTCR_RTSEN;
316 break;
317 case HAL_UART_FLOW_CONTROL_CTS:
318 cr |= UARTCR_CTSEN;
319 break;
320 case HAL_UART_FLOW_CONTROL_RTSCTS:
321 cr |= UARTCR_RTSEN
322 | UARTCR_CTSEN;
323 break;
324 default:
325 ASSERT(false, "Invalid flow control param: %d", cfg->flow);
326 break;
327 }
328
329
330 dmacr = 0;
331
332 if (cfg->dma_rx) {
333 lcr |= UARTLCR_H_DMA_RT_EN;
334 dmacr |= UARTDMACR_RXDMAE;
335 }
336 if (cfg->dma_tx) {
337 dmacr |= UARTDMACR_TXDMAE;
338 }
339 if (cfg->dma_rx_stop_on_err) {
340 dmacr |= UARTDMACR_DMAONERR;
341 }
342
343 // Disable UART
344 uart[id].base->UARTCR &= ~UARTCR_UARTEN;
345 // Empty FIFO
346 uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN;
347 // Wait until UART becomes idle
348 while (((uart[id].base->UARTFR) & UARTFR_BUSY) != 0);
349 // Clear previous errors
350 uart[id].base->UARTECR = 1;
351 // Clear previous IRQs
352 uart[id].base->UARTIMSC = 0;
353 uart[id].base->UARTICR = ~0UL;
354 // Configure UART
355 set_baud_rate(id, cfg->baud);
356 uart[id].base->UARTRXEXT = UARTRXEXT_BYPASS_HANDSHAKE | UARTRXEXT_USE_RXD_REG;
357 uart[id].base->UARTLCR_H = lcr;
358 uart[id].base->UARTDMACR = dmacr;
359 uart[id].base->UARTIFLS = UARTIFLS_TXFIFO_LEVEL(cfg->tx_level) |
360 UARTIFLS_RXFIFO_LEVEL(cfg->rx_level);
361 uart[id].base->UARTCR = cr;
362
363 if (uart[id].irq != INVALID_IRQn) {
364 NVIC_SetVector(uart[id].irq, (uint32_t)hal_uart_irq_handler);
365 // The priority should be the same as DMA's
366 NVIC_SetPriority(uart[id].irq, IRQ_PRIORITY_NORMAL);
367 NVIC_ClearPendingIRQ(uart[id].irq);
368 NVIC_EnableIRQ(uart[id].irq);
369 }
370
371 return 0;
372 }
373
hal_uart_reopen(enum HAL_UART_ID_T id,const struct HAL_UART_CFG_T * cfg)374 int hal_uart_reopen(enum HAL_UART_ID_T id, const struct HAL_UART_CFG_T *cfg)
375 {
376 uint32_t cr, lcr, dmacr;
377 int i;
378
379 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
380
381 if (!init_done) {
382 init_done = true;
383 for (i = HAL_UART_ID_0; i < HAL_UART_ID_QTY; i++) {
384 recv_dma_chan[i] = HAL_DMA_CHAN_NONE;
385 send_dma_chan[i] = HAL_DMA_CHAN_NONE;
386 }
387 }
388
389 #ifdef CORE_SLEEP_POWER_DOWN
390 uart_opened[id] = true;
391 #endif
392
393 cr = uart[id].base->UARTCR & ~(UARTCR_RTSEN | UARTCR_CTSEN);
394 cr |= UARTCR_UARTEN | UARTCR_TXE | UARTCR_RXE;
395
396 switch (cfg->flow) {
397 case HAL_UART_FLOW_CONTROL_NONE:
398 break;
399 case HAL_UART_FLOW_CONTROL_RTS:
400 cr |= UARTCR_RTSEN;
401 break;
402 case HAL_UART_FLOW_CONTROL_CTS:
403 cr |= UARTCR_CTSEN;
404 break;
405 case HAL_UART_FLOW_CONTROL_RTSCTS:
406 cr |= UARTCR_RTSEN
407 | UARTCR_CTSEN;
408 break;
409 default:
410 ASSERT(false, "Invalid flow control param: %d", cfg->flow);
411 break;
412 }
413
414 lcr = uart[id].base->UARTLCR_H | UARTLCR_H_FEN;
415 dmacr = 0;
416
417 if (cfg->dma_rx) {
418 lcr |= UARTLCR_H_DMA_RT_EN;
419 dmacr |= UARTDMACR_RXDMAE;
420 }
421 if (cfg->dma_tx) {
422 dmacr |= UARTDMACR_TXDMAE;
423 }
424 if (cfg->dma_rx_stop_on_err) {
425 dmacr |= UARTDMACR_DMAONERR;
426 }
427
428 // Disable UART
429 uart[id].base->UARTCR &= ~UARTCR_UARTEN;
430 // Empty FIFO
431 uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN;
432 // Wait until UART becomes idle
433 while (((uart[id].base->UARTFR) & UARTFR_BUSY) != 0);
434 // Clear previous errors
435 uart[id].base->UARTECR = 1;
436 // Clear previous IRQs
437 uart[id].base->UARTIMSC = 0;
438 uart[id].base->UARTICR = ~0UL;
439 // Configure UART
440 uart[id].base->UARTLCR_H = lcr;
441 uart[id].base->UARTDMACR = dmacr;
442 uart[id].base->UARTCR = cr;
443
444 if (uart[id].irq != INVALID_IRQn) {
445 NVIC_SetVector(uart[id].irq, (uint32_t)hal_uart_irq_handler);
446 // The priority should be the same as DMA's
447 NVIC_SetPriority(uart[id].irq, IRQ_PRIORITY_NORMAL);
448 NVIC_ClearPendingIRQ(uart[id].irq);
449 NVIC_EnableIRQ(uart[id].irq);
450 }
451
452 return 0;
453 }
454
hal_uart_close(enum HAL_UART_ID_T id)455 int hal_uart_close(enum HAL_UART_ID_T id)
456 {
457 uint32_t lock;
458
459 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
460
461 if (uart[id].irq != INVALID_IRQn) {
462 NVIC_DisableIRQ(uart[id].irq);
463 }
464
465 if (init_done) {
466 lock = int_lock();
467 if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) {
468 hal_gpdma_cancel(recv_dma_chan[id]);
469 hal_gpdma_free_chan(recv_dma_chan[id]);
470 recv_dma_chan[id] = HAL_DMA_CHAN_NONE;
471 }
472 if (send_dma_chan[id] != HAL_DMA_CHAN_NONE) {
473 hal_gpdma_cancel(send_dma_chan[id]);
474 hal_gpdma_free_chan(send_dma_chan[id]);
475 send_dma_chan[id] = HAL_DMA_CHAN_NONE;
476 }
477 int_unlock(lock);
478 }
479
480 // Disable UART
481 uart[id].base->UARTCR &= ~UARTCR_UARTEN;
482 // Empty FIFO
483 uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN;
484
485 hal_cmu_reset_set(uart[id].apb);
486 hal_cmu_reset_set(uart[id].mod);
487 hal_cmu_clock_disable(uart[id].apb);
488 hal_cmu_clock_disable(uart[id].mod);
489
490 #ifdef CORE_SLEEP_POWER_DOWN
491 uart_opened[id] = false;
492 #endif
493
494 return 0;
495 }
496
hal_uart_opened(enum HAL_UART_ID_T id)497 int hal_uart_opened(enum HAL_UART_ID_T id)
498 {
499 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
500 if (uart[id].apb < HAL_CMU_MOD_QTY &&
501 hal_cmu_clock_get_status(uart[id].apb) != HAL_CMU_CLK_ENABLED) {
502 return 0;
503 }
504 if (uart[id].base->UARTCR & UARTCR_UARTEN) {
505 return 1;
506 }
507 return 0;
508 }
509
510 #ifdef CORE_SLEEP_POWER_DOWN
hal_uart_sleep(void)511 void hal_uart_sleep(void)
512 {
513 enum HAL_UART_ID_T id;
514
515 for (id = 0; id < HAL_UART_ID_QTY; id++) {
516 if (uart_opened[id]) {
517 saved_uart_regs[id].UARTILPR = uart[id].base->UARTILPR;
518 saved_uart_regs[id].UARTIBRD = uart[id].base->UARTIBRD;
519 saved_uart_regs[id].UARTFBRD = uart[id].base->UARTFBRD;
520 saved_uart_regs[id].UARTLCR_H = uart[id].base->UARTLCR_H;
521 saved_uart_regs[id].UARTCR = uart[id].base->UARTCR;
522 saved_uart_regs[id].UARTIFLS = uart[id].base->UARTIFLS;
523 saved_uart_regs[id].UARTIMSC = uart[id].base->UARTIMSC;
524 saved_uart_regs[id].UARTDMACR = uart[id].base->UARTDMACR;
525 }
526 }
527 }
528
hal_uart_wakeup(void)529 void hal_uart_wakeup(void)
530 {
531 enum HAL_UART_ID_T id;
532
533 for (id = 0; id < HAL_UART_ID_QTY; id++) {
534 if (uart_opened[id]) {
535 uart[id].base->UARTCR = 0;
536 uart[id].base->UARTILPR = saved_uart_regs[id].UARTILPR;
537 uart[id].base->UARTIBRD = saved_uart_regs[id].UARTIBRD;
538 uart[id].base->UARTFBRD = saved_uart_regs[id].UARTFBRD;
539 uart[id].base->UARTLCR_H = saved_uart_regs[id].UARTLCR_H;
540 uart[id].base->UARTIFLS = saved_uart_regs[id].UARTIFLS;
541 uart[id].base->UARTIMSC = saved_uart_regs[id].UARTIMSC;
542 uart[id].base->UARTDMACR = saved_uart_regs[id].UARTDMACR;
543 uart[id].base->UARTCR = saved_uart_regs[id].UARTCR;
544 }
545 }
546 }
547 #endif
548
hal_uart_change_baud_rate(enum HAL_UART_ID_T id,uint32_t rate)549 int hal_uart_change_baud_rate(enum HAL_UART_ID_T id, uint32_t rate)
550 {
551 union HAL_UART_FLAG_T flag;
552
553 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
554
555 if (!hal_uart_opened(id)) {
556 return 1;
557 }
558
559 flag.reg = uart[id].base->UARTFR;
560 if (flag.BUSY) {
561 return 2;
562 }
563
564 uart[id].base->UARTCR &= ~UARTCR_UARTEN;
565
566 set_baud_rate(id, rate);
567
568 uart[id].base->UARTLCR_H = uart[id].base->UARTLCR_H;
569 uart[id].base->UARTCR |= UARTCR_UARTEN;
570
571 return 0;
572 }
573
hal_uart_pause(enum HAL_UART_ID_T id,enum HAL_UART_XFER_TYPE_T type)574 int hal_uart_pause(enum HAL_UART_ID_T id, enum HAL_UART_XFER_TYPE_T type)
575 {
576 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
577 if (hal_uart_opened(id)) {
578 uint32_t val = 0;
579 if (type & HAL_UART_XFER_TYPE_TX) {
580 val |= UARTCR_TXE;
581 }
582 if (type & HAL_UART_XFER_TYPE_RX) {
583 val |= UARTCR_RXE;
584 }
585 uart[id].base->UARTCR &= ~val;
586 return 0;
587 }
588 return 1;
589 }
590
hal_uart_continue(enum HAL_UART_ID_T id,enum HAL_UART_XFER_TYPE_T type)591 int hal_uart_continue(enum HAL_UART_ID_T id, enum HAL_UART_XFER_TYPE_T type)
592 {
593 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
594 if (hal_uart_opened(id)) {
595 uint32_t val = 0;
596 if (type & HAL_UART_XFER_TYPE_TX) {
597 val |= UARTCR_TXE;
598 }
599 if (type & HAL_UART_XFER_TYPE_RX) {
600 val |= UARTCR_RXE;
601 }
602 uart[id].base->UARTCR |= val;
603 return 0;
604 }
605 return 1;
606 }
607
hal_uart_readable(enum HAL_UART_ID_T id)608 int hal_uart_readable(enum HAL_UART_ID_T id)
609 {
610 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
611 return (uart[id].base->UARTFR & UARTFR_RXFE) == 0;
612 }
613
hal_uart_writable(enum HAL_UART_ID_T id)614 int hal_uart_writable(enum HAL_UART_ID_T id)
615 {
616 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
617 return (uart[id].base->UARTFR & UARTFR_TXFF) == 0;
618 }
619
hal_uart_getc(enum HAL_UART_ID_T id)620 uint8_t hal_uart_getc(enum HAL_UART_ID_T id)
621 {
622 uint32_t c;
623 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
624 ASSERT((uart[id].base->UARTDMACR & UARTDMACR_RXDMAE) == 0, "RX-DMA configured on UART %d", id);
625 c = uart[id].base->UARTDR;
626 return (c & 0xFF);
627 }
628
hal_uart_putc(enum HAL_UART_ID_T id,uint8_t c)629 int hal_uart_putc(enum HAL_UART_ID_T id, uint8_t c)
630 {
631 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
632 #if !defined(ARM_CMSE) && !defined(CP_BUILD) && !defined(__ARM_ARCH_ISA_ARM)
633 ASSERT((uart[id].base->UARTDMACR & UARTDMACR_TXDMAE) == 0, "TX-DMA configured on UART %d", id);
634 #endif
635 uart[id].base->UARTDR = c;
636 return 0;
637 }
638
hal_uart_blocked_getc(enum HAL_UART_ID_T id)639 uint8_t hal_uart_blocked_getc(enum HAL_UART_ID_T id)
640 {
641 while (hal_uart_readable(id) == 0);
642 return hal_uart_getc(id);
643 }
644
hal_uart_blocked_putc(enum HAL_UART_ID_T id,uint8_t c)645 int hal_uart_blocked_putc(enum HAL_UART_ID_T id, uint8_t c)
646 {
647 while (hal_uart_writable(id) == 0);
648 return hal_uart_putc(id, c);
649 }
650
hal_uart_get_flag(enum HAL_UART_ID_T id)651 union HAL_UART_FLAG_T hal_uart_get_flag(enum HAL_UART_ID_T id)
652 {
653 union HAL_UART_FLAG_T flag;
654 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
655 flag.reg = uart[id].base->UARTFR;
656 return flag;
657 }
658
hal_uart_get_status(enum HAL_UART_ID_T id)659 union HAL_UART_STATUS_T hal_uart_get_status(enum HAL_UART_ID_T id)
660 {
661 union HAL_UART_STATUS_T status;
662 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
663 status.reg = uart[id].base->UARTRSR;
664 return status;
665 }
666
hal_uart_clear_status(enum HAL_UART_ID_T id)667 void hal_uart_clear_status(enum HAL_UART_ID_T id)
668 {
669 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
670 uart[id].base->UARTECR = 0;
671 }
672
hal_uart_break_set(enum HAL_UART_ID_T id)673 void hal_uart_break_set(enum HAL_UART_ID_T id)
674 {
675 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
676 uart[id].base->UARTLCR_H |= UARTLCR_H_BRK;
677 }
678
hal_uart_break_clear(enum HAL_UART_ID_T id)679 void hal_uart_break_clear(enum HAL_UART_ID_T id)
680 {
681 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
682 uart[id].base->UARTLCR_H &= ~UARTLCR_H_BRK;
683 }
684
hal_uart_flush(enum HAL_UART_ID_T id,uint32_t ticks)685 void hal_uart_flush(enum HAL_UART_ID_T id, uint32_t ticks)
686 {
687 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
688
689 if (!hal_uart_opened(id)) {
690 return;
691 }
692 if ((uart[id].base->UARTLCR_H & UARTLCR_H_FEN) == 0) {
693 return;
694 }
695
696 // Disable the UART
697 uart[id].base->UARTCR &= ~UARTCR_UARTEN;
698 // Wait for the end of transmission or reception of the current character
699 hal_sys_timer_delay((ticks > 0) ? ticks : UART_FLUSH_DELAY_DEFAULT);
700
701 // Flush FIFO
702 uart[id].base->UARTLCR_H &= ~UARTLCR_H_FEN;
703 uart[id].base->UARTLCR_H |= UARTLCR_H_FEN;
704
705 // Enable the UART
706 uart[id].base->UARTCR |= UARTCR_UARTEN;
707 }
708
hal_uart_get_raw_irq(enum HAL_UART_ID_T id)709 union HAL_UART_IRQ_T hal_uart_get_raw_irq(enum HAL_UART_ID_T id)
710 {
711 union HAL_UART_IRQ_T irq;
712
713 irq.reg = uart[id].base->UARTRIS;
714
715 return irq;
716 }
717
hal_uart_clear_irq(enum HAL_UART_ID_T id,union HAL_UART_IRQ_T irq)718 void hal_uart_clear_irq(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T irq)
719 {
720 uart[id].base->UARTICR = irq.reg;
721 }
722
hal_uart_irq_get_mask(enum HAL_UART_ID_T id)723 union HAL_UART_IRQ_T hal_uart_irq_get_mask(enum HAL_UART_ID_T id)
724 {
725 union HAL_UART_IRQ_T mask;
726
727 mask.reg = uart[id].base->UARTIMSC;
728
729 return mask;
730 }
731
hal_uart_irq_set_mask(enum HAL_UART_ID_T id,union HAL_UART_IRQ_T mask)732 union HAL_UART_IRQ_T hal_uart_irq_set_mask(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T mask)
733 {
734 union HAL_UART_IRQ_T old_mask;
735
736 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
737
738 old_mask.reg = uart[id].base->UARTIMSC;
739
740 if (old_mask.RT == 0 && mask.RT) {
741 ASSERT(recv_dma_chan[id] == HAL_DMA_CHAN_NONE, err_recv_dma_api, __FUNCTION__);
742 }
743
744 uart[id].base->UARTIMSC = mask.reg;
745
746 return old_mask;
747 }
748
hal_uart_irq_set_handler(enum HAL_UART_ID_T id,HAL_UART_IRQ_HANDLER_T handler)749 HAL_UART_IRQ_HANDLER_T hal_uart_irq_set_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_HANDLER_T handler)
750 {
751 HAL_UART_IRQ_HANDLER_T old_handler;
752
753 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
754 old_handler = irq_handler[id];
755 irq_handler[id] = handler;
756
757 return old_handler;
758 }
759
dma_mode_uart_irq_handler(enum HAL_UART_ID_T id,union HAL_UART_IRQ_T status)760 static void dma_mode_uart_irq_handler(enum HAL_UART_ID_T id, union HAL_UART_IRQ_T status)
761 {
762 uint32_t xfer = 0;
763
764 if (status.RT || status.FE || status.OE || status.PE || status.BE) {
765 if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) {
766 if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) {
767 xfer = hal_uart_stop_dma_recv(id);
768 if (recv_dma_size[id] > xfer) {
769 xfer = recv_dma_size[id] - xfer;
770 } else {
771 xfer = 0;
772 }
773 }
774 }
775
776 if (rxdma_handler[id]) {
777 rxdma_handler[id](xfer, 0, status);
778 }
779 }
780 }
781
hal_uart_irq_set_dma_handler(enum HAL_UART_ID_T id,HAL_UART_IRQ_RXDMA_HANDLER_T rxdma,HAL_UART_IRQ_TXDMA_HANDLER_T txdma)782 void hal_uart_irq_set_dma_handler(enum HAL_UART_ID_T id, HAL_UART_IRQ_RXDMA_HANDLER_T rxdma, HAL_UART_IRQ_TXDMA_HANDLER_T txdma)
783 {
784 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
785 rxdma_handler[id] = rxdma;
786 txdma_handler[id] = txdma;
787 irq_handler[id] = dma_mode_uart_irq_handler;
788 }
789
recv_dma_irq_handler(uint8_t chan,uint32_t remain_tsize,uint32_t error,struct HAL_DMA_DESC_T * lli)790 static void recv_dma_irq_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli)
791 {
792 enum HAL_UART_ID_T id;
793 uint32_t xfer;
794 uint32_t lock;
795 union HAL_UART_IRQ_T status;
796
797 lock = int_lock();
798 for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) {
799 if (recv_dma_chan[id] == chan) {
800 if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) {
801 recv_dma_chan[id] = HAL_DMA_CHAN_NONE;
802 }
803 break;
804 }
805 }
806 int_unlock(lock);
807
808 if (id == HAL_UART_ID_QTY) {
809 return;
810 }
811
812 if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) {
813 // Get remain xfer size
814 xfer = hal_gpdma_get_sg_remain_size(chan);
815 hal_gpdma_free_chan(chan);
816 } else {
817 xfer = 0;
818 }
819
820 if (rxdma_handler[id]) {
821 if (recv_dma_mode[id] == UART_RX_DMA_MODE_NORMAL) {
822 // Already get xfer size
823 if (recv_dma_size[id] > xfer) {
824 xfer = recv_dma_size[id] - xfer;
825 } else {
826 xfer = 0;
827 }
828 } else if (recv_dma_mode[id] == UART_RX_DMA_MODE_PINGPANG) {
829 xfer = recv_dma_size[id] / 2;
830 }
831 status.reg = 0;
832 rxdma_handler[id](xfer, error, status);
833 }
834 }
835
recv_dma_start_callback(uint8_t chan)836 static void recv_dma_start_callback(uint8_t chan)
837 {
838 enum HAL_UART_ID_T id;
839
840 for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) {
841 if (recv_dma_chan[id] == chan) {
842 break;
843 }
844 }
845
846 if (id == HAL_UART_ID_QTY) {
847 return;
848 }
849
850 uart[id].base->UARTIMSC = recv_mask[id].reg;
851 }
852
fill_buf_list_dma_desc(struct HAL_DMA_DESC_T * desc,uint32_t cnt,struct HAL_DMA_CH_CFG_T * cfg,const struct HAL_UART_BUF_T * ubuf,uint32_t ucnt,uint32_t step)853 static int fill_buf_list_dma_desc(struct HAL_DMA_DESC_T *desc, uint32_t cnt, struct HAL_DMA_CH_CFG_T *cfg,
854 const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt, uint32_t step)
855 {
856 enum HAL_DMA_RET_T ret;
857 struct HAL_DMA_DESC_T *last_desc;
858 int tc_irq;
859 int i;
860 int u;
861 uint32_t remain;
862 uint32_t dlen;
863
864 last_desc = NULL;
865
866 u = 0;
867 remain = ubuf[0].len;
868
869 for (i = 0, u = 0; i < cnt - 1; i++) {
870 if (ubuf[u].loop_hdr && last_desc == NULL) {
871 last_desc = &desc[i];
872 }
873 if (remain <= step) {
874 dlen = remain;
875 tc_irq = ubuf[u].irq;
876 } else {
877 dlen = step;
878 tc_irq = 0;
879 }
880 cfg->src_tsize = dlen;
881 ret = hal_gpdma_init_desc(&desc[i], cfg, &desc[i + 1], tc_irq);
882 if (ret != HAL_DMA_OK) {
883 return 1;
884 }
885 remain -= dlen;
886 if (remain) {
887 cfg->dst += dlen;
888 } else {
889 u++;
890 if (u >= ucnt) {
891 return 2;
892 }
893 cfg->dst = (uint32_t)ubuf[u].buf;
894 remain = ubuf[u].len;
895 }
896 }
897
898 cfg->src_tsize = remain;
899 ret = hal_gpdma_init_desc(&desc[i], cfg, last_desc, ubuf[u].irq);
900 if (ret != HAL_DMA_OK) {
901 return 1;
902 }
903
904 return 0;
905 }
906
fill_dma_desc(struct HAL_DMA_DESC_T * desc,uint32_t cnt,struct HAL_DMA_CH_CFG_T * cfg,uint32_t len,enum UART_RX_DMA_MODE_T mode,uint32_t step)907 static int fill_dma_desc(struct HAL_DMA_DESC_T *desc, uint32_t cnt, struct HAL_DMA_CH_CFG_T *cfg,
908 uint32_t len, enum UART_RX_DMA_MODE_T mode, uint32_t step)
909 {
910 enum HAL_DMA_RET_T ret;
911 struct HAL_DMA_DESC_T *last_desc;
912 int tc_irq;
913 int i;
914
915 for (i = 0; i < cnt - 1; i++) {
916 cfg->src_tsize = step;
917 tc_irq = 0;
918 if (mode == UART_RX_DMA_MODE_PINGPANG) {
919 tc_irq = (i == cnt / 2 - 1) ? 1 : 0;
920 } else if (mode == UART_RX_DMA_MODE_STREAM) {
921 tc_irq = 1;
922 }
923 ret = hal_gpdma_init_desc(&desc[i], cfg, &desc[i + 1], tc_irq);
924 if (ret != HAL_DMA_OK) {
925 return 1;
926 }
927 cfg->dst += step;
928 }
929
930 cfg->src_tsize = len - (step * i);
931 last_desc = NULL;
932 if (mode == UART_RX_DMA_MODE_PINGPANG || mode == UART_RX_DMA_MODE_STREAM) {
933 last_desc = &desc[0];
934 }
935 ret = hal_gpdma_init_desc(&desc[i], cfg, last_desc, 1);
936 if (ret != HAL_DMA_OK) {
937 return 1;
938 }
939
940 return 0;
941 }
942
start_recv_dma_with_mask(enum HAL_UART_ID_T id,const struct HAL_UART_BUF_T * ubuf,uint32_t ucnt,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,const union HAL_UART_IRQ_T * mask,enum UART_RX_DMA_MODE_T mode,uint32_t step)943 static int start_recv_dma_with_mask(enum HAL_UART_ID_T id, const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt,
944 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,
945 const union HAL_UART_IRQ_T *mask,
946 enum UART_RX_DMA_MODE_T mode, uint32_t step)
947 {
948 uint8_t *buf;
949 uint32_t len;
950 struct HAL_DMA_CH_CFG_T dma_cfg;
951 enum HAL_DMA_RET_T ret;
952 uint32_t lock;
953 uint32_t cnt;
954 uint32_t i;
955 enum HAL_DMA_PERIPH_T periph;
956 struct HAL_DMA_DESC_T desc_c1;
957 enum HAL_UART_FIFO_LEVEL_T rx_level;
958 enum HAL_DMA_BSIZE_T src_bsize;
959
960 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
961 ASSERT(uart[id].irq != INVALID_IRQn, "DMA not supported on UART %d", id);
962 ASSERT((uart[id].base->UARTDMACR & UARTDMACR_RXDMAE), "DMA not configured on UART %d", id);
963
964 if (ucnt == 0) {
965 return -21;
966 }
967 if (step > HAL_UART_DMA_TRANSFER_STEP || step == 0) {
968 return -22;
969 }
970
971 buf = ubuf[0].buf;
972 len = ubuf[0].len;
973
974 if (buf == NULL) {
975 return -23;
976 }
977 if (len == 0) {
978 return -24;
979 }
980
981 if (0) {
982 } else if (mode == UART_RX_DMA_MODE_NORMAL) {
983 cnt = (len + step - 1) / step;
984 } else if (mode == UART_RX_DMA_MODE_PINGPANG) {
985 cnt = ((len / 2 + step - 1) / step) * 2;
986 step = len / cnt;
987 if (len % cnt != 0) {
988 return -11;
989 }
990 if (step == 0) {
991 return -12;
992 }
993 } else if (mode == UART_RX_DMA_MODE_STREAM) {
994 cnt = (len + step - 1) / step;
995 if (cnt == 1) {
996 // cnt should >= 2
997 cnt++;
998 }
999 step = (len + cnt - 1) / cnt;
1000 if (step == 0) {
1001 return -13;
1002 }
1003 } else if (mode == UART_RX_DMA_MODE_BUF_LIST) {
1004 cnt = 0;
1005 for (i = 0; i < ucnt; i++) {
1006 if (ubuf->buf == NULL) {
1007 return -14;
1008 }
1009 if (ubuf->len == 0) {
1010 return -15;
1011 }
1012 cnt += (ubuf->len + step - 1) / step;
1013 }
1014 } else {
1015 return -10;
1016 }
1017
1018 // Return the required DMA descriptor count
1019 if (desc == NULL && desc_cnt) {
1020 *desc_cnt = (cnt == 1) ? 0 : cnt;
1021 return 0;
1022 }
1023
1024 if (cnt > 1) {
1025 if (desc == NULL || desc_cnt == NULL) {
1026 return -1;
1027 }
1028 if (*desc_cnt < cnt) {
1029 return -2;
1030 }
1031 } else {
1032 // Use desc in current stack
1033 desc = &desc_c1;
1034 }
1035 if (desc_cnt) {
1036 *desc_cnt = (cnt == 1) ? 0 : cnt;
1037 }
1038
1039 if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) {
1040 return 1;
1041 }
1042
1043 periph = uart[id].rx_periph;
1044 rx_level = GET_BITFIELD(uart[id].base->UARTIFLS, UARTIFLS_RXFIFO_LEVEL);
1045 // WARNING: this config is used for uart fifo length 16
1046 switch (rx_level) {
1047 case HAL_UART_FIFO_LEVEL_1_4:
1048 src_bsize = HAL_DMA_BSIZE_4;
1049 break;
1050 case HAL_UART_FIFO_LEVEL_1_2:
1051 src_bsize = HAL_DMA_BSIZE_8;
1052 break;
1053 case HAL_UART_FIFO_LEVEL_1_8:
1054 case HAL_UART_FIFO_LEVEL_3_4:
1055 case HAL_UART_FIFO_LEVEL_7_8:
1056 default:
1057 src_bsize = HAL_DMA_BSIZE_1;
1058 break;
1059 }
1060
1061 memset(&dma_cfg, 0, sizeof(dma_cfg));
1062 dma_cfg.dst = (uint32_t)buf;
1063 dma_cfg.dst_bsize = HAL_DMA_BSIZE_32;
1064 dma_cfg.dst_periph = 0; // useless
1065 dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE;
1066 dma_cfg.handler = recv_dma_irq_handler;
1067 dma_cfg.src = 0; // useless
1068 dma_cfg.src_bsize = src_bsize;
1069 dma_cfg.src_periph = periph;
1070 dma_cfg.src_tsize = len;
1071 dma_cfg.src_width = HAL_DMA_WIDTH_BYTE;
1072 dma_cfg.type = HAL_DMA_FLOW_P2M_DMA;
1073 dma_cfg.try_burst = 0;
1074
1075 if (mask) {
1076 dma_cfg.start_cb = recv_dma_start_callback;
1077 } else {
1078 union HAL_UART_IRQ_T irq_mask;
1079
1080 irq_mask.reg = uart[id].base->UARTIMSC;
1081 ASSERT(irq_mask.RT == 0, err_recv_dma_api, __FUNCTION__);
1082 }
1083
1084 if (cnt == 1) {
1085 ret = hal_dma_init_desc(desc, &dma_cfg, NULL, 1);
1086 if (ret != HAL_DMA_OK) {
1087 ret = 1;
1088 }
1089 } else {
1090 if (mode == UART_RX_DMA_MODE_BUF_LIST) {
1091 ret = fill_buf_list_dma_desc(desc, cnt, &dma_cfg, ubuf, ucnt, step);
1092 } else {
1093 ret = fill_dma_desc(desc, cnt, &dma_cfg, len, mode, step);
1094 }
1095 }
1096 if (ret) {
1097 return 2;
1098 }
1099
1100 lock = int_lock();
1101 if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) {
1102 int_unlock(lock);
1103 return 3;
1104 }
1105 dma_cfg.ch = hal_gpdma_get_chan(periph, HAL_DMA_HIGH_PRIO);
1106 if (dma_cfg.ch == HAL_DMA_CHAN_NONE) {
1107 int_unlock(lock);
1108 return 4;
1109 }
1110 recv_dma_chan[id] = dma_cfg.ch;
1111 recv_dma_mode[id] = mode;
1112 recv_dma_size[id] = len;
1113 if (mask) {
1114 recv_mask[id] = *mask;
1115 }
1116
1117 // Clear previous RT interrupt if any
1118 uart[id].base->UARTICR = UARTINTERRUPT_RT;
1119
1120 ret = hal_gpdma_sg_start(desc, &dma_cfg);
1121 if (ret == HAL_DMA_OK) {
1122 ret = 0;
1123 } else {
1124 hal_gpdma_free_chan(recv_dma_chan[id]);
1125 recv_dma_chan[id] = HAL_DMA_CHAN_NONE;
1126 ret = 5;
1127 }
1128 int_unlock(lock);
1129
1130 return ret;
1131 }
1132
1133 // Safe API to trigger receive timeout IRQ and DMA IRQ
hal_uart_dma_recv_mask(enum HAL_UART_ID_T id,uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,const union HAL_UART_IRQ_T * mask)1134 int hal_uart_dma_recv_mask(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
1135 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,
1136 const union HAL_UART_IRQ_T *mask)
1137 {
1138 struct HAL_UART_BUF_T uart_buf;
1139
1140 uart_buf.buf = buf;
1141 uart_buf.len = len;
1142 uart_buf.irq = false;
1143 uart_buf.loop_hdr = false;
1144 return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_NORMAL, HAL_UART_DMA_TRANSFER_STEP);
1145 }
1146
1147 // Safe API to trigger receive timeout IRQ and DMA IRQ
hal_uart_dma_recv_mask_pingpang(enum HAL_UART_ID_T id,uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,const union HAL_UART_IRQ_T * mask,uint32_t step)1148 int hal_uart_dma_recv_mask_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
1149 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,
1150 const union HAL_UART_IRQ_T *mask, uint32_t step)
1151 {
1152 struct HAL_UART_BUF_T uart_buf;
1153
1154 uart_buf.buf = buf;
1155 uart_buf.len = len;
1156 uart_buf.irq = false;
1157 uart_buf.loop_hdr = false;
1158 return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_PINGPANG, step);
1159 }
1160
1161 // Safe API to trigger receive timeout IRQ and DMA IRQ
hal_uart_dma_recv_mask_stream(enum HAL_UART_ID_T id,uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,const union HAL_UART_IRQ_T * mask,uint32_t step)1162 int hal_uart_dma_recv_mask_stream(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
1163 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt,
1164 const union HAL_UART_IRQ_T *mask, uint32_t step)
1165 {
1166 struct HAL_UART_BUF_T uart_buf;
1167
1168 uart_buf.buf = buf;
1169 uart_buf.len = len;
1170 uart_buf.irq = false;
1171 uart_buf.loop_hdr = false;
1172 return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, mask, UART_RX_DMA_MODE_STREAM, step);
1173 }
1174
1175 // Safe API to trigger receive timeout IRQ and DMA IRQ
hal_uart_dma_recv_mask_buf_list(enum HAL_UART_ID_T id,const struct HAL_UART_BUF_T * ubuf,uint32_t ucnt,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt,const union HAL_UART_IRQ_T * mask)1176 int hal_uart_dma_recv_mask_buf_list(enum HAL_UART_ID_T id, const struct HAL_UART_BUF_T *ubuf, uint32_t ucnt,
1177 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt, const union HAL_UART_IRQ_T *mask)
1178 {
1179 return start_recv_dma_with_mask(id, ubuf, ucnt, desc, desc_cnt, mask, UART_RX_DMA_MODE_BUF_LIST, HAL_UART_DMA_TRANSFER_STEP);
1180 }
1181
hal_uart_dma_recv(enum HAL_UART_ID_T id,uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt)1182 int hal_uart_dma_recv(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
1183 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt)
1184 {
1185 struct HAL_UART_BUF_T uart_buf;
1186
1187 uart_buf.buf = buf;
1188 uart_buf.len = len;
1189 uart_buf.irq = false;
1190 uart_buf.loop_hdr = false;
1191 return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, NULL, UART_RX_DMA_MODE_NORMAL, HAL_UART_DMA_TRANSFER_STEP);
1192 }
1193
hal_uart_dma_recv_pingpang(enum HAL_UART_ID_T id,uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt)1194 int hal_uart_dma_recv_pingpang(enum HAL_UART_ID_T id, uint8_t *buf, uint32_t len,
1195 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt)
1196 {
1197 struct HAL_UART_BUF_T uart_buf;
1198
1199 uart_buf.buf = buf;
1200 uart_buf.len = len;
1201 uart_buf.irq = false;
1202 uart_buf.loop_hdr = false;
1203 return start_recv_dma_with_mask(id, &uart_buf, 1, desc, desc_cnt, NULL, UART_RX_DMA_MODE_PINGPANG, HAL_UART_DMA_TRANSFER_STEP_PINGPANG);
1204 }
1205
hal_uart_get_dma_recv_addr(enum HAL_UART_ID_T id)1206 uint32_t hal_uart_get_dma_recv_addr(enum HAL_UART_ID_T id)
1207 {
1208 uint32_t lock;
1209 uint32_t addr;
1210 int i;
1211
1212 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
1213
1214 addr = 0;
1215
1216 lock = int_lock();
1217 if (recv_dma_chan[id] != HAL_DMA_CHAN_NONE) {
1218 for (i = 0; i < 2; i++) {
1219 addr = hal_dma_get_cur_dst_addr(recv_dma_chan[id]);
1220 if (addr) {
1221 break;
1222 }
1223 }
1224 }
1225 int_unlock(lock);
1226
1227 return addr;
1228 }
1229
hal_uart_stop_dma_recv(enum HAL_UART_ID_T id)1230 uint32_t hal_uart_stop_dma_recv(enum HAL_UART_ID_T id)
1231 {
1232 uint32_t remains;
1233 uint32_t lock;
1234 uint8_t chan;
1235
1236 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
1237
1238 lock = int_lock();
1239 chan = recv_dma_chan[id];
1240 recv_dma_chan[id] = HAL_DMA_CHAN_NONE;
1241 int_unlock(lock);
1242
1243 if (chan == HAL_DMA_CHAN_NONE) {
1244 return 0;
1245 }
1246
1247 // Save the data in DMA FIFO
1248 hal_gpdma_stop(chan);
1249 remains = hal_gpdma_get_sg_remain_size(chan);
1250 hal_gpdma_free_chan(chan);
1251
1252 return remains;
1253 }
1254
send_dma_irq_handler(uint8_t chan,uint32_t remain_tsize,uint32_t error,struct HAL_DMA_DESC_T * lli)1255 static void send_dma_irq_handler(uint8_t chan, uint32_t remain_tsize, uint32_t error, struct HAL_DMA_DESC_T *lli)
1256 {
1257 enum HAL_UART_ID_T id;
1258 uint32_t xfer;
1259 uint32_t lock;
1260
1261 lock = int_lock();
1262 for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) {
1263 if (send_dma_chan[id] == chan) {
1264 send_dma_chan[id] = HAL_DMA_CHAN_NONE;
1265 break;
1266 }
1267 }
1268 int_unlock(lock);
1269
1270 if (id == HAL_UART_ID_QTY) {
1271 return;
1272 }
1273
1274 // Get remain xfer size
1275 xfer = hal_gpdma_get_sg_remain_size(chan);
1276
1277 hal_gpdma_free_chan(chan);
1278
1279 if (txdma_handler[id]) {
1280 // Get already xfer size
1281 if (send_dma_size[id] > xfer) {
1282 xfer = send_dma_size[id] - xfer;
1283 } else {
1284 xfer = 0;
1285 }
1286 txdma_handler[id](xfer, error);
1287 }
1288 }
1289
hal_uart_dma_send(enum HAL_UART_ID_T id,const uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt)1290 int hal_uart_dma_send(enum HAL_UART_ID_T id, const uint8_t *buf, uint32_t len,
1291 struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt)
1292 {
1293 struct HAL_DMA_CH_CFG_T dma_cfg;
1294 enum HAL_DMA_RET_T ret;
1295 uint32_t lock;
1296 uint32_t cnt;
1297 uint32_t i;
1298 enum HAL_DMA_PERIPH_T periph;
1299
1300 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
1301 ASSERT(uart[id].irq != INVALID_IRQn, "DMA not supported on UART %d", id);
1302 ASSERT((uart[id].base->UARTDMACR & UARTDMACR_TXDMAE), "DMA not configured on UART %d", id);
1303
1304 cnt = (len + HAL_UART_DMA_TRANSFER_STEP - 1) / HAL_UART_DMA_TRANSFER_STEP;
1305
1306 // Return the required DMA descriptor count
1307 if (desc == NULL && desc_cnt) {
1308 *desc_cnt = (cnt == 1) ? 0 : cnt;
1309 return 0;
1310 }
1311
1312 if (cnt == 0) {
1313 return 0;
1314 }
1315 if (cnt > 1) {
1316 if (desc == NULL || desc_cnt == NULL) {
1317 return -1;
1318 }
1319 if (*desc_cnt < cnt) {
1320 return -2;
1321 }
1322 }
1323 if (desc_cnt) {
1324 *desc_cnt = (cnt == 1) ? 0 : cnt;
1325 }
1326
1327 periph = uart[id].tx_periph;
1328
1329 lock = int_lock();
1330 if (send_dma_chan[id] != HAL_DMA_CHAN_NONE) {
1331 int_unlock(lock);
1332 return 1;
1333 }
1334 send_dma_chan[id] = hal_gpdma_get_chan(periph, HAL_DMA_HIGH_PRIO);
1335 if (send_dma_chan[id] == HAL_DMA_CHAN_NONE) {
1336 int_unlock(lock);
1337 return 2;
1338 }
1339 int_unlock(lock);
1340
1341 send_dma_size[id] = len;
1342
1343 memset(&dma_cfg, 0, sizeof(dma_cfg));
1344 dma_cfg.ch = send_dma_chan[id];
1345 dma_cfg.dst = 0; // useless
1346 dma_cfg.dst_bsize = HAL_DMA_BSIZE_8;
1347 dma_cfg.dst_periph = periph;
1348 dma_cfg.dst_width = HAL_DMA_WIDTH_BYTE;
1349 dma_cfg.handler = send_dma_irq_handler;
1350 dma_cfg.src = (uint32_t)buf;
1351 dma_cfg.src_bsize = HAL_DMA_BSIZE_32;
1352 dma_cfg.src_periph = 0; // useless
1353 dma_cfg.src_tsize = len;
1354 dma_cfg.src_width = HAL_DMA_WIDTH_BYTE;
1355 dma_cfg.type = HAL_DMA_FLOW_M2P_DMA;
1356 dma_cfg.try_burst = 0;
1357
1358 if (cnt == 1) {
1359 ret = hal_gpdma_start(&dma_cfg);
1360 } else {
1361 for (i = 0; i < cnt - 1; i++) {
1362 dma_cfg.src_tsize = HAL_UART_DMA_TRANSFER_STEP;
1363 ret = hal_gpdma_init_desc(&desc[i], &dma_cfg, &desc[i + 1], 0);
1364 if (ret != HAL_DMA_OK) {
1365 goto _err_exit;
1366 }
1367 dma_cfg.src += HAL_UART_DMA_TRANSFER_STEP;
1368 }
1369 dma_cfg.src_tsize = len - (HAL_UART_DMA_TRANSFER_STEP * i);
1370 ret = hal_gpdma_init_desc(&desc[i], &dma_cfg, NULL, 1);
1371 if (ret != HAL_DMA_OK) {
1372 goto _err_exit;
1373 }
1374 ret = hal_gpdma_sg_start(desc, &dma_cfg);
1375 }
1376
1377 if (ret != HAL_DMA_OK) {
1378 _err_exit:
1379 hal_gpdma_free_chan(send_dma_chan[id]);
1380 send_dma_chan[id] = HAL_DMA_CHAN_NONE;
1381 return 3;
1382 }
1383
1384 return 0;
1385 }
1386
hal_uart_stop_dma_send(enum HAL_UART_ID_T id)1387 uint32_t hal_uart_stop_dma_send(enum HAL_UART_ID_T id)
1388 {
1389 uint32_t remains;
1390 uint32_t lock;
1391 uint8_t chan;
1392
1393 ASSERT(id < HAL_UART_ID_QTY, err_invalid_id, id);
1394
1395 lock = int_lock();
1396 chan = send_dma_chan[id];
1397 send_dma_chan[id] = HAL_DMA_CHAN_NONE;
1398 int_unlock(lock);
1399
1400 if (chan == HAL_DMA_CHAN_NONE) {
1401 return 0;
1402 }
1403
1404 // Not to keep the data in DMA FIFO
1405 hal_gpdma_cancel(chan);
1406 remains = hal_gpdma_get_sg_remain_size(chan);
1407 hal_gpdma_free_chan(chan);
1408
1409 return remains;
1410 }
1411
hal_uart_irq_handler(void)1412 static void hal_uart_irq_handler(void)
1413 {
1414 enum HAL_UART_ID_T id;
1415 union HAL_UART_IRQ_T state;
1416
1417 for (id = HAL_UART_ID_0; id < HAL_UART_ID_QTY; id++) {
1418 state.reg = uart[id].base->UARTMIS;
1419
1420 if (state.reg) {
1421 uart[id].base->UARTICR = state.reg;
1422
1423 if (irq_handler[id] != NULL) {
1424 irq_handler[id](id, state);
1425 }
1426 }
1427 }
1428 }
1429
1430 // ========================================================================
1431 // Test function
1432
1433 #include "stdarg.h"
1434 #include "stdio.h"
1435
1436 #ifndef UART_PRINTF_ID
1437 #if (CHIP_HAS_UART >= 4) && (DEBUG_PORT == 4)
1438 #define UART_PRINTF_ID HAL_UART_ID_3
1439 #elif (CHIP_HAS_UART >= 3) && (DEBUG_PORT == 3)
1440 #define UART_PRINTF_ID HAL_UART_ID_2
1441 #elif (CHIP_HAS_UART >= 2) && (DEBUG_PORT == 2)
1442 #define UART_PRINTF_ID HAL_UART_ID_1
1443 #elif (DEBUG_PORT == 1)
1444 #define UART_PRINTF_ID HAL_UART_ID_0
1445 #else
1446 #define UART_PRINTF_ID HAL_UART_ID_QTY
1447 #endif
1448 #endif
1449
1450 #ifndef TRACE_BAUD_RATE
1451 #define TRACE_BAUD_RATE (921600)
1452 #endif
1453
1454 #ifndef TRACE_PRINTF_LEN
1455 #define TRACE_PRINTF_LEN (120)
1456 #endif
1457
hal_uart_printf_init(void)1458 int hal_uart_printf_init(void)
1459 {
1460 static const struct HAL_UART_CFG_T uart_cfg = {
1461 .parity = HAL_UART_PARITY_NONE,
1462 .stop = HAL_UART_STOP_BITS_1,
1463 .data = HAL_UART_DATA_BITS_8,
1464 .flow = HAL_UART_FLOW_CONTROL_NONE,//HAL_UART_FLOW_CONTROL_RTSCTS,
1465 .tx_level = HAL_UART_FIFO_LEVEL_1_2,
1466 .rx_level = HAL_UART_FIFO_LEVEL_1_4,
1467 .baud = TRACE_BAUD_RATE,
1468 .dma_rx = false,
1469 .dma_tx = false,
1470 .dma_rx_stop_on_err = false,
1471 };
1472
1473 if (0) {
1474 } else if (UART_PRINTF_ID == HAL_UART_ID_0) {
1475 hal_iomux_set_uart0();
1476 #if (CHIP_HAS_UART >= 2)
1477 } else if (UART_PRINTF_ID == HAL_UART_ID_1) {
1478 hal_iomux_set_uart1();
1479 #endif
1480 #if (CHIP_HAS_UART >= 3)
1481 } else if (UART_PRINTF_ID == HAL_UART_ID_2) {
1482 hal_iomux_set_uart2();
1483 #endif
1484 #if (CHIP_HAS_UART >= 4)
1485 } else if (UART_PRINTF_ID == HAL_UART_ID_3) {
1486 hal_iomux_set_uart3();
1487 #endif
1488 } else {
1489 return 0;
1490 }
1491
1492 return hal_uart_open(UART_PRINTF_ID, &uart_cfg);
1493 }
1494
hal_uart_get_port(void)1495 int hal_uart_get_port(void)
1496 {
1497 return UART_PRINTF_ID;
1498 }
1499
hal_uart_printf_output(const uint8_t * buf,uint32_t len)1500 void hal_uart_printf_output(const uint8_t *buf, uint32_t len)
1501 {
1502 uint32_t i;
1503
1504 if (UART_PRINTF_ID >= HAL_UART_ID_QTY) {
1505 return;
1506 }
1507 if (!hal_uart_opened(UART_PRINTF_ID)) {
1508 return;
1509 }
1510
1511 for (i = 0; i < len; i++) {
1512 hal_uart_blocked_putc(UART_PRINTF_ID, buf[i]);
1513 }
1514 }
1515
hal_uart_printf(const char * fmt,...)1516 void hal_uart_printf(const char *fmt, ...)
1517 {
1518 char buf[TRACE_PRINTF_LEN];
1519 int ret;
1520 va_list ap;
1521
1522 va_start(ap, fmt);
1523 ret = vsnprintf(buf, sizeof(buf), fmt, ap);
1524 #ifdef TRACE_CRLF
1525 if (ret + 2 < sizeof(buf)) {
1526 buf[ret++] = '\r';
1527 }
1528 #endif
1529 if (ret + 1 < sizeof(buf)) {
1530 buf[ret++] = '\n';
1531 }
1532 //buf[ret] = 0;
1533 va_end(ap);
1534
1535 if (ret > 0) {
1536 hal_uart_printf_output((const uint8_t *)buf, ret);
1537 }
1538 }
1539
hal_uart_dma_send_sync_cache(enum HAL_UART_ID_T id,const uint8_t * buf,uint32_t len,struct HAL_DMA_DESC_T * desc,uint32_t * desc_cnt)1540 int hal_uart_dma_send_sync_cache(enum HAL_UART_ID_T id, const uint8_t *buf, uint32_t len,struct HAL_DMA_DESC_T *desc, uint32_t *desc_cnt)
1541 {
1542 hal_cache_sync_all(HAL_CACHE_ID_D_CACHE);
1543 hal_uart_dma_send(id,buf,len,desc,desc_cnt);
1544 return 0;
1545 }
1546 #endif // CHIP_HAS_UART
1547