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