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
nrfx_uart_task_address_get(nrfx_uart_t const * p_instance,nrf_uart_task_t task)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
nrfx_uart_event_address_get(nrfx_uart_t const * p_instance,nrf_uart_event_t event)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