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, i.e. 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  * The receive buffer pointer is double buffered in non-blocking mode. The secondary
257  * buffer can be set immediately after starting the transfer and will be filled
258  * when the primary buffer is full. The double buffering feature allows
259  * receiving data continuously.
260  *
261  * @param[in] p_instance Pointer to the driver instance structure.
262  * @param[in] p_data     Pointer to data.
263  * @param[in] length     Number of bytes to receive.
264  *
265  * @retval    NRFX_SUCCESS If initialization was successful.
266  * @retval    NRFX_ERROR_BUSY If the driver is already receiving
267  *                            (and the secondary buffer has already been set
268  *                            in non-blocking mode).
269  * @retval    NRFX_ERROR_FORBIDDEN If the transfer was aborted from a different context
270  *                                (blocking mode only, also see @ref nrfx_uart_rx_disable).
271  * @retval    NRFX_ERROR_INTERNAL If UART peripheral reported an error.
272  */
273 nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
274                         uint8_t *           p_data,
275                         size_t              length);
276 
277 
278 
279 /**
280  * @brief Function for testing the receiver state in blocking mode.
281  *
282  * @param[in] p_instance Pointer to the driver instance structure.
283  *
284  * @retval true  If the receiver has at least one byte of data to get.
285  * @retval false If the receiver is empty.
286  */
287 bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance);
288 
289 /**
290  * @brief Function for enabling the receiver.
291  *
292  * UART has a 6-byte-long RX FIFO and it is used to store incoming data. If a user does not call the
293  * UART receive function before the FIFO is filled, an overrun error will appear. The receiver must be
294  * explicitly closed by the user @sa nrfx_uart_rx_disable.
295  *
296  * @param[in] p_instance Pointer to the driver instance structure.
297  */
298 void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance);
299 
300 /**
301  * @brief Function for disabling the receiver.
302  *
303  * This function must be called to close the receiver after it has been explicitly enabled by
304  * @sa nrfx_uart_rx_enable.
305  *
306  * @param[in] p_instance Pointer to the driver instance structure.
307  */
308 void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance);
309 
310 /**
311  * @brief Function for aborting any ongoing reception.
312  * @note @ref NRFX_UART_EVT_TX_DONE event will be generated in non-blocking mode.
313  *       It will contain number of bytes received until abort was called. The event
314  *       handler will be called from the UART interrupt context.
315  *
316  * @param[in] p_instance Pointer to the driver instance structure.
317  */
318 void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance);
319 
320 /**
321  * @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t.
322  * @note Function should be used in blocking mode only. In case of non-blocking mode, an error event is
323  *       generated. Function clears error sources after reading.
324  *
325  * @param[in] p_instance Pointer to the driver instance structure.
326  *
327  * @retval    Mask of reported errors.
328  */
329 uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance);
330 
331 
332 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
nrfx_uart_task_address_get(nrfx_uart_t const * p_instance,nrf_uart_task_t task)333 __STATIC_INLINE uint32_t nrfx_uart_task_address_get(nrfx_uart_t const * p_instance,
334                                                     nrf_uart_task_t     task)
335 {
336     return nrf_uart_task_address_get(p_instance->p_reg, task);
337 }
338 
nrfx_uart_event_address_get(nrfx_uart_t const * p_instance,nrf_uart_event_t event)339 __STATIC_INLINE uint32_t nrfx_uart_event_address_get(nrfx_uart_t const * p_instance,
340                                                      nrf_uart_event_t    event)
341 {
342     return nrf_uart_event_address_get(p_instance->p_reg, event);
343 }
344 #endif // SUPPRESS_INLINE_IMPLEMENTATION
345 
346 
347 void nrfx_uart_0_irq_handler(void);
348 
349 
350 /** @} */
351 
352 #ifdef __cplusplus
353 }
354 #endif
355 
356 #endif // NRFX_UART_H__
357