1 /* 2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRFX_UART_H__ 33 #define NRFX_UART_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_uart.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup nrfx_uart UART driver 44 * @{ 45 * @ingroup nrf_uart 46 * @brief UART peripheral driver. 47 */ 48 49 /** 50 * @brief UART driver instance data structure. 51 */ 52 typedef struct 53 { 54 NRF_UART_Type * p_reg; ///< Pointer to a structure with UART registers. 55 uint8_t drv_inst_idx; ///< Driver instance index. 56 } nrfx_uart_t; 57 58 enum { 59 #if NRFX_CHECK(NRFX_UART0_ENABLED) 60 NRFX_UART0_INST_IDX, 61 #endif 62 NRFX_UART_ENABLED_COUNT 63 }; 64 65 /** 66 * @brief Macro for creating a UART driver instance. 67 */ 68 #define NRFX_UART_INSTANCE(id) \ 69 { \ 70 .p_reg = NRFX_CONCAT_2(NRF_UART, id), \ 71 .drv_inst_idx = NRFX_CONCAT_3(NRFX_UART, id, _INST_IDX), \ 72 } 73 74 /** 75 * @brief Types of UART driver events. 76 */ 77 typedef enum 78 { 79 NRFX_UART_EVT_TX_DONE, ///< Requested TX transfer completed. 80 NRFX_UART_EVT_RX_DONE, ///< Requested RX transfer completed. 81 NRFX_UART_EVT_ERROR, ///< Error reported by UART peripheral. 82 } nrfx_uart_evt_type_t; 83 84 /** 85 * @brief Structure for UART configuration. 86 */ 87 typedef struct 88 { 89 uint32_t pseltxd; ///< TXD pin number. 90 uint32_t pselrxd; ///< RXD pin number. 91 uint32_t pselcts; ///< CTS pin number. 92 uint32_t pselrts; ///< RTS pin number. 93 void * p_context; ///< Context passed to interrupt handler. 94 nrf_uart_hwfc_t hwfc; ///< Flow control configuration. 95 nrf_uart_parity_t parity; ///< Parity configuration. 96 nrf_uart_baudrate_t baudrate; ///< Baudrate. 97 uint8_t interrupt_priority; ///< Interrupt priority. 98 } nrfx_uart_config_t; 99 100 /** 101 * @brief UART default configuration. 102 */ 103 #define NRFX_UART_DEFAULT_CONFIG \ 104 { \ 105 .pseltxd = NRF_UART_PSEL_DISCONNECTED, \ 106 .pselrxd = NRF_UART_PSEL_DISCONNECTED, \ 107 .pselcts = NRF_UART_PSEL_DISCONNECTED, \ 108 .pselrts = NRF_UART_PSEL_DISCONNECTED, \ 109 .p_context = NULL, \ 110 .hwfc = (nrf_uart_hwfc_t)NRFX_UART_DEFAULT_CONFIG_HWFC, \ 111 .parity = (nrf_uart_parity_t)NRFX_UART_DEFAULT_CONFIG_PARITY, \ 112 .baudrate = (nrf_uart_baudrate_t)NRFX_UART_DEFAULT_CONFIG_BAUDRATE, \ 113 .interrupt_priority = NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY, \ 114 } 115 116 /** 117 * @brief Structure for UART transfer completion event. 118 */ 119 typedef struct 120 { 121 uint8_t * p_data; ///< Pointer to memory used for transfer. 122 uint32_t bytes; ///< Number of bytes transfered. 123 } nrfx_uart_xfer_evt_t; 124 125 /** 126 * @brief Structure for UART error event. 127 */ 128 typedef struct 129 { 130 nrfx_uart_xfer_evt_t rxtx; ///< Transfer details includes number of bytes transferred. 131 uint32_t error_mask; ///< Mask of error flags that generated the event. 132 } nrfx_uart_error_evt_t; 133 134 /** 135 * @brief Structure for UART event. 136 */ 137 typedef struct 138 { 139 nrfx_uart_evt_type_t type; ///< Event type. 140 union 141 { 142 nrfx_uart_xfer_evt_t rxtx; ///< Data provided for transfer completion events. 143 nrfx_uart_error_evt_t error; ///< Data provided for error event. 144 } data; 145 } nrfx_uart_event_t; 146 147 /** 148 * @brief UART interrupt event handler. 149 * 150 * @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available 151 * only within the context of the event handler. 152 * @param[in] p_context Context passed to interrupt handler, set on initialization. 153 */ 154 typedef void (*nrfx_uart_event_handler_t)(nrfx_uart_event_t const * p_event, 155 void * p_context); 156 157 /** 158 * @brief Function for initializing the UART driver. 159 * 160 * This function configures and enables UART. After this function GPIO pins are controlled by UART. 161 * 162 * @param[in] p_instance Pointer to the driver instance structure. 163 * @param[in] p_config Pointer to the structure with initial configuration. 164 * @param[in] event_handler Event handler provided by the user. If not provided driver works in 165 * blocking mode. 166 * 167 * @retval NRFX_SUCCESS If initialization was successful. 168 * @retval NRFX_ERROR_INVALID_STATE If driver is already initialized. 169 * @retval NRFX_ERROR_BUSY If some other peripheral with the same 170 * instance ID is already in use. This is 171 * possible only if @ref nrfx_prs module 172 * is enabled. 173 */ 174 nrfx_err_t nrfx_uart_init(nrfx_uart_t const * p_instance, 175 nrfx_uart_config_t const * p_config, 176 nrfx_uart_event_handler_t event_handler); 177 178 /** 179 * @brief Function for uninitializing the UART driver. 180 * @param[in] p_instance Pointer to the driver instance structure. 181 */ 182 void nrfx_uart_uninit(nrfx_uart_t const * p_instance); 183 184 /** 185 * @brief Function for getting the address of a specific UART task. 186 * 187 * @param[in] p_instance Pointer to the driver instance structure. 188 * @param[in] task Task. 189 * 190 * @return Task address. 191 */ 192 __STATIC_INLINE uint32_t nrfx_uart_task_address_get(nrfx_uart_t const * p_instance, 193 nrf_uart_task_t task); 194 195 /** 196 * @brief Function for getting the address of a specific UART event. 197 * 198 * @param[in] p_instance Pointer to the driver instance structure. 199 * @param[in] event Event. 200 * 201 * @return Event address. 202 */ 203 __STATIC_INLINE uint32_t nrfx_uart_event_address_get(nrfx_uart_t const * p_instance, 204 nrf_uart_event_t event); 205 206 /** 207 * @brief Function for sending data over UART. 208 * 209 * If an event handler was provided in nrfx_uart_init() call, this function 210 * returns immediately and the handler is called when the transfer is done. 211 * Otherwise, the transfer is performed in blocking mode, i.e. this function 212 * returns when the transfer is finished. Blocking mode is not using interrupt 213 * so there is no context switching inside the function. 214 * 215 * @param[in] p_instance Pointer to the driver instance structure. 216 * @param[in] p_data Pointer to data. 217 * @param[in] length Number of bytes to send. 218 * 219 * @retval NRFX_SUCCESS If initialization was successful. 220 * @retval NRFX_ERROR_BUSY If driver is already transferring. 221 * @retval NRFX_ERROR_FORBIDDEN If the transfer was aborted from a different context 222 * (blocking mode only). 223 */ 224 nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance, 225 uint8_t const * p_data, 226 size_t length); 227 228 /** 229 * @brief Function for checking if UART is currently transmitting. 230 * 231 * @param[in] p_instance Pointer to the driver instance structure. 232 * 233 * @retval true If UART is transmitting. 234 * @retval false If UART is not transmitting. 235 */ 236 bool nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance); 237 238 /** 239 * @brief Function for aborting any ongoing transmission. 240 * @note @ref NRFX_UART_EVT_TX_DONE event will be generated in non-blocking mode. 241 * It will contain number of bytes sent until abort was called. The event 242 * handler will be called from the function context. 243 * 244 * @param[in] p_instance Pointer to the driver instance structure. 245 */ 246 void nrfx_uart_tx_abort(nrfx_uart_t const * p_instance); 247 248 /** 249 * @brief Function for receiving data over UART. 250 * 251 * If an event handler was provided in the nrfx_uart_init() call, this function 252 * returns immediately and the handler is called when the transfer is done. 253 * Otherwise, the transfer is performed in blocking mode, meaning that this function 254 * returns when the transfer is finished. Blocking mode is not using interrupt so 255 * there is no context switching inside the function. 256 * 257 * The receive buffer pointer is double buffered in non-blocking mode. The secondary 258 * buffer can be set immediately after starting the transfer and will be filled 259 * when the primary buffer is full. The double buffering feature allows 260 * receiving data continuously. 261 * 262 * If this function is used without a previous call to @ref nrfx_uart_rx_enable, the reception 263 * will be stopped on error or when the supplied buffer fills up. In both cases, 264 * RX FIFO gets disabled. This means that, in case of error, the bytes that follow are lost. 265 * If this nrfx_uart_rx() function is used with the previous call to @ref nrfx_uart_rx_enable, 266 * the reception is stopped in case of error, but FIFO is still ongoing. The receiver is still 267 * working, so after handling the error, an immediate repeated call to this nrfx_uart_rx() 268 * function with fresh data buffer will re-establish reception. To disable the receiver, 269 * you must call @ref nrfx_uart_rx_disable explicitly. 270 * 271 * @param[in] p_instance Pointer to the driver instance structure. 272 * @param[in] p_data Pointer to data. 273 * @param[in] length Number of bytes to receive. 274 * 275 * @retval NRFX_SUCCESS If reception is complete (in case of blocking mode) or it is 276 * successfully started (in case of non-blocking mode). 277 * @retval NRFX_ERROR_BUSY If the driver is already receiving 278 * (and the secondary buffer has already been set 279 * in non-blocking mode). 280 * @retval NRFX_ERROR_FORBIDDEN If the transfer was aborted from a different context 281 * (blocking mode only, also see @ref nrfx_uart_rx_disable). 282 * @retval NRFX_ERROR_INTERNAL If UART peripheral reported an error. 283 */ 284 nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance, 285 uint8_t * p_data, 286 size_t length); 287 288 289 290 /** 291 * @brief Function for testing the receiver state in blocking mode. 292 * 293 * @param[in] p_instance Pointer to the driver instance structure. 294 * 295 * @retval true If the receiver has at least one byte of data to get. 296 * @retval false If the receiver is empty. 297 */ 298 bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance); 299 300 /** 301 * @brief Function for enabling the receiver. 302 * 303 * UART has a 6-byte-long RX FIFO and it is used to store incoming data. If a user does not call the 304 * UART receive function before the FIFO is filled, an overrun error will appear. The receiver must be 305 * explicitly closed by the user @sa nrfx_uart_rx_disable. 306 * 307 * @param[in] p_instance Pointer to the driver instance structure. 308 */ 309 void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance); 310 311 /** 312 * @brief Function for disabling the receiver. 313 * 314 * This function must be called to close the receiver after it has been explicitly enabled by 315 * @sa nrfx_uart_rx_enable. 316 * 317 * @param[in] p_instance Pointer to the driver instance structure. 318 */ 319 void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance); 320 321 /** 322 * @brief Function for aborting any ongoing reception. 323 * @note @ref NRFX_UART_EVT_TX_DONE event will be generated in non-blocking mode. 324 * It will contain number of bytes received until abort was called. The event 325 * handler will be called from the UART interrupt context. 326 * 327 * @param[in] p_instance Pointer to the driver instance structure. 328 */ 329 void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance); 330 331 /** 332 * @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t. 333 * @note Function should be used in blocking mode only. In case of non-blocking mode, an error event is 334 * generated. Function clears error sources after reading. 335 * 336 * @param[in] p_instance Pointer to the driver instance structure. 337 * 338 * @retval Mask of reported errors. 339 */ 340 uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance); 341 342 343 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 344 __STATIC_INLINE uint32_t nrfx_uart_task_address_get(nrfx_uart_t const * p_instance, 345 nrf_uart_task_t task) 346 { 347 return nrf_uart_task_address_get(p_instance->p_reg, task); 348 } 349 350 __STATIC_INLINE uint32_t nrfx_uart_event_address_get(nrfx_uart_t const * p_instance, 351 nrf_uart_event_t event) 352 { 353 return nrf_uart_event_address_get(p_instance->p_reg, event); 354 } 355 #endif // SUPPRESS_INLINE_IMPLEMENTATION 356 357 358 void nrfx_uart_0_irq_handler(void); 359 360 361 /** @} */ 362 363 #ifdef __cplusplus 364 } 365 #endif 366 367 #endif // NRFX_UART_H__ 368