2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /******************************************************************************
19 * @brief CSI Source File for usart Driver
22 ******************************************************************************/
25 #include "drv_usart.h"
29 #define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
32 * setting config may be accessed when the USART is not
33 * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
36 #define WAIT_USART_IDLE(addr)\
38 int32_t timecount = 0; \
39 while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
42 if (timecount >= UART_BUSY_TIMEOUT) {\
43 return ERR_USART(EDRV_TIMEOUT);\
47 #define USART_NULL_PARAM_CHK(para) \
50 return ERR_USART(EDRV_PARAMETER); \
58 extern int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq);
59 extern int32_t target_usart_flowctrl_init(pin_t tx_flow, pin_t rx_flow, uint32_t flag);
61 static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
63 static const usart_capabilities_t usart_capabilities = {
64 .asynchronous = 0, /* 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 = 0, /* Transmit completed event */
69 .event_rx_timeout = 0, /* Signal receive character timeout event */
73 \brief set the baut drate of usart.
74 \param[in] addr usart base to operate.
75 \param[in] baudrate baud rate
76 \param[in] apbfreq the frequency of the apb.
79 int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baudrate, uint32_t apbfreq)
81 USART_NULL_PARAM_CHK(handle);
82 dw_usart_priv_t *usart_priv = handle;
83 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
86 #ifdef CONFIG_CHIP_HOBBIT1_2
88 csi_usart_receive_query(handle, data, 16);
91 WAIT_USART_IDLE(addr);
93 /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
94 uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
96 if ((divisor % 10) >= 5) {
97 divisor = (divisor / 10) + 1;
99 divisor = divisor / 10;
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;
107 * The DLAB must be cleared after the baudrate is setted
108 * to access other registers.
110 addr->LCR &= (~LCR_SET_DLAB);
116 \brief config usart mode.
117 \param[in] handle usart handle to operate.
118 \param[in] mode \ref usart_mode_e
121 int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode)
123 if (mode == USART_MODE_ASYNCHRONOUS) {
127 return ERR_USART(EDRV_USART_MODE);
131 \brief config usart parity.
132 \param[in] handle usart handle to operate.
133 \param[in] parity \ref usart_parity_e
136 int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity)
138 USART_NULL_PARAM_CHK(handle);
139 dw_usart_priv_t *usart_priv = handle;
140 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
142 WAIT_USART_IDLE(addr);
145 case USART_PARITY_NONE:
146 /*CLear the PEN bit(LCR[3]) to disable parity.*/
147 addr->LCR &= (~LCR_PARITY_ENABLE);
150 case USART_PARITY_ODD:
151 /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
152 addr->LCR |= LCR_PARITY_ENABLE;
153 addr->LCR &= LCR_PARITY_ODD;
156 case USART_PARITY_EVEN:
157 /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
158 addr->LCR |= LCR_PARITY_ENABLE;
159 addr->LCR |= LCR_PARITY_EVEN;
163 return ERR_USART(EDRV_USART_PARITY);
170 \brief config usart stop bit number.
171 \param[in] handle usart handle to operate.
172 \param[in] stopbits \ref usart_stop_bits_e
175 int32_t dw_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit)
177 USART_NULL_PARAM_CHK(handle);
178 dw_usart_priv_t *usart_priv = handle;
179 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
181 WAIT_USART_IDLE(addr);
184 case USART_STOP_BITS_1:
185 /* Clear the STOP bit to set 1 stop bit*/
186 addr->LCR &= LCR_STOP_BIT1;
189 case USART_STOP_BITS_2:
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.
194 addr->LCR |= LCR_STOP_BIT2;
198 return ERR_USART(EDRV_USART_STOP_BITS);
205 \brief config usart data length.
206 \param[in] handle usart handle to operate.
207 \param[in] databits \ref usart_data_bits_e
210 int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits)
212 USART_NULL_PARAM_CHK(handle);
213 dw_usart_priv_t *usart_priv = handle;
214 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
216 #ifdef CONFIG_CHIP_HOBBIT1_2
218 csi_usart_receive_query(handle, data, 16);
221 WAIT_USART_IDLE(addr);
222 /* The word size decides by the DLS bits(LCR[1:0]), and the
223 * corresponding relationship between them is:
232 case USART_DATA_BITS_5:
233 addr->LCR &= LCR_WORD_SIZE_5;
236 case USART_DATA_BITS_6:
238 addr->LCR |= LCR_WORD_SIZE_6;
241 case USART_DATA_BITS_7:
243 addr->LCR |= LCR_WORD_SIZE_7;
246 case USART_DATA_BITS_8:
247 addr->LCR |= LCR_WORD_SIZE_8;
251 return ERR_USART(EDRV_USART_DATA_BITS);
258 \brief get character in query mode.
259 \param[in] handle usart handle to operate.
260 \param[in] the pointer to the received character if return 0.
263 int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
265 dw_usart_priv_t *usart_priv = handle;
266 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
268 while (!(addr->LSR & LSR_DATA_READY));
276 \brief transmit character in query mode.
277 \param[in] handle usart handle to operate.
278 \param[in] ch the input character
281 int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
283 dw_usart_priv_t *usart_priv = handle;
284 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
286 while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
294 \brief the interrupt service function.
295 \param[in] index of usart instance.
297 void dw_usart_irqhandler(int32_t idx)
303 \brief Get driver capabilities.
304 \param[in] handle usart handle to operate.
305 \return \ref usart_capabilities_t
307 usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
309 return usart_capabilities;
313 \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
314 \param[in] usart pin of tx
315 \param[in] usart pin of rx
316 \param[in] cb_event Pointer to \ref usart_event_cb_t
317 \return return usart handle if success
319 usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
323 int32_t idx = target_usart_init(tx, rx, &base, &irq);
325 if (idx < 0 || idx >= CONFIG_USART_NUM) {
329 dw_usart_priv_t *usart_priv = &usart_instance[idx];
330 usart_priv->base = base;
332 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
334 addr->FCR = DW_FCR_FIFOE | DW_FCR_RT_FIFO_HALF;
340 \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
341 \param[in] handle usart handle to operate.
344 int32_t csi_usart_uninitialize(usart_handle_t handle)
346 USART_NULL_PARAM_CHK(handle);
351 \brief config usart mode.
352 \param[in] handle usart handle to operate.
353 \param[in] sysclk configured system clock.
354 \param[in] baud baud rate
355 \param[in] mode \ref usart_mode_e
356 \param[in] parity \ref usart_parity_e
357 \param[in] stopbits \ref usart_stop_bits_e
358 \param[in] bits \ref usart_data_bits_e
361 int32_t csi_usart_config(usart_handle_t handle,
365 usart_parity_e parity,
366 usart_stop_bits_e stopbits,
367 usart_data_bits_e bits)
371 /* control the data_bit of the usart*/
372 ret = csi_usart_config_baudrate(handle, baud, sysclk);
378 /* control mode of the usart*/
379 ret = csi_usart_config_mode(handle, mode);
385 /* control the parity of the usart*/
386 ret = csi_usart_config_parity(handle, parity);
392 /* control the stopbit of the usart*/
393 ret = dw_usart_config_stopbits(handle, stopbits);
399 ret = csi_usart_config_databits(handle, bits);
409 \brief config usart default tx value. used in syn mode
410 \param[in] handle usart handle to operate.
411 \param[in] value default tx value
414 int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
416 USART_NULL_PARAM_CHK(handle);
417 return ERR_USART(EDRV_UNSUPPORTED);
421 \brief Start sending data to UART transmitter,(received data is ignored).
422 The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
423 csi_usart_get_status can indicates if transmission is still in progress or pending
424 \param[in] handle usart handle to operate.
425 \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,
426 \param[in] num Number of data items to send
429 int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
431 USART_NULL_PARAM_CHK(handle);
432 USART_NULL_PARAM_CHK(data);
434 return ERR_USART(EDRV_UNSUPPORTED);
438 \brief Abort Send data to UART transmitter
439 \param[in] handle usart handle to operate.
442 int32_t csi_usart_abort_send(usart_handle_t handle)
444 USART_NULL_PARAM_CHK(handle);
445 return ERR_USART(EDRV_UNSUPPORTED);
449 \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
450 \param[in] handle usart handle to operate.
451 \param[out] data Pointer to buffer for data to receive from UART receiver
452 \param[in] num Number of data items to receive
455 int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
457 return ERR_USART(EDRV_UNSUPPORTED);
462 \brief query data from UART receiver FIFO.
463 \param[in] handle usart handle to operate.
464 \param[out] data Pointer to buffer for data to receive from UART receiver
465 \param[in] num Number of data items to receive
466 \return receive fifo data num
468 int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
470 return ERR_USART(EDRV_UNSUPPORTED);
475 \brief Abort Receive data from UART receiver
476 \param[in] handle usart handle to operate.
479 int32_t csi_usart_abort_receive(usart_handle_t handle)
481 USART_NULL_PARAM_CHK(handle);
482 return ERR_USART(EDRV_UNSUPPORTED);
486 \brief Start sending/receiving data to/from UART transmitter/receiver.
487 \param[in] handle usart handle to operate.
488 \param[in] data_out Pointer to buffer with data to send to USART transmitter
489 \param[out] data_in Pointer to buffer for data to receive from USART receiver
490 \param[in] num Number of data items to transfer
493 int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
495 USART_NULL_PARAM_CHK(handle);
496 return ERR_USART(EDRV_UNSUPPORTED);
500 \brief abort sending/receiving data to/from USART transmitter/receiver.
501 \param[in] handle usart handle to operate.
504 int32_t csi_usart_abort_transfer(usart_handle_t handle)
506 USART_NULL_PARAM_CHK(handle);
507 return ERR_USART(EDRV_UNSUPPORTED);
511 \brief Get USART status.
512 \param[in] handle usart handle to operate.
513 \return USART status \ref usart_status_t
515 usart_status_t csi_usart_get_status(usart_handle_t handle)
517 usart_status_t status = {0};
522 \brief control the transmit.
523 \param[in] handle usart handle to operate.
524 \param[in] 1 - enable the transmitter. 0 - disable the transmitter
527 int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
529 USART_NULL_PARAM_CHK(handle);
534 \brief control the receive.
535 \param[in] handle usart handle to operate.
536 \param[in] 1 - enable the receiver. 0 - disable the receiver
539 int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
541 USART_NULL_PARAM_CHK(handle);
546 \brief control the break.
547 \param[in] handle usart handle to operate.
548 \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
551 int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
553 USART_NULL_PARAM_CHK(handle);
554 return ERR_USART(EDRV_UNSUPPORTED);
558 \brief flush receive/send data.
559 \param[in] handle usart handle to operate.
560 \param[in] type \ref usart_flush_type_e.
563 int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
565 USART_NULL_PARAM_CHK(handle);
567 dw_usart_priv_t *usart_priv = handle;
568 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
570 if (type == USART_FLUSH_WRITE) {
571 addr->FCR |= DW_FCR_XFIFOR;
573 while (addr->FCR & DW_FCR_XFIFOR);
574 } else if (type == USART_FLUSH_READ) {
575 addr->FCR |= DW_FCR_RFIFOR;
577 while (addr->FCR & DW_FCR_RFIFOR);
579 return ERR_USART(EDRV_PARAMETER);
586 \brief control interrupt on/off.
587 \param[in] handle usart handle to operate.
588 \param[in] type \ref usart_intr_type_e.
589 \param[in] flag 0-OFF, 1-ON.
592 int32_t csi_usart_interrupt_on_off(usart_handle_t handle, usart_intr_type_e type, int flag)
594 return ERR_USART(EDRV_UNSUPPORTED);
598 \brief Get usart send data count.
599 \param[in] handle usart handle to operate.
600 \return number of data bytes transferred
602 uint32_t csi_usart_get_tx_count(usart_handle_t handle)
604 return ERR_USART(EDRV_UNSUPPORTED);
608 \brief Get usart receive data count.
609 \param[in] handle usart handle to operate.
610 \return number of data bytes transferred
612 uint32_t csi_usart_get_rx_count(usart_handle_t handle)
614 return ERR_USART(EDRV_UNSUPPORTED);
618 \brief control usart power.
619 \param[in] handle usart handle to operate.
620 \param[in] state power state.\ref csi_power_stat_e.
623 int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state)
625 return ERR_USART(EDRV_UNSUPPORTED);
629 \brief config usart flow control type.
630 \param[in] handle usart handle to operate.
631 \param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
632 \param[in] tx_flow The TX flow pin name
633 \param[in] rx_flow The RX flow pin name
636 int32_t csi_usart_config_flowctrl(usart_handle_t handle,
637 usart_flowctrl_type_e flowctrl_type,
638 pin_t tx_flow, pin_t rx_flow)
640 USART_NULL_PARAM_CHK(handle);
641 dw_usart_priv_t *usart_priv = handle;
642 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
645 switch (flowctrl_type) {
646 case USART_FLOWCTRL_CTS:
647 return ERR_USART(EDRV_UNSUPPORTED);
649 case USART_FLOWCTRL_RTS:
650 return ERR_USART(EDRV_UNSUPPORTED);
652 case USART_FLOWCTRL_CTS_RTS:
653 ret = target_usart_flowctrl_init(tx_flow, rx_flow, 1);
656 return ERR_USART(EDRV_PARAMETER);
659 WAIT_USART_IDLE(addr);
660 addr->MCR |= DW_MCR_AFCE | DW_MCR_RTS;
663 case USART_FLOWCTRL_NONE:
664 ret = target_usart_flowctrl_init(tx_flow, rx_flow, 0);
667 return ERR_USART(EDRV_PARAMETER);
670 WAIT_USART_IDLE(addr);
675 return ERR_USART(EDRV_UNSUPPORTED);
682 \brief usart modem control.
683 \param[in] handle usart handle to operate.
684 \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
687 int32_t csi_usart_modem_ctrl(usart_handle_t handle, usart_modem_ctrl_e modem_ctrl)
689 return ERR_USART(EDRV_UNSUPPORTED);
693 \brief get usart modem status.
694 \param[in] handle usart handle to operate.
695 \param[in] modem_ctrl modem control action.\ref usart_modem_ctrl_e.
696 \return modem status.\ref usart_modem_stat_t.
698 usart_modem_stat_t csi_usart_get_modem_stat(usart_handle_t handle)
700 usart_modem_stat_t modem_stat = {0};
705 \brief config usart clock Polarity and Phase.
706 \param[in] handle usart handle to operate.
707 \param[in] cpol Clock Polarity.\ref usart_cpol_e.
708 \param[in] cpha Clock Phase.\ref usart_cpha_e.
711 int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha)
713 return ERR_USART(EDRV_UNSUPPORTED);
717 \brief config usart guard time.
718 \param[in] handle usart handle to operate.
719 \param[in] num_of_bits guard time in number of bit periods.
722 int32_t csi_usart_config_guard_time(usart_handle_t handle, uint32_t num_of_bits)
724 return ERR_USART(EDRV_UNSUPPORTED);
728 \brief check if usart is readable(data received).
729 \param[in] handle usart handle to operate.
730 \return 1 - a character can be read, 0 if nothing to read ,negative for error code
732 int32_t csi_usart_readable(usart_handle_t handle)
734 USART_NULL_PARAM_CHK(handle);
735 dw_usart_priv_t *usart_priv = handle;
736 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
738 if (addr->LSR & LSR_DATA_READY) {
746 \brief check if usart is writable(free for data sending).
747 \param[in] handle usart handle to operate.
748 \return 1 - a character can be written, 0 - cannot be written ,negative for error code
750 int32_t csi_usart_writable(usart_handle_t handle)
752 USART_NULL_PARAM_CHK(handle);
753 dw_usart_priv_t *usart_priv = handle;
754 dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
756 if (addr->LSR & DW_LSR_TRANS_EMPTY) {