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