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  * 2023-07-15     yby          the first version
9  */
10 
11 #include "drv_uart.h"
12 
13 #ifdef RT_USING_SERIAL
14 #include "uart_config.h"
15 #include "interrupt.h"
16 #include "uart.h"
17 
18 #define   LOG_TAG  "drv.uart"
19 #include <drv_log.h>
20 
21 #if !defined(BSP_USING_UART0)&&!defined(BSP_USING_UART1)&&!defined(BSP_USING_UART2)&&!defined(BSP_USING_UART3)
22     #error "Please define at least one BSP_USING_UARTx"
23 #endif
24 
25 enum
26 {
27 #ifdef BSP_USING_UART0
28     UART0_INDEX,
29 #endif
30 #ifdef BSP_USING_UART1
31     UART1_INDEX,
32 #endif
33 #ifdef BSP_USING_UART2
34     UART2_INDEX,
35 #endif
36 #ifdef BSP_USING_UART3
37     UART3_INDEX,
38 #endif
39 };
40 
41 uint32_t uart_intbase[] =
42 {
43 #ifdef BSP_USING_UART0
44     INT_UART0,
45 #endif
46 #ifdef BSP_USING_UART1
47     INT_UART1,
48 #endif
49 #ifdef BSP_USING_UART2
50     INT_UART2,
51 #endif
52 #ifdef BSP_USING_UART3
53     INT_UART3
54 #endif
55 };
56 
57 static struct msp432_uart_config uart_config[] =
58 {
59 #ifdef BSP_USING_UART0
60     UART0_CONFIG,
61 #endif
62 
63 #ifdef BSP_USING_UART1
64     UART1_CONFIG,
65 #endif
66 
67 #ifdef BSP_USING_UART2
68     UART2_CONFIG,
69 #endif
70 
71 #ifdef BSP_USING_UART3
72     UART3_CONFIG,
73 #endif
74 };
75 static struct msp432_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
76 
msp432_configure(struct rt_serial_device * serial,struct serial_configure * cfg)77 static rt_err_t msp432_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
78 {
79     struct msp432_uart *uart;
80     RT_ASSERT(serial != RT_NULL);
81     RT_ASSERT(cfg != RT_NULL);
82     uart = rt_container_of(serial, struct msp432_uart, serial);
83 
84     UARTConfigSetExpClk(uart->config->uartbase, SystemCoreClock, uart->config->baudrate,
85                         uart->config->mode);
86     UARTIntEnable(uart->config->uartbase, UART_INT_RX);
87     UARTEnable(uart->config->uartbase);
88     UARTFIFODisable(uart->config->uartbase);
89     IntEnable(uart->uartintbase);
90 
91     return RT_EOK;
92 }
93 
94 
msp432_control(struct rt_serial_device * serial,int cmd,void * arg)95 static rt_err_t msp432_control(struct rt_serial_device *serial, int cmd, void *arg)
96 {
97     struct msp432_uart  *uart;
98     RT_ASSERT(serial != RT_NULL);
99     uart = rt_container_of(serial, struct msp432_uart, serial);
100 
101     switch (cmd)
102     {
103     /* disable interrupt */
104     case RT_DEVICE_CTRL_CLR_INT:
105         /* disable rx irq */
106         IntDisable(uart->uartintbase);
107         UARTIntDisable(uart->config->uartbase, UART_INT_RX);
108         break;
109     /* enable interrupt */
110     case RT_DEVICE_CTRL_SET_INT:
111         /* enable rx irq */
112         IntEnable(uart->uartintbase);
113         UARTIntEnable(uart->config->uartbase, UART_INT_RX);
114         break;
115     }
116 
117     return RT_EOK;
118 }
119 
msp432_putc(struct rt_serial_device * serial,char c)120 static int msp432_putc(struct rt_serial_device *serial, char c)
121 {
122     struct msp432_uart *uart;
123     RT_ASSERT(serial != RT_NULL);
124 
125     uart = rt_container_of(serial, struct msp432_uart, serial);
126     UARTCharPut(uart->config->uartbase, c);
127 
128     return 1;
129 }
130 
msp432_getc(struct rt_serial_device * serial)131 static int msp432_getc(struct rt_serial_device *serial)
132 {
133     int ch;
134     struct msp432_uart *uart;
135     RT_ASSERT(serial != RT_NULL);
136 
137     uart = rt_container_of(serial, struct msp432_uart, serial);
138     ch = -1;
139     ch = UARTCharGetNonBlocking(uart->config->uartbase);
140 
141     return ch;
142 }
143 
msp432_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)144 static rt_ssize_t msp432_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
145 {
146     /* this is an interface for uart dma, reserved for uptate. */
147     return 0;
148 }
149 
150 static const struct rt_uart_ops msp432_uart_ops =
151 {
152     .configure = msp432_configure,
153     .control = msp432_control,
154     .putc = msp432_putc,
155     .getc = msp432_getc,
156     .dma_transmit = msp432_dma_transmit
157 };
158 
159 /**
160  * Uart common interrupt process. This need add to uart ISR.
161  *
162  * @param serial serial device
163  */
uart_isr(struct rt_serial_device * serial)164 static void uart_isr(struct rt_serial_device *serial)
165 {
166     struct msp432_uart *uart;
167     uint32_t ui32Ints;
168     RT_ASSERT(serial != RT_NULL);
169     uart = rt_container_of(serial, struct msp432_uart, serial);
170 
171     ui32Ints = UARTIntStatus(uart->config->uartbase, true);
172     UARTIntClear(uart->config->uartbase, ui32Ints);
173 
174     /* UART in mode Receiver -------------------------------------------------*/
175     if (ui32Ints & (UART_INT_RX | UART_INT_RT))
176     {
177         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
178     }
179 }
180 
181 #if defined(BSP_USING_UART0)
UART0_IRQHandler(void)182 void UART0_IRQHandler(void)
183 {
184     /* enter interrupt */
185     rt_interrupt_enter();
186 
187     uart_isr(&(uart_obj[UART0_INDEX].serial));
188     /* leave interrupt */
189     rt_interrupt_leave();
190 }
191 #endif /* BSP_USING_UART0 */
192 
193 #if defined(BSP_USING_UART1)
UART1_IRQHandler(void)194 void UART1_IRQHandler(void)
195 {
196     /* enter interrupt */
197     rt_interrupt_enter();
198 
199     uart_isr(&(uart_obj[UART1_INDEX].serial));
200     /* leave interrupt */
201     rt_interrupt_leave();
202 }
203 #endif /* BSP_USING_UART1 */
204 
205 #if defined(BSP_USING_UART2)
UART2_IRQHandler(void)206 void UART2_IRQHandler(void)
207 {
208     /* enter interrupt */
209     rt_interrupt_enter();
210 
211     uart_isr(&(uart_obj[UART2_INDEX].serial));
212     /* leave interrupt */
213     rt_interrupt_leave();
214 }
215 #endif /* BSP_USING_UART2 */
216 
217 #if defined(BSP_USING_UART3)
UART3_IRQHandler(void)218 void UART3_IRQHandler(void)
219 {
220     /* enter interrupt */
221     rt_interrupt_enter();
222 
223     uart_isr(&(uart_obj[UART3_INDEX].serial));
224     /* leave interrupt */
225     rt_interrupt_leave();
226 }
227 #endif /* BSP_USING_UART3 */
228 
rt_hw_usart_init(void)229 int rt_hw_usart_init(void)
230 {
231     rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct msp432_uart);
232     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
233     rt_err_t result = 0;
234 
235     uart_hw_config();
236 
237     for (int i = 0; i < obj_num; i++)
238     {
239         uart_obj[i].config        = &uart_config[i];
240         uart_obj[i].uartintbase   = uart_intbase[i];
241         uart_obj[i].serial.ops    = &msp432_uart_ops;
242         uart_obj[i].serial.config = config;
243         /* register UART device */
244         result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
245                                        RT_DEVICE_FLAG_RDWR
246                                        | RT_DEVICE_FLAG_INT_RX
247                                        | RT_DEVICE_FLAG_INT_TX
248                                        | uart_obj[i].uart_dma_flag
249                                        , NULL);
250         RT_ASSERT(result == RT_EOK);
251     }
252 
253     return result;
254 }
255 
256 #endif /* RT_USING_SERIAL */
257 
258 /************************** end of file ******************/
259