1 /*
2 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-08-20 zx.chen CSI Source File for usart Driver
9 */
10
11 #include <csi_config.h>
12 #include <stdbool.h>
13 #include <string.h>
14 #include <drv_irq.h>
15 #include <drv_usart.h>
16 #include <ck_usart.h>
17 #include <soc.h>
18 #include <csi_core.h>
19
20 #define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
21
22 /*
23 * setting config may be accessed when the USART is not
24 * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
25 */
26
27 #define WAIT_USART_IDLE(addr)\
28 do { \
29 int32_t timecount = 0; \
30 while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
31 timecount++;\
32 }\
33 if (timecount >= UART_BUSY_TIMEOUT) {\
34 return ERR_USART(DRV_ERROR_TIMEOUT);\
35 } \
36 } while(0)
37
38 #define USART_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_USART(DRV_ERROR_PARAMETER))
39
40 typedef struct
41 {
42 uint32_t base;
43 uint32_t irq;
44 usart_event_cb_t cb_event; ///< Event callback
45 uint32_t rx_total_num;
46 uint32_t tx_total_num;
47 uint8_t *rx_buf;
48 uint8_t *tx_buf;
49 volatile uint32_t rx_cnt;
50 volatile uint32_t tx_cnt;
51 volatile uint32_t tx_busy;
52 volatile uint32_t rx_busy;
53 uint32_t last_tx_num;
54 uint32_t last_rx_num;
55 int32_t idx;
56 } ck_usart_priv_t;
57
58 extern int32_t target_usart_init(int32_t idx, uint32_t *base, uint32_t *irq, void **handler);
59
60 static ck_usart_priv_t usart_instance[CONFIG_USART_NUM];
61
62 static const usart_capabilities_t usart_capabilities =
63 {
64 .asynchronous = 1, /* supports USART (Asynchronous) mode */
65 .synchronous_master = 0, /* supports Synchronous Master mode */
66 .synchronous_slave = 0, /* supports Synchronous Slave mode */
67 .single_wire = 0, /* supports USART Single-wire mode */
68 .event_tx_complete = 1, /* Transmit completed event */
69 .event_rx_timeout = 0, /* Signal receive character timeout event */
70 };
71
72 /**
73 \brief set the bautrate of usart.
74 \param[in] addr usart base to operate.
75 \return error code
76 */
csi_usart_config_baudrate(usart_handle_t handle,uint32_t baud)77 int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baud)
78 {
79 USART_NULL_PARAM_CHK(handle);
80 ck_usart_priv_t *usart_priv = handle;
81 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
82
83
84 WAIT_USART_IDLE(addr);
85
86 /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
87 uint32_t divisor = ((drv_get_usart_freq(usart_priv->idx) * 10) / baud) >> 4;
88
89 if ((divisor % 10) >= 5)
90 {
91 divisor = (divisor / 10) + 1;
92 } else
93 {
94 divisor = divisor / 10;
95 }
96
97 addr->LCR |= LCR_SET_DLAB;
98 /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
99 addr->DLL = divisor & 0xff;
100 addr->DLH = (divisor >> 8) & 0xff;
101 /*
102 * The DLAB must be cleared after the baudrate is setted
103 * to access other registers.
104 */
105 addr->LCR &= (~LCR_SET_DLAB);
106
107 return 0;
108 }
109
110 /**
111 \brief config usart mode.
112 \param[in] handle usart handle to operate.
113 \param[in] mode \ref usart_mode_e
114 \return error code
115 */
csi_usart_config_mode(usart_handle_t handle,usart_mode_e mode)116 int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode)
117 {
118 USART_NULL_PARAM_CHK(handle);
119
120 if (mode == USART_MODE_ASYNCHRONOUS)
121 {
122 return 0;
123 }
124
125 return ERR_USART(USART_ERROR_MODE);
126 }
127
128 /**
129 \brief config usart parity.
130 \param[in] handle usart handle to operate.
131 \param[in] parity \ref usart_parity_e
132 \return error code
133 */
csi_usart_config_parity(usart_handle_t handle,usart_parity_e parity)134 int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity)
135 {
136 USART_NULL_PARAM_CHK(handle);
137 ck_usart_priv_t *usart_priv = handle;
138 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
139
140 WAIT_USART_IDLE(addr);
141
142 switch (parity)
143 {
144 case USART_PARITY_NONE:
145 /*CLear the PEN bit(LCR[3]) to disable parity.*/
146 addr->LCR &= (~LCR_PARITY_ENABLE);
147 break;
148
149 case USART_PARITY_ODD:
150 /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
151 addr->LCR |= LCR_PARITY_ENABLE;
152 addr->LCR &= LCR_PARITY_ODD;
153 break;
154
155 case USART_PARITY_EVEN:
156 /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
157 addr->LCR |= LCR_PARITY_ENABLE;
158 addr->LCR |= LCR_PARITY_EVEN;
159 break;
160
161 default:
162 return ERR_USART(USART_ERROR_PARITY);
163 }
164
165 return 0;
166 }
167
168 /**
169 \brief config usart stop bit number.
170 \param[in] handle usart handle to operate.
171 \param[in] stopbits \ref usart_stop_bits_e
172 \return error code
173 */
csi_usart_config_stopbits(usart_handle_t handle,usart_stop_bits_e stopbit)174 int32_t csi_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit)
175 {
176 USART_NULL_PARAM_CHK(handle);
177 ck_usart_priv_t *usart_priv = handle;
178 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
179
180 WAIT_USART_IDLE(addr);
181
182 switch (stopbit)
183 {
184 case USART_STOP_BITS_1:
185 /* Clear the STOP bit to set 1 stop bit*/
186 addr->LCR &= LCR_STOP_BIT1;
187 break;
188
189 case USART_STOP_BITS_2:
190 /*
191 * If the STOP bit is set "1",we'd gotten 1.5 stop
192 * bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
193 */
194 addr->LCR |= LCR_STOP_BIT2;
195 break;
196
197 default:
198 return ERR_USART(USART_ERROR_STOP_BITS);
199 }
200
201 return 0;
202 }
203
204 /**
205 \brief config usart data length.
206 \param[in] handle usart handle to operate.
207 \param[in] databits \ref usart_data_bits_e
208 \return error code
209 */
csi_usart_config_databits(usart_handle_t handle,usart_data_bits_e databits)210 int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits)
211 {
212 USART_NULL_PARAM_CHK(handle);
213 ck_usart_priv_t *usart_priv = handle;
214 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
215
216 WAIT_USART_IDLE(addr);
217 /* The word size decides by the DLS bits(LCR[1:0]), and the
218 * corresponding relationship between them is:
219 * DLS word size
220 * 00 -- 5 bits
221 * 01 -- 6 bits
222 * 10 -- 7 bits
223 * 11 -- 8 bits
224 */
225
226 switch (databits)
227 {
228 case USART_DATA_BITS_5:
229 addr->LCR &= LCR_WORD_SIZE_5;
230 break;
231
232 case USART_DATA_BITS_6:
233 addr->LCR &= 0xfd;
234 addr->LCR |= LCR_WORD_SIZE_6;
235 break;
236
237 case USART_DATA_BITS_7:
238 addr->LCR &= 0xfe;
239 addr->LCR |= LCR_WORD_SIZE_7;
240 break;
241
242 case USART_DATA_BITS_8:
243 addr->LCR |= LCR_WORD_SIZE_8;
244 break;
245
246 default:
247 return ERR_USART(USART_ERROR_DATA_BITS);
248 }
249
250 return 0;
251 }
252
253
ck_usart_set_int_flag(usart_handle_t handle,uint32_t flag)254 int32_t ck_usart_set_int_flag(usart_handle_t handle,uint32_t flag)
255 {
256 ck_usart_priv_t *usart_priv = handle;
257 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
258
259 addr->IER |= flag;
260
261 return 0;
262 }
263
ck_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)264 int32_t ck_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)
265 {
266 ck_usart_priv_t *usart_priv = handle;
267 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
268
269 addr->IER &= ~flag;
270
271 return 0;
272 }
273
274
275 /**
276 \brief get character in query mode.
277 \param[in] instance usart instance to operate.
278 \param[in] the pointer to the recieve charater.
279 \return error code
280 */
csi_usart_getchar(usart_handle_t handle,uint8_t * ch)281 int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
282 {
283 USART_NULL_PARAM_CHK(handle);
284 USART_NULL_PARAM_CHK(ch);
285
286 ck_usart_priv_t *usart_priv = handle;
287 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
288
289 while (!(addr->LSR & LSR_DATA_READY));
290
291 *ch = addr->RBR;
292
293 return 0;
294 }
295
296
297 /**
298 \brief get character in query mode.
299 \param[in] instance usart instance to operate.
300 \param[in] the pointer to the recieve charater.
301 \return error code
302 */
csi_uart_getchar(usart_handle_t handle)303 int csi_uart_getchar(usart_handle_t handle)
304 {
305 volatile int ch;
306 USART_NULL_PARAM_CHK(handle);
307
308 ck_usart_priv_t *usart_priv = handle;
309 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
310
311 ch = -1;
312
313 if (addr->LSR & LSR_DATA_READY)
314 {
315 ch = addr->RBR & 0xff;
316 }
317
318 return ch;
319 }
320
321
322 /**
323 \brief transmit character in query mode.
324 \param[in] instance usart instance to operate.
325 \param[in] ch the input charater
326 \return error code
327 */
csi_usart_putchar(usart_handle_t handle,uint8_t ch)328 int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
329 {
330 USART_NULL_PARAM_CHK(handle);
331 ck_usart_priv_t *usart_priv = handle;
332 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
333 uint32_t timecount = 0;
334
335 while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)))
336 {
337 timecount++;
338
339 if (timecount >= UART_BUSY_TIMEOUT)
340 {
341 return ERR_USART(DRV_ERROR_TIMEOUT);
342 }
343 }
344
345 addr->THR = ch;
346
347 return 0;
348
349 }
350
351 /**
352 \brief interrupt service function for transmitter holding register empty.
353 \param[in] usart_priv usart private to operate.
354 */
ck_usart_intr_threshold_empty(int32_t idx,ck_usart_priv_t * usart_priv)355 void ck_usart_intr_threshold_empty(int32_t idx, ck_usart_priv_t *usart_priv)
356 {
357 if (usart_priv->tx_total_num == 0)
358 {
359 return;
360 }
361
362 volatile int i = 500;
363 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
364
365 if (usart_priv->tx_cnt >= usart_priv->tx_total_num)
366 {
367 addr->IER &= (~IER_THRE_INT_ENABLE);
368 usart_priv->last_tx_num = usart_priv->tx_total_num;
369
370 /* fix hardware bug */
371 while (addr->USR & USR_UART_BUSY);
372
373 i = 500;
374
375 while (i--);
376
377 usart_priv->tx_cnt = 0;
378 usart_priv->tx_busy = 0;
379 usart_priv->tx_buf = NULL;
380 usart_priv->tx_total_num = 0;
381
382 if (usart_priv->cb_event)
383 {
384 usart_priv->cb_event(idx, USART_EVENT_SEND_COMPLETE);
385 }
386 } else
387 {
388 /* fix hardware bug */
389 while (addr->USR & USR_UART_BUSY);
390
391 i = 500;
392
393 while (i--);
394
395 addr->THR = *((uint8_t *)usart_priv->tx_buf);
396 usart_priv->tx_cnt++;
397 usart_priv->tx_buf++;
398 }
399 }
400
401 /**
402 \brief interrupt service function for receiver data available.
403 \param[in] usart_priv usart private to operate.
404 */
ck_usart_intr_recv_data(int32_t idx,ck_usart_priv_t * usart_priv)405 static void ck_usart_intr_recv_data(int32_t idx, ck_usart_priv_t *usart_priv)
406 {
407 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
408 uint8_t data = addr->RBR;
409
410 *((uint8_t *)usart_priv->rx_buf) = data;
411 usart_priv->rx_cnt++;
412 usart_priv->rx_buf++;
413
414 if (usart_priv->rx_cnt >= usart_priv->rx_total_num)
415 {
416 usart_priv->last_rx_num = usart_priv->rx_total_num;
417 usart_priv->rx_cnt = 0;
418 usart_priv->rx_buf = NULL;
419 usart_priv->rx_busy = 0;
420 usart_priv->rx_total_num = 0;
421
422 if (usart_priv->cb_event)
423 {
424 usart_priv->cb_event(idx, USART_EVENT_RECEIVE_COMPLETE);
425 }
426 }
427
428 }
429
430 /**
431 \brief interrupt service function for receiver line.
432 \param[in] usart_priv usart private to operate.
433 */
ck_usart_intr_recv_line(int32_t idx,ck_usart_priv_t * usart_priv)434 static void ck_usart_intr_recv_line(int32_t idx, ck_usart_priv_t *usart_priv)
435 {
436 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
437 uint32_t lsr_stat = addr->LSR;
438
439 addr->IER &= (~IER_THRE_INT_ENABLE);
440
441 uint32_t timecount = 0;
442
443 while (addr->LSR & 0x1)
444 {
445 addr->RBR;
446 timecount++;
447
448 if (timecount >= UART_BUSY_TIMEOUT)
449 {
450 if (usart_priv->cb_event)
451 {
452 usart_priv->cb_event(idx, USART_EVENT_RX_TIMEOUT);
453 }
454
455 return;
456 }
457 }
458
459 /** Break Interrupt bit. This is used to indicate the detection of a
460 * break sequence on the serial input data.
461 */
462 if (lsr_stat & DW_LSR_BI)
463 {
464 if (usart_priv->cb_event)
465 {
466 usart_priv->cb_event(idx, USART_EVENT_RX_BREAK);
467 }
468
469 return;
470 }
471
472 /** Framing Error bit. This is used to indicate the occurrence of a
473 * framing error in the receiver. A framing error occurs when the receiver
474 * does not detect a valid STOP bit in the received data.
475 */
476 if (lsr_stat & DW_LSR_FE)
477 {
478 if (usart_priv->cb_event)
479 {
480 usart_priv->cb_event(idx, USART_EVENT_RX_FRAMING_ERROR);
481 }
482
483 return;
484 }
485
486 /** Framing Error bit. This is used to indicate the occurrence of a
487 * framing error in the receiver. A framing error occurs when the
488 * receiver does not detect a valid STOP bit in the received data.
489 */
490 if (lsr_stat & DW_LSR_PE)
491 {
492 if (usart_priv->cb_event)
493 {
494 usart_priv->cb_event(idx, USART_EVENT_RX_PARITY_ERROR);
495 }
496
497 return;
498 }
499
500 /** Overrun error bit. This is used to indicate the occurrence of an overrun error.
501 * This occurs if a new data character was received before the previous data was read.
502 */
503 if (lsr_stat & DW_LSR_OE)
504 {
505 if (usart_priv->cb_event)
506 {
507 usart_priv->cb_event(idx, USART_EVENT_RX_OVERFLOW);
508 }
509
510 return;
511 }
512 }
513 /**
514 \brief interrupt service function for character timeout.
515 \param[in] usart_priv usart private to operate.
516 */
ck_usart_intr_char_timeout(int32_t idx,ck_usart_priv_t * usart_priv)517 static void ck_usart_intr_char_timeout(int32_t idx, ck_usart_priv_t *usart_priv)
518 {
519 if ((usart_priv->rx_total_num != 0) && (usart_priv->rx_buf != NULL))
520 {
521 ck_usart_intr_recv_data(idx, usart_priv);
522 return;
523 }
524
525 if (usart_priv->cb_event)
526 {
527 usart_priv->cb_event(idx, USART_EVENT_RECEIVED);
528 } else
529 {
530 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
531
532 uint32_t timecount = 0;
533
534 while (addr->LSR & 0x1)
535 {
536 addr->RBR;
537 timecount++;
538
539 if (timecount >= UART_BUSY_TIMEOUT)
540 {
541 if (usart_priv->cb_event)
542 {
543 usart_priv->cb_event(idx, USART_EVENT_RX_TIMEOUT);
544 }
545
546 return;
547 }
548 }
549 }
550 }
551
552 /**
553 \brief the interrupt service function.
554 \param[in] index of usart instance.
555 */
ck_usart_irqhandler(int32_t idx)556 void ck_usart_irqhandler(int32_t idx)
557 {
558 ck_usart_priv_t *usart_priv = &usart_instance[idx];
559 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
560
561 uint8_t intr_state = addr->IIR & 0xf;
562
563 switch (intr_state)
564 {
565 case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
566 ck_usart_intr_threshold_empty(idx, usart_priv);
567 break;
568
569 case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
570 ck_usart_intr_char_timeout(idx, usart_priv);
571 //ck_usart_intr_recv_data(idx, usart_priv);
572 break;
573
574 case DW_IIR_RECV_LINE:
575 ck_usart_intr_recv_line(idx, usart_priv);
576 break;
577
578 case DW_IIR_CHAR_TIMEOUT:
579 ck_usart_intr_char_timeout(idx, usart_priv);
580 break;
581
582 default:
583 break;
584 }
585 }
586
587 /**
588 \brief Get driver capabilities.
589 \param[in] idx usart index
590 \return \ref usart_capabilities_t
591 */
csi_usart_get_capabilities(int32_t idx)592 usart_capabilities_t csi_usart_get_capabilities(int32_t idx)
593 {
594 if (idx < 0 || idx >= CONFIG_USART_NUM)
595 {
596 usart_capabilities_t ret;
597 memset(&ret, 0, sizeof(usart_capabilities_t));
598 return ret;
599 }
600
601 return usart_capabilities;
602 }
603
604 /**
605 \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
606 \param[in] idx usart index
607 \param[in] cb_event Pointer to \ref usart_event_cb_t
608 \return return usart handle if success
609 */
csi_usart_initialize(int32_t idx,usart_event_cb_t cb_event)610 usart_handle_t csi_usart_initialize(int32_t idx, usart_event_cb_t cb_event)
611 {
612 uint32_t base = 0u;
613 uint32_t irq = 0u;
614 void *handler;
615
616 int32_t ret = target_usart_init(idx, &base, &irq, &handler);
617
618 if (ret < 0 || ret >= CONFIG_USART_NUM)
619 {
620 return NULL;
621 }
622
623 ck_usart_priv_t *usart_priv = &usart_instance[idx];
624 usart_priv->base = base;
625 usart_priv->irq = irq;
626 usart_priv->cb_event = cb_event;
627 usart_priv->idx = idx;
628 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
629
630 /* enable received data available */
631 addr->IER = IER_RDA_INT_ENABLE | IIR_RECV_LINE_ENABLE;
632 drv_irq_register(usart_priv->irq, handler);
633 drv_irq_enable(usart_priv->irq);
634
635 return usart_priv;
636 }
637
638 /**
639 \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
640 \param[in] handle usart handle to operate.
641 \return error code
642 */
csi_usart_uninitialize(usart_handle_t handle)643 int32_t csi_usart_uninitialize(usart_handle_t handle)
644 {
645 USART_NULL_PARAM_CHK(handle);
646
647 ck_usart_priv_t *usart_priv = handle;
648
649 drv_irq_disable(usart_priv->irq);
650 drv_irq_unregister(usart_priv->irq);
651 usart_priv->cb_event = NULL;
652
653 return 0;
654 }
655
656 /**
657 \brief config usart mode.
658 \param[in] handle usart handle to operate.
659 \param[in] baud baud rate
660 \param[in] mode \ref usart_mode_e
661 \param[in] parity \ref usart_parity_e
662 \param[in] stopbits \ref usart_stop_bits_e
663 \param[in] bits \ref usart_data_bits_e
664 \return error code
665 */
csi_usart_config(usart_handle_t handle,uint32_t baud,usart_mode_e mode,usart_parity_e parity,usart_stop_bits_e stopbits,usart_data_bits_e bits)666 int32_t csi_usart_config(usart_handle_t handle,
667 uint32_t baud,
668 usart_mode_e mode,
669 usart_parity_e parity,
670 usart_stop_bits_e stopbits,
671 usart_data_bits_e bits)
672 {
673 int32_t ret;
674
675 /* control the data_bit of the usart*/
676 ret = csi_usart_config_baudrate(handle, baud);
677
678 if (ret < 0)
679 {
680 return ret;
681 }
682
683 /* control mode of the usart*/
684 ret = csi_usart_config_mode(handle, mode);
685
686 if (ret < 0)
687 {
688 return ret;
689 }
690
691 /* control the parity of the usart*/
692 ret = csi_usart_config_parity(handle, parity);
693
694 if (ret < 0)
695 {
696 return ret;
697 }
698
699 /* control the stopbit of the usart*/
700 ret = csi_usart_config_stopbits(handle, stopbits);
701
702 if (ret < 0)
703 {
704 return ret;
705 }
706
707 ret = csi_usart_config_databits(handle, bits);
708
709 if (ret < 0)
710 {
711 return ret;
712 }
713
714 return 0;
715 }
716
717
718 /**
719 \brief Start sending data to UART transmitter,(received data is ignored).
720 The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
721 csi_usart_get_status can indicates if transmission is still in progress or pending
722 \param[in] handle usart handle to operate.
723 \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
724 \param[in] num Number of data items to send
725 \return error code
726 */
csi_usart_send(usart_handle_t handle,const void * data,uint32_t num)727 int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
728 {
729 USART_NULL_PARAM_CHK(handle);
730 USART_NULL_PARAM_CHK(data);
731
732 if (num == 0)
733 {
734 return ERR_USART(DRV_ERROR_PARAMETER);
735 }
736
737 ck_usart_priv_t *usart_priv = handle;
738
739 usart_priv->tx_buf = (uint8_t *)data;
740 usart_priv->tx_total_num = num;
741 usart_priv->tx_cnt = 0;
742 usart_priv->tx_busy = 1;
743 usart_priv->last_tx_num = 0;
744
745 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
746 ck_usart_intr_threshold_empty(usart_priv->idx, usart_priv);
747 /* enable the interrupt*/
748 addr->IER |= IER_THRE_INT_ENABLE;
749 return 0;
750 }
751
752 /**
753 \brief Abort Send data to UART transmitter
754 \param[in] handle usart handle to operate.
755 \return error code
756 */
csi_usart_abort_send(usart_handle_t handle)757 int32_t csi_usart_abort_send(usart_handle_t handle)
758 {
759 USART_NULL_PARAM_CHK(handle);
760 ck_usart_priv_t *usart_priv = handle;
761
762 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
763 addr->IER &= (~IER_THRE_INT_ENABLE);
764
765 usart_priv->tx_cnt = usart_priv->tx_total_num;
766 usart_priv->tx_cnt = 0;
767 usart_priv->tx_busy = 0;
768 usart_priv->tx_buf = NULL;
769 usart_priv->tx_total_num = 0;
770 return 0;
771 }
772
773 /**
774 \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
775 \param[in] handle usart handle to operate.
776 \param[out] data Pointer to buffer for data to receive from UART receiver
777 \param[in] num Number of data items to receive
778 \return error code
779 */
csi_usart_receive(usart_handle_t handle,void * data,uint32_t num)780 int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
781 {
782 USART_NULL_PARAM_CHK(handle);
783 USART_NULL_PARAM_CHK(data);
784
785 ck_usart_priv_t *usart_priv = handle;
786
787 usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
788 usart_priv->rx_total_num = num; // Save number of data to be received
789 usart_priv->rx_cnt = 0;
790 usart_priv->rx_busy = 1;
791 usart_priv->last_rx_num = 0;
792
793 return 0;
794
795 }
796
797 /**
798 \brief query data from UART receiver FIFO.
799 \param[in] handle usart handle to operate.
800 \param[out] data Pointer to buffer for data to receive from UART receiver
801 \param[in] num Number of data items to receive
802 \return receive fifo data num
803 */
csi_usart_receive_query(usart_handle_t handle,void * data,uint32_t num)804 int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
805 {
806 USART_NULL_PARAM_CHK(handle);
807 USART_NULL_PARAM_CHK(data);
808
809 ck_usart_priv_t *usart_priv = handle;
810 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
811 int32_t recv_num = 0;
812 uint8_t *dest = (uint8_t *)data;
813
814 while (addr->LSR & 0x1)
815 {
816 *dest++ = addr->RBR;
817 recv_num++;
818
819 if (recv_num >= num)
820 {
821 break;
822 }
823 }
824
825 return recv_num;
826
827 }
828
829 /**
830 \brief Abort Receive data from UART receiver
831 \param[in] handle usart handle to operate.
832 \return error code
833 */
csi_usart_abort_receive(usart_handle_t handle)834 int32_t csi_usart_abort_receive(usart_handle_t handle)
835 {
836 USART_NULL_PARAM_CHK(handle);
837 ck_usart_priv_t *usart_priv = handle;
838
839 usart_priv->rx_cnt = usart_priv->rx_total_num;
840 return 0;
841 }
842
843 /**
844 \brief Start sending/receiving data to/from UART transmitter/receiver.
845 \param[in] handle usart handle to operate.
846 \param[in] data_out Pointer to buffer with data to send to USART transmitter
847 \param[out] data_in Pointer to buffer for data to receive from USART receiver
848 \param[in] num Number of data items to transfer
849 \return error code
850 */
csi_usart_transfer(usart_handle_t handle,const void * data_out,void * data_in,uint32_t num)851 int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
852 {
853 USART_NULL_PARAM_CHK(handle);
854 return ERR_USART(DRV_ERROR_UNSUPPORTED);
855 }
856
857 /**
858 \brief abort sending/receiving data to/from USART transmitter/receiver.
859 \param[in] handle usart handle to operate.
860 \return error code
861 */
csi_usart_abort_transfer(usart_handle_t handle)862 int32_t csi_usart_abort_transfer(usart_handle_t handle)
863 {
864 USART_NULL_PARAM_CHK(handle);
865 return ERR_USART(DRV_ERROR_UNSUPPORTED);
866 }
867
868 /**
869 \brief Get USART status.
870 \param[in] handle usart handle to operate.
871 \return USART status \ref usart_status_t
872 */
csi_usart_get_status(usart_handle_t handle)873 usart_status_t csi_usart_get_status(usart_handle_t handle)
874 {
875 usart_status_t usart_status;
876
877 memset(&usart_status, 0, sizeof(usart_status_t));
878
879 if (handle == NULL)
880 {
881 return usart_status;
882 }
883
884 ck_usart_priv_t *usart_priv = handle;
885 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
886 uint32_t line_status_reg = addr->LSR;
887
888 usart_status.tx_busy = usart_priv->tx_busy;
889 usart_status.rx_busy = usart_priv->rx_busy;
890
891 if (line_status_reg & DW_LSR_BI)
892 {
893 usart_status.rx_break = 1;
894 }
895
896 if (line_status_reg & DW_LSR_FE)
897 {
898 usart_status.rx_framing_error = 1;
899 }
900
901 if (line_status_reg & DW_LSR_PE)
902 {
903 usart_status.rx_parity_error = 1;
904 }
905
906 usart_status.tx_enable = 1;
907 usart_status.rx_enable = 1;
908
909 return usart_status;
910 }
911
912 /**
913 \brief control the transmit.
914 \param[in] handle usart handle to operate.
915 \param[in] 1 - enable the transmitter. 0 - disable the transmitter
916 \return error code
917 */
csi_usart_control_tx(usart_handle_t handle,uint32_t enable)918 int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
919 {
920 USART_NULL_PARAM_CHK(handle);
921 return 0;
922 }
923
924 /**
925 \brief control the receive.
926 \param[in] handle usart handle to operate.
927 \param[in] 1 - enable the receiver. 0 - disable the receiver
928 \return error code
929 */
csi_usart_control_rx(usart_handle_t handle,uint32_t enable)930 int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
931 {
932 USART_NULL_PARAM_CHK(handle);
933 return 0;
934 }
935
936 /**
937 \brief control the break.
938 \param[in] handle usart handle to operate.
939 \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
940 \return error code
941 */
csi_usart_control_break(usart_handle_t handle,uint32_t enable)942 int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
943 {
944 USART_NULL_PARAM_CHK(handle);
945 return ERR_USART(DRV_ERROR_UNSUPPORTED);
946 }
947
948 /**
949 \brief flush receive/send data.
950 \param[in] handle usart handle to operate.
951 \param[in] type \ref usart_flush_type_e.
952 \return error code
953 */
csi_usart_flush(usart_handle_t handle,usart_flush_type_e type)954 int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
955 {
956 USART_NULL_PARAM_CHK(handle);
957
958 ck_usart_priv_t *usart_priv = handle;
959 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
960
961 uint32_t timecount = 0;
962
963 if (type == USART_FLUSH_WRITE) {
964 while ((!(addr->LSR & DW_LSR_TEMT)))
965 {
966 timecount++;
967
968 if (timecount >= UART_BUSY_TIMEOUT)
969 {
970 return ERR_USART(DRV_ERROR_TIMEOUT);
971 }
972 }
973 } else if (type == USART_FLUSH_READ)
974 {
975 while (addr->LSR & 0x1) {
976 timecount++;
977
978 if (timecount >= UART_BUSY_TIMEOUT)
979 {
980 return ERR_USART(DRV_ERROR_TIMEOUT);
981 }
982 }
983 } else
984 {
985 return ERR_USART(DRV_ERROR_PARAMETER);
986 }
987
988 return 0;
989 }
990
991 /**
992 \brief set interrupt mode.
993 \param[in] handle usart handle to operate.
994 \param[in] type \ref usart_intr_type_e.
995 \param[in] flag 0-OFF, 1-ON.
996 \return error code
997 */
csi_usart_set_interrupt(usart_handle_t handle,usart_intr_type_e type,int32_t flag)998 int32_t csi_usart_set_interrupt(usart_handle_t handle, usart_intr_type_e type, int32_t flag)
999 {
1000 USART_NULL_PARAM_CHK(handle);
1001
1002 ck_usart_priv_t *usart_priv = handle;
1003 ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
1004
1005 switch (type)
1006 {
1007 case USART_INTR_WRITE:
1008 if (flag == 0)
1009 {
1010 addr->IER &= ~IER_THRE_INT_ENABLE;
1011 } else if (flag == 1)
1012 {
1013 addr->IER |= IER_THRE_INT_ENABLE;
1014 } else
1015 {
1016 return ERR_USART(DRV_ERROR_PARAMETER);
1017 }
1018
1019 break;
1020
1021 case USART_INTR_READ:
1022 if (flag == 0)
1023 {
1024 addr->IER &= ~IER_RDA_INT_ENABLE;
1025 } else if (flag == 1)
1026 {
1027 addr->IER |= IER_RDA_INT_ENABLE;
1028 } else
1029 {
1030 return ERR_USART(DRV_ERROR_PARAMETER);
1031 }
1032
1033 break;
1034
1035 default:
1036 return ERR_USART(DRV_ERROR_PARAMETER);
1037
1038 }
1039
1040 return 0;
1041 }
1042
1043 /**
1044 \brief Get usart send data count.
1045 \param[in] handle usart handle to operate.
1046 \return number of currently transmitted data bytes
1047 */
csi_usart_get_tx_count(usart_handle_t handle)1048 uint32_t csi_usart_get_tx_count(usart_handle_t handle)
1049 {
1050 USART_NULL_PARAM_CHK(handle);
1051
1052 ck_usart_priv_t *usart_priv = handle;
1053
1054 if (usart_priv->tx_busy)
1055 {
1056 return usart_priv->tx_cnt;
1057 } else
1058 {
1059 return usart_priv->last_tx_num;
1060 }
1061 }
1062
1063 /**
1064 \brief Get usart receive data count.
1065 \param[in] handle usart handle to operate.
1066 \return number of currently received data bytes
1067 */
csi_usart_get_rx_count(usart_handle_t handle)1068 uint32_t csi_usart_get_rx_count(usart_handle_t handle)
1069 {
1070 USART_NULL_PARAM_CHK(handle);
1071 ck_usart_priv_t *usart_priv = handle;
1072
1073 if (usart_priv->rx_busy)
1074 {
1075 return usart_priv->rx_cnt;
1076 } else
1077 {
1078 return usart_priv->last_rx_num;
1079 }
1080 }
1081
1082 /**
1083 \brief control usart power.
1084 \param[in] handle usart handle to operate.
1085 \param[in] state power state.\ref csi_power_stat_e.
1086 \return error code
1087 */
csi_usart_power_control(usart_handle_t handle,csi_power_stat_e state)1088 int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state)
1089 {
1090 USART_NULL_PARAM_CHK(handle);
1091 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1092 }
1093
1094 /**
1095 \brief config usart flow control type.
1096 \param[in] handle usart handle to operate.
1097 \param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
1098 \return error code
1099 */
csi_usart_config_flowctrl(usart_handle_t handle,usart_flowctrl_type_e flowctrl_type)1100 int32_t csi_usart_config_flowctrl(usart_handle_t handle,
1101 usart_flowctrl_type_e flowctrl_type)
1102 {
1103 USART_NULL_PARAM_CHK(handle);
1104
1105 switch (flowctrl_type)
1106 {
1107 case USART_FLOWCTRL_CTS:
1108 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1109
1110 case USART_FLOWCTRL_RTS:
1111 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1112
1113 case USART_FLOWCTRL_CTS_RTS:
1114 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1115 break;
1116
1117 case USART_FLOWCTRL_NONE:
1118 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1119 break;
1120
1121 default:
1122 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1123 }
1124
1125 return 0;
1126 }
1127
1128
1129 /**
1130 \brief config usart clock Polarity and Phase.
1131 \param[in] handle usart handle to operate.
1132 \param[in] cpol Clock Polarity.\ref usart_cpol_e.
1133 \param[in] cpha Clock Phase.\ref usart_cpha_e.
1134 \return error code
1135 */
csi_usart_config_clock(usart_handle_t handle,usart_cpol_e cpol,usart_cpha_e cpha)1136 int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha)
1137 {
1138 USART_NULL_PARAM_CHK(handle);
1139 return ERR_USART(DRV_ERROR_UNSUPPORTED);
1140 }
1141
1142