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_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 typedef struct
89 {
90     void                     * p_context;
91     nrfx_uarte_event_handler_t handler;
92     uint8_t            const * p_tx_buffer;
93     uint8_t                  * p_rx_buffer;
94     uint8_t                  * p_rx_secondary_buffer;
95     volatile size_t            tx_buffer_length;
96     size_t                     rx_buffer_length;
97     size_t                     rx_secondary_buffer_length;
98     nrfx_drv_state_t           state;
99     bool                       rx_aborted;
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->hal_cfg);
118     nrf_uarte_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
119     if (p_config->hal_cfg.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_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
142     nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
143                                             NRF_UARTE_INT_ENDTX_MASK |
144                                             NRF_UARTE_INT_ERROR_MASK |
145                                             NRF_UARTE_INT_RXTO_MASK  |
146                                             NRF_UARTE_INT_TXSTOPPED_MASK);
147     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg),
148                           interrupt_priority);
149     NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
150 }
151 
interrupts_disable(nrfx_uarte_t const * p_instance)152 static void interrupts_disable(nrfx_uarte_t const * p_instance)
153 {
154     nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
155                                              NRF_UARTE_INT_ENDTX_MASK |
156                                              NRF_UARTE_INT_ERROR_MASK |
157                                              NRF_UARTE_INT_RXTO_MASK  |
158                                              NRF_UARTE_INT_TXSTOPPED_MASK);
159     NRFX_IRQ_DISABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
160 }
161 
pins_to_default(nrfx_uarte_t const * p_instance)162 static void pins_to_default(nrfx_uarte_t const * p_instance)
163 {
164     /* Reset pins to default states */
165     uint32_t txd;
166     uint32_t rxd;
167     uint32_t rts;
168     uint32_t cts;
169 
170     txd = nrf_uarte_tx_pin_get(p_instance->p_reg);
171     rxd = nrf_uarte_rx_pin_get(p_instance->p_reg);
172     rts = nrf_uarte_rts_pin_get(p_instance->p_reg);
173     cts = nrf_uarte_cts_pin_get(p_instance->p_reg);
174     nrf_uarte_txrx_pins_disconnect(p_instance->p_reg);
175     nrf_uarte_hwfc_pins_disconnect(p_instance->p_reg);
176 
177     if (txd != NRF_UARTE_PSEL_DISCONNECTED)
178     {
179         nrf_gpio_cfg_default(txd);
180     }
181     if (rxd != NRF_UARTE_PSEL_DISCONNECTED)
182     {
183         nrf_gpio_cfg_default(rxd);
184     }
185     if (cts != NRF_UARTE_PSEL_DISCONNECTED)
186     {
187         nrf_gpio_cfg_default(cts);
188     }
189     if (rts != NRF_UARTE_PSEL_DISCONNECTED)
190     {
191         nrf_gpio_cfg_default(rts);
192     }
193 }
194 
apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance)195 static void apply_workaround_for_enable_anomaly(nrfx_uarte_t const * p_instance)
196 {
197 #if defined(NRF5340_XXAA_APPLICATION) || defined(NRF5340_XXAA_NETWORK) || defined(NRF9160_XXAA)
198     // Apply workaround for anomalies:
199     // - nRF9160 - anomaly 23
200     // - nRF5340 - anomaly 44
201     volatile uint32_t const * rxenable_reg =
202         (volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x564);
203     volatile uint32_t const * txenable_reg =
204         (volatile uint32_t *)(((uint32_t)p_instance->p_reg) + 0x568);
205 
206     if (*txenable_reg == 1)
207     {
208         nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
209     }
210 
211     if (*rxenable_reg == 1)
212     {
213         nrf_uarte_enable(p_instance->p_reg);
214         nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
215 
216         bool workaround_succeded;
217         // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
218         // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
219         // (resulting in 12 bits per data byte sent), this may take up to 40 ms.
220         NRFX_WAIT_FOR(*rxenable_reg == 0, 40000, 1, workaround_succeded);
221         if (!workaround_succeded)
222         {
223             NRFX_LOG_ERROR("Failed to apply workaround for instance with base address: %p.",
224                            (void *)p_instance->p_reg);
225         }
226 
227         (void)nrf_uarte_errorsrc_get_and_clear(p_instance->p_reg);
228         nrf_uarte_disable(p_instance->p_reg);
229     }
230 #else
231     (void)(p_instance);
232 #endif // defined(NRF5340_XXAA_APPLICATION) || defined(NRF5340_XXAA_NETWORK) || defined(NRF9160_XXAA)
233 }
234 
nrfx_uarte_init(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config,nrfx_uarte_event_handler_t event_handler)235 nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const *        p_instance,
236                            nrfx_uarte_config_t const * p_config,
237                            nrfx_uarte_event_handler_t  event_handler)
238 {
239     NRFX_ASSERT(p_config);
240     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
241     nrfx_err_t err_code = NRFX_SUCCESS;
242 
243     if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
244     {
245         err_code = NRFX_ERROR_INVALID_STATE;
246         NRFX_LOG_WARNING("Function: %s, error code: %s.",
247                          __func__,
248                          NRFX_LOG_ERROR_STRING_GET(err_code));
249         return err_code;
250     }
251 
252 #if NRFX_CHECK(NRFX_PRS_ENABLED)
253     static nrfx_irq_handler_t const irq_handlers[NRFX_UARTE_ENABLED_COUNT] = {
254         #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
255         nrfx_uarte_0_irq_handler,
256         #endif
257         #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
258         nrfx_uarte_1_irq_handler,
259         #endif
260         #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
261         nrfx_uarte_2_irq_handler,
262         #endif
263         #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
264         nrfx_uarte_3_irq_handler,
265         #endif
266     };
267     if (nrfx_prs_acquire(p_instance->p_reg,
268             irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
269     {
270         err_code = NRFX_ERROR_BUSY;
271         NRFX_LOG_WARNING("Function: %s, error code: %s.",
272                          __func__,
273                          NRFX_LOG_ERROR_STRING_GET(err_code));
274         return err_code;
275     }
276 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
277 
278     apply_config(p_instance, p_config);
279 
280     apply_workaround_for_enable_anomaly(p_instance);
281 
282     p_cb->handler   = event_handler;
283     p_cb->p_context = p_config->p_context;
284 
285     if (p_cb->handler)
286     {
287         interrupts_enable(p_instance, p_config->interrupt_priority);
288     }
289 
290     nrf_uarte_enable(p_instance->p_reg);
291     p_cb->rx_buffer_length           = 0;
292     p_cb->rx_secondary_buffer_length = 0;
293     p_cb->tx_buffer_length           = 0;
294     p_cb->state                      = NRFX_DRV_STATE_INITIALIZED;
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 
nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)301 void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
302 {
303     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
304     NRF_UARTE_Type * p_reg = p_instance->p_reg;
305 
306     if (p_cb->handler)
307     {
308         interrupts_disable(p_instance);
309     }
310     // Make sure all transfers are finished before UARTE is disabled
311     // to achieve the lowest power consumption.
312     nrf_uarte_shorts_disable(p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
313 
314     // Check if there is any ongoing reception.
315     if (p_cb->rx_buffer_length)
316     {
317         nrf_uarte_event_clear(p_reg, NRF_UARTE_EVENT_RXTO);
318         nrf_uarte_task_trigger(p_reg, NRF_UARTE_TASK_STOPRX);
319     }
320 
321     nrf_uarte_event_clear(p_reg, NRF_UARTE_EVENT_TXSTOPPED);
322     nrf_uarte_task_trigger(p_reg, NRF_UARTE_TASK_STOPTX);
323 
324     // Wait for TXSTOPPED event and for RXTO event, provided that there was ongoing reception.
325     bool stopped;
326 
327     // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
328     // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
329     // (resulting in 12 bits per data byte sent), this may take up to 40 ms.
330     NRFX_WAIT_FOR((nrf_uarte_event_check(p_reg, NRF_UARTE_EVENT_TXSTOPPED) &&
331                   (!p_cb->rx_buffer_length || nrf_uarte_event_check(p_reg, NRF_UARTE_EVENT_RXTO))),
332                   40000, 1, stopped);
333     if (!stopped)
334     {
335         NRFX_LOG_ERROR("Failed to stop instance with base address: %p.", (void *)p_instance->p_reg);
336     }
337 
338     nrf_uarte_disable(p_reg);
339     pins_to_default(p_instance);
340 
341 #if NRFX_CHECK(NRFX_PRS_ENABLED)
342     nrfx_prs_release(p_reg);
343 #endif
344 
345     p_cb->state   = NRFX_DRV_STATE_UNINITIALIZED;
346     p_cb->handler = NULL;
347     NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
348 }
349 
nrfx_uarte_tx(nrfx_uarte_t const * p_instance,uint8_t const * p_data,size_t length)350 nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
351                          uint8_t const *      p_data,
352                          size_t               length)
353 {
354     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
355     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
356     NRFX_ASSERT(p_data);
357     NRFX_ASSERT(length > 0);
358     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
359 
360     nrfx_err_t err_code;
361 
362     // EasyDMA requires that transfer buffers are placed in DataRAM,
363     // signal error if the are not.
364     if (!nrfx_is_in_ram(p_data))
365     {
366         err_code = NRFX_ERROR_INVALID_ADDR;
367         NRFX_LOG_WARNING("Function: %s, error code: %s.",
368                          __func__,
369                          NRFX_LOG_ERROR_STRING_GET(err_code));
370         return err_code;
371     }
372 
373     if (nrfx_uarte_tx_in_progress(p_instance))
374     {
375         err_code = NRFX_ERROR_BUSY;
376         NRFX_LOG_WARNING("Function: %s, error code: %s.",
377                          __func__,
378                          NRFX_LOG_ERROR_STRING_GET(err_code));
379         return err_code;
380     }
381     p_cb->tx_buffer_length = length;
382     p_cb->p_tx_buffer      = p_data;
383 
384     NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
385     NRFX_LOG_DEBUG("Tx data:");
386     NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
387                            p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
388 
389     err_code = NRFX_SUCCESS;
390 
391     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
392     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
393     nrf_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
394     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTTX);
395 
396     if (p_cb->handler == NULL)
397     {
398         bool endtx;
399         bool txstopped;
400         do
401         {
402             endtx     = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
403             txstopped = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
404         }
405         while ((!endtx) && (!txstopped));
406 
407         if (txstopped)
408         {
409             err_code = NRFX_ERROR_FORBIDDEN;
410         }
411         else
412         {
413             // Transmitter has to be stopped by triggering the STOPTX task to achieve
414             // the lowest possible level of the UARTE power consumption.
415             nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
416 
417             while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED))
418             {}
419         }
420         p_cb->tx_buffer_length = 0;
421     }
422 
423     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
424     return err_code;
425 }
426 
nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)427 bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)
428 {
429     return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
430 }
431 
nrfx_uarte_rx(nrfx_uarte_t const * p_instance,uint8_t * p_data,size_t length)432 nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
433                          uint8_t *            p_data,
434                          size_t               length)
435 {
436     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
437 
438     NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
439     NRFX_ASSERT(p_data);
440     NRFX_ASSERT(length > 0);
441     NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
442 
443     nrfx_err_t err_code;
444 
445     // EasyDMA requires that transfer buffers are placed in DataRAM,
446     // signal error if the are not.
447     if (!nrfx_is_in_ram(p_data))
448     {
449         err_code = NRFX_ERROR_INVALID_ADDR;
450         NRFX_LOG_WARNING("Function: %s, error code: %s.",
451                          __func__,
452                          NRFX_LOG_ERROR_STRING_GET(err_code));
453         return err_code;
454     }
455 
456     bool second_buffer = false;
457 
458     if (p_cb->handler)
459     {
460         nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
461                                                  NRF_UARTE_INT_ENDRX_MASK);
462     }
463     if (p_cb->rx_buffer_length != 0)
464     {
465         if (p_cb->rx_secondary_buffer_length != 0)
466         {
467             if (p_cb->handler)
468             {
469                 nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
470                                                         NRF_UARTE_INT_ENDRX_MASK);
471             }
472             err_code = NRFX_ERROR_BUSY;
473             NRFX_LOG_WARNING("Function: %s, error code: %s.",
474                              __func__,
475                              NRFX_LOG_ERROR_STRING_GET(err_code));
476             return err_code;
477         }
478         second_buffer = true;
479     }
480 
481     if (!second_buffer)
482     {
483         p_cb->rx_buffer_length = length;
484         p_cb->p_rx_buffer      = p_data;
485         p_cb->rx_secondary_buffer_length = 0;
486     }
487     else
488     {
489         p_cb->p_rx_secondary_buffer = p_data;
490         p_cb->rx_secondary_buffer_length = length;
491     }
492 
493     NRFX_LOG_INFO("Transfer rx_len: %d.", length);
494 
495     err_code = NRFX_SUCCESS;
496 
497     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
498     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
499     nrf_uarte_rx_buffer_set(p_instance->p_reg, p_data, length);
500     if (!second_buffer)
501     {
502         nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTRX);
503     }
504     else
505     {
506         nrf_uarte_shorts_enable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
507     }
508 
509     if (m_cb[p_instance->drv_inst_idx].handler == NULL)
510     {
511         bool endrx;
512         bool rxto;
513         bool error;
514         do {
515             endrx  = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
516             rxto   = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
517             error  = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
518         } while ((!endrx) && (!rxto) && (!error));
519 
520         m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0;
521 
522         if (error)
523         {
524             err_code = NRFX_ERROR_INTERNAL;
525         }
526 
527         if (rxto)
528         {
529             err_code = NRFX_ERROR_FORBIDDEN;
530         }
531     }
532     else
533     {
534         p_cb->rx_aborted = false;
535         nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
536                                                 NRF_UARTE_INT_ENDRX_MASK);
537     }
538     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
539     return err_code;
540 }
541 
nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)542 bool nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)
543 {
544     return nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
545 }
546 
nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)547 uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)
548 {
549     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
550     return nrf_uarte_errorsrc_get_and_clear(p_instance->p_reg);
551 }
552 
rx_done_event(uarte_control_block_t * p_cb,size_t bytes,uint8_t * p_data)553 static void rx_done_event(uarte_control_block_t * p_cb,
554                           size_t                  bytes,
555                           uint8_t *               p_data)
556 {
557     nrfx_uarte_event_t event;
558 
559     event.type             = NRFX_UARTE_EVT_RX_DONE;
560     event.data.rxtx.bytes  = bytes;
561     event.data.rxtx.p_data = p_data;
562 
563     p_cb->handler(&event, p_cb->p_context);
564 }
565 
tx_done_event(uarte_control_block_t * p_cb,size_t bytes)566 static void tx_done_event(uarte_control_block_t * p_cb,
567                           size_t                  bytes)
568 {
569     nrfx_uarte_event_t event;
570 
571     event.type             = NRFX_UARTE_EVT_TX_DONE;
572     event.data.rxtx.bytes  = bytes;
573     event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
574 
575     p_cb->tx_buffer_length = 0;
576 
577     p_cb->handler(&event, p_cb->p_context);
578 }
579 
nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)580 void nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)
581 {
582     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
583 
584     nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
585     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
586     if (p_cb->handler == NULL)
587     {
588         while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED))
589         {}
590     }
591     NRFX_LOG_INFO("TX transaction aborted.");
592 }
593 
nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)594 void nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)
595 {
596     uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
597 
598     // Short between ENDRX event and STARTRX task must be disabled before
599     // aborting transmission.
600     if (p_cb->rx_secondary_buffer_length != 0)
601     {
602         nrf_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
603     }
604     p_cb->rx_aborted = true;
605     nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
606     NRFX_LOG_INFO("RX transaction aborted.");
607 }
608 
uarte_irq_handler(NRF_UARTE_Type * p_uarte,uarte_control_block_t * p_cb)609 static void uarte_irq_handler(NRF_UARTE_Type *        p_uarte,
610                               uarte_control_block_t * p_cb)
611 {
612     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
613     {
614         nrfx_uarte_event_t event;
615 
616         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);
617 
618         event.type                   = NRFX_UARTE_EVT_ERROR;
619         event.data.error.error_mask  = nrf_uarte_errorsrc_get_and_clear(p_uarte);
620         event.data.error.rxtx.bytes  = nrf_uarte_rx_amount_get(p_uarte);
621         event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
622 
623         // Abort transfer.
624         p_cb->rx_buffer_length = 0;
625         p_cb->rx_secondary_buffer_length = 0;
626 
627         p_cb->handler(&event, p_cb->p_context);
628     }
629     else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
630     {
631         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
632 
633         // Aborted transfers are handled in RXTO event processing.
634         if (!p_cb->rx_aborted)
635         {
636             size_t amount = p_cb->rx_buffer_length;
637             if (p_cb->rx_secondary_buffer_length != 0)
638             {
639                 uint8_t * p_data = p_cb->p_rx_buffer;
640                 nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
641                 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
642                 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
643                 p_cb->rx_secondary_buffer_length = 0;
644                 rx_done_event(p_cb, amount, p_data);
645             }
646             else
647             {
648                 p_cb->rx_buffer_length = 0;
649                 rx_done_event(p_cb, amount, p_cb->p_rx_buffer);
650             }
651         }
652     }
653 
654     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
655     {
656         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
657 
658         if (p_cb->rx_buffer_length != 0)
659         {
660             p_cb->rx_buffer_length = 0;
661             // In case of using double-buffered reception both variables storing buffer length
662             // have to be cleared to prevent incorrect behaviour of the driver.
663             p_cb->rx_secondary_buffer_length = 0;
664             rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer);
665         }
666     }
667 
668     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
669     {
670         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
671 
672         // Transmitter has to be stopped by triggering STOPTX task to achieve
673         // the lowest possible level of the UARTE power consumption.
674         nrf_uarte_task_trigger(p_uarte, NRF_UARTE_TASK_STOPTX);
675 
676         if (p_cb->tx_buffer_length != 0)
677         {
678             tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte));
679         }
680     }
681 
682     if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_TXSTOPPED))
683     {
684         nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_TXSTOPPED);
685         if (p_cb->tx_buffer_length != 0)
686         {
687             tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte));
688         }
689     }
690 }
691 
692 #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
nrfx_uarte_0_irq_handler(void)693 void nrfx_uarte_0_irq_handler(void)
694 {
695     uarte_irq_handler(NRF_UARTE0, &m_cb[NRFX_UARTE0_INST_IDX]);
696 }
697 #endif
698 
699 #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
nrfx_uarte_1_irq_handler(void)700 void nrfx_uarte_1_irq_handler(void)
701 {
702     uarte_irq_handler(NRF_UARTE1, &m_cb[NRFX_UARTE1_INST_IDX]);
703 }
704 #endif
705 
706 #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
nrfx_uarte_2_irq_handler(void)707 void nrfx_uarte_2_irq_handler(void)
708 {
709     uarte_irq_handler(NRF_UARTE2, &m_cb[NRFX_UARTE2_INST_IDX]);
710 }
711 #endif
712 
713 #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
nrfx_uarte_3_irq_handler(void)714 void nrfx_uarte_3_irq_handler(void)
715 {
716     uarte_irq_handler(NRF_UARTE3, &m_cb[NRFX_UARTE3_INST_IDX]);
717 }
718 #endif
719 
720 #endif // NRFX_CHECK(NRFX_UARTE_ENABLED)
721