1 /*
2  * Copyright (c) 2020-2021, Bluetrum Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2020-11-20     greedyhao         first version
9  */
10 
11 #include "board.h"
12 #include "drv_usart.h"
13 #include "api_huart.h"
14 
15 #ifdef RT_USING_SERIAL
16 
17 //#define DRV_DEBUG
18 #define LOG_TAG             "drv.usart"
19 #include <drv_log.h>
20 
21 #undef  RT_SERIAL_USING_DMA
22 
23 enum
24 {
25 #ifdef BSP_USING_UART0
26     UART0_INDEX,
27 #endif
28 #ifdef BSP_USING_UART1
29     UART1_INDEX,
30 #endif
31 #ifdef BSP_USING_UART2
32     UART2_INDEX,
33 #endif
34 };
35 
36 static struct ab32_uart_config uart_config[] =
37 {
38 #ifdef BSP_USING_UART0
39     {
40         .name = "uart0",
41         .instance = UART0_BASE,
42         .mode = UART_MODE_TX_RX | UART_MODE_1LINE,
43         .fifo_size = BSP_UART0_FIFO_SIZE,
44     },
45 #endif
46 #ifdef BSP_USING_UART1
47     {
48         .name = "uart1",
49         .instance = UART1_BASE,
50         .mode = UART_MODE_TX_RX,
51         .fifo_size = BSP_UART1_FIFO_SIZE,
52     },
53 #endif
54 #ifdef BSP_USING_UART2
55     {
56         .name = "uart2",
57         .instance = UART2_BASE,
58         .mode = UART_MODE_TX_RX,
59         .fifo_size = BSP_UART2_FIFO_SIZE,
60     }
61 #endif
62 };
63 
64 static struct ab32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
65 
66 #ifdef HUART_ENABLE
67 static rt_uint8_t huart_dma[512];
68 #endif
69 
ab32_configure(struct rt_serial_device * serial,struct serial_configure * cfg)70 static rt_err_t ab32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
71 {
72     struct ab32_uart *uart;
73     RT_ASSERT(serial != RT_NULL);
74     RT_ASSERT(cfg != RT_NULL);
75 
76     uart = rt_container_of(serial, struct ab32_uart, serial);
77     uart->handle.instance           = uart->config->instance;
78     uart->handle.init.baud          = cfg->baud_rate;
79     uart->handle.init.mode          = uart->config->mode;
80 
81     switch (cfg->data_bits)
82     {
83     case DATA_BITS_8:
84         uart->handle.init.word_len  = UART_WORDLENGTH_8B;
85         break;
86     case DATA_BITS_9:
87         uart->handle.init.word_len  = UART_WORDLENGTH_9B;
88         break;
89     default:
90         uart->handle.init.word_len  = UART_WORDLENGTH_8B;
91         break;
92     }
93 
94     switch (cfg->stop_bits)
95     {
96     case STOP_BITS_1:
97         uart->handle.init.stop_bits = UART_STOPBITS_1;
98         break;
99     case STOP_BITS_2:
100         uart->handle.init.stop_bits = UART_STOPBITS_2;
101         break;
102     default:
103         uart->handle.init.stop_bits = UART_STOPBITS_1;
104         break;
105     }
106 
107 #ifdef RT_SERIAL_USING_DMA
108     uart->dma_rx.last_index = 0;
109 #endif
110 
111     if (!uart->uart_dma_flag) {
112         hal_uart_init(&uart->handle);
113     }
114 #ifdef HUART_ENABLE
115     else {
116         huart_init_do(HUART_TR_PB3, HUART_TR_PB4, uart->handle.init.baud, huart_dma, 512);
117     }
118 #endif
119 
120     return RT_EOK;
121 }
122 
ab32_control(struct rt_serial_device * serial,int cmd,void * arg)123 static rt_err_t ab32_control(struct rt_serial_device *serial, int cmd, void *arg)
124 {
125     struct ab32_uart *uart;
126 #ifdef RT_SERIAL_USING_DMA
127     rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
128 #endif
129 
130     RT_ASSERT(serial != RT_NULL);
131     uart = rt_container_of(serial, struct ab32_uart, serial);
132 
133     switch (cmd)
134     {
135     /* disable interrupt */
136     case RT_DEVICE_CTRL_CLR_INT:
137         hal_uart_control(uart->handle.instance, UART_RXIT_ENABLE, HAL_DISABLE);
138         break;
139     /* enable interrupt */
140     case RT_DEVICE_CTRL_SET_INT:
141         hal_uart_clrflag(uart->handle.instance, UART_FLAG_RXPND);
142         hal_uart_control(uart->handle.instance, UART_RXIT_ENABLE, HAL_ENABLE);
143         break;
144     case RT_DEVICE_CTRL_CLOSE:
145         hal_uart_deinit(uart->handle.instance);
146         break;
147     }
148 
149     return RT_EOK;
150 }
151 
ab32_putc(struct rt_serial_device * serial,char ch)152 static int ab32_putc(struct rt_serial_device *serial, char ch)
153 {
154     struct ab32_uart *uart;
155     RT_ASSERT(serial != RT_NULL);
156 
157     uart = rt_container_of(serial, struct ab32_uart, serial);
158 
159     if (!uart->uart_dma_flag) {
160         hal_uart_clrflag(uart->handle.instance,  UART_FLAG_TXPND);
161         hal_uart_write(uart->handle.instance, ch);
162         while(hal_uart_getflag(uart->handle.instance, UART_FLAG_TXPND) == 0);
163     }
164 #ifdef HUART_ENABLE
165     else {
166         huart_putchar(ch);
167     }
168 #endif
169 
170     return 1;
171 }
172 
ab32_getc(struct rt_serial_device * serial)173 static int ab32_getc(struct rt_serial_device *serial)
174 {
175     int ch;
176     struct ab32_uart *uart;
177     RT_ASSERT(serial != RT_NULL);
178 
179     uart = rt_container_of(serial, struct ab32_uart, serial);
180 
181     ch = -1;
182     switch ((rt_uint32_t)(uart->handle.instance)) {
183         case (rt_uint32_t)UART0_BASE:
184             if (uart->rx_idx != uart->rx_idx_prev) {
185                 ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
186             }
187             break;
188         case (rt_uint32_t)UART1_BASE:
189 #ifdef HUART_ENABLE
190             if ((uart->uart_dma_flag) && (huart_get_rxcnt())) {
191                 ch = huart_getchar();
192             } else
193 #endif
194             {
195                 if (uart->rx_idx != uart->rx_idx_prev) {
196                     ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
197                 }
198             }
199             break;
200         case (rt_uint32_t)UART2_BASE:
201             if (uart->rx_idx != uart->rx_idx_prev) {
202                 ch = (int)(uart->rx_buf[uart->rx_idx_prev++ % 10]);
203             }
204             break;
205         default:
206             break;
207     }
208 
209     return ch;
210 }
211 
ab32_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)212 static rt_ssize_t ab32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
213 {
214     return -1;
215 }
216 
uart0_irq_process(void)217 void uart0_irq_process(void)
218 {
219     rt_hw_serial_isr(&(uart_obj[UART0_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
220 }
221 
222 #ifdef BSP_USING_UART1
uart1_irq_process(void)223 void uart1_irq_process(void)
224 {
225     rt_hw_serial_isr(&(uart_obj[UART1_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
226 }
227 #endif
228 
229 #ifdef BSP_USING_UART2
uart2_irq_process(void)230 void uart2_irq_process(void)
231 {
232     rt_hw_serial_isr(&(uart_obj[UART2_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
233 }
234 #endif
235 
236 rt_section(".irq.usart")
uart_isr(int vector,void * param)237 static void uart_isr(int vector, void *param)
238 {
239     rt_interrupt_enter();
240 
241 #ifdef BSP_USING_UART0
242     if(hal_uart_getflag(UART0_BASE, UART_FLAG_RXPND))       //RX one byte finish
243     {
244         uart_obj[0].rx_buf[uart_obj[0].rx_idx++ % 10] = hal_uart_read(UART0_BASE);
245         hal_uart_clrflag(UART0_BASE, UART_FLAG_RXPND);
246         uart0_irq_post();
247     }
248 #endif
249 #ifdef BSP_USING_UART1
250     if(hal_uart_getflag(UART1_BASE, UART_FLAG_RXPND))       //RX one byte finish
251     {
252         uart_obj[1].rx_buf[uart_obj[1].rx_idx++ % 10] = hal_uart_read(UART1_BASE);
253         hal_uart_clrflag(UART1_BASE, UART_FLAG_RXPND);
254         uart1_irq_post();
255     }
256 #endif
257 #ifdef BSP_USING_UART2
258     if(hal_uart_getflag(UART2_BASE, UART_FLAG_RXPND))       //RX one byte finish
259     {
260         uart_obj[2].rx_buf[uart_obj[2].rx_idx++ % 10] = hal_uart_read(UART2_BASE);
261         hal_uart_clrflag(UART2_BASE, UART_FLAG_RXPND);
262         uart2_irq_post();
263     }
264 #endif
265 
266     rt_interrupt_leave();
267 }
268 
269 #ifdef HUART_ENABLE
270 rt_section(".irq.huart")
huart_timer_isr(void)271 void huart_timer_isr(void)
272 {
273     huart_if_rx_ovflow();
274 
275     if (0 == huart_get_rxcnt()) {
276         return;
277     }
278 
279     uart1_irq_post();
280 }
281 #else
282 rt_section(".irq.huart")
huart_timer_isr(void)283 void huart_timer_isr(void)
284 {
285 }
286 #endif
287 
288 static const struct rt_uart_ops ab32_uart_ops =
289 {
290     .configure = ab32_configure,
291     .control = ab32_control,
292     .putc = ab32_putc,
293     .getc = ab32_getc,
294     .dma_transmit = ab32_dma_transmit
295 };
296 
rt_hw_usart_init(void)297 int rt_hw_usart_init(void)
298 {
299     rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ab32_uart);
300     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
301     rt_err_t result = 0;
302 
303     rt_hw_interrupt_install(IRQ_UART0_2_VECTOR, uart_isr, RT_NULL, "ut_isr");
304 
305     for (int i = 0; i < obj_num; i++)
306     {
307         /* init UART object */
308         uart_obj[i].config          = &uart_config[i];
309         uart_obj[i].rx_idx          = 0;
310         uart_obj[i].rx_idx_prev     = 0;
311         uart_obj[i].serial.ops      = &ab32_uart_ops;
312         uart_obj[i].serial.config   = config;
313         uart_obj[i].serial.config.baud_rate = 1500000;
314         uart_obj[i].rx_buf          = rt_malloc(uart_config[i].fifo_size);
315 
316         if (uart_obj[i].rx_buf == RT_NULL) {
317             LOG_E("uart%d malloc failed!", i);
318             continue;
319         }
320 
321         /* register UART device */
322         result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
323                                        RT_DEVICE_FLAG_RDWR
324                                        | RT_DEVICE_FLAG_INT_RX
325                                        | RT_DEVICE_FLAG_INT_TX
326                                        | uart_obj[i].uart_dma_flag
327                                        , RT_NULL);
328         RT_ASSERT(result == RT_EOK);
329     }
330 
331     return result;
332 }
333 
334 #endif
335