1 /*
2  * Copyright (c) 2015 - 2023, 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_UARTE_H__
35 #define NRFX_UARTE_H__
36 
37 #include <nrfx.h>
38 #include <haly/nrfy_uarte.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /**
45  * @defgroup nrfx_uarte UARTE driver
46  * @{
47  * @ingroup nrf_uarte
48  * @brief   UARTE peripheral driver.
49  */
50 
51 /** @brief Structure for the UARTE driver instance. */
52 typedef struct
53 {
54     NRF_UARTE_Type * p_reg;        ///< Pointer to a structure with UARTE registers.
55     uint8_t          drv_inst_idx; ///< Index of the driver instance. For internal use only.
56 } nrfx_uarte_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(UARTE)
62     NRFX_UARTE_ENABLED_COUNT
63 };
64 #endif
65 
66 /** @brief Macro for creating a UARTE driver instance. */
67 #define NRFX_UARTE_INSTANCE(id)                               \
68 {                                                             \
69     .p_reg        = NRFX_CONCAT_2(NRF_UARTE, id),             \
70     .drv_inst_idx = NRFX_CONCAT_3(NRFX_UARTE, id, _INST_IDX), \
71 }
72 
73 /** @brief Types of UARTE driver events. */
74 typedef enum
75 {
76     NRFX_UARTE_EVT_TX_DONE, ///< Requested TX transfer completed.
77     NRFX_UARTE_EVT_RX_DONE, ///< Requested RX transfer completed.
78     NRFX_UARTE_EVT_ERROR,   ///< Error reported by UART peripheral.
79 } nrfx_uarte_evt_type_t;
80 
81 /** @brief Structure for the UARTE configuration. */
82 typedef struct
83 {
84     uint32_t             txd_pin;            ///< TXD pin number.
85     uint32_t             rxd_pin;            ///< RXD pin number.
86     uint32_t             rts_pin;            ///< RTS pin number.
87     uint32_t             cts_pin;            ///< CTS pin number.
88     void *               p_context;          ///< Context passed to interrupt handler.
89     nrf_uarte_baudrate_t baudrate;           ///< Baud rate.
90     uint8_t              interrupt_priority; ///< Interrupt priority.
91     nrf_uarte_config_t   config;             ///< Peripheral configuration.
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_uarte_config_t;
107 
108 /**
109  * @brief UARTE driver default configuration.
110  *
111  * This configuration sets up UARTE with the following options:
112  * - hardware flow control disabled
113  * - no parity bit
114  * - one stop bit
115  * - baudrate: 115200
116  *
117  * @param[in] _pin_tx TX pin.
118  * @param[in] _pin_rx RX pin.
119  */
120 #define NRFX_UARTE_DEFAULT_CONFIG(_pin_tx, _pin_rx)                             \
121 {                                                                               \
122     .txd_pin            = _pin_tx,                                              \
123     .rxd_pin            = _pin_rx,                                              \
124     .rts_pin            = NRF_UARTE_PSEL_DISCONNECTED,                          \
125     .cts_pin            = NRF_UARTE_PSEL_DISCONNECTED,                          \
126     .p_context          = NULL,                                                 \
127     .baudrate           = NRF_UARTE_BAUDRATE_115200,                            \
128     .interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY,               \
129     .config             =                                                       \
130     {                                                                           \
131         .hwfc           = NRF_UARTE_HWFC_DISABLED,                              \
132         .parity         = NRF_UARTE_PARITY_EXCLUDED,                            \
133         NRFX_COND_CODE_1(NRFX_ARG_HAS_PARENTHESIS(UARTE_CONFIG_STOP_Msk),       \
134                 (.stop = (nrf_uarte_stop_t)NRF_UARTE_STOP_ONE,), ())            \
135         NRFX_COND_CODE_1(NRFX_ARG_HAS_PARENTHESIS(UARTE_CONFIG_PARITYTYPE_Msk), \
136                 (.paritytype = NRF_UARTE_PARITYTYPE_EVEN,), ())                 \
137     },                                                                          \
138 }
139 
140 /** @brief Structure for the UARTE transfer completion event. */
141 typedef struct
142 {
143     uint8_t * p_data; ///< Pointer to memory used for transfer.
144     size_t    bytes;  ///< Number of bytes transfered.
145 } nrfx_uarte_xfer_evt_t;
146 
147 /** @brief Structure for UARTE error event. */
148 typedef struct
149 {
150     nrfx_uarte_xfer_evt_t rx;         ///< Transfer details, including number of bytes received.
151     uint32_t              error_mask; ///< Mask of error flags that generated the event.
152 } nrfx_uarte_error_evt_t;
153 
154 /** @brief Structure for UARTE event. */
155 typedef struct
156 {
157     nrfx_uarte_evt_type_t type; ///< Event type.
158     union
159     {
160         nrfx_uarte_xfer_evt_t  rx;    ///< Data provided for RX completion events.
161         nrfx_uarte_xfer_evt_t  tx;    ///< Data provided for TX completion events.
162         nrfx_uarte_error_evt_t error; ///< Data provided for error event.
163     } data;                           ///< Union to store event data.
164 } nrfx_uarte_event_t;
165 
166 /**
167  * @brief UARTE interrupt event handler.
168  *
169  * @param[in] p_event   Pointer to event structure. Event is allocated on the stack so it is available
170  *                      only within the context of the event handler.
171  * @param[in] p_context Context passed to the interrupt handler, set on initialization.
172  */
173 typedef void (*nrfx_uarte_event_handler_t)(nrfx_uarte_event_t const * p_event,
174                                            void *                     p_context);
175 
176 /**
177  * @brief Function for initializing the UARTE driver.
178  *
179  * This function configures and enables UARTE. After this function GPIO pins are controlled by UARTE.
180  *
181  * @param[in] p_instance    Pointer to the driver instance structure.
182  * @param[in] p_config      Pointer to the structure with the initial configuration.
183  * @param[in] event_handler Event handler provided by the user. If not provided driver works in
184  *                          blocking mode.
185  *
186  * @retval NRFX_SUCCESS             Initialization was successful.
187  * @retval NRFX_ERROR_INVALID_STATE Driver is already initialized.
188  * @retval NRFX_ERROR_BUSY          Some other peripheral with the same
189  *                                  instance ID is already in use. This is
190  *                                  possible only if @ref nrfx_prs module
191  *                                  is enabled.
192  */
193 nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const *        p_instance,
194                            nrfx_uarte_config_t const * p_config,
195                            nrfx_uarte_event_handler_t  event_handler);
196 
197 /**
198  * @brief Function for reconfiguring the UARTE driver.
199  *
200  * @param[in] p_instance Pointer to the driver instance structure.
201  * @param[in] p_config   Pointer to the structure with the configuration.
202  *
203  * @retval NRFX_SUCCESS             Reconfiguration was successful.
204  * @retval NRFX_ERROR_BUSY          The driver is during transfer.
205  * @retval NRFX_ERROR_INVALID_STATE The driver is uninitialized.
206  */
207 nrfx_err_t nrfx_uarte_reconfigure(nrfx_uarte_t const *        p_instance,
208                                   nrfx_uarte_config_t const * p_config);
209 
210 /**
211  * @brief Function for uninitializing the UARTE driver.
212  *
213  * @param[in] p_instance Pointer to the driver instance structure.
214  */
215 void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance);
216 
217 /**
218  * @brief Function for getting the address of the specified UARTE task.
219  *
220  * @param[in] p_instance Pointer to the driver instance structure.
221  * @param[in] task       Task.
222  *
223  * @return Task address.
224  */
225 NRFX_STATIC_INLINE uint32_t nrfx_uarte_task_address_get(nrfx_uarte_t const * p_instance,
226                                                         nrf_uarte_task_t     task);
227 
228 /**
229  * @brief Function for getting the address of the specified UARTE event.
230  *
231  * @param[in] p_instance Pointer to the driver instance structure.
232  * @param[in] event      Event.
233  *
234  * @return Event address.
235  */
236 NRFX_STATIC_INLINE uint32_t nrfx_uarte_event_address_get(nrfx_uarte_t const * p_instance,
237                                                          nrf_uarte_event_t    event);
238 
239 /**
240  * @brief Function for sending data over UARTE.
241  *
242  * If an event handler is provided in nrfx_uarte_init() call, this function
243  * returns immediately and the handler is called when the transfer is done.
244  * Otherwise, the transfer is performed in blocking mode, that is this function
245  * returns when the transfer is finished. Blocking mode is not using interrupt
246  * so there is no context switching inside the function.
247  *
248  * @note Peripherals using EasyDMA (including UARTE) require the transfer buffers
249  *       to be placed in the Data RAM region. If this condition is not met,
250  *       this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
251  *
252  * @param[in] p_instance Pointer to the driver instance structure.
253  * @param[in] p_data     Pointer to data.
254  * @param[in] length     Number of bytes to send. Maximum possible length is
255  *                       dependent on the used SoC (see the MAXCNT register
256  *                       description in the Product Specification). The driver
257  *                       checks it with assertion.
258  * @param[in] flags      Transfer options (0 for default settings).
259  *
260  * @retval NRFX_SUCCESS            Initialization was successful.
261  * @retval NRFX_ERROR_BUSY         Driver is already transferring.
262  * @retval NRFX_ERROR_FORBIDDEN    The transfer was aborted from a different context
263  *                                 (blocking mode only).
264  * @retval NRFX_ERROR_INVALID_ADDR p_data does not point to RAM buffer.
265  */
266 nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
267                          uint8_t const *      p_data,
268                          size_t               length,
269                          uint32_t             flags);
270 
271 /**
272  * @brief Function for checking if UARTE is currently transmitting.
273  *
274  * @param[in] p_instance Pointer to the driver instance structure.
275  *
276  * @retval true  The UARTE is transmitting.
277  * @retval false The UARTE is not transmitting.
278  */
279 bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance);
280 
281 /**
282  * @brief Function for aborting any ongoing transmission.
283  * @note @ref NRFX_UARTE_EVT_TX_DONE event will be generated in non-blocking mode.
284  *       It will contain number of bytes sent until the abort was called. The event
285  *       handler will be called from the UARTE interrupt context.
286  *
287  * @param[in] p_instance Pointer to the driver instance structure.
288  * @param[in] sync       For future use.
289  *
290  * @retval NRFX_SUCCESS Successfully initiated abort.
291  */
292 nrfx_err_t nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance, bool sync);
293 
294 /**
295  * @brief Function for receiving data over UARTE.
296  *
297  * If an event handler is provided in the nrfx_uarte_init() call, this function
298  * returns immediately and the handler is called when the transfer is done.
299  * Otherwise, the transfer is performed in blocking mode, that is this function
300  * returns when the transfer is finished. Blocking mode is not using interrupt so
301  * there is no context switching inside the function.
302  * The receive buffer pointer is double-buffered in non-blocking mode. The secondary
303  * buffer can be set immediately after starting the transfer and will be filled
304  * when the primary buffer is full. The double-buffering feature allows
305  * receiving data continuously.
306  *
307  * @note Peripherals using EasyDMA (including UARTE) require the transfer buffers
308  *       to be placed in the Data RAM region. If this condition is not met,
309  *       this function fails with the error code NRFX_ERROR_INVALID_ADDR.
310  *
311  * @warning When the double-buffering feature is used and the UARTE interrupt
312  *          is processed with a delay (for example, due to a higher priority interrupt)
313  *          long enough for both buffers to get filled completely,
314  *          the event handler will be invoked only once, to notify that
315  *          the first buffer has been filled. This is because from hardware perspective it
316  *          is impossible to deduce in such case if the second buffer was also filled completely or not.
317  *          To prevent this from happening, keep the UARTE interrupt latency low
318  *          or use large enough reception buffers.
319  *
320  * @param[in] p_instance Pointer to the driver instance structure.
321  * @param[in] p_data     Pointer to data.
322  * @param[in] length     Number of bytes to receive. Maximum possible length is
323  *                       dependent on the used SoC (see the MAXCNT register
324  *                       description in the Product Specification). The driver
325  *                       checks it with assertion.
326  *
327  * @retval NRFX_SUCCESS            Initialization is successful.
328  * @retval NRFX_ERROR_BUSY         The driver is already receiving
329  *                                 (and the secondary buffer has already been set
330  *                                 in non-blocking mode).
331  * @retval NRFX_ERROR_FORBIDDEN    The transfer is aborted from a different context
332  *                                 (blocking mode only).
333  * @retval NRFX_ERROR_INTERNAL     The UARTE peripheral reports an error.
334  * @retval NRFX_ERROR_INVALID_ADDR p_data does not point to RAM buffer.
335  */
336 nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
337                          uint8_t *            p_data,
338                          size_t               length);
339 
340 
341 
342 /**
343  * @brief Function for testing the receiver state in blocking mode.
344  *
345  * @param[in]  p_instance  Pointer to the driver instance structure.
346  * @param[out] p_rx_amount For future use.
347  *
348  * @retval NRFX_SUCCESS    The receiving operation is completed.
349  * @retval NRFX_ERROR_BUSY The receiver did not complete the operation.
350  */
351 nrfx_err_t nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance, size_t * p_rx_amount);
352 
353 /**
354  * @brief Function for aborting any ongoing reception.
355  * @note @ref NRFX_UARTE_EVT_RX_DONE event will be generated in non-blocking mode.
356  *       It will contain number of bytes received until the abort was called. The event
357  *       handler will be called from the UARTE interrupt context.
358  *
359  * @warning When the double-buffering feature is used and the UARTE interrupt
360  *          is processed with a delay (for example, due to a higher priority
361  *          interrupt) long enough for the first buffer to be filled completely,
362  *          the event handler will be supplied with the pointer to the first
363  *          buffer and the number of bytes received in the second buffer.
364  *          This is because from hardware perspective it is impossible to deduce
365  *          the reception of which buffer has been aborted.
366  *          To prevent this from happening, keep the UARTE interrupt latency low
367  *          or use large enough reception buffers.
368  *
369  * @param[in] p_instance  Pointer to the driver instance structure.
370  * @param[in] disable_all For future use.
371  * @param[in] sync        For future use.
372  *
373  * @retval NRFX_SUCCESS Successfully initiated abort.
374  */
375 nrfx_err_t nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance, bool disable_all, bool sync);
376 
377 /**
378  * @brief Function for reading error source mask. Mask contains values from @ref nrf_uarte_error_mask_t.
379  * @note Function must be used in the blocking mode only. In case of non-blocking mode, an error event is
380  *       generated. Function clears error sources after reading.
381  *
382  * @param[in] p_instance Pointer to the driver instance structure.
383  *
384  * @return Mask of reported errors.
385  */
386 uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance);
387 
388 
389 #ifndef NRFX_DECLARE_ONLY
nrfx_uarte_task_address_get(nrfx_uarte_t const * p_instance,nrf_uarte_task_t task)390 NRFX_STATIC_INLINE uint32_t nrfx_uarte_task_address_get(nrfx_uarte_t const * p_instance,
391                                                         nrf_uarte_task_t     task)
392 {
393     return nrfy_uarte_task_address_get(p_instance->p_reg, task);
394 }
395 
nrfx_uarte_event_address_get(nrfx_uarte_t const * p_instance,nrf_uarte_event_t event)396 NRFX_STATIC_INLINE uint32_t nrfx_uarte_event_address_get(nrfx_uarte_t const * p_instance,
397                                                          nrf_uarte_event_t    event)
398 {
399     return nrfy_uarte_event_address_get(p_instance->p_reg, event);
400 }
401 #endif // NRFX_DECLARE_ONLY
402 
403 /**
404  * @brief Macro returning UARTE interrupt handler.
405  *
406  * param[in] idx UARTE index.
407  *
408  * @return Interrupt handler.
409  */
410 #define NRFX_UARTE_INST_HANDLER_GET(idx) NRFX_CONCAT_3(nrfx_uarte_, idx, _irq_handler)
411 
412 /** @} */
413 
414 /*
415  * Declare interrupt handlers for all enabled driver instances in the following format:
416  * nrfx_\<periph_name\>_\<idx\>_irq_handler (for example, nrfx_uarte_0_irq_handler).
417  *
418  * A specific interrupt handler for the driver instance can be retrieved by using
419  * the NRFX_UARTE_INST_HANDLER_GET macro.
420  *
421  * Here is a sample of using the NRFX_UARTE_INST_HANDLER_GET macro to directly map
422  * an interrupt handler in a Zephyr application:
423  *
424  * IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_UARTE_INST_GET(\<instance_index\>)), \<priority\>,
425  *                    NRFX_UARTE_INST_HANDLER_GET(\<instance_index\>), 0);
426  */
427 NRFX_INSTANCE_IRQ_HANDLERS_DECLARE(UARTE, uarte)
428 
429 #ifdef __cplusplus
430 }
431 #endif
432 
433 #endif // NRFX_UARTE_H__
434