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