1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-02-22     airm2m       first version
9  */
10 
11 
12 #include "board.h"
13 #include "drv_usart_v2.h"
14 
15 #ifdef RT_USING_SERIAL_V2
16 
17 //#define DRV_DEBUG
18 #define DBG_TAG              "drv.usart"
19 #ifdef DRV_DEBUG
20 #define DBG_LVL               DBG_LOG
21 #else
22 #define DBG_LVL               DBG_INFO
23 #endif /* DRV_DEBUG */
24 #include <rtdbg.h>
25 
26 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
27     #error "Please define at least one BSP_USING_UARTx"
28     /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
29 #endif
30 
31 static struct air_uart_config uart_config[] =
32 {
33 #ifdef BSP_USING_UART0
34     UART0_CONFIG,
35 #endif
36 #ifdef BSP_USING_UART1
37     UART1_CONFIG,
38 #endif
39 #ifdef BSP_USING_UART2
40     UART2_CONFIG,
41 #endif
42 #ifdef BSP_USING_UART3
43     UART3_CONFIG,
44 #endif
45 };
46 
47 enum
48 {
49 #ifdef BSP_USING_UART0
50     UART0_INDEX,
51 #endif
52 #ifdef BSP_USING_UART1
53     UART1_INDEX,
54 #endif
55 #ifdef BSP_USING_UART2
56     UART2_INDEX,
57 #endif
58 #ifdef BSP_USING_UART3
59     UART3_INDEX,
60 #endif
61 };
62 
63 static struct air_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
64 
air_uart_get_config(void)65 static void air_uart_get_config(void)
66 {
67     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
68 
69 #ifdef BSP_USING_UART0
70     uart_obj[UART0_INDEX].serial.config = config;
71     uart_obj[UART0_INDEX].serial.config.rx_bufsz = BSP_UART0_RX_BUFSIZE;
72     uart_obj[UART0_INDEX].serial.config.tx_bufsz = BSP_UART0_TX_BUFSIZE;
73 #endif
74 #ifdef BSP_USING_UART1
75     uart_obj[UART1_INDEX].serial.config = config;
76     uart_obj[UART1_INDEX].serial.config.rx_bufsz = BSP_UART1_RX_BUFSIZE;
77     uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE;
78 #endif
79 #ifdef BSP_USING_UART2
80     uart_obj[UART2_INDEX].serial.config = config;
81     uart_obj[UART2_INDEX].serial.config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
82     uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
83 #endif
84 #ifdef BSP_USING_UART3
85     uart_obj[UART3_INDEX].serial.config = config;
86     uart_obj[UART3_INDEX].serial.config.rx_bufsz = BSP_UART3_RX_BUFSIZE;
87     uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE;
88 #endif
89 }
90 
air105_uart_irq(void * pData,void * pParam)91 static int air105_uart_irq(void *pData, void *pParam)
92 {
93     rt_uint32_t uartid = (rt_uint32_t)pData;
94     rt_uint32_t State = (rt_uint32_t)pParam;
95     uint8_t temp[32];
96     rt_uint32_t len;
97     struct rt_serial_device *serial = NULL;
98 
99     rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct air_uart);
100     for (int i = 0; i < obj_num; i++)
101     {
102         if (uart_obj[i].config->id == uartid)
103             serial = &(uart_obj[i].serial);
104     }
105     struct rt_serial_rx_fifo *rx_fifo;
106 
107     switch (State){
108         case UART_CB_TX_BUFFER_DONE:
109             break;
110         case DMA_CB_DONE:
111             DMA_ClearStreamFlag(DBG_UART_TX_DMA_STREAM);
112             rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);
113             break;
114         case UART_CB_TX_ALL_DONE:
115             rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);
116             break;
117         case UART_CB_RX_BUFFER_FULL:
118             break;
119         case UART_CB_RX_TIMEOUT:
120         case UART_CB_RX_NEW:
121             rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
122             len = Uart_FifoRead(uartid, temp);
123             if (len)
124             {
125                 rt_ringbuffer_put(&(rx_fifo->rb), temp, len);
126                 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
127             }
128             break;
129         case UART_CB_ERROR:
130             break;
131         case DMA_CB_ERROR:
132             break;
133     }
134 }
135 
air105_configure(struct rt_serial_device * serial,struct serial_configure * cfg)136 static rt_err_t air105_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
137 {
138     rt_uint32_t uart_id = serial->parent.user_data;
139     RT_ASSERT(serial != RT_NULL);
140     RT_ASSERT(cfg != RT_NULL);
141 
142     switch (cfg->stop_bits)
143     {
144     case STOP_BITS_1:
145         cfg->stop_bits = UART_STOP_BIT1;
146         break;
147     case STOP_BITS_2:
148         cfg->stop_bits = UART_STOP_BIT2;
149         break;
150     default:
151         cfg->stop_bits = UART_STOP_BIT1_5;
152         break;
153     }
154 
155     Uart_BaseInit(uart_id, cfg->baud_rate, 0, cfg->data_bits, cfg->parity, cfg->stop_bits, air105_uart_irq);
156     switch (uart_id){
157     case UART_ID0:
158         GPIO_Iomux(GPIOA_01, 0);
159         GPIO_Iomux(GPIOA_00, 0);
160         break;
161     case UART_ID1:
162         GPIO_Iomux(GPIOC_01, 3);
163         GPIO_Iomux(GPIOC_00, 3);
164         break;
165     case UART_ID2:
166         GPIO_Iomux(GPIOD_13, 0);
167         GPIO_Iomux(GPIOD_12, 0);
168         break;
169     case UART_ID3:
170         GPIO_Iomux(GPIOE_08, 2);
171         GPIO_Iomux(GPIOE_09, 2);
172         break;
173     default:
174         break;
175     }
176     return RT_EOK;
177 }
178 
air105_control(struct rt_serial_device * serial,int cmd,void * arg)179 static rt_err_t air105_control(struct rt_serial_device *serial, int cmd, void *arg)
180 {
181     rt_uint32_t uart_id = serial->parent.user_data;
182 
183     rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
184     RT_ASSERT(serial != RT_NULL);
185 
186     switch (cmd)
187     {
188     /* disable interrupt */
189     case RT_DEVICE_CTRL_CLR_INT:
190         Uart_IrqOnOff(uart_id, 0);
191         if (DBG_UART_ID == uart_id)
192         {
193             DMA_StopStream(DBG_UART_TX_DMA_STREAM);
194         }
195         break;
196 
197     case RT_DEVICE_CTRL_SET_INT:
198         break;
199 
200     case RT_DEVICE_CTRL_CONFIG:
201         if (ctrl_arg & (RT_SERIAL_RX_NON_BLOCKING|RT_SERIAL_RX_BLOCKING))
202         {
203             Uart_EnableRxIrq(uart_id);
204         }
205         Uart_IrqOnOff(uart_id, 1);
206         break;
207 
208     case RT_DEVICE_CHECK_OPTMODE:
209         return RT_SERIAL_TX_BLOCKING_NO_BUFFER;
210 
211     case RT_DEVICE_CTRL_CLOSE:
212         Uart_DeInit(uart_id);
213         switch (uart_id){
214         case UART_ID0:
215             GPIO_Iomux(GPIOA_01, 1);
216             GPIO_Iomux(GPIOA_00, 1);
217             break;
218         case UART_ID1:
219             GPIO_Iomux(GPIOC_01, 1);
220             GPIO_Iomux(GPIOC_00, 1);
221             break;
222         case UART_ID2:
223             GPIO_Iomux(GPIOD_13, 1);
224             GPIO_Iomux(GPIOD_12, 1);
225             break;
226         case UART_ID3:
227             GPIO_Iomux(GPIOE_08, 1);
228             GPIO_Iomux(GPIOE_09, 1);
229             break;
230         default:
231             break;
232         }
233         break;
234     default:
235         return -RT_EINVAL;
236 
237     }
238     return RT_EOK;
239 }
240 
air105_putc(struct rt_serial_device * serial,char c)241 static int air105_putc(struct rt_serial_device *serial, char c)
242 {
243     rt_uint32_t uart_id = serial->parent.user_data;
244     RT_ASSERT(serial != RT_NULL);
245     Uart_NoBlockTx(uart_id, c);
246     return 1;
247 }
248 
249 
air105_getc(struct rt_serial_device * serial)250 static int air105_getc(struct rt_serial_device *serial)
251 {
252     rt_uint32_t uart_id = serial->parent.user_data;
253     RT_ASSERT(serial != RT_NULL);
254     uint8_t data;
255     if (Uart_ReadByte(uart_id, &data) < 0)
256     {
257         return -1;
258     }
259     else
260     {
261         return data;
262     }
263 }
264 
air105_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,rt_uint32_t tx_flag)265 static rt_ssize_t air105_transmit(struct rt_serial_device     *serial,
266                                        rt_uint8_t           *buf,
267                                        rt_size_t             size,
268                                        rt_uint32_t           tx_flag)
269 {
270     rt_uint32_t uart_id = serial->parent.user_data;
271     RT_ASSERT(serial != RT_NULL);
272     RT_ASSERT(buf != RT_NULL);
273     if (DBG_UART_ID == uart_id)
274     {
275         Uart_BlockTx(uart_id, buf, size);
276     }
277     else
278     {
279         Uart_BufferTx(uart_id, buf, size);
280     }
281     return size;
282 }
283 
284 
285 static const struct rt_uart_ops air105_uart_ops =
286 {
287     .configure = air105_configure,
288     .control = air105_control,
289     .putc = air105_putc,
290     .getc = air105_getc,
291     .transmit = air105_transmit
292 };
293 
rt_hw_usart_init(void)294 int rt_hw_usart_init(void)
295 {
296     rt_err_t result = 0;
297     rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct air_uart);
298 
299     air_uart_get_config();
300     for (int i = 0; i < obj_num; i++)
301     {
302         /* init UART object */
303         uart_obj[i].config = &uart_config[i];
304         if (uart_obj[i].config->id == DBG_UART_ID)
305             uart_obj[i].serial.config.baud_rate = DBG_UART_BR;
306         uart_obj[i].serial.ops = &air105_uart_ops;
307         /* register UART device */
308         result = rt_hw_serial_register(&uart_obj[i].serial,uart_obj[i].config->name,
309                                         RT_DEVICE_FLAG_RDWR,
310                                         i);
311         RT_ASSERT(result == RT_EOK);
312     }
313     return result;
314 }
315 
316 #endif /* RT_USING_SERIAL_V2 */
317