1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2017-09-23     Urey         first implementation
9  */
10 
11 #include <rtthread.h>
12 
13 #ifdef RT_USING_CONSOLE
14 
15 #include <rthw.h>
16 #include <rtdevice.h>
17 
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdbool.h>
22 
23 #include "board.h"
24 #include "soc.h"
25 #include "dw_usart.h"
26 #include "drv_usart.h"
27 #include "pin_name.h"
28 #include "pinmux.h"
29 
30 #if CONFIG_USART
31 struct
32 {
33     uint32_t base;
34     uint32_t irq;
35 } const sg_usart_config[CONFIG_USART_NUM] =
36 {
37     { CSKY_UART0_BASE, UART0_IRQn },
38     { CSKY_UART1_BASE, UART1_IRQn },
39     { CSKY_UART2_BASE, UART2_IRQn },
40     { CSKY_UART3_BASE, UART3_IRQn }
41 };
42 
43 typedef struct
44 {
45     pin_t    tx;
46     pin_t    rx;
47     uint16_t cfg_idx;    //idx of sg_usart_config[]
48     uint16_t function;
49 } usart_pin_map_t;
50 const static usart_pin_map_t s_usart_pin_map[] =
51 {
52     {
53         PA0_TXD0_PWM0_XX_SIROUT0,
54         PA1_RXD0_PWM1_XX_SIRIN0,
55         0,
56         0
57     },
58     {
59         PA10_TXD1_PWM1_XX_SIROUT1,
60         PA11_RXD1_PWM2_XX_SIRIN1,
61         1,
62         0
63     },
64     {
65         PA23_TXD2_PWM5_XX_SIROUT2,
66         PA22_RXD2_PWM4_XX_SIRIN2,
67         2,
68         0
69     },
70     {
71         PA26_TXD3_PWMFAULT_XX_SIROUT3,
72         PA27_RXD3_PWM0_XX_SIRIN3,
73         3,
74         0
75     }
76 };
77 
target_usart_init(pin_t tx,pin_t rx,uint32_t * base,uint32_t * irq)78 int32_t target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
79 {
80     uint32_t idx;
81 
82     for (idx = 0; idx < sizeof(s_usart_pin_map) / sizeof(usart_pin_map_t); idx++)
83     {
84         if (s_usart_pin_map[idx].tx == tx && s_usart_pin_map[idx].rx == rx)
85         {
86             *base = sg_usart_config[s_usart_pin_map[idx].cfg_idx].base;
87             *irq = sg_usart_config[s_usart_pin_map[idx].cfg_idx].irq;
88 
89             /*pinmux*/
90             pin_mux(s_usart_pin_map[idx].tx, s_usart_pin_map[idx].function);
91             pin_mux(s_usart_pin_map[idx].rx, s_usart_pin_map[idx].function);
92             return s_usart_pin_map[idx].cfg_idx;
93         }
94     }
95     return -1;
96 }
97 #endif
98 
99 #ifdef RT_USING_UART1
100 #define UART_TXD1     PA10_TXD1_PWM1_XX_SIROUT1
101 #define UART_RXD1     PA11_RXD1_PWM2_XX_SIRIN1
102 
103 static  usart_handle_t uart1_handle;
104 static struct rt_serial_device  serial1;
105 /*
106 static void usart1_event_cb(uint32_t event, void *cb_arg)
107 {
108     switch (event)
109     {
110     case USART_EVENT_SEND_COMPLETE:
111         rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_TX_DONE);
112         break;
113 
114     case USART_EVENT_RECEIVED:
115         rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
116         break;
117 
118     default:
119         break;
120     }
121 }
122 */
123 
USART1_IRQHandler(void)124 __attribute__((isr)) void USART1_IRQHandler(void)
125 {
126     rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
127 }
128 #endif
129 
130 /*
131  * UART interface
132  */
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)133 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
134 {
135     int ret;
136     usart_handle_t uart;
137 
138     uint32_t bauds;
139     usart_mode_e mode;
140     usart_parity_e parity;
141     usart_stop_bits_e stopbits;
142     usart_data_bits_e databits;
143 
144     RT_ASSERT(serial != RT_NULL);
145     uart = (usart_handle_t)serial->parent.user_data;
146     RT_ASSERT(uart != RT_NULL);
147 
148     /* set baudrate parity...*/
149     bauds = cfg->baud_rate;
150     mode = USART_MODE_ASYNCHRONOUS;
151 
152     if (cfg->parity == PARITY_EVEN)
153         parity = USART_PARITY_EVEN;
154     else if (cfg->parity == PARITY_ODD)
155         parity = USART_PARITY_ODD;
156     else
157         parity = USART_PARITY_NONE;
158 
159     stopbits = USART_STOP_BITS_1 ;
160     databits = USART_DATA_BITS_8;
161 
162     ret = csi_usart_config(uart, SYSTEM_CLOCK, bauds, USART_MODE_ASYNCHRONOUS, parity, stopbits, databits);
163 
164     if (ret < 0)
165     {
166         return -RT_ERROR;
167     }
168 
169     return RT_EOK;
170 }
171 
uart_control(struct rt_serial_device * serial,int cmd,void * arg)172 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
173 {
174     usart_handle_t uart;
175 
176     RT_ASSERT(serial != RT_NULL);
177     uart = (usart_handle_t)serial->parent.user_data;
178     RT_ASSERT(uart != RT_NULL);
179 
180     switch (cmd)
181     {
182     case RT_DEVICE_CTRL_CLR_INT:
183         /* Disable the UART Interrupt */
184         dw_usart_clr_int_flag(uart,IER_RDA_INT_ENABLE);
185         break;
186 
187     case RT_DEVICE_CTRL_SET_INT:
188         /* Enable the UART Interrupt */
189         dw_usart_set_int_flag(uart,IER_RDA_INT_ENABLE);
190         break;
191     }
192 
193     return (RT_EOK);
194 }
195 
uart_putc(struct rt_serial_device * serial,char c)196 static int uart_putc(struct rt_serial_device *serial, char c)
197 {
198     usart_handle_t uart;
199 
200     RT_ASSERT(serial != RT_NULL);
201     uart = (usart_handle_t)serial->parent.user_data;
202     RT_ASSERT(uart != RT_NULL);
203 
204     dw_usart_putchar(uart,c);
205 
206     return (1);
207 }
208 
uart_getc(struct rt_serial_device * serial)209 static int uart_getc(struct rt_serial_device *serial)
210 {
211     uint8_t ch;
212     usart_handle_t uart;
213 
214     RT_ASSERT(serial != RT_NULL);
215     uart = (usart_handle_t)serial->parent.user_data;
216     RT_ASSERT(uart != RT_NULL);
217 
218     if (!dw_usart_getchar_no_poll(uart, &ch))
219     {
220         return (int)(ch);
221     }
222     else
223     {
224         return -1;
225     }
226 }
227 
228 const struct rt_uart_ops _uart_ops =
229 {
230     uart_configure,
231     uart_control,
232     uart_putc,
233     uart_getc,
234 };
235 
236 
rt_hw_usart_init(void)237 int rt_hw_usart_init(void)
238 {
239     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
240 
241 #ifdef RT_USING_UART1
242     serial1.ops                 = & _uart_ops;
243     serial1.config              = config;
244     serial1.config.bufsz        = 2048;
245     serial1.config.baud_rate    = 115200;
246 
247     uart1_handle = csi_usart_initialize(UART_TXD1, UART_RXD1, NULL/*usart1_event_cb*/,
248                                         (void *) 0);
249 
250     rt_hw_serial_register(&serial1,
251                           "uart1",
252                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
253                           uart1_handle);
254 #endif
255 
256     return 0;
257 }
258 INIT_BOARD_EXPORT(rt_hw_usart_init);
259 #endif
260