]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/T-HEAD_CB2201_CDK/csi/csi_driver/csky/common/usart/ck_usart.c
Introduce a port for T-HEAD CK802. A simple demo for T-HEAD CB2201 is also included.
[freertos] / FreeRTOS / Demo / T-HEAD_CB2201_CDK / csi / csi_driver / csky / common / usart / ck_usart.c
1 /*
2  * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /******************************************************************************
18  * @file     ck_usart.c
19  * @brief    CSI Source File for usart Driver
20  * @version  V1.0
21  * @date     02. June 2017
22  ******************************************************************************/
23 #include <stdbool.h>
24 #include "csi_core.h"
25 #include "drv_usart.h"
26 #include "ck_usart.h"
27 #include "soc.h"
28
29 #define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
30
31 /*
32  * setting config may be accessed when the USART is not
33  * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
34  */
35
36 #define WAIT_USART_IDLE(addr)\
37     do {                       \
38         int32_t timecount = 0;  \
39         while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
40             timecount++;\
41         }\
42         if (timecount >= UART_BUSY_TIMEOUT) {\
43             return ERR_USART(EDRV_TIMEOUT);\
44         }                                   \
45     } while(0)
46
47 #define USART_NULL_PARAM_CHK(para)                   \
48     do {                                        \
49         if (para == NULL) {                     \
50             return ERR_USART(EDRV_PARAMETER);   \
51         }                                       \
52     } while (0)
53
54 typedef struct {
55     uint32_t base;
56     uint32_t irq;
57     usart_event_cb_t cb_event;           ///< Event callback
58     void *cb_arg;
59     uint32_t rx_total_num;
60     uint32_t tx_total_num;
61     uint8_t *rx_buf;
62     uint8_t *tx_buf;
63     volatile uint32_t rx_cnt;
64     volatile uint32_t tx_cnt;
65     volatile uint32_t tx_busy;
66     volatile uint32_t rx_busy;
67 } dw_usart_priv_t;
68
69 extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq);
70
71 static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
72
73 static const usart_capabilities_t usart_capabilities = {
74     .asynchronous = 1,          /* supports USART (Asynchronous) mode */
75     .synchronous_master = 0,    /* supports Synchronous Master mode */
76     .synchronous_slave = 0,     /* supports Synchronous Slave mode */
77     .single_wire = 0,           /* supports USART Single-wire mode */
78     .event_tx_complete = 1,     /* Transmit completed event */
79     .event_rx_timeout = 0,      /* Signal receive character timeout event */
80 };
81
82 /**
83   \brief       set the bautrate of usart.
84   \param[in]   addr  usart base to operate.
85   \param[in]   baudrate.
86   \param[in]   apbfreq the frequence of the apb.
87   \return      error code
88 */
89 static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq)
90 {
91     WAIT_USART_IDLE(addr);
92
93     /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
94     uint32_t divisor = ((apbfreq  * 10) / baudrate) >> 4;
95
96     if ((divisor % 10) >= 5) {
97         divisor = (divisor / 10) + 1;
98     } else {
99         divisor = divisor / 10;
100     }
101
102     addr->LCR |= LCR_SET_DLAB;
103     /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
104     addr->DLL = divisor & 0xff;
105     addr->DLH = (divisor >> 8) & 0xff;
106     /*
107      * The DLAB must be cleared after the baudrate is setted
108      * to access other registers.
109      */
110     addr->LCR &= (~LCR_SET_DLAB);
111
112     return 0;
113 }
114
115 /**
116   \brief       enable or disable parity.
117   \param[in]   addr  usart base to operate.
118   \param[in]   parity ODD=8, EVEN=16, or NONE=0.
119   \return      error code
120 */
121
122 static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity)
123 {
124     WAIT_USART_IDLE(addr);
125
126     switch (parity) {
127         case USART_PARITY_NONE:
128             /*CLear the PEN bit(LCR[3]) to disable parity.*/
129             addr->LCR &= (~LCR_PARITY_ENABLE);
130             break;
131
132         case USART_PARITY_ODD:
133             /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
134             addr->LCR |= LCR_PARITY_ENABLE;
135             addr->LCR &= LCR_PARITY_ODD;
136             break;
137
138         case USART_PARITY_EVEN:
139             /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
140             addr->LCR |= LCR_PARITY_ENABLE;
141             addr->LCR |= LCR_PARITY_EVEN;
142             break;
143
144         default:
145             return ERR_USART(EDRV_USART_PARITY);
146     }
147
148     return 0;
149 }
150
151 /**
152   \brief       set the stop bit.
153   \param[in]   addr  usart base to operate.
154   \param[in]   stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2.
155   \return      error code
156 */
157 static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit)
158 {
159     WAIT_USART_IDLE(addr);
160
161     switch (stopbit) {
162         case USART_STOP_BITS_1:
163             /* Clear the STOP bit to set 1 stop bit*/
164             addr->LCR &= LCR_STOP_BIT1;
165             break;
166
167         case USART_STOP_BITS_2:
168             /*
169             * If the STOP bit is set "1",we'd gotten 1.5 stop
170             * bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
171             */
172             addr->LCR |= LCR_STOP_BIT2;
173             break;
174
175         default:
176             return ERR_USART(EDRV_USART_STOP_BITS);
177     }
178
179     return 0;
180 }
181
182 /**
183   \brief       the transmit data length,and we have four choices:5, 6, 7, and 8 bits.
184   \param[in]   addr  usart base to operate.
185   \param[in]   databits the data length that user decides.
186   \return      error code
187 */
188 static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits)
189 {
190     WAIT_USART_IDLE(addr);
191    /* The word size decides by the DLS bits(LCR[1:0]), and the
192     * corresponding relationship between them is:
193     *   DLS   word size
194     *       00 -- 5 bits
195     *       01 -- 6 bits
196     *       10 -- 7 bits
197     *       11 -- 8 bits
198     */
199
200     switch (databits) {
201         case USART_DATA_BITS_5:
202             addr->LCR &= LCR_WORD_SIZE_5;
203             break;
204
205         case USART_DATA_BITS_6:
206             addr->LCR &= 0xfd;
207             addr->LCR |= LCR_WORD_SIZE_6;
208             break;
209
210         case USART_DATA_BITS_7:
211             addr->LCR &= 0xfe;
212             addr->LCR |= LCR_WORD_SIZE_7;
213             break;
214
215         case USART_DATA_BITS_8:
216             addr->LCR |= LCR_WORD_SIZE_8;
217             break;
218
219         default:
220             return ERR_USART(EDRV_USART_DATA_BITS);
221     }
222
223     return 0;
224 }
225
226 /**
227   \brief       get character in query mode.
228   \param[in]   instance  usart instance to operate.
229   \param[in]   the pointer to the recieve charater.
230   \return      error code
231 */
232 int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
233 {
234     dw_usart_priv_t *usart_priv = handle;
235     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
236
237     while (!(addr->LSR & LSR_DATA_READY));
238
239     *ch = addr->RBR;
240
241     return 0;
242 }
243
244 /**
245   \brief       transmit character in query mode.
246   \param[in]   instance  usart instance to operate.
247   \param[in]   ch  the input charater
248   \return      error code
249 */
250 int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
251 {
252     dw_usart_priv_t *usart_priv = handle;
253     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
254
255     while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
256
257     addr->THR = ch;
258
259     return 0;
260
261 }
262
263 /**
264   \brief       interrupt service function for transmitter holding register empty.
265   \param[in]   usart_priv usart private to operate.
266 */
267 static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv)
268 {
269     if (usart_priv->tx_total_num == 0) {
270         return;
271     }
272
273     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
274
275     addr->THR = *((uint8_t *)usart_priv->tx_buf);
276     usart_priv->tx_cnt++;
277     usart_priv->tx_buf++;
278
279     if (usart_priv->tx_cnt >= usart_priv->tx_total_num) {
280         addr->IER &= (~IER_THRE_INT_ENABLE);
281
282         while ((!(addr->LSR & DW_LSR_TEMT)));
283
284         usart_priv->tx_cnt = 0;
285         usart_priv->tx_busy = 0;
286         usart_priv->tx_buf = NULL;
287         usart_priv->tx_total_num = 0;
288
289         if (usart_priv->cb_event) {
290             usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg);
291         }
292     }
293
294 }
295
296 /**
297   \brief        interrupt service function for receiver data available.
298   \param[in]   usart_priv usart private to operate.
299 */
300 static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv)
301 {
302     if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) {
303         usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg);
304         return;
305     }
306
307     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
308     uint8_t data = addr->RBR;
309
310     if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) {
311         return;
312     }
313
314     *((uint8_t *)usart_priv->rx_buf) = data;
315     usart_priv->rx_cnt++;
316     usart_priv->rx_buf++;
317
318     if (usart_priv->rx_cnt >= usart_priv->rx_total_num) {
319         usart_priv->rx_cnt = 0;
320         usart_priv->rx_buf = NULL;
321         usart_priv->rx_busy = 0;
322         usart_priv->rx_total_num = 0;
323
324         if (usart_priv->cb_event) {
325             usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg);
326         }
327     }
328
329 }
330
331 /**
332   \brief       the interrupt service function.
333   \param[in]   index of usart instance.
334 */
335 void dw_usart_irqhandler(int32_t idx)
336 {
337     dw_usart_priv_t *usart_priv = &usart_instance[idx];
338     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
339
340     uint8_t intr_state = addr->IIR & 0xf;
341
342     switch (intr_state) {
343         case DW_IIR_THR_EMPTY:       /* interrupt source:transmitter holding register empty */
344             dw_usart_intr_threshold_empty(usart_priv);
345             break;
346
347         case DW_IIR_RECV_DATA:       /* interrupt source:receiver data available or receiver fifo trigger level reached */
348             dw_usart_intr_recv_data(usart_priv);
349             break;
350
351         default:
352             break;
353     }
354 }
355
356 /**
357   \brief       Get driver capabilities.
358   \param[in]   handle  usart handle to operate.
359   \return      \ref usart_capabilities_t
360 */
361 usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
362 {
363     return usart_capabilities;
364 }
365
366 /**
367   \brief       Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
368   \param[in]   usart pin of tx
369   \param[in]   usart pin of rx
370   \param[in]   cb_event  Pointer to \ref usart_event_cb_t
371   \return      return usart handle if success
372 */
373 usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
374 {
375     uint32_t base = 0u;
376     uint32_t irq = 0u;
377
378     int32_t idx = target_usart_init(tx, rx, &base, &irq);
379
380     if (idx < 0 || idx >= CONFIG_USART_NUM) {
381         return NULL;
382     }
383
384     dw_usart_priv_t *usart_priv = &usart_instance[idx];
385     usart_priv->base = base;
386     usart_priv->irq = irq;
387     usart_priv->cb_event = cb_event;
388     usart_priv->cb_arg = cb_arg;
389
390     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
391
392     /* enable received data available */
393     addr->IER = IER_RDA_INT_ENABLE;
394     drv_nvic_enable_irq(usart_priv->irq);
395
396     return usart_priv;
397 }
398
399 /**
400   \brief       De-initialize UART Interface. stops operation and releases the software resources used by the interface
401   \param[in]   handle  usart handle to operate.
402   \return      error code
403 */
404 int32_t csi_usart_uninitialize(usart_handle_t handle)
405 {
406     USART_NULL_PARAM_CHK(handle);
407
408     dw_usart_priv_t *usart_priv = handle;
409
410     drv_nvic_disable_irq(usart_priv->irq);
411     usart_priv->cb_event   = NULL;
412
413     return 0;
414 }
415
416 /**
417   \brief       config usart mode.
418   \param[in]   handle  usart handle to operate.
419   \param[in]   sysclk    configured system clock.
420   \param[in]   mode      \ref usart_mode_e
421   \param[in]   parity    \ref usart_parity_e
422   \param[in]   stopbits  \ref usart_stop_bits_e
423   \param[in]   bits      \ref usart_data_bits_e
424   \param[in]   baud      configured baud
425   \return      error code
426 */
427 int32_t csi_usart_config(usart_handle_t handle,
428                          uint32_t sysclk,
429                          uint32_t baud,
430                          usart_mode_e mode,
431                          usart_parity_e parity,
432                          usart_stop_bits_e stopbits,
433                          usart_data_bits_e bits)
434 {
435     USART_NULL_PARAM_CHK(handle);
436     dw_usart_priv_t *usart_priv = handle;
437     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
438
439     /* control the data_bit of the usart*/
440     int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk);
441
442     if (ret < 0) {
443         return ret;
444     }
445
446     /* control the parity of the usart*/
447     ret = dw_usart_set_parity(addr, parity);
448
449     if (ret < 0) {
450         return ret;
451     }
452
453     /* control the stopbit of the usart*/
454     ret = dw_usart_set_stopbit(addr, stopbits);
455
456     if (ret < 0) {
457         return ret;
458     }
459
460     ret = dw_usart_set_databit(addr, bits);
461
462     if (ret < 0) {
463         return ret;
464     }
465
466     return 0;
467 }
468 /**
469   \brief       config usart default tx value. used in syn mode
470   \param[in]   handle  usart handle to operate.
471   \param[in]   value  default tx value
472   \return      error code
473 */
474 int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
475 {
476     USART_NULL_PARAM_CHK(handle);
477     return ERR_USART(EDRV_UNSUPPORTED);
478 }
479
480 /**
481   \brief       Start sending data to UART transmitter,(received data is ignored).
482                The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
483                csi_usart_get_status can indicates if transmission is still in progress or pending
484   \param[in]   handle  usart handle to operate.
485   \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,
486   \param[in]   num   Number of data items to send
487   \return      error code
488 */
489 int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
490 {
491     USART_NULL_PARAM_CHK(handle);
492     USART_NULL_PARAM_CHK(data);
493
494     if (num == 0) {
495         return ERR_USART(EDRV_PARAMETER);
496     }
497
498     dw_usart_priv_t *usart_priv = handle;
499     uint8_t *source = NULL;
500     source = (uint8_t *)data;
501
502     usart_priv->tx_buf = (uint8_t *)data;
503     usart_priv->tx_total_num = num;
504     usart_priv->tx_cnt = 0;
505     usart_priv->tx_busy = 1;
506
507     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
508     /* enable the interrupt*/
509     addr->IER |= IER_THRE_INT_ENABLE;
510     return 0;
511 }
512
513 /**
514   \brief       Abort Send data to UART transmitter
515   \param[in]   handle  usart handle to operate.
516   \return      error code
517 */
518 int32_t csi_usart_abort_send(usart_handle_t handle)
519 {
520     USART_NULL_PARAM_CHK(handle);
521     dw_usart_priv_t *usart_priv = handle;
522
523     usart_priv->tx_cnt = usart_priv->tx_total_num;
524     return 0;
525 }
526
527 /**
528   \brief       Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
529   \param[in]   handle  usart handle to operate.
530   \param[out]  data  Pointer to buffer for data to receive from UART receiver
531   \param[in]   num   Number of data items to receive
532   \return      error code
533 */
534 int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
535 {
536     USART_NULL_PARAM_CHK(handle);
537     USART_NULL_PARAM_CHK(data);
538
539     uint8_t *dest = NULL;
540     dw_usart_priv_t *usart_priv = handle;
541     dest = (uint8_t *)data;
542
543     usart_priv->rx_buf = (uint8_t *)data;   // Save receive buffer usart
544     usart_priv->rx_total_num = num;         // Save number of data to be received
545     usart_priv->rx_cnt = 0;
546     usart_priv->rx_busy = 1;
547
548     return 0;
549
550 }
551
552 /**
553   \brief       query data from UART receiver FIFO.
554   \param[in]   handle  usart handle to operate.
555   \param[out]  data  Pointer to buffer for data to receive from UART receiver
556   \param[in]   num   Number of data items to receive
557   \return      receive fifo data num
558 */
559 int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
560 {
561     USART_NULL_PARAM_CHK(handle);
562     USART_NULL_PARAM_CHK(data);
563
564     dw_usart_priv_t *usart_priv = handle;
565     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
566     int32_t recv_num = 0;
567
568     while (addr->LSR & 0x1) {
569         *((uint8_t *)data++) = addr->RBR;
570         recv_num++;
571
572         if (recv_num >= num) {
573             break;
574         }
575     }
576
577     return recv_num;
578
579 }
580
581 /**
582   \brief       Abort Receive data from UART receiver
583   \param[in]   handle  usart handle to operate.
584   \return      error code
585 */
586 int32_t csi_usart_abort_receive(usart_handle_t handle)
587 {
588     USART_NULL_PARAM_CHK(handle);
589     dw_usart_priv_t *usart_priv = handle;
590
591     usart_priv->rx_cnt = usart_priv->rx_total_num;
592     return 0;
593 }
594
595 /**
596   \brief       Start sending/receiving data to/from UART transmitter/receiver.
597   \param[in]   handle  usart handle to operate.
598   \param[in]   data_out  Pointer to buffer with data to send to USART transmitter
599   \param[out]  data_in   Pointer to buffer for data to receive from USART receiver
600   \param[in]   num       Number of data items to transfer
601   \return      error code
602 */
603 int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
604 {
605     USART_NULL_PARAM_CHK(handle);
606     return ERR_USART(EDRV_UNSUPPORTED);
607 }
608
609 /**
610   \brief       abort sending/receiving data to/from USART transmitter/receiver.
611   \param[in]   handle  usart handle to operate.
612   \return      error code
613 */
614 int32_t csi_usart_abort_transfer(usart_handle_t handle)
615 {
616     USART_NULL_PARAM_CHK(handle);
617     return ERR_USART(EDRV_UNSUPPORTED);
618 }
619
620 /**
621   \brief       Get USART status.
622   \param[in]   handle  usart handle to operate.
623   \return      USART status \ref usart_status_t
624 */
625 usart_status_t csi_usart_get_status(usart_handle_t handle)
626 {
627     usart_status_t usart_status;
628     dw_usart_priv_t *usart_priv = handle;
629     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
630     uint32_t line_status_reg    = addr->LSR;
631
632     usart_status.tx_busy = usart_priv->tx_busy;
633     usart_status.rx_busy = usart_priv->rx_busy;
634
635     if (line_status_reg & DW_LSR_BI) {
636         usart_status.rx_break = 1;
637     }
638
639     if (line_status_reg & DW_LSR_FE) {
640         usart_status.rx_framing_error = 1;
641     }
642
643     if (line_status_reg & DW_LSR_PE) {
644         usart_status.rx_parity_error = 1;
645     }
646
647     return usart_status;
648 }
649
650 /**
651   \brief       control the transmit.
652   \param[in]   handle  usart handle to operate.
653   \param[in]   1 - enable the transmitter. 0 - disable the transmitter
654   \return      error code
655 */
656 int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
657 {
658     USART_NULL_PARAM_CHK(handle);
659     return 0;
660 }
661
662 /**
663   \brief       control the receive.
664   \param[in]   handle  usart handle to operate.
665   \param[in]   1 - enable the receiver. 0 - disable the receiver
666   \return      error code
667 */
668 int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
669 {
670     USART_NULL_PARAM_CHK(handle);
671     return 0;
672 }
673
674 /**
675   \brief       control the break.
676   \param[in]   handle  usart handle to operate.
677   \param[in]   1- Enable continuous Break transmission,0 - disable continuous Break transmission
678   \return      error code
679 */
680 int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
681 {
682     USART_NULL_PARAM_CHK(handle);
683     return ERR_USART(EDRV_UNSUPPORTED);
684 }
685
686 /**
687   \brief       flush receive/send data.
688   \param[in]   handle usart handle to operate.
689   \param[in]   type \ref usart_flush_type_e.
690   \return      error code
691 */
692 int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
693 {
694     USART_NULL_PARAM_CHK(handle);
695
696     dw_usart_priv_t *usart_priv = handle;
697     dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
698
699     if (type == USART_FLUSH_WRITE) {
700         while ((!(addr->LSR & DW_LSR_TEMT)));
701     } else if (type == USART_FLUSH_READ) {
702         while (addr->LSR & 0x1) {
703             addr->RBR;
704         }
705     } else {
706         return ERR_USART(EDRV_PARAMETER);
707     }
708
709     return 0;
710 }