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 #include <nrfx.h>
35 
36 #if NRFX_CHECK(NRFX_UARTE_ENABLED)
37 
38 #if !NRFX_FEATURE_PRESENT(NRFX_UARTE, _ENABLED)
39 #error "No enabled UARTE instances. Check <nrfx_config.h>."
40 #endif
41 
42 #include <nrfx_uarte.h>
43 #include "prs/nrfx_prs.h"
44 #include <haly/nrfy_gpio.h>
45 
46 #define NRFX_LOG_MODULE UARTE
47 #include <nrfx_log.h>
48 
49 #define EVT_TO_STR(event) \
50     (event == NRF_UARTE_EVENT_ERROR ? "NRF_UARTE_EVENT_ERROR" : \
51                                       "UNKNOWN EVENT")
52 
53 #define UARTEX_LENGTH_VALIDATE(periph_name, prefix, i, drv_inst_idx, len1, len2) \
54     (((drv_inst_idx) == NRFX_CONCAT(NRFX_, periph_name, prefix, i, _INST_IDX)) && \
55      NRFX_EASYDMA_LENGTH_VALIDATE(NRFX_CONCAT(periph_name, prefix, i), len1, len2))
56 
57 #define UARTE_LENGTH_VALIDATE(drv_inst_idx, len)    \
58         (NRFX_FOREACH_ENABLED(UARTE, UARTEX_LENGTH_VALIDATE, (||), (0), drv_inst_idx, len, 0))
59 
60 typedef struct
61 {
62     void                     * p_context;
63     nrfx_uarte_event_handler_t handler;
64     uint8_t            const * p_tx_buffer;
65     uint8_t                  * p_rx_buffer;
66     uint8_t                  * p_rx_secondary_buffer;
67     volatile size_t            tx_buffer_length;
68     size_t                     rx_buffer_length;
69     size_t                     rx_secondary_buffer_length;
70     nrfx_drv_state_t           state;
71     bool                       rx_aborted;
72     bool                       skip_gpio_cfg : 1;
73     bool                       skip_psel_cfg : 1;
74 } uarte_control_block_t;
75 static uarte_control_block_t m_cb[NRFX_UARTE_ENABLED_COUNT];
76 
77 static void apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance);
78 
uarte_configure(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config)79 static void uarte_configure(nrfx_uarte_t        const * p_instance,
80                             nrfx_uarte_config_t const * p_config)
81 {
82     if (!p_config->skip_gpio_cfg)
83     {
84         if (p_config->txd_pin != NRF_UARTE_PSEL_DISCONNECTED)
85         {
86             nrfy_gpio_pin_set(p_config->txd_pin);
87             nrfy_gpio_cfg_output(p_config->txd_pin);
88         }
89         if (p_config->rxd_pin != NRF_UARTE_PSEL_DISCONNECTED)
90         {
91             nrfy_gpio_cfg_input(p_config->rxd_pin, NRF_GPIO_PIN_NOPULL);
92         }
93     }
94 
95     if (p_config->config.hwfc == NRF_UARTE_HWFC_ENABLED)
96     {
97         if (!p_config->skip_gpio_cfg)
98         {
99             if (p_config->cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
100             {
101                 nrfy_gpio_cfg_input(p_config->cts_pin, NRF_GPIO_PIN_NOPULL);
102             }
103             if (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
104             {
105                 nrfy_gpio_pin_set(p_config->rts_pin);
106                 nrfy_gpio_cfg_output(p_config->rts_pin);
107 #if NRF_GPIO_HAS_CLOCKPIN
108                 nrfy_gpio_pin_clock_set(p_config->rts_pin, true);
109 #endif
110             }
111         }
112     }
113 
114     nrfy_uarte_config_t nrfy_config =
115     {
116         .pins =
117         {
118             .txd_pin = p_config->txd_pin,
119             .rxd_pin = p_config->rxd_pin,
120             .rts_pin = p_config->rts_pin,
121             .cts_pin = p_config->cts_pin
122         },
123         .baudrate = p_config->baudrate,
124         .skip_psel_cfg = p_config->skip_psel_cfg
125     };
126     nrfy_config.config = p_config->config;
127 
128     nrfy_uarte_periph_configure(p_instance->p_reg, &nrfy_config);
129 
130     apply_workaround_for_enable_anomaly(p_instance);
131 
132     if (m_cb[p_instance->drv_inst_idx].handler)
133     {
134         nrfy_uarte_int_init(p_instance->p_reg,
135                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDRX) |
136                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDTX) |
137                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ERROR) |
138                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_RXTO)  |
139                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_TXSTOPPED),
140                             p_config->interrupt_priority,
141                             true);
142     }
143 }
144 
pins_to_default(nrfx_uarte_t const * p_instance)145 static void pins_to_default(nrfx_uarte_t const * p_instance)
146 {
147     uarte_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx];
148 
149     /* Reset pins to default states */
150     nrfy_uarte_pins_t pins;
151     nrfy_uarte_pins_get(p_instance->p_reg, &pins);
152     if (!p_cb->skip_psel_cfg)
153     {
154         nrfy_uarte_pins_disconnect(p_instance->p_reg);
155     }
156     if (!p_cb->skip_gpio_cfg)
157     {
158         if (pins.txd_pin != NRF_UARTE_PSEL_DISCONNECTED)
159         {
160             nrfy_gpio_cfg_default(pins.txd_pin);
161         }
162         if (pins.rxd_pin != NRF_UARTE_PSEL_DISCONNECTED)
163         {
164             nrfy_gpio_cfg_default(pins.rxd_pin);
165         }
166         if (pins.cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
167         {
168             nrfy_gpio_cfg_default(pins.cts_pin);
169         }
170         if (pins.rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
171         {
172             nrfy_gpio_cfg_default(pins.rts_pin);
173         }
174     }
175 }
176 
apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance)177 static void apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance)
178 {
179 #if defined(NRF53_SERIES) || defined(NRF91_SERIES)
180     // Apply workaround for anomalies:
181     // - nRF91 - anomaly 23
182     // - nRF53 - anomaly 44
183     volatile uint32_t const * rxenable_reg =
184         (volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x564);
185     volatile uint32_t const * txenable_reg =
186         (volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x568);
187 
188     if (*txenable_reg == 1)
189     {
190         nrfy_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
191     }
192 
193     if (*rxenable_reg == 1)
194     {
195         nrfy_uarte_enable(p_instance->p_reg);
196         nrfy_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
197 
198         bool workaround_succeded;
199         // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
200         // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
201         // (resulting in 12 bits per data byte sent), this may take up to 40 ms.
202         NRFX_WAIT_FOR(*rxenable_reg == 0, 40000, 1, workaround_succeded);
203         if (!workaround_succeded)
204         {
205             NRFX_LOG_ERROR("Failed to apply workaround for instance with base address: %p.",
206                            (void *)p_instance->p_reg);
207         }
208 
209         (void)nrfy_uarte_errorsrc_get_and_clear(p_instance->p_reg);
210         nrfy_uarte_disable(p_instance->p_reg);
211     }
212 #else
213     (void)(p_instance);
214 #endif // defined(NRF53_SERIES) || defined(NRF91_SERIES)
215 }
216 
nrfx_uarte_init(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config,nrfx_uarte_event_handler_t event_handler)217 nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const *        p_instance,
218                            nrfx_uarte_config_t const * p_config,
219                            nrfx_uarte_event_handler_t  event_handler)
220 {
221     NRFX_ASSERT(p_config);
222     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
223     nrfx_err_t err_code = NRFX_SUCCESS;
224 
225     if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
226     {
227         err_code = NRFX_ERROR_INVALID_STATE;
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 
234 #if NRFX_CHECK(NRFX_PRS_ENABLED)
235     static nrfx_irq_handler_t const irq_handlers[NRFX_UARTE_ENABLED_COUNT] = {
236         NRFX_INSTANCE_IRQ_HANDLERS_LIST(UARTE, uarte)
237     };
238     if (nrfx_prs_acquire(p_instance->p_reg,
239             irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
240     {
241         err_code = NRFX_ERROR_BUSY;
242         NRFX_LOG_WARNING("Function: %s, error code: %s.",
243                          __func__,
244                          NRFX_LOG_ERROR_STRING_GET(err_code));
245         return err_code;
246     }
247 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
248 
249     p_cb->handler = event_handler;
250 
251     if (p_config)
252     {
253         p_cb->p_context = p_config->p_context;
254         p_cb->skip_gpio_cfg = p_config->skip_gpio_cfg;
255         p_cb->skip_psel_cfg = p_config->skip_psel_cfg;
256         uarte_configure(p_instance, p_config);
257     }
258 
259     nrfy_uarte_enable(p_instance->p_reg);
260     p_cb->rx_buffer_length           = 0;
261     p_cb->rx_secondary_buffer_length = 0;
262     p_cb->tx_buffer_length           = 0;
263     p_cb->state                      = NRFX_DRV_STATE_INITIALIZED;
264     NRFX_LOG_INFO("Function: %s, error code: %s.",
265                   __func__,
266                   NRFX_LOG_ERROR_STRING_GET(err_code));
267     return err_code;
268 }
269 
nrfx_uarte_reconfigure(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config)270 nrfx_err_t nrfx_uarte_reconfigure(nrfx_uarte_t const *        p_instance,
271                                   nrfx_uarte_config_t const * p_config)
272 {
273     NRFX_ASSERT(p_config);
274     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
275 
276     if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED)
277     {
278         return NRFX_ERROR_INVALID_STATE;
279     }
280     if (nrfx_uarte_tx_in_progress(p_instance))
281     {
282         return NRFX_ERROR_BUSY;
283     }
284     nrfy_uarte_disable(p_instance->p_reg);
285     if (p_cb->handler)
286     {
287         p_cb->p_context = p_config->p_context;
288     }
289     uarte_configure(p_instance, p_config);
290     nrfy_uarte_enable(p_instance->p_reg);
291     return NRFX_SUCCESS;
292 }
293 
nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)294 void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
295 {
296     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
297 
298     if (p_cb->handler)
299     {
300         nrfy_uarte_int_disable(p_instance->p_reg,
301                                NRF_UARTE_INT_ENDRX_MASK |
302                                NRF_UARTE_INT_ENDTX_MASK |
303                                NRF_UARTE_INT_ERROR_MASK |
304                                NRF_UARTE_INT_RXTO_MASK  |
305                                NRF_UARTE_INT_TXSTOPPED_MASK);
306         nrfy_uarte_int_uninit(p_instance->p_reg);
307     }
308     // Make sure all transfers are finished before UARTE is disabled
309     // to achieve the lowest power consumption.
310     nrfy_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
311 
312     nrfy_uarte_xfer_desc_t xfer_desc = {
313         .p_buffer = p_cb->p_rx_buffer,
314         .length   = p_cb->rx_buffer_length
315     };
316     nrfy_uarte_stop(p_instance->p_reg, &xfer_desc);
317 
318     nrfy_uarte_disable(p_instance->p_reg);
319     pins_to_default(p_instance);
320 
321 #if NRFX_CHECK(NRFX_PRS_ENABLED)
322     nrfx_prs_release(p_instance->p_reg);
323 #endif
324 
325     p_cb->state   = NRFX_DRV_STATE_UNINITIALIZED;
326     p_cb->handler = NULL;
327     NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
328 }
329 
nrfx_uarte_tx(nrfx_uarte_t const * p_instance,uint8_t const * p_data,size_t length,uint32_t flags)330 nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
331                          uint8_t const *      p_data,
332                          size_t               length,
333                          uint32_t             flags)
334 {
335     (void)flags;
336     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
337     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
338     NRFX_ASSERT(p_data);
339     NRFX_ASSERT(length > 0);
340     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
341 
342     nrfx_err_t err_code = NRFX_SUCCESS;
343 
344     // EasyDMA requires that transfer buffers are placed in DataRAM,
345     // signal error if the are not.
346     if (!nrf_dma_accessible_check(p_instance->p_reg, p_data))
347     {
348         err_code = NRFX_ERROR_INVALID_ADDR;
349         NRFX_LOG_WARNING("Function: %s, error code: %s.",
350                          __func__,
351                          NRFX_LOG_ERROR_STRING_GET(err_code));
352         return err_code;
353     }
354 
355     if (nrfx_uarte_tx_in_progress(p_instance))
356     {
357         err_code = NRFX_ERROR_BUSY;
358         NRFX_LOG_WARNING("Function: %s, error code: %s.",
359                          __func__,
360                          NRFX_LOG_ERROR_STRING_GET(err_code));
361         return err_code;
362     }
363     p_cb->tx_buffer_length = length;
364     p_cb->p_tx_buffer      = p_data;
365 
366     NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
367     NRFX_LOG_DEBUG("Tx data:");
368     NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
369                            p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
370 
371     nrfy_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
372     nrfy_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
373     nrfy_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
374 
375     uint32_t evt_mask = nrfy_uarte_tx_start(p_instance->p_reg, !p_cb->handler);
376     if (p_cb->handler == NULL)
377     {
378         if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_TXSTOPPED))
379         {
380             err_code = NRFX_ERROR_FORBIDDEN;
381         }
382         else
383         {
384             // Transmitter has to be stopped by triggering the STOPTX task to achieve
385             // the lowest possible level of the UARTE power consumption.
386             nrfy_uarte_stop(p_instance->p_reg, NULL);
387         }
388         p_cb->tx_buffer_length = 0;
389     }
390     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
391     return err_code;
392 }
393 
nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)394 bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)
395 {
396     return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
397 }
398 
nrfx_uarte_rx(nrfx_uarte_t const * p_instance,uint8_t * p_data,size_t length)399 nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
400                          uint8_t *            p_data,
401                          size_t               length)
402 {
403     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
404 
405     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
406     NRFX_ASSERT(p_data);
407     NRFX_ASSERT(length > 0);
408     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
409 
410     nrfx_err_t err_code = NRFX_SUCCESS;
411 
412     // EasyDMA requires that transfer buffers are placed in DataRAM,
413     // signal error if the are not.
414     if (!nrf_dma_accessible_check(p_instance->p_reg, p_data))
415     {
416         err_code = NRFX_ERROR_INVALID_ADDR;
417         NRFX_LOG_WARNING("Function: %s, error code: %s.",
418                          __func__,
419                          NRFX_LOG_ERROR_STRING_GET(err_code));
420         return err_code;
421     }
422 
423     bool second_buffer = false;
424 
425     if (p_cb->handler)
426     {
427         nrfy_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
428                                                   NRF_UARTE_INT_ENDRX_MASK);
429     }
430     if (p_cb->rx_buffer_length != 0)
431     {
432         if (p_cb->rx_secondary_buffer_length != 0)
433         {
434             if (p_cb->handler)
435             {
436                 nrfy_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
437                                                          NRF_UARTE_INT_ENDRX_MASK);
438             }
439             err_code = NRFX_ERROR_BUSY;
440             NRFX_LOG_WARNING("Function: %s, error code: %s.",
441                              __func__,
442                              NRFX_LOG_ERROR_STRING_GET(err_code));
443             return err_code;
444         }
445         second_buffer = true;
446     }
447 
448     if (!second_buffer)
449     {
450         p_cb->rx_buffer_length = length;
451         p_cb->p_rx_buffer      = p_data;
452         p_cb->rx_secondary_buffer_length = 0;
453     }
454     else
455     {
456         p_cb->p_rx_secondary_buffer = p_data;
457         p_cb->rx_secondary_buffer_length = length;
458     }
459 
460     NRFX_LOG_INFO("Transfer rx_len: %d.", length);
461 
462     nrfy_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
463     nrfy_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
464     nrfy_uarte_rx_buffer_set(p_instance->p_reg, p_data, length);
465     uint32_t evt_mask = 0;
466     if (second_buffer)
467     {
468         nrfy_uarte_shorts_enable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
469     }
470     else
471     {
472         nrfy_uarte_xfer_desc_t xfer_desc = {
473             .p_buffer = p_cb->p_rx_buffer,
474             .length   = p_cb->rx_buffer_length
475         };
476 
477         evt_mask = nrfy_uarte_rx_start(p_instance->p_reg, !p_cb->handler ? &xfer_desc : NULL);
478     }
479 
480     if (p_cb->handler == NULL)
481     {
482         p_cb->rx_buffer_length = 0;
483 
484         if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ERROR))
485         {
486             err_code = NRFX_ERROR_INTERNAL;
487         }
488 
489         if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_RXTO))
490         {
491             err_code = NRFX_ERROR_FORBIDDEN;
492         }
493     }
494     else
495     {
496         p_cb->rx_aborted = false;
497         nrfy_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
498                                                  NRF_UARTE_INT_ENDRX_MASK);
499     }
500     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
501     return err_code;
502 }
503 
nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance,size_t * p_rx_amount)504 nrfx_err_t nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance, size_t * p_rx_amount)
505 {
506     (void)p_rx_amount;
507 
508     return nrfy_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX) ?
509             NRFX_SUCCESS : NRFX_ERROR_BUSY;
510 }
511 
nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)512 uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)
513 {
514     nrfy_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
515     return nrfy_uarte_errorsrc_get_and_clear(p_instance->p_reg);
516 }
517 
rx_done_event(uarte_control_block_t * p_cb,size_t bytes,uint8_t * p_data)518 static void rx_done_event(uarte_control_block_t * p_cb,
519                           size_t                  bytes,
520                           uint8_t *               p_data)
521 {
522     nrfx_uarte_event_t event;
523     event.type             = NRFX_UARTE_EVT_RX_DONE;
524     event.data.rx.bytes  = bytes;
525     event.data.rx.p_data = p_data;
526 
527     p_cb->handler(&event, p_cb->p_context);
528 }
529 
tx_done_event(uarte_control_block_t * p_cb,size_t bytes)530 static void tx_done_event(uarte_control_block_t * p_cb,
531                           size_t                  bytes)
532 {
533     nrfx_uarte_event_t event;
534     event.type             = NRFX_UARTE_EVT_TX_DONE;
535     event.data.tx.bytes  = bytes;
536     event.data.tx.p_data = (uint8_t *)p_cb->p_tx_buffer;
537 
538     p_cb->tx_buffer_length = 0;
539     p_cb->handler(&event, p_cb->p_context);
540 }
541 
nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance,bool sync)542 nrfx_err_t nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance, bool sync)
543 {
544     (void)sync;
545     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
546     nrfy_uarte_tx_abort(p_instance->p_reg, !p_cb->handler ? true : false);
547     NRFX_LOG_INFO("TX transaction aborted.");
548 
549     return NRFX_SUCCESS;
550 }
551 
nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance,bool disable_all,bool sync)552 nrfx_err_t nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance, bool disable_all, bool sync)
553 {
554     (void)disable_all;
555     (void)sync;
556     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
557 
558     // Short between ENDRX event and STARTRX task must be disabled before
559     // aborting transmission.
560     if (p_cb->rx_secondary_buffer_length != 0)
561     {
562         nrfy_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
563     }
564     p_cb->rx_aborted = true;
565     nrfy_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
566     NRFX_LOG_INFO("RX transaction aborted.");
567 
568     return NRFX_SUCCESS;
569 }
570 
irq_handler(NRF_UARTE_Type * p_reg,uarte_control_block_t * p_cb)571 static void irq_handler(NRF_UARTE_Type * p_reg, uarte_control_block_t * p_cb)
572 {
573     nrfy_uarte_xfer_desc_t xfer_desc = {
574         .p_buffer = p_cb->p_rx_buffer,
575         .length   = p_cb->rx_buffer_length
576     };
577     uint32_t evt_mask = nrfy_uarte_events_process(p_reg,
578                                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ERROR) |
579                                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDRX) |
580                                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDTX) |
581                                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_RXTO)  |
582                                             NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_TXSTOPPED),
583                                             &xfer_desc);
584 
585     if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ERROR))
586     {
587         nrfx_uarte_event_t event;
588         event.type                   = NRFX_UARTE_EVT_ERROR;
589         event.data.error.error_mask  = nrfy_uarte_errorsrc_get_and_clear(p_reg);
590         event.data.error.rx.bytes  = nrfy_uarte_rx_amount_get(p_reg);
591         event.data.error.rx.p_data = p_cb->p_rx_buffer;
592 
593         // Abort transfer.
594         p_cb->rx_buffer_length = 0;
595         p_cb->rx_secondary_buffer_length = 0;
596 
597         p_cb->handler(&event, p_cb->p_context);
598     }
599     else if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDRX))
600     {
601         // Aborted transfers are handled in RXTO event processing.
602         if (!p_cb->rx_aborted)
603         {
604             size_t amount = p_cb->rx_buffer_length;
605             if (p_cb->rx_secondary_buffer_length != 0)
606             {
607                 uint8_t * p_data = p_cb->p_rx_buffer;
608                 nrfy_uarte_shorts_disable(p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
609                 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
610                 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
611                 p_cb->rx_secondary_buffer_length = 0;
612                 rx_done_event(p_cb, amount, p_data);
613             }
614             else
615             {
616                 p_cb->rx_buffer_length = 0;
617                 rx_done_event(p_cb, amount, p_cb->p_rx_buffer);
618             }
619         }
620     }
621 
622     if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_RXTO))
623     {
624         if (p_cb->rx_buffer_length != 0)
625         {
626             p_cb->rx_buffer_length = 0;
627             // In case of using double-buffered reception both variables storing buffer length
628             // have to be cleared to prevent incorrect behaviour of the driver.
629             p_cb->rx_secondary_buffer_length = 0;
630             rx_done_event(p_cb, nrfy_uarte_rx_amount_get(p_reg), p_cb->p_rx_buffer);
631         }
632     }
633 
634     if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_ENDTX))
635     {
636         // Transmitter has to be stopped by triggering STOPTX task to achieve
637         // the lowest possible level of the UARTE power consumption.
638         nrfy_uarte_task_trigger(p_reg, NRF_UARTE_TASK_STOPTX);
639 
640         if (p_cb->tx_buffer_length != 0)
641         {
642             tx_done_event(p_cb, nrfy_uarte_tx_amount_get(p_reg));
643         }
644     }
645 
646     if (evt_mask & NRFY_EVENT_TO_INT_BITMASK(NRF_UARTE_EVENT_TXSTOPPED))
647     {
648         if (p_cb->tx_buffer_length != 0)
649         {
650             tx_done_event(p_cb, nrfy_uarte_tx_amount_get(p_reg));
651         }
652     }
653 }
654 
655 NRFX_INSTANCE_IRQ_HANDLERS(UARTE, uarte)
656 
657 #endif // NRFX_CHECK(NRFX_UARTE_ENABLED)
658