1 /*
2 * Copyright (c) 2006-2025, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-04-28 xckhmf Modify for <nrfx>
9 * 2020-10-31 xckhmf Support for UART1
10 *
11 */
12 #include <rtdevice.h>
13 #include <nrfx_uarte.h>
14 #include "drv_uart.h"
15
16 #ifdef BSP_USING_UART
17 #if defined(BSP_USING_UART0) || defined(BSP_USING_UART1)|| defined(BSP_USING_UART2)|| defined(BSP_USING_UART3)
18 typedef struct
19 {
20 struct rt_serial_device *serial;
21 nrfx_uarte_t uarte_instance;
22 uint8_t rx_length;
23 uint8_t tx_buffer[1];
24 uint8_t rx_buffer[1];
25 bool isInit;
26 uint32_t rx_pin;
27 uint32_t tx_pin;
28 } drv_uart_cb_t;
29
30 #ifdef BSP_USING_UART0
31 static struct rt_serial_device m_serial_0;
32 drv_uart_cb_t m_uarte0_cb = {
33 .uarte_instance = NRFX_UARTE_INSTANCE(0),
34 .rx_length = 0,
35 .rx_pin = BSP_UART0_RX_PIN,
36 .tx_pin = BSP_UART0_TX_PIN,
37 .isInit = false
38 };
39 #endif /* BSP_USING_UART0 */
40
41 #ifdef BSP_USING_UART1
42 static struct rt_serial_device m_serial_1;
43 drv_uart_cb_t m_uarte1_cb = {
44 .uarte_instance = NRFX_UARTE_INSTANCE(1),
45 .rx_length = 0,
46 .rx_pin = BSP_UART1_RX_PIN,
47 .tx_pin = BSP_UART1_TX_PIN,
48 .isInit = false
49 };
50 #endif /* BSP_USING_UART1 */
51 #ifdef BSP_USING_UART2
52 static struct rt_serial_device m_serial_2;
53 drv_uart_cb_t m_uarte2_cb = {
54 .uarte_instance = NRFX_UARTE_INSTANCE(2),
55 .rx_length = 0,
56 .rx_pin = BSP_UART2_RX_PIN,
57 .tx_pin = BSP_UART2_TX_PIN,
58 .isInit = false
59 };
60 #endif /* BSP_USING_UART2 */
61 #ifdef BSP_USING_UART3
62 static struct rt_serial_device m_serial_3;
63 drv_uart_cb_t m_uarte3_cb = {
64 .uarte_instance = NRFX_UARTE_INSTANCE(3),
65 .rx_length = 0,
66 .rx_pin = BSP_UART3_RX_PIN,
67 .tx_pin = BSP_UART3_TX_PIN,
68 .isInit = false
69 };
70 #endif /* BSP_USING_UART3 */
71
72
uarte_evt_handler(nrfx_uarte_event_t const * p_event,void * p_context)73 static void uarte_evt_handler(nrfx_uarte_event_t const * p_event,
74 void * p_context)
75 {
76 drv_uart_cb_t *p_cb = RT_NULL;
77 p_cb = (drv_uart_cb_t*)p_context;
78 switch (p_event->type)
79 {
80 case NRFX_UARTE_EVT_RX_DONE:
81 p_cb->rx_length = p_event->data.rxtx.bytes;
82 if(p_cb->serial->parent.open_flag&RT_DEVICE_FLAG_INT_RX)
83 {
84 rt_hw_serial_isr(p_cb->serial, RT_SERIAL_EVENT_RX_IND);
85 }
86 (void)nrfx_uarte_rx(&(p_cb->uarte_instance), p_cb->rx_buffer, 1);
87 break;
88
89 case NRFX_UARTE_EVT_ERROR:
90 (void)nrfx_uarte_rx(&(p_cb->uarte_instance), p_cb->rx_buffer, 1);
91 break;
92
93 case NRFX_UARTE_EVT_TX_DONE:
94 if(p_cb->serial->parent.open_flag&RT_DEVICE_FLAG_INT_TX)
95 {
96 rt_hw_serial_isr(p_cb->serial, RT_SERIAL_EVENT_TX_DONE);
97 }
98 break;
99
100 default:
101 break;
102 }
103 }
104
_uart_cfg(struct rt_serial_device * serial,struct serial_configure * cfg)105 static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg)
106 {
107 nrfx_uarte_config_t config = NRFX_UARTE_DEFAULT_CONFIG(NRF_UARTE_PSEL_DISCONNECTED,\
108 NRF_UARTE_PSEL_DISCONNECTED);
109
110 drv_uart_cb_t *p_cb = RT_NULL;
111
112 RT_ASSERT(serial != RT_NULL);
113 RT_ASSERT(cfg != RT_NULL);
114
115 if (serial->parent.user_data == RT_NULL)
116 {
117 return -RT_ERROR;
118 }
119 p_cb = (drv_uart_cb_t*)serial->parent.user_data;
120 if(p_cb->isInit)
121 {
122 nrfx_uarte_uninit(&(p_cb->uarte_instance));
123 p_cb->isInit = false;
124 }
125
126 switch (cfg->baud_rate)
127 {
128 case BAUD_RATE_2400:
129 config.baudrate = NRF_UARTE_BAUDRATE_2400;
130 break;
131 case BAUD_RATE_4800:
132 config.baudrate = NRF_UARTE_BAUDRATE_4800;
133 break;
134 case BAUD_RATE_9600:
135 config.baudrate = NRF_UARTE_BAUDRATE_9600;
136 break;
137 case BAUD_RATE_19200:
138 config.baudrate = NRF_UARTE_BAUDRATE_19200;
139 break;
140 case BAUD_RATE_38400:
141 config.baudrate = NRF_UARTE_BAUDRATE_38400;
142 break;
143 case BAUD_RATE_57600:
144 config.baudrate = NRF_UARTE_BAUDRATE_57600;
145 break;
146 case BAUD_RATE_115200:
147 config.baudrate = NRF_UARTE_BAUDRATE_115200;
148 break;
149 case BAUD_RATE_230400:
150 config.baudrate = NRF_UARTE_BAUDRATE_230400;
151 break;
152 case BAUD_RATE_460800:
153 config.baudrate = NRF_UARTE_BAUDRATE_460800;
154 break;
155 case BAUD_RATE_921600:
156 config.baudrate = NRF_UARTE_BAUDRATE_921600;
157 break;
158 #if defined(SOC_NRF5340)
159 case 1000000:
160 config.baudrate = NRF_UARTE_BAUDRATE_1000000;
161 break;
162 #endif /* SOC_NRF5340*/
163 case BAUD_RATE_2000000:
164 case BAUD_RATE_3000000:
165 return -RT_EINVAL;
166 default:
167 config.baudrate = NRF_UARTE_BAUDRATE_115200;
168 break;
169 }
170 config.hal_cfg.parity = (cfg->parity == PARITY_NONE)?\
171 NRF_UARTE_PARITY_EXCLUDED:NRF_UARTE_PARITY_INCLUDED;
172 config.hal_cfg.hwfc = NRF_UARTE_HWFC_DISABLED;
173 config.pselrxd = p_cb->rx_pin;
174 config.pseltxd = p_cb->tx_pin;
175 config.p_context = (void *)p_cb;
176
177 nrfx_uarte_init(&(p_cb->uarte_instance),(nrfx_uarte_config_t const *)&config,uarte_evt_handler);
178 nrfx_uarte_rx(&(p_cb->uarte_instance),p_cb->rx_buffer,1);
179 p_cb->isInit = true;
180 return RT_EOK;
181 }
182
_uart_ctrl(struct rt_serial_device * serial,int cmd,void * arg)183 static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg)
184 {
185 drv_uart_cb_t *p_cb = RT_NULL;
186 RT_ASSERT(serial != RT_NULL);
187
188 if (serial->parent.user_data == RT_NULL)
189 {
190 return -RT_ERROR;
191 }
192 p_cb = (drv_uart_cb_t*)serial->parent.user_data;
193
194 switch (cmd)
195 {
196 /* disable interrupt */
197 case RT_DEVICE_CTRL_CLR_INT:
198 break;
199
200 /* enable interrupt */
201 case RT_DEVICE_CTRL_SET_INT:
202 break;
203
204 case RT_DEVICE_CTRL_CUSTOM:
205 if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_9600)
206 {
207 p_cb->serial->config.baud_rate = 9600;
208 }
209 else if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_115200)
210 {
211 p_cb->serial->config.baud_rate = 115200;
212 }
213 _uart_cfg(serial, &(serial->config));
214 break;
215
216 case RT_DEVICE_CTRL_PIN:
217 _uart_cfg(serial, &(serial->config));
218 break;
219
220 case RT_DEVICE_POWERSAVE:
221 if(p_cb->isInit)
222 {
223 nrfx_uarte_uninit(&(p_cb->uarte_instance));
224 p_cb->isInit = false;
225 }
226 break;
227
228 case RT_DEVICE_WAKEUP:
229 _uart_cfg(serial, &(serial->config));
230 break;
231
232 default:
233 return -RT_ERROR;
234 }
235
236 return RT_EOK;
237 }
238
_uart_putc(struct rt_serial_device * serial,char c)239 static int _uart_putc(struct rt_serial_device *serial, char c)
240 {
241 drv_uart_cb_t *p_cb = RT_NULL;
242 int rtn = -1;
243 RT_ASSERT(serial != RT_NULL);
244
245 if (serial->parent.user_data != RT_NULL)
246 {
247 p_cb = (drv_uart_cb_t*)serial->parent.user_data;
248 }
249 p_cb->tx_buffer[0] = c;
250 nrfx_uarte_tx(&(p_cb->uarte_instance),p_cb->tx_buffer,1);
251 if(!(serial->parent.open_flag&RT_DEVICE_FLAG_INT_TX))
252 {
253 while(nrfx_uarte_tx_in_progress(&(p_cb->uarte_instance)))
254 {
255 }
256 }
257 #if defined(SOC_NRF5340)
258 return 1;
259 #endif /* SOC_NRF5340*/
260 return rtn;
261 }
262
_uart_getc(struct rt_serial_device * serial)263 static int _uart_getc(struct rt_serial_device *serial)
264 {
265 int ch = -1;
266 drv_uart_cb_t *p_cb = RT_NULL;
267 RT_ASSERT(serial != RT_NULL);
268
269 if (serial->parent.user_data != RT_NULL)
270 {
271 p_cb = (drv_uart_cb_t*)serial->parent.user_data;
272 }
273
274 if(p_cb->rx_length)
275 {
276 ch = p_cb->rx_buffer[0];
277 p_cb->rx_length--;
278 }
279 return ch;
280 }
281
282 static struct rt_uart_ops _uart_ops = {
283 _uart_cfg,
284 _uart_ctrl,
285 _uart_putc,
286 _uart_getc
287 };
288
rt_hw_uart_init(void)289 int rt_hw_uart_init(void)
290 {
291 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
292
293 #ifdef BSP_USING_UART0
294 m_serial_0.config = config;
295 #if defined(SOC_NRF5340)
296 m_serial_0.config.baud_rate = 1000000;
297 #endif /* SOC_NRF5340*/
298 m_serial_0.ops = &_uart_ops;
299 m_uarte0_cb.serial = &m_serial_0;
300 rt_hw_serial_register(&m_serial_0, "uart0", \
301 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX , &m_uarte0_cb);
302 #endif /* BSP_USING_UART0 */
303
304 #ifdef BSP_USING_UART1
305 m_serial_1.config = config;
306 #if defined(SOC_NRF5340)
307 m_serial_1.config.baud_rate = 1000000;
308 #endif /* SOC_NRF5340*/
309 m_serial_1.ops = &_uart_ops;
310 m_uarte1_cb.serial = &m_serial_1;
311 rt_hw_serial_register(&m_serial_1, "uart1", \
312 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX, &m_uarte1_cb);
313 #endif /* BSP_USING_UART1 */
314
315 #ifdef BSP_USING_UART2
316 m_serial_2.config = config;
317 m_serial_2.ops = &_uart_ops;
318 m_uarte2_cb.serial = &m_serial_2;
319 rt_hw_serial_register(&m_serial_2, "uart2", \
320 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX, &m_uarte2_cb);
321 #endif /* BSP_USING_UART2 */
322
323 #ifdef BSP_USING_UART3
324 m_serial_3.config = config;
325 m_serial_3.ops = &_uart_ops;
326 m_uarte3_cb.serial = &m_serial_3;
327 rt_hw_serial_register(&m_serial_3, "uart3", \
328 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX, &m_uarte3_cb);
329 #endif /* BSP_USING_UART3 */
330
331 return RT_EOK;
332 }
333 #endif /* defined(BSP_USING_UART0) || defined(BSP_USING_UART1) */
334 #endif /* BSP_USING_UART */
335
336