1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 */
7
8 #include <rtthread.h>
9 #include <rtdevice.h>
10
11 #include "board.h"
12 #include "drv_uart.h"
13
14 #include "nrf.h"
15 #include "nrf_gpio.h"
16 #include "nrfx_uart.h"
17
18 static struct rt_serial_device _serial0_0;
19 #if USE_UART0_1
20 static struct rt_serial_device _serial0_1;
21 #endif
22
23 typedef struct
24 {
25 struct rt_serial_device *serial;
26 nrfx_uart_t uart;
27 uint32_t rx_pin;
28 uint32_t tx_pin;
29 } UART_CFG_T;
30
31 UART_CFG_T uart0 =
32 {
33 .uart = {.p_reg = NRF_UART0, .drv_inst_idx = 0},
34 #ifdef RT_USING_CONSOLE
35 .rx_pin = 8,
36 .tx_pin = 6
37 #else
38 .rx_pin = 3,
39 .tx_pin = 4
40 #endif
41 };
42
43 #if USE_UART0_1
44 UART_CFG_T uart1 =
45 {
46 .uart = NRF_DRV_UART_INSTANCE(0),
47 .rx_pin = 3,
48 .tx_pin = 4
49 };
50 #endif
51
52 UART_CFG_T *working_cfg = RT_NULL;
53
UART0_IRQHandler(void)54 void UART0_IRQHandler(void)
55 {
56 if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR)
57 && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR))
58 {
59 nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
60 }
61
62 if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY)
63 && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY))
64 {
65 rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_IND);
66 }
67
68 if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_TXDRDY)
69 && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY))
70 {
71 rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_TX_DONE);
72 }
73
74 if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO))
75 {
76 rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_TIMEOUT);
77 }
78 }
79
_uart_cfg(struct rt_serial_device * serial,struct serial_configure * cfg)80 static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg)
81 {
82 nrfx_uart_config_t config = NRFX_UART_DEFAULT_CONFIG;
83 UART_CFG_T *instance = &uart0;
84
85 RT_ASSERT(serial != RT_NULL);
86 RT_ASSERT(cfg != RT_NULL);
87
88 if (serial->parent.user_data != RT_NULL)
89 {
90 instance = (UART_CFG_T *)serial->parent.user_data;
91 }
92
93 nrf_uart_disable(instance->uart.p_reg);
94
95 switch (cfg->baud_rate)
96 {
97 case 115200:
98 config.baudrate = NRF_UART_BAUDRATE_115200;
99 break;
100
101 case 9600:
102 config.baudrate = NRF_UART_BAUDRATE_9600;
103 break;
104
105 default:
106 config.baudrate = NRF_UART_BAUDRATE_115200;
107 break;
108 }
109
110 if (cfg->parity == PARITY_NONE)
111 {
112 config.parity = NRF_UART_PARITY_EXCLUDED;
113 }
114 else
115 {
116 config.parity = NRF_UART_PARITY_INCLUDED;
117 }
118
119 config.hwfc = NRF_UART_HWFC_DISABLED;
120 config.interrupt_priority = 6;
121 config.pselcts = 0;
122 config.pselrts = 0;
123 config.pselrxd = instance->rx_pin;
124 config.pseltxd = instance->tx_pin;
125
126 nrf_gpio_pin_set(config.pseltxd);
127 nrf_gpio_cfg_output(config.pseltxd);
128 nrf_gpio_pin_clear(config.pseltxd);
129 nrf_gpio_cfg_input(config.pselrxd, NRF_GPIO_PIN_NOPULL);
130 nrf_uart_baudrate_set(instance->uart.p_reg, config.baudrate);
131 nrf_uart_configure(instance->uart.p_reg, config.parity, config.hwfc);
132 nrf_uart_txrx_pins_set(instance->uart.p_reg, config.pseltxd, config.pselrxd);
133
134 if (config.hwfc == NRF_UART_HWFC_ENABLED)
135 {
136 nrf_uart_hwfc_pins_set(instance->uart.p_reg, config.pselrts, config.pselcts);
137 }
138
139 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_TXDRDY);
140 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_RXDRDY);
141 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_RXTO);
142 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_ERROR);
143
144 nrf_uart_int_enable(instance->uart.p_reg, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_RXTO | NRF_UART_INT_MASK_ERROR);
145 NVIC_SetPriority(nrfx_get_irq_number((void *)instance->uart.p_reg), config.interrupt_priority);
146 NVIC_EnableIRQ(nrfx_get_irq_number((void *)instance->uart.p_reg));
147 nrf_uart_enable(instance->uart.p_reg);
148 working_cfg = instance;
149 return RT_EOK;
150 }
151
_uart_ctrl(struct rt_serial_device * serial,int cmd,void * arg)152 static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg)
153 {
154 UART_CFG_T *instance = working_cfg;
155
156 RT_ASSERT(serial != RT_NULL);
157
158 if (serial->parent.user_data != RT_NULL)
159 {
160 instance = (UART_CFG_T *)serial->parent.user_data;
161 }
162
163 switch (cmd)
164 {
165 /* disable interrupt */
166 case RT_DEVICE_CTRL_CLR_INT:
167 nrf_uart_task_trigger(instance->uart.p_reg, NRF_UART_TASK_STOPRX);
168 nrf_uart_int_disable(instance->uart.p_reg, NRF_UART_INT_MASK_RXDRDY
169 | NRF_UART_INT_MASK_RXTO
170 | NRF_UART_INT_MASK_ERROR);
171 NVIC_DisableIRQ(nrfx_get_irq_number((void *)instance->uart.p_reg));
172 break;
173
174 /* enable interrupt */
175 case RT_DEVICE_CTRL_SET_INT:
176 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_RXDRDY);
177 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_RXTO);
178 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_ERROR);
179 /* Enable RX interrupt. */
180 nrf_uart_int_enable(instance->uart.p_reg, NRF_UART_INT_MASK_RXDRDY
181 | NRF_UART_INT_MASK_RXTO
182 | NRF_UART_INT_MASK_ERROR);
183 NVIC_SetPriority(nrfx_get_irq_number((void *)instance->uart.p_reg), 6);
184 NVIC_EnableIRQ(nrfx_get_irq_number((void *)instance->uart.p_reg));
185 nrf_uart_task_trigger(instance->uart.p_reg, NRF_UART_TASK_STARTRX);
186 break;
187
188 case RT_DEVICE_CTRL_CUSTOM:
189 if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_9600)
190 {
191 instance->serial->config.baud_rate = 9600;
192 nrf_uart_baudrate_set(instance->uart.p_reg, NRF_UART_BAUDRATE_9600);
193 }
194 else if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_115200)
195 {
196 instance->serial->config.baud_rate = 115200;
197 nrf_uart_baudrate_set(instance->uart.p_reg, NRF_UART_BAUDRATE_115200);
198 }
199
200 // _uart_cfg(instance->serial, &(instance->serial->config));
201 // nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX);
202 break;
203
204 case RT_DEVICE_CTRL_PIN:
205 if (working_cfg != instance)
206 {
207 _uart_cfg(instance->serial, &(instance->serial->config));
208 }
209 break;
210
211 case RT_DEVICE_POWERSAVE:
212 nrf_uart_disable(instance->uart.p_reg);
213 nrf_uart_txrx_pins_disconnect(instance->uart.p_reg);
214 nrf_gpio_pin_clear(instance->rx_pin);
215 nrf_gpio_cfg_output(instance->rx_pin);
216 nrf_gpio_pin_clear(instance->tx_pin);
217 nrf_gpio_cfg_output(instance->tx_pin);
218 break;
219
220 case RT_DEVICE_WAKEUP:
221 _uart_cfg(instance->serial, &(instance->serial->config));
222 break;
223
224 default:
225 return RT_ERROR;
226 }
227
228 return RT_EOK;
229 }
230
_uart_putc(struct rt_serial_device * serial,char c)231 static int _uart_putc(struct rt_serial_device *serial, char c)
232 {
233 UART_CFG_T *instance = working_cfg;
234
235 RT_ASSERT(serial != RT_NULL);
236
237 if (serial->parent.user_data != RT_NULL)
238 {
239 instance = (UART_CFG_T *)serial->parent.user_data;
240 }
241
242 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_TXDRDY);
243 nrf_uart_task_trigger(instance->uart.p_reg, NRF_UART_TASK_STARTTX);
244 nrf_uart_txd_set(instance->uart.p_reg, (uint8_t)c);
245 while (!nrf_uart_event_check(instance->uart.p_reg, NRF_UART_EVENT_TXDRDY))
246 {
247 }
248
249 return 1;
250 }
251
_uart_getc(struct rt_serial_device * serial)252 static int _uart_getc(struct rt_serial_device *serial)
253 {
254 int ch = -1;
255 UART_CFG_T *instance = working_cfg;
256
257 RT_ASSERT(serial != RT_NULL);
258
259 if (serial->parent.user_data != RT_NULL)
260 {
261 instance = (UART_CFG_T *)serial->parent.user_data;
262 }
263
264 if (nrf_uart_event_check(instance->uart.p_reg, NRF_UART_EVENT_RXDRDY))
265 {
266 nrf_uart_event_clear(instance->uart.p_reg, NRF_UART_EVENT_RXDRDY);
267 ch = (int)(nrf_uart_rxd_get(instance->uart.p_reg));
268 }
269
270 return ch;
271 }
272
273 static struct rt_uart_ops _uart_ops =
274 {
275 _uart_cfg,
276 _uart_ctrl,
277 _uart_putc,
278 _uart_getc
279 };
280
rt_hw_uart_init(void)281 int rt_hw_uart_init(void)
282 {
283 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
284
285 nrf_gpio_pin_write(uart0.tx_pin, 1);
286 nrf_gpio_cfg_output(uart0.tx_pin);
287
288 config.bufsz = RT_SERIAL_RB_BUFSZ;
289 _serial0_0.config = config;
290 _serial0_0.ops = &_uart_ops;
291 uart0.serial = &_serial0_0;
292
293 rt_hw_serial_register(&_serial0_0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart0);
294
295 #if USE_UART0_1
296 config.bufsz = UART0_RB_SIZE;
297 _serial0_1.config = config;
298 _serial0_1.ops = &_uart_ops;
299 uart1.serial = &_serial0_1;
300 rt_hw_serial_register(&_serial0_1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart1);
301 #endif
302
303 return 0;
304 }
305
306 INIT_BOARD_EXPORT(rt_hw_uart_init);
307