xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_uarte.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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 #include <nrfx.h>
33 
34 #if NRFX_CHECK(NRFX_UARTE_ENABLED)
35 
36 #if !(NRFX_CHECK(NRFX_UARTE0_ENABLED) || \
37       NRFX_CHECK(NRFX_UARTE1_ENABLED) || \
38       NRFX_CHECK(NRFX_UARTE2_ENABLED) || \
39       NRFX_CHECK(NRFX_UARTE3_ENABLED))
40 #error "No enabled UARTE instances. Check <nrfx_config.h>."
41 #endif
42 
43 #include <nrfx_uarte.h>
44 #include "prs/nrfx_prs.h"
45 #include <hal/nrf_gpio.h>
46 
47 #define NRFX_LOG_MODULE UARTE
48 #include <nrfx_log.h>
49 
50 #define EVT_TO_STR(event) \
51     (event == NRF_UARTE_EVENT_ERROR ? "NRF_UARTE_EVENT_ERROR" : \
52                                       "UNKNOWN EVENT")
53 
54 #define UARTEX_LENGTH_VALIDATE(peripheral, drv_inst_idx, len1, len2)     \
55     (((drv_inst_idx) == NRFX_CONCAT_3(NRFX_, peripheral, _INST_IDX)) && \
56      NRFX_EASYDMA_LENGTH_VALIDATE(peripheral, len1, len2))
57 
58 #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
59 #define UARTE0_LENGTH_VALIDATE(...)  UARTEX_LENGTH_VALIDATE(UARTE0, __VA_ARGS__)
60 #else
61 #define UARTE0_LENGTH_VALIDATE(...)  0
62 #endif
63 
64 #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
65 #define UARTE1_LENGTH_VALIDATE(...)  UARTEX_LENGTH_VALIDATE(UARTE1, __VA_ARGS__)
66 #else
67 #define UARTE1_LENGTH_VALIDATE(...)  0
68 #endif
69 
70 #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
71 #define UARTE2_LENGTH_VALIDATE(...)  UARTEX_LENGTH_VALIDATE(UARTE2, __VA_ARGS__)
72 #else
73 #define UARTE2_LENGTH_VALIDATE(...)  0
74 #endif
75 
76 #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
77 #define UARTE3_LENGTH_VALIDATE(...)  UARTEX_LENGTH_VALIDATE(UARTE3, __VA_ARGS__)
78 #else
79 #define UARTE3_LENGTH_VALIDATE(...)  0
80 #endif
81 
82 #define UARTE_LENGTH_VALIDATE(drv_inst_idx, length)     \
83     (UARTE0_LENGTH_VALIDATE(drv_inst_idx, length, 0) || \
84      UARTE1_LENGTH_VALIDATE(drv_inst_idx, length, 0) || \
85      UARTE2_LENGTH_VALIDATE(drv_inst_idx, length, 0) || \
86      UARTE3_LENGTH_VALIDATE(drv_inst_idx, length, 0))
87 
88 
89 typedef struct
90 {
91     void                     * p_context;
92     nrfx_uarte_event_handler_t handler;
93     uint8_t            const * p_tx_buffer;
94     uint8_t                  * p_rx_buffer;
95     uint8_t                  * p_rx_secondary_buffer;
96     size_t                     tx_buffer_length;
97     size_t                     rx_buffer_length;
98     size_t                     rx_secondary_buffer_length;
99     nrfx_drv_state_t           state;
100 } uarte_control_block_t;
101 static uarte_control_block_t m_cb[NRFX_UARTE_ENABLED_COUNT];
102 
apply_config(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config)103 static void apply_config(nrfx_uarte_t        const * p_instance,
104                          nrfx_uarte_config_t const * p_config)
105 {
106     if (p_config->pseltxd != NRF_UARTE_PSEL_DISCONNECTED)
107     {
108         nrf_gpio_pin_set(p_config->pseltxd);
109         nrf_gpio_cfg_output(p_config->pseltxd);
110     }
111     if (p_config->pselrxd != NRF_UARTE_PSEL_DISCONNECTED)
112     {
113         nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL);
114     }
115 
116     nrf_uarte_baudrate_set(p_instance->p_reg, p_config->baudrate);
117     nrf_uarte_configure(p_instance->p_reg, p_config->parity, p_config->hwfc);
118     nrf_uarte_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
119     if (p_config->hwfc == NRF_UARTE_HWFC_ENABLED)
120     {
121         if (p_config->pselcts != NRF_UARTE_PSEL_DISCONNECTED)
122         {
123             nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL);
124         }
125         if (p_config->pselrts != NRF_UARTE_PSEL_DISCONNECTED)
126         {
127             nrf_gpio_pin_set(p_config->pselrts);
128             nrf_gpio_cfg_output(p_config->pselrts);
129         }
130         nrf_uarte_hwfc_pins_set(p_instance->p_reg, p_config->pselrts, p_config->pselcts);
131     }
132 }
133 
interrupts_enable(nrfx_uarte_t const * p_instance,uint8_t interrupt_priority)134 static void interrupts_enable(nrfx_uarte_t const * p_instance,
135                               uint8_t              interrupt_priority)
136 {
137     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
138     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
139     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
140     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
141     nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
142                                             NRF_UARTE_INT_ENDTX_MASK |
143                                             NRF_UARTE_INT_ERROR_MASK |
144                                             NRF_UARTE_INT_RXTO_MASK);
145     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg),
146                           interrupt_priority);
147     NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
148 }
149 
interrupts_disable(nrfx_uarte_t const * p_instance)150 static void interrupts_disable(nrfx_uarte_t const * p_instance)
151 {
152     nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
153                                              NRF_UARTE_INT_ENDTX_MASK |
154                                              NRF_UARTE_INT_ERROR_MASK |
155                                              NRF_UARTE_INT_RXTO_MASK);
156     NRFX_IRQ_DISABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
157 }
158 
pins_to_default(nrfx_uarte_t const * p_instance)159 static void pins_to_default(nrfx_uarte_t const * p_instance)
160 {
161     /* Reset pins to default states */
162     uint32_t txd;
163     uint32_t rxd;
164     uint32_t rts;
165     uint32_t cts;
166 
167     txd = nrf_uarte_tx_pin_get(p_instance->p_reg);
168     rxd = nrf_uarte_rx_pin_get(p_instance->p_reg);
169     rts = nrf_uarte_rts_pin_get(p_instance->p_reg);
170     cts = nrf_uarte_cts_pin_get(p_instance->p_reg);
171     nrf_uarte_txrx_pins_disconnect(p_instance->p_reg);
172     nrf_uarte_hwfc_pins_disconnect(p_instance->p_reg);
173 
174     if (txd != NRF_UARTE_PSEL_DISCONNECTED)
175     {
176         nrf_gpio_cfg_default(txd);
177     }
178     if (rxd != NRF_UARTE_PSEL_DISCONNECTED)
179     {
180         nrf_gpio_cfg_default(rxd);
181     }
182     if (cts != NRF_UARTE_PSEL_DISCONNECTED)
183     {
184         nrf_gpio_cfg_default(cts);
185     }
186     if (rts != NRF_UARTE_PSEL_DISCONNECTED)
187     {
188         nrf_gpio_cfg_default(rts);
189     }
190 }
191 
nrfx_uarte_init(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config,nrfx_uarte_event_handler_t event_handler)192 nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const *        p_instance,
193                            nrfx_uarte_config_t const * p_config,
194                            nrfx_uarte_event_handler_t  event_handler)
195 {
196     NRFX_ASSERT(p_config);
197     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
198     nrfx_err_t err_code = NRFX_SUCCESS;
199 
200     if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
201     {
202         err_code = NRFX_ERROR_INVALID_STATE;
203         NRFX_LOG_WARNING("Function: %s, error code: %s.",
204                          __func__,
205                          NRFX_LOG_ERROR_STRING_GET(err_code));
206         return err_code;
207     }
208 
209 #if NRFX_CHECK(NRFX_PRS_ENABLED)
210     static nrfx_irq_handler_t const irq_handlers[NRFX_UARTE_ENABLED_COUNT] = {
211         #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
212         nrfx_uarte_0_irq_handler,
213         #endif
214         #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
215         nrfx_uarte_1_irq_handler,
216         #endif
217         #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
218         nrfx_uarte_2_irq_handler,
219         #endif
220         #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
221         nrfx_uarte_3_irq_handler,
222         #endif
223     };
224     if (nrfx_prs_acquire(p_instance->p_reg,
225             irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
226     {
227         err_code = NRFX_ERROR_BUSY;
228         NRFX_LOG_WARNING("Function: %s, error code: %s.",
229                          __func__,
230                          NRFX_LOG_ERROR_STRING_GET(err_code));
231         return err_code;
232     }
233 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
234 
235     apply_config(p_instance, p_config);
236 
237     p_cb->handler   = event_handler;
238     p_cb->p_context = p_config->p_context;
239 
240     if (p_cb->handler)
241     {
242         interrupts_enable(p_instance, p_config->interrupt_priority);
243     }
244 
245     nrf_uarte_enable(p_instance->p_reg);
246     p_cb->rx_buffer_length           = 0;
247     p_cb->rx_secondary_buffer_length = 0;
248     p_cb->tx_buffer_length           = 0;
249     p_cb->state                      = NRFX_DRV_STATE_INITIALIZED;
250     NRFX_LOG_WARNING("Function: %s, error code: %s.",
251                      __func__,
252                      NRFX_LOG_ERROR_STRING_GET(err_code));
253     return err_code;
254 }
255 
nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)256 void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
257 {
258     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
259 
260     nrf_uarte_disable(p_instance->p_reg);
261 
262     if (p_cb->handler)
263     {
264         interrupts_disable(p_instance);
265     }
266 
267     pins_to_default(p_instance);
268 
269 #if NRFX_CHECK(NRFX_PRS_ENABLED)
270     nrfx_prs_release(p_instance->p_reg);
271 #endif
272 
273     p_cb->state   = NRFX_DRV_STATE_UNINITIALIZED;
274     p_cb->handler = NULL;
275     NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
276 }
277 
nrfx_uarte_tx(nrfx_uarte_t const * p_instance,uint8_t const * p_data,size_t length)278 nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
279                          uint8_t const *      p_data,
280                          size_t               length)
281 {
282     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
283     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
284     NRFX_ASSERT(p_data);
285     NRFX_ASSERT(length > 0);
286     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
287 
288     nrfx_err_t err_code;
289 
290     // EasyDMA requires that transfer buffers are placed in DataRAM,
291     // signal error if the are not.
292     if (!nrfx_is_in_ram(p_data))
293     {
294         err_code = NRFX_ERROR_INVALID_ADDR;
295         NRFX_LOG_WARNING("Function: %s, error code: %s.",
296                          __func__,
297                          NRFX_LOG_ERROR_STRING_GET(err_code));
298         return err_code;
299     }
300 
301     if (nrfx_uarte_tx_in_progress(p_instance))
302     {
303         err_code = NRFX_ERROR_BUSY;
304         NRFX_LOG_WARNING("Function: %s, error code: %s.",
305                          __func__,
306                          NRFX_LOG_ERROR_STRING_GET(err_code));
307         return err_code;
308     }
309     p_cb->tx_buffer_length = length;
310     p_cb->p_tx_buffer      = p_data;
311 
312     NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
313     NRFX_LOG_DEBUG("Tx data:");
314     NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
315                            p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
316 
317     err_code = NRFX_SUCCESS;
318 
319     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
320     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
321     nrf_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
322     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTTX);
323 
324     if (p_cb->handler == NULL)
325     {
326         bool endtx;
327         bool txstopped;
328         do
329         {
330             endtx     = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
331             txstopped = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
332         }
333         while ((!endtx) && (!txstopped));
334 
335         if (txstopped)
336         {
337             err_code = NRFX_ERROR_FORBIDDEN;
338         }
339         p_cb->tx_buffer_length = 0;
340     }
341 
342     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
343     return err_code;
344 }
345 
nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)346 bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)
347 {
348     return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
349 }
350 
nrfx_uarte_rx(nrfx_uarte_t const * p_instance,uint8_t * p_data,size_t length)351 nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
352                          uint8_t *            p_data,
353                          size_t               length)
354 {
355     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
356 
357     NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
358     NRFX_ASSERT(p_data);
359     NRFX_ASSERT(length > 0);
360     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
361 
362     nrfx_err_t err_code;
363 
364     // EasyDMA requires that transfer buffers are placed in DataRAM,
365     // signal error if the are not.
366     if (!nrfx_is_in_ram(p_data))
367     {
368         err_code = NRFX_ERROR_INVALID_ADDR;
369         NRFX_LOG_WARNING("Function: %s, error code: %s.",
370                          __func__,
371                          NRFX_LOG_ERROR_STRING_GET(err_code));
372         return err_code;
373     }
374 
375     bool second_buffer = false;
376 
377     if (p_cb->handler)
378     {
379         nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
380                                                  NRF_UARTE_INT_ENDRX_MASK);
381     }
382     if (p_cb->rx_buffer_length != 0)
383     {
384         if (p_cb->rx_secondary_buffer_length != 0)
385         {
386             if (p_cb->handler)
387             {
388                 nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
389                                                         NRF_UARTE_INT_ENDRX_MASK);
390             }
391             err_code = NRFX_ERROR_BUSY;
392             NRFX_LOG_WARNING("Function: %s, error code: %s.",
393                              __func__,
394                              NRFX_LOG_ERROR_STRING_GET(err_code));
395             return err_code;
396         }
397         second_buffer = true;
398     }
399 
400     if (!second_buffer)
401     {
402         p_cb->rx_buffer_length = length;
403         p_cb->p_rx_buffer      = p_data;
404         p_cb->rx_secondary_buffer_length = 0;
405     }
406     else
407     {
408         p_cb->p_rx_secondary_buffer = p_data;
409         p_cb->rx_secondary_buffer_length = length;
410     }
411 
412     NRFX_LOG_INFO("Transfer rx_len: %d.", length);
413 
414     err_code = NRFX_SUCCESS;
415 
416     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
417     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
418     nrf_uarte_rx_buffer_set(p_instance->p_reg, p_data, length);
419     if (!second_buffer)
420     {
421         nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTRX);
422     }
423     else
424     {
425         nrf_uarte_shorts_enable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
426     }
427 
428     if (m_cb[p_instance->drv_inst_idx].handler == NULL)
429     {
430         bool endrx;
431         bool rxto;
432         bool error;
433         do {
434             endrx  = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
435             rxto   = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
436             error  = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
437         } while ((!endrx) && (!rxto) && (!error));
438 
439         m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0;
440 
441         if (error)
442         {
443             err_code = NRFX_ERROR_INTERNAL;
444         }
445 
446         if (rxto)
447         {
448             err_code = NRFX_ERROR_FORBIDDEN;
449         }
450     }
451     else
452     {
453         nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
454                                                 NRF_UARTE_INT_ENDRX_MASK);
455     }
456     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
457     return err_code;
458 }
459 
nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)460 bool nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)
461 {
462     return nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
463 }
464 
nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)465 uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)
466 {
467     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
468     return nrf_uarte_errorsrc_get_and_clear(p_instance->p_reg);
469 }
470 
rx_done_event(uarte_control_block_t * p_cb,size_t bytes,uint8_t * p_data)471 static void rx_done_event(uarte_control_block_t * p_cb,
472                           size_t                  bytes,
473                           uint8_t *               p_data)
474 {
475     nrfx_uarte_event_t event;
476 
477     event.type             = NRFX_UARTE_EVT_RX_DONE;
478     event.data.rxtx.bytes  = bytes;
479     event.data.rxtx.p_data = p_data;
480 
481     p_cb->handler(&event, p_cb->p_context);
482 }
483 
tx_done_event(uarte_control_block_t * p_cb,size_t bytes)484 static void tx_done_event(uarte_control_block_t * p_cb,
485                           size_t                  bytes)
486 {
487     nrfx_uarte_event_t event;
488 
489     event.type             = NRFX_UARTE_EVT_TX_DONE;
490     event.data.rxtx.bytes  = bytes;
491     event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
492 
493     p_cb->tx_buffer_length = 0;
494 
495     p_cb->handler(&event, p_cb->p_context);
496 }
497 
nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)498 void nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)
499 {
500     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
501 
502     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
503     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
504     if (p_cb->handler == NULL)
505     {
506         while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED))
507         {}
508     }
509     NRFX_LOG_INFO("TX transaction aborted.");
510 }
511 
nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)512 void nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)
513 {
514     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
515 
516     // Short between ENDRX event and STARTRX task must be disabled before
517     // aborting transmission.
518     if (p_cb->rx_secondary_buffer_length != 0)
519     {
520         nrf_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
521     }
522     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
523     NRFX_LOG_INFO("RX transaction aborted.");
524 }
525 
uarte_irq_handler(NRF_UARTE_Type * p_uarte,uarte_control_block_t * p_cb)526 static void uarte_irq_handler(NRF_UARTE_Type *        p_uarte,
527                               uarte_control_block_t * p_cb)
528 {
529     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
530     {
531         nrfx_uarte_event_t event;
532 
533         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);
534 
535         event.type                   = NRFX_UARTE_EVT_ERROR;
536         event.data.error.error_mask  = nrf_uarte_errorsrc_get_and_clear(p_uarte);
537         event.data.error.rxtx.bytes  = nrf_uarte_rx_amount_get(p_uarte);
538         event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
539 
540         // Abort transfer.
541         p_cb->rx_buffer_length = 0;
542         p_cb->rx_secondary_buffer_length = 0;
543 
544         p_cb->handler(&event, p_cb->p_context);
545     }
546     else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
547     {
548         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
549         size_t amount = nrf_uarte_rx_amount_get(p_uarte);
550         // If the transfer was stopped before completion, amount of transfered bytes
551         // will not be equal to the buffer length. Interrupted transfer is ignored.
552         if (amount == p_cb->rx_buffer_length)
553         {
554             if (p_cb->rx_secondary_buffer_length != 0)
555             {
556                 uint8_t * p_data = p_cb->p_rx_buffer;
557                 nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
558                 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
559                 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
560                 p_cb->rx_secondary_buffer_length = 0;
561                 rx_done_event(p_cb, amount, p_data);
562             }
563             else
564             {
565                 p_cb->rx_buffer_length = 0;
566                 rx_done_event(p_cb, amount, p_cb->p_rx_buffer);
567             }
568         }
569     }
570 
571     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
572     {
573         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
574 
575         if (p_cb->rx_buffer_length != 0)
576         {
577             p_cb->rx_buffer_length = 0;
578             // In case of using double-buffered reception both variables storing buffer length
579             // have to be cleared to prevent incorrect behaviour of the driver.
580             p_cb->rx_secondary_buffer_length = 0;
581             rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer);
582         }
583     }
584 
585     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
586     {
587         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
588         if (p_cb->tx_buffer_length != 0)
589         {
590             tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte));
591         }
592     }
593 }
594 
595 #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
nrfx_uarte_0_irq_handler(void)596 void nrfx_uarte_0_irq_handler(void)
597 {
598     uarte_irq_handler(NRF_UARTE0, &m_cb[NRFX_UARTE0_INST_IDX]);
599 }
600 #endif
601 
602 #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
nrfx_uarte_1_irq_handler(void)603 void nrfx_uarte_1_irq_handler(void)
604 {
605     uarte_irq_handler(NRF_UARTE1, &m_cb[NRFX_UARTE1_INST_IDX]);
606 }
607 #endif
608 
609 #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
nrfx_uarte_2_irq_handler(void)610 void nrfx_uarte_2_irq_handler(void)
611 {
612     uarte_irq_handler(NRF_UARTE2, &m_cb[NRFX_UARTE2_INST_IDX]);
613 }
614 #endif
615 
616 #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
nrfx_uarte_3_irq_handler(void)617 void nrfx_uarte_3_irq_handler(void)
618 {
619     uarte_irq_handler(NRF_UARTE3, &m_cb[NRFX_UARTE3_INST_IDX]);
620 }
621 #endif
622 
623 #endif // NRFX_CHECK(NRFX_UARTE_ENABLED)
624