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 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 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 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 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 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 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