• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #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