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