1 /*
2 * Copyright (c) 2006-2020, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-02-11 supperthomas first version
9 *
10 */
11
12
13 #include "board.h"
14 #include "uart.h"
15 #include "rtdevice.h"
16 #ifdef RT_USING_SERIAL
17
18 //#define DRV_DEBUG
19 //#define LOG_TAG "drv.usart"
20 //#include <drv_log.h>
21
22 #define UART0_CONFIG \
23 { \
24 .name = "uart0", \
25 .Instance = MXC_UART_GET_UART(0), \
26 .irq_type = MXC_UART_GET_IRQ(0), \
27 }
28
29 #define UART1_CONFIG \
30 { \
31 .name = "uart1", \
32 .Instance = MXC_UART_GET_UART(1), \
33 .irq_type = MXC_UART_GET_IRQ(1), \
34 }
35
36 struct mcu_uart_config
37 {
38 const char *name;
39 mxc_uart_regs_t *Instance;
40 IRQn_Type irq_type;
41 };
42
43 struct mcu_uart
44 {
45 mxc_uart_regs_t *handle;
46 struct mcu_uart_config *config;
47
48 rt_uint16_t uart_dma_flag;
49 struct rt_serial_device serial;
50 };
51
52
53
54
55 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1)
56
57 #error "Please define at least one BSP_USING_UARTx"
58 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
59 #endif
60
61 enum
62 {
63 #ifdef BSP_USING_UART0
64 UART0_INDEX,
65 #endif
66 #ifdef BSP_USING_UART1
67 UART1_INDEX,
68 #endif
69
70 };
71
72 static struct mcu_uart_config uart_config[] =
73 {
74 #ifdef BSP_USING_UART0
75 UART0_CONFIG,
76 #endif
77 #ifdef BSP_USING_UART1
78 UART1_CONFIG,
79 #endif
80 };
81
82 static struct mcu_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
83
84 #ifdef BSP_USING_UART1
UART1_IRQHandler(void)85 void UART1_IRQHandler(void)
86 {
87 rt_interrupt_enter();
88
89 rt_hw_serial_isr(&(uart_obj[UART1_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
90
91 uint32_t intst = 0;
92 intst = MXC_UART1->int_fl;
93 MXC_UART1->int_fl = intst;
94
95 rt_interrupt_leave();
96 }
97 #endif
98
99 #ifdef BSP_USING_UART0
UART0_IRQHandler(void)100 void UART0_IRQHandler(void)
101 {
102 /* enter interrupt */
103 rt_interrupt_enter();
104
105 rt_hw_serial_isr(&(uart_obj[UART0_INDEX].serial), RT_SERIAL_EVENT_RX_IND);
106 /* clear flags */
107
108 uint32_t intst = 0;
109 intst = MXC_UART0->int_fl;
110 MXC_UART0->int_fl = intst;
111
112 /* leave interrupt */
113 rt_interrupt_leave();
114 }
115 #endif
116
117
mcu_configure(struct rt_serial_device * serial,struct serial_configure * cfg)118 static rt_err_t mcu_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
119 {
120 int error;
121 struct mcu_uart *uart;
122 RT_ASSERT(serial != RT_NULL);
123 RT_ASSERT(cfg != RT_NULL);
124 const sys_cfg_uart_t sys_uart_cfg =
125 {
126 MAP_A,
127 UART_FLOW_DISABLE,
128 };
129 uart = rt_container_of(serial, struct mcu_uart, serial);
130 uart_cfg_t mcu_cfg;
131 uart->handle = uart->config->Instance;
132 mcu_cfg.baud = cfg->baud_rate;
133 mcu_cfg.stop = UART_STOP_1;
134 mcu_cfg.parity = UART_PARITY_DISABLE;
135 mcu_cfg.size = UART_DATA_SIZE_8_BITS;
136 mcu_cfg.flow = UART_FLOW_CTRL_EN;
137 mcu_cfg.pol = UART_FLOW_POL_EN;
138
139 error = UART_Init(uart->handle, &mcu_cfg, &sys_uart_cfg);
140 if (error != E_NO_ERROR)
141 {
142 rt_kprintf("Error initializing UART %d\n", error);
143 while (1) {}
144 }
145 return RT_EOK;
146 }
147
mcu_control(struct rt_serial_device * serial,int cmd,void * arg)148 static rt_err_t mcu_control(struct rt_serial_device *serial, int cmd, void *arg)
149 {
150 struct mcu_uart *uart;
151
152 RT_ASSERT(serial != RT_NULL);
153 uart = rt_container_of(serial, struct mcu_uart, serial);
154
155 switch (cmd)
156 {
157 /* disable interrupt */
158 case RT_DEVICE_CTRL_CLR_INT:
159 /* disable rx irq */
160 NVIC_ClearPendingIRQ(uart->config->irq_type);
161 NVIC_DisableIRQ(uart->config->irq_type);
162 /* disable interrupt */
163 break;
164
165 /* enable interrupt */
166 case RT_DEVICE_CTRL_SET_INT:
167 /* enable rx irq */
168 NVIC_SetPriority(uart->config->irq_type, 1);
169 NVIC_EnableIRQ(uart->config->irq_type);
170 /* enable interrupt */
171 uart->handle->ctrl |= 0x05 << MXC_F_UART_CTRL_RX_TO_POS;
172 uart->handle->int_en |= MXC_F_UART_INT_EN_RX_FIFO_THRESH | \
173 MXC_F_UART_INT_EN_RX_TIMEOUT;
174
175 uart->handle->int_en |= MXC_F_UART_INT_EN_RX_FRAME_ERROR | \
176 MXC_F_UART_INT_EN_RX_PARITY_ERROR | \
177 MXC_F_UART_INT_EN_RX_OVERRUN ;
178
179 uart->handle->thresh_ctrl = MXC_UART_FIFO_DEPTH <<
180 MXC_F_UART_THRESH_CTRL_RX_FIFO_THRESH_POS;
181 break;
182
183 case RT_DEVICE_CTRL_CLOSE:
184 UART_Shutdown(uart->handle);
185 break;
186
187 }
188 return RT_EOK;
189 }
190
mcu_putc(struct rt_serial_device * serial,char c)191 static int mcu_putc(struct rt_serial_device *serial, char c)
192 {
193 struct mcu_uart *uart;
194 RT_ASSERT(serial != RT_NULL);
195
196 uart = rt_container_of(serial, struct mcu_uart, serial);
197 UART_WriteByte(uart->handle, c);
198 return 1;
199 }
200
mcu_getc(struct rt_serial_device * serial)201 static int mcu_getc(struct rt_serial_device *serial)
202 {
203 int ch;
204 struct mcu_uart *uart;
205 RT_ASSERT(serial != RT_NULL);
206 uart = rt_container_of(serial, struct mcu_uart, serial);
207
208 ch = -1;
209
210 if (UART_NumReadAvail(uart->handle))
211 {
212 ch = UART_ReadByte(uart->handle);
213 }
214
215 return ch;
216 }
217
218 static const struct rt_uart_ops mcu_uart_ops =
219 {
220 .configure = mcu_configure,
221 .control = mcu_control,
222 .putc = mcu_putc,
223 .getc = mcu_getc,
224 };
225
rt_hw_usart_init(void)226 int rt_hw_usart_init(void)
227 {
228 rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct mcu_uart);
229 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
230 rt_err_t result = 0;
231
232 for (int i = 0; i < obj_num; i++)
233 {
234 /* init UART object */
235 uart_obj[i].config = &uart_config[i];
236 uart_obj[i].serial.ops = &mcu_uart_ops;
237 uart_obj[i].serial.config = config;
238
239 /* register UART device */
240 result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
241 RT_DEVICE_FLAG_RDWR
242 | RT_DEVICE_FLAG_INT_RX
243 | RT_DEVICE_FLAG_INT_TX
244 , RT_NULL);
245 RT_ASSERT(result == RT_EOK);
246 }
247
248 return result;
249 }
250 //INIT_BOARD_EXPORT(rt_hw_usart_init);
251 #endif /* RT_USING_SERIAL */
252