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_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     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->parity, p_config->hwfc);
87     nrf_uart_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
88     if (p_config->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     while (p_cb->tx_counter < p_cb->tx_buffer_length)
246     {
247         // Wait until the transmitter is ready to accept a new byte.
248         // Exit immediately if the transfer has been aborted.
249         while (!nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
250         {
251             if (p_cb->tx_abort)
252             {
253                 return false;
254             }
255         }
256 
257         tx_byte(p_uart, p_cb);
258     }
259 
260     return true;
261 }
262 
nrfx_uart_tx(nrfx_uart_t const * p_instance,uint8_t const * p_data,size_t length)263 nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
264                         uint8_t const *     p_data,
265                         size_t              length)
266 {
267     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
268     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
269     NRFX_ASSERT(p_data);
270     NRFX_ASSERT(length > 0);
271 
272     nrfx_err_t err_code;
273 
274     if (nrfx_uart_tx_in_progress(p_instance))
275     {
276         err_code = NRFX_ERROR_BUSY;
277         NRFX_LOG_WARNING("Function: %s, error code: %s.",
278                          __func__,
279                          NRFX_LOG_ERROR_STRING_GET(err_code));
280         return err_code;
281     }
282     p_cb->tx_buffer_length = length;
283     p_cb->p_tx_buffer      = p_data;
284     p_cb->tx_counter       = 0;
285     p_cb->tx_abort         = false;
286 
287     NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
288     NRFX_LOG_DEBUG("Tx data:");
289     NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
290                            p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
291 
292     err_code = NRFX_SUCCESS;
293 
294     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
295     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX);
296 
297     tx_byte(p_instance->p_reg, p_cb);
298 
299     if (p_cb->handler == NULL)
300     {
301         if (!tx_blocking(p_instance->p_reg, p_cb))
302         {
303             // The transfer has been aborted.
304             err_code = NRFX_ERROR_FORBIDDEN;
305         }
306         else
307         {
308             // Wait until the last byte is completely transmitted.
309             while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY))
310             {}
311             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
312         }
313         p_cb->tx_buffer_length = 0;
314     }
315 
316     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
317     return err_code;
318 }
319 
nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)320 bool nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)
321 {
322     return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
323 }
324 
rx_enable(nrfx_uart_t const * p_instance)325 static void rx_enable(nrfx_uart_t const * p_instance)
326 {
327     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
328     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
329     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
330 }
331 
rx_byte(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)332 static void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
333 {
334     if (!p_cb->rx_buffer_length)
335     {
336         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
337         // Byte received when buffer is not set - data lost.
338         (void) nrf_uart_rxd_get(p_uart);
339         return;
340     }
341     nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
342     p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart);
343     p_cb->rx_counter++;
344 }
345 
nrfx_uart_rx(nrfx_uart_t const * p_instance,uint8_t * p_data,size_t length)346 nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
347                         uint8_t *           p_data,
348                         size_t              length)
349 {
350     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
351 
352     NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
353     NRFX_ASSERT(p_data);
354     NRFX_ASSERT(length > 0);
355 
356     nrfx_err_t err_code;
357 
358     bool second_buffer = false;
359 
360     if (p_cb->handler)
361     {
362         nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
363                                                 NRF_UART_INT_MASK_ERROR);
364     }
365     if (p_cb->rx_buffer_length != 0)
366     {
367         if (p_cb->rx_secondary_buffer_length != 0)
368         {
369             if (p_cb->handler)
370             {
371                 nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
372                                                        NRF_UART_INT_MASK_ERROR);
373             }
374             err_code = NRFX_ERROR_BUSY;
375             NRFX_LOG_WARNING("Function: %s, error code: %s.",
376                              __func__,
377                              NRFX_LOG_ERROR_STRING_GET(err_code));
378             return err_code;
379         }
380         second_buffer = true;
381     }
382 
383     if (!second_buffer)
384     {
385         p_cb->rx_buffer_length = length;
386         p_cb->p_rx_buffer      = p_data;
387         p_cb->rx_counter       = 0;
388         p_cb->rx_secondary_buffer_length = 0;
389     }
390     else
391     {
392         p_cb->p_rx_secondary_buffer = p_data;
393         p_cb->rx_secondary_buffer_length = length;
394     }
395 
396     NRFX_LOG_INFO("Transfer rx_len: %d.", length);
397 
398     if ((!p_cb->rx_enabled) && (!second_buffer))
399     {
400         rx_enable(p_instance);
401     }
402 
403     if (p_cb->handler == NULL)
404     {
405         nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);
406 
407         bool rxrdy;
408         bool rxto;
409         bool error;
410         do
411         {
412             do
413             {
414                 error = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_ERROR);
415                 rxrdy = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
416                 rxto  = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXTO);
417             } while ((!rxrdy) && (!rxto) && (!error));
418 
419             if (error || rxto)
420             {
421                 break;
422             }
423             rx_byte(p_instance->p_reg, p_cb);
424         } while (p_cb->rx_buffer_length > p_cb->rx_counter);
425 
426         p_cb->rx_buffer_length = 0;
427         if (error)
428         {
429             err_code = NRFX_ERROR_INTERNAL;
430             NRFX_LOG_WARNING("Function: %s, error code: %s.",
431                              __func__,
432                              NRFX_LOG_ERROR_STRING_GET(err_code));
433             return err_code;
434         }
435 
436         if (rxto)
437         {
438             err_code = NRFX_ERROR_FORBIDDEN;
439             NRFX_LOG_WARNING("Function: %s, error code: %s.",
440                              __func__,
441                              NRFX_LOG_ERROR_STRING_GET(err_code));
442             return err_code;
443         }
444 
445         if (p_cb->rx_enabled)
446         {
447             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
448         }
449         else
450         {
451             // Skip stopping RX if driver is forced to be enabled.
452             nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
453         }
454     }
455     else
456     {
457         nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
458                                                NRF_UART_INT_MASK_ERROR);
459     }
460     err_code = NRFX_SUCCESS;
461     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
462     return err_code;
463 }
464 
nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)465 bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)
466 {
467     return nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
468 }
469 
nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)470 void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)
471 {
472     if (!m_cb[p_instance->drv_inst_idx].rx_enabled)
473     {
474         rx_enable(p_instance);
475         m_cb[p_instance->drv_inst_idx].rx_enabled = true;
476     }
477 }
478 
nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)479 void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)
480 {
481     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
482     m_cb[p_instance->drv_inst_idx].rx_enabled = false;
483 }
484 
nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)485 uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)
486 {
487     nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
488     return nrf_uart_errorsrc_get_and_clear(p_instance->p_reg);
489 }
490 
rx_done_event(uart_control_block_t * p_cb,size_t bytes,uint8_t * p_data)491 static void rx_done_event(uart_control_block_t * p_cb,
492                           size_t                 bytes,
493                           uint8_t *              p_data)
494 {
495     nrfx_uart_event_t event;
496 
497     event.type             = NRFX_UART_EVT_RX_DONE;
498     event.data.rxtx.bytes  = bytes;
499     event.data.rxtx.p_data = p_data;
500 
501     p_cb->handler(&event, p_cb->p_context);
502 }
503 
tx_done_event(uart_control_block_t * p_cb,size_t bytes)504 static void tx_done_event(uart_control_block_t * p_cb,
505                           size_t                 bytes)
506 {
507     nrfx_uart_event_t event;
508 
509     event.type             = NRFX_UART_EVT_TX_DONE;
510     event.data.rxtx.bytes  = bytes;
511     event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
512 
513     p_cb->tx_buffer_length = 0;
514 
515     p_cb->handler(&event, p_cb->p_context);
516 }
517 
nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)518 void nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)
519 {
520     uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
521 
522     p_cb->tx_abort = true;
523     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
524     if (p_cb->handler)
525     {
526         tx_done_event(p_cb, p_cb->tx_counter);
527     }
528 
529     NRFX_LOG_INFO("TX transaction aborted.");
530 }
531 
nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)532 void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)
533 {
534     nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
535                                             NRF_UART_INT_MASK_ERROR);
536     nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
537 
538     NRFX_LOG_INFO("RX transaction aborted.");
539 }
540 
uart_irq_handler(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)541 static void uart_irq_handler(NRF_UART_Type *        p_uart,
542                              uart_control_block_t * p_cb)
543 {
544     if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) &&
545         nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR))
546     {
547         nrfx_uart_event_t event;
548         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR);
549         NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR));
550         nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
551                                      NRF_UART_INT_MASK_ERROR);
552         if (!p_cb->rx_enabled)
553         {
554             nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
555         }
556         event.type                   = NRFX_UART_EVT_ERROR;
557         event.data.error.error_mask  = nrf_uart_errorsrc_get_and_clear(p_uart);
558         event.data.error.rxtx.bytes  = p_cb->rx_buffer_length;
559         event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
560 
561         // Abort transfer.
562         p_cb->rx_buffer_length = 0;
563         p_cb->rx_secondary_buffer_length = 0;
564 
565         p_cb->handler(&event,p_cb->p_context);
566     }
567     else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) &&
568              nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY))
569     {
570         rx_byte(p_uart, p_cb);
571         if (p_cb->rx_buffer_length == p_cb->rx_counter)
572         {
573             if (p_cb->rx_secondary_buffer_length)
574             {
575                 uint8_t * p_data     = p_cb->p_rx_buffer;
576                 size_t    rx_counter = p_cb->rx_counter;
577 
578                 // Switch to secondary buffer.
579                 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
580                 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
581                 p_cb->rx_secondary_buffer_length = 0;
582                 p_cb->rx_counter = 0;
583                 rx_done_event(p_cb, rx_counter, p_data);
584             }
585             else
586             {
587                 if (!p_cb->rx_enabled)
588                 {
589                     nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
590                 }
591                 nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
592                                              NRF_UART_INT_MASK_ERROR);
593                 p_cb->rx_buffer_length = 0;
594                 rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
595             }
596         }
597     }
598 
599     if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
600     {
601         if (p_cb->tx_counter < p_cb->tx_buffer_length &&
602             !p_cb->tx_abort)
603         {
604             tx_byte(p_uart, p_cb);
605         }
606         else
607         {
608             nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
609             if (p_cb->tx_buffer_length)
610             {
611                 tx_done_event(p_cb, p_cb->tx_buffer_length);
612             }
613         }
614     }
615 
616     if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO))
617     {
618         nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO);
619 
620         // RXTO event may be triggered as a result of abort call. In th
621         if (p_cb->rx_enabled)
622         {
623             nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX);
624         }
625         if (p_cb->rx_buffer_length)
626         {
627             p_cb->rx_buffer_length = 0;
628             rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
629         }
630     }
631 }
632 
633 #if NRFX_CHECK(NRFX_UART0_ENABLED)
nrfx_uart_0_irq_handler(void)634 void nrfx_uart_0_irq_handler(void)
635 {
636     uart_irq_handler(NRF_UART0, &m_cb[NRFX_UART0_INST_IDX]);
637 }
638 #endif
639 
640 #endif // NRFX_CHECK(NRFX_UART_ENABLED)
641