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