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