1 /*
2  * Copyright (c) 2015 - 2020, 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_UART_ENABLED)
35 
36 #if !NRFX_CHECK(NRFX_UART0_ENABLED)
37 #error "No enabled UART instances. Check <nrfx_config.h>."
38 #endif
39 
40 #include <nrfx_uart.h>
41 #include "prs/nrfx_prs.h"
42 #include <hal/nrf_gpio.h>
43 
44 #define NRFX_LOG_MODULE UART
45 #include <nrfx_log.h>
46 
47 #define EVT_TO_STR(event) \
48     (event == NRF_UART_EVENT_ERROR ? "NRF_UART_EVENT_ERROR" : \
49                                      "UNKNOWN EVENT")
50 
51 
52 #define TX_COUNTER_ABORT_REQ_VALUE  UINT32_MAX
53 
54 typedef struct
55 {
56     void                    * p_context;
57     nrfx_uart_event_handler_t handler;
58     uint8_t           const * p_tx_buffer;
59     uint8_t                 * p_rx_buffer;
60     uint8_t                 * p_rx_secondary_buffer;
61     volatile size_t           tx_buffer_length;
62     size_t                    rx_buffer_length;
63     size_t                    rx_secondary_buffer_length;
64     volatile size_t           tx_counter;
65     volatile size_t           rx_counter;
66     volatile bool             tx_abort;
67     bool                      rx_enabled;
68     nrfx_drv_state_t          state;
69 } uart_control_block_t;
70 static uart_control_block_t m_cb[NRFX_UART_ENABLED_COUNT];
71 
apply_config(nrfx_uart_t const * p_instance,nrfx_uart_config_t const * p_config)72 static void apply_config(nrfx_uart_t        const * p_instance,
73                          nrfx_uart_config_t const * p_config)
74 {
75     if (p_config->pseltxd != NRF_UART_PSEL_DISCONNECTED)
76     {
77         nrf_gpio_pin_set(p_config->pseltxd);
78         nrf_gpio_cfg_output(p_config->pseltxd);
79     }
80     if (p_config->pselrxd != NRF_UART_PSEL_DISCONNECTED)
81     {
82         nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL);
83     }
84 
85     nrf_uart_baudrate_set(p_instance->p_reg, p_config->baudrate);
86     nrf_uart_configure(p_instance->p_reg, &p_config->hal_cfg);
87     nrf_uart_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
88     if (p_config->hal_cfg.hwfc == NRF_UART_HWFC_ENABLED)
89     {
90         if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED)
91         {
92             nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL);
93         }
94         if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED)
95         {
96             nrf_gpio_pin_set(p_config->pselrts);
97             nrf_gpio_cfg_output(p_config->pselrts);
98         }
99         nrf_uart_hwfc_pins_set(p_instance->p_reg, p_config->pselrts, p_config->pselcts);
100     }
101 }
102 
interrupts_enable(nrfx_uart_t const * p_instance,uint8_t interrupt_priority)103 static void interrupts_enable(nrfx_uart_t const * p_instance,
104                               uint8_t             interrupt_priority)
105 {
106     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
107     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);
108     nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_TXDRDY |
109                                            NRF_UART_INT_MASK_RXTO);
110     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg),
111                           interrupt_priority);
112     NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
113 }
114 
interrupts_disable(nrfx_uart_t const * p_instance)115 static void interrupts_disable(nrfx_uart_t const * p_instance)
116 {
117     nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
118                                             NRF_UART_INT_MASK_TXDRDY |
119                                             NRF_UART_INT_MASK_ERROR  |
120                                             NRF_UART_INT_MASK_RXTO);
121     NRFX_IRQ_DISABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
122 }
123 
pins_to_default(nrfx_uart_t const * p_instance)124 static void pins_to_default(nrfx_uart_t const * p_instance)
125 {
126     /* Reset pins to default states */
127     uint32_t txd;
128     uint32_t rxd;
129     uint32_t rts;
130     uint32_t cts;
131 
132     txd = nrf_uart_tx_pin_get(p_instance->p_reg);
133     rxd = nrf_uart_rx_pin_get(p_instance->p_reg);
134     rts = nrf_uart_rts_pin_get(p_instance->p_reg);
135     cts = nrf_uart_cts_pin_get(p_instance->p_reg);
136     nrf_uart_txrx_pins_disconnect(p_instance->p_reg);
137     nrf_uart_hwfc_pins_disconnect(p_instance->p_reg);
138 
139     if (txd != NRF_UART_PSEL_DISCONNECTED)
140     {
141         nrf_gpio_cfg_default(txd);
142     }
143     if (rxd != NRF_UART_PSEL_DISCONNECTED)
144     {
145         nrf_gpio_cfg_default(rxd);
146     }
147     if (cts != NRF_UART_PSEL_DISCONNECTED)
148     {
149         nrf_gpio_cfg_default(cts);
150     }
151     if (rts != NRF_UART_PSEL_DISCONNECTED)
152     {
153         nrf_gpio_cfg_default(rts);
154     }
155 }
156 
nrfx_uart_init(nrfx_uart_t const * p_instance,nrfx_uart_config_t const * p_config,nrfx_uart_event_handler_t event_handler)157 nrfx_err_t nrfx_uart_init(nrfx_uart_t const *        p_instance,
158                           nrfx_uart_config_t const * p_config,
159                           nrfx_uart_event_handler_t  event_handler)
160 {
161     NRFX_ASSERT(p_config);
162     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
163     nrfx_err_t err_code = NRFX_SUCCESS;
164 
165     if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
166     {
167         err_code = NRFX_ERROR_INVALID_STATE;
168         NRFX_LOG_WARNING("Function: %s, error code: %s.",
169                          __func__,
170                          NRFX_LOG_ERROR_STRING_GET(err_code));
171         return err_code;
172     }
173 
174 #if NRFX_CHECK(NRFX_PRS_ENABLED)
175     static nrfx_irq_handler_t const irq_handlers[NRFX_UART_ENABLED_COUNT] = {
176         #if NRFX_CHECK(NRFX_UART0_ENABLED)
177         nrfx_uart_0_irq_handler,
178         #endif
179     };
180     if (nrfx_prs_acquire(p_instance->p_reg,
181             irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
182     {
183         err_code = NRFX_ERROR_BUSY;
184         NRFX_LOG_WARNING("Function: %s, error code: %s.",
185                          __func__,
186                          NRFX_LOG_ERROR_STRING_GET(err_code));
187         return err_code;
188     }
189 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
190 
191     apply_config(p_instance, p_config);
192 
193     p_cb->handler   = event_handler;
194     p_cb->p_context = p_config->p_context;
195 
196     if (p_cb->handler)
197     {
198         interrupts_enable(p_instance, p_config->interrupt_priority);
199     }
200 
201     nrf_uart_enable(p_instance->p_reg);
202     p_cb->rx_buffer_length           = 0;
203     p_cb->rx_secondary_buffer_length = 0;
204     p_cb->rx_enabled                 = false;
205     p_cb->tx_buffer_length           = 0;
206     p_cb->state                      = NRFX_DRV_STATE_INITIALIZED;
207     NRFX_LOG_WARNING("Function: %s, error code: %s.",
208                      __func__,
209                      NRFX_LOG_ERROR_STRING_GET(err_code));
210     return err_code;
211 }
212 
nrfx_uart_uninit(nrfx_uart_t const * p_instance)213 void nrfx_uart_uninit(nrfx_uart_t const * p_instance)
214 {
215     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
216 
217     nrf_uart_disable(p_instance->p_reg);
218 
219     if (p_cb->handler)
220     {
221         interrupts_disable(p_instance);
222     }
223 
224     pins_to_default(p_instance);
225 
226 #if NRFX_CHECK(NRFX_PRS_ENABLED)
227     nrfx_prs_release(p_instance->p_reg);
228 #endif
229 
230     p_cb->state   = NRFX_DRV_STATE_UNINITIALIZED;
231     p_cb->handler = NULL;
232     NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
233 }
234 
tx_byte(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)235 static void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
236 {
237     nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
238     uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter];
239     p_cb->tx_counter++;
240     nrf_uart_txd_set(p_uart, txd);
241 }
242 
tx_blocking(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)243 static bool tx_blocking(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
244 {
245     // Use a local variable to avoid undefined order of accessing two volatile variables
246     // in one statement.
247     size_t const tx_buffer_length = p_cb->tx_buffer_length;
248     while (p_cb->tx_counter < tx_buffer_length)
249     {
250         // Wait until the transmitter is ready to accept a new byte.
251         // Exit immediately if the transfer has been aborted.
252         while (!nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
253         {
254             if (p_cb->tx_abort)
255             {
256                 return false;
257             }
258         }
259 
260         tx_byte(p_uart, p_cb);
261     }
262 
263     return true;
264 }
265 
nrfx_uart_tx(nrfx_uart_t const * p_instance,uint8_t const * p_data,size_t length)266 nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
267                         uint8_t const *     p_data,
268                         size_t              length)
269 {
270     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
271     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
272     NRFX_ASSERT(p_data);
273     NRFX_ASSERT(length > 0);
274 
275     nrfx_err_t err_code;
276 
277     if (nrfx_uart_tx_in_progress(p_instance))
278     {
279         err_code = NRFX_ERROR_BUSY;
280         NRFX_LOG_WARNING("Function: %s, error code: %s.",
281                          __func__,
282                          NRFX_LOG_ERROR_STRING_GET(err_code));
283         return err_code;
284     }
285     p_cb->tx_buffer_length = length;
286     p_cb->p_tx_buffer      = p_data;
287     p_cb->tx_counter       = 0;
288     p_cb->tx_abort         = false;
289 
290     NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
291     NRFX_LOG_DEBUG("Tx data:");
292     NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
293                            p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
294 
295     err_code = NRFX_SUCCESS;
296 
297     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
298     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX);
299 
300     tx_byte(p_instance->p_reg, p_cb);
301 
302     if (p_cb->handler == NULL)
303     {
304         if (!tx_blocking(p_instance->p_reg, p_cb))
305         {
306             // The transfer has been aborted.
307             err_code = NRFX_ERROR_FORBIDDEN;
308         }
309         else
310         {
311             // Wait until the last byte is completely transmitted.
312             while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY))
313             {}
314             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
315         }
316         p_cb->tx_buffer_length = 0;
317     }
318 
319     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
320     return err_code;
321 }
322 
nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)323 bool nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)
324 {
325     return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
326 }
327 
rx_enable(nrfx_uart_t const * p_instance)328 static void rx_enable(nrfx_uart_t const * p_instance)
329 {
330     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
331     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
332     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
333 }
334 
rx_byte(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)335 static void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
336 {
337     if (!p_cb->rx_buffer_length)
338     {
339         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
340         // Byte received when buffer is not set - data lost.
341         (void) nrf_uart_rxd_get(p_uart);
342         return;
343     }
344     nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
345     p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart);
346     p_cb->rx_counter++;
347 }
348 
nrfx_uart_rx(nrfx_uart_t const * p_instance,uint8_t * p_data,size_t length)349 nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
350                         uint8_t *           p_data,
351                         size_t              length)
352 {
353     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
354 
355     NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
356     NRFX_ASSERT(p_data);
357     NRFX_ASSERT(length > 0);
358 
359     nrfx_err_t err_code;
360 
361     bool second_buffer = false;
362 
363     if (p_cb->handler)
364     {
365         nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
366                                                 NRF_UART_INT_MASK_ERROR);
367     }
368     if (p_cb->rx_buffer_length != 0)
369     {
370         if (p_cb->rx_secondary_buffer_length != 0)
371         {
372             if (p_cb->handler)
373             {
374                 nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
375                                                        NRF_UART_INT_MASK_ERROR);
376             }
377             err_code = NRFX_ERROR_BUSY;
378             NRFX_LOG_WARNING("Function: %s, error code: %s.",
379                              __func__,
380                              NRFX_LOG_ERROR_STRING_GET(err_code));
381             return err_code;
382         }
383         second_buffer = true;
384     }
385 
386     if (!second_buffer)
387     {
388         p_cb->rx_buffer_length = length;
389         p_cb->p_rx_buffer      = p_data;
390         p_cb->rx_counter       = 0;
391         p_cb->rx_secondary_buffer_length = 0;
392     }
393     else
394     {
395         p_cb->p_rx_secondary_buffer = p_data;
396         p_cb->rx_secondary_buffer_length = length;
397     }
398 
399     NRFX_LOG_INFO("Transfer rx_len: %d.", length);
400 
401     if ((!p_cb->rx_enabled) && (!second_buffer))
402     {
403         rx_enable(p_instance);
404     }
405 
406     if (p_cb->handler == NULL)
407     {
408         nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);
409 
410         bool rxrdy;
411         bool rxto;
412         bool error;
413         do
414         {
415             do
416             {
417                 error = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_ERROR);
418                 rxrdy = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
419                 rxto  = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXTO);
420             } while ((!rxrdy) && (!rxto) && (!error));
421 
422             if (error || rxto)
423             {
424                 break;
425             }
426             rx_byte(p_instance->p_reg, p_cb);
427         } while (p_cb->rx_buffer_length > p_cb->rx_counter);
428 
429         p_cb->rx_buffer_length = 0;
430         if (error)
431         {
432             err_code = NRFX_ERROR_INTERNAL;
433             NRFX_LOG_WARNING("Function: %s, error code: %s.",
434                              __func__,
435                              NRFX_LOG_ERROR_STRING_GET(err_code));
436             return err_code;
437         }
438 
439         if (rxto)
440         {
441             err_code = NRFX_ERROR_FORBIDDEN;
442             NRFX_LOG_WARNING("Function: %s, error code: %s.",
443                              __func__,
444                              NRFX_LOG_ERROR_STRING_GET(err_code));
445             return err_code;
446         }
447 
448         if (p_cb->rx_enabled)
449         {
450             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
451         }
452         else
453         {
454             // Skip stopping RX if driver is forced to be enabled.
455             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
456         }
457     }
458     else
459     {
460         nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
461                                                NRF_UART_INT_MASK_ERROR);
462     }
463     err_code = NRFX_SUCCESS;
464     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
465     return err_code;
466 }
467 
nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)468 bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)
469 {
470     return nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
471 }
472 
nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)473 void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)
474 {
475     if (!m_cb[p_instance->drv_inst_idx].rx_enabled)
476     {
477         rx_enable(p_instance);
478         m_cb[p_instance->drv_inst_idx].rx_enabled = true;
479     }
480 }
481 
nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)482 void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)
483 {
484     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
485     m_cb[p_instance->drv_inst_idx].rx_enabled = false;
486 }
487 
nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)488 uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)
489 {
490     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
491     return nrf_uart_errorsrc_get_and_clear(p_instance->p_reg);
492 }
493 
rx_done_event(uart_control_block_t * p_cb,size_t bytes,uint8_t * p_data)494 static void rx_done_event(uart_control_block_t * p_cb,
495                           size_t                 bytes,
496                           uint8_t *              p_data)
497 {
498     nrfx_uart_event_t event;
499 
500     event.type             = NRFX_UART_EVT_RX_DONE;
501     event.data.rxtx.bytes  = bytes;
502     event.data.rxtx.p_data = p_data;
503 
504     p_cb->handler(&event, p_cb->p_context);
505 }
506 
tx_done_event(uart_control_block_t * p_cb,size_t bytes)507 static void tx_done_event(uart_control_block_t * p_cb,
508                           size_t                 bytes)
509 {
510     nrfx_uart_event_t event;
511 
512     event.type             = NRFX_UART_EVT_TX_DONE;
513     event.data.rxtx.bytes  = bytes;
514     event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
515 
516     p_cb->tx_buffer_length = 0;
517 
518     p_cb->handler(&event, p_cb->p_context);
519 }
520 
nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)521 void nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)
522 {
523     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
524 
525     p_cb->tx_abort = true;
526     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
527     if (p_cb->handler)
528     {
529         tx_done_event(p_cb, p_cb->tx_counter);
530     }
531 
532     NRFX_LOG_INFO("TX transaction aborted.");
533 }
534 
nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)535 void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)
536 {
537     nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
538                                             NRF_UART_INT_MASK_ERROR);
539     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
540 
541     NRFX_LOG_INFO("RX transaction aborted.");
542 }
543 
uart_irq_handler(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)544 static void uart_irq_handler(NRF_UART_Type *        p_uart,
545                              uart_control_block_t * p_cb)
546 {
547     if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) &&
548         nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR))
549     {
550         nrfx_uart_event_t event;
551         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR);
552         NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR));
553         nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
554                                      NRF_UART_INT_MASK_ERROR);
555         if (!p_cb->rx_enabled)
556         {
557             nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
558         }
559         event.type                   = NRFX_UART_EVT_ERROR;
560         event.data.error.error_mask  = nrf_uart_errorsrc_get_and_clear(p_uart);
561         event.data.error.rxtx.bytes  = p_cb->rx_buffer_length;
562         event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
563 
564         // Abort transfer.
565         p_cb->rx_buffer_length = 0;
566         p_cb->rx_secondary_buffer_length = 0;
567 
568         p_cb->handler(&event,p_cb->p_context);
569     }
570     else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) &&
571              nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY))
572     {
573         rx_byte(p_uart, p_cb);
574         if (p_cb->rx_buffer_length == p_cb->rx_counter)
575         {
576             if (p_cb->rx_secondary_buffer_length)
577             {
578                 uint8_t * p_data     = p_cb->p_rx_buffer;
579                 size_t    rx_counter = p_cb->rx_counter;
580 
581                 // Switch to secondary buffer.
582                 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
583                 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
584                 p_cb->rx_secondary_buffer_length = 0;
585                 p_cb->rx_counter = 0;
586                 rx_done_event(p_cb, rx_counter, p_data);
587             }
588             else
589             {
590                 if (!p_cb->rx_enabled)
591                 {
592                     nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
593                 }
594                 nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
595                                              NRF_UART_INT_MASK_ERROR);
596                 p_cb->rx_buffer_length = 0;
597                 rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
598             }
599         }
600     }
601 
602     if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
603     {
604         // Use a local variable to avoid undefined order of accessing two volatile variables
605         // in one statement.
606         size_t const tx_buffer_length = p_cb->tx_buffer_length;
607         if (p_cb->tx_counter < tx_buffer_length && !p_cb->tx_abort)
608         {
609             tx_byte(p_uart, p_cb);
610         }
611         else
612         {
613             nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
614             if (p_cb->tx_buffer_length)
615             {
616                 tx_done_event(p_cb, p_cb->tx_buffer_length);
617             }
618         }
619     }
620 
621     if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO))
622     {
623         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO);
624 
625         // RXTO event may be triggered as a result of abort call. In th
626         if (p_cb->rx_enabled)
627         {
628             nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX);
629         }
630         if (p_cb->rx_buffer_length)
631         {
632             p_cb->rx_buffer_length = 0;
633             rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
634         }
635     }
636 }
637 
638 #if NRFX_CHECK(NRFX_UART0_ENABLED)
nrfx_uart_0_irq_handler(void)639 void nrfx_uart_0_irq_handler(void)
640 {
641     uart_irq_handler(NRF_UART0, &m_cb[NRFX_UART0_INST_IDX]);
642 }
643 #endif
644 
645 #endif // NRFX_CHECK(NRFX_UART_ENABLED)
646