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_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
89 typedef struct
90 {
91 void * p_context;
92 nrfx_uarte_event_handler_t handler;
93 uint8_t const * p_tx_buffer;
94 uint8_t * p_rx_buffer;
95 uint8_t * p_rx_secondary_buffer;
96 size_t tx_buffer_length;
97 size_t rx_buffer_length;
98 size_t rx_secondary_buffer_length;
99 nrfx_drv_state_t state;
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->parity, p_config->hwfc);
118 nrf_uarte_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
119 if (p_config->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_int_enable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
142 NRF_UARTE_INT_ENDTX_MASK |
143 NRF_UARTE_INT_ERROR_MASK |
144 NRF_UARTE_INT_RXTO_MASK);
145 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg),
146 interrupt_priority);
147 NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
148 }
149
interrupts_disable(nrfx_uarte_t const * p_instance)150 static void interrupts_disable(nrfx_uarte_t const * p_instance)
151 {
152 nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ENDRX_MASK |
153 NRF_UARTE_INT_ENDTX_MASK |
154 NRF_UARTE_INT_ERROR_MASK |
155 NRF_UARTE_INT_RXTO_MASK);
156 NRFX_IRQ_DISABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
157 }
158
pins_to_default(nrfx_uarte_t const * p_instance)159 static void pins_to_default(nrfx_uarte_t const * p_instance)
160 {
161 /* Reset pins to default states */
162 uint32_t txd;
163 uint32_t rxd;
164 uint32_t rts;
165 uint32_t cts;
166
167 txd = nrf_uarte_tx_pin_get(p_instance->p_reg);
168 rxd = nrf_uarte_rx_pin_get(p_instance->p_reg);
169 rts = nrf_uarte_rts_pin_get(p_instance->p_reg);
170 cts = nrf_uarte_cts_pin_get(p_instance->p_reg);
171 nrf_uarte_txrx_pins_disconnect(p_instance->p_reg);
172 nrf_uarte_hwfc_pins_disconnect(p_instance->p_reg);
173
174 if (txd != NRF_UARTE_PSEL_DISCONNECTED)
175 {
176 nrf_gpio_cfg_default(txd);
177 }
178 if (rxd != NRF_UARTE_PSEL_DISCONNECTED)
179 {
180 nrf_gpio_cfg_default(rxd);
181 }
182 if (cts != NRF_UARTE_PSEL_DISCONNECTED)
183 {
184 nrf_gpio_cfg_default(cts);
185 }
186 if (rts != NRF_UARTE_PSEL_DISCONNECTED)
187 {
188 nrf_gpio_cfg_default(rts);
189 }
190 }
191
nrfx_uarte_init(nrfx_uarte_t const * p_instance,nrfx_uarte_config_t const * p_config,nrfx_uarte_event_handler_t event_handler)192 nrfx_err_t nrfx_uarte_init(nrfx_uarte_t const * p_instance,
193 nrfx_uarte_config_t const * p_config,
194 nrfx_uarte_event_handler_t event_handler)
195 {
196 NRFX_ASSERT(p_config);
197 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
198 nrfx_err_t err_code = NRFX_SUCCESS;
199
200 if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
201 {
202 err_code = NRFX_ERROR_INVALID_STATE;
203 NRFX_LOG_WARNING("Function: %s, error code: %s.",
204 __func__,
205 NRFX_LOG_ERROR_STRING_GET(err_code));
206 return err_code;
207 }
208
209 #if NRFX_CHECK(NRFX_PRS_ENABLED)
210 static nrfx_irq_handler_t const irq_handlers[NRFX_UARTE_ENABLED_COUNT] = {
211 #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
212 nrfx_uarte_0_irq_handler,
213 #endif
214 #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
215 nrfx_uarte_1_irq_handler,
216 #endif
217 #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
218 nrfx_uarte_2_irq_handler,
219 #endif
220 #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
221 nrfx_uarte_3_irq_handler,
222 #endif
223 };
224 if (nrfx_prs_acquire(p_instance->p_reg,
225 irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
226 {
227 err_code = NRFX_ERROR_BUSY;
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 #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
234
235 apply_config(p_instance, p_config);
236
237 p_cb->handler = event_handler;
238 p_cb->p_context = p_config->p_context;
239
240 if (p_cb->handler)
241 {
242 interrupts_enable(p_instance, p_config->interrupt_priority);
243 }
244
245 nrf_uarte_enable(p_instance->p_reg);
246 p_cb->rx_buffer_length = 0;
247 p_cb->rx_secondary_buffer_length = 0;
248 p_cb->tx_buffer_length = 0;
249 p_cb->state = NRFX_DRV_STATE_INITIALIZED;
250 NRFX_LOG_WARNING("Function: %s, error code: %s.",
251 __func__,
252 NRFX_LOG_ERROR_STRING_GET(err_code));
253 return err_code;
254 }
255
nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)256 void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
257 {
258 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
259
260 nrf_uarte_disable(p_instance->p_reg);
261
262 if (p_cb->handler)
263 {
264 interrupts_disable(p_instance);
265 }
266
267 pins_to_default(p_instance);
268
269 #if NRFX_CHECK(NRFX_PRS_ENABLED)
270 nrfx_prs_release(p_instance->p_reg);
271 #endif
272
273 p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
274 p_cb->handler = NULL;
275 NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
276 }
277
nrfx_uarte_tx(nrfx_uarte_t const * p_instance,uint8_t const * p_data,size_t length)278 nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
279 uint8_t const * p_data,
280 size_t length)
281 {
282 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
283 NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
284 NRFX_ASSERT(p_data);
285 NRFX_ASSERT(length > 0);
286 NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
287
288 nrfx_err_t err_code;
289
290 // EasyDMA requires that transfer buffers are placed in DataRAM,
291 // signal error if the are not.
292 if (!nrfx_is_in_ram(p_data))
293 {
294 err_code = NRFX_ERROR_INVALID_ADDR;
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
301 if (nrfx_uarte_tx_in_progress(p_instance))
302 {
303 err_code = NRFX_ERROR_BUSY;
304 NRFX_LOG_WARNING("Function: %s, error code: %s.",
305 __func__,
306 NRFX_LOG_ERROR_STRING_GET(err_code));
307 return err_code;
308 }
309 p_cb->tx_buffer_length = length;
310 p_cb->p_tx_buffer = p_data;
311
312 NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
313 NRFX_LOG_DEBUG("Tx data:");
314 NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
315 p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
316
317 err_code = NRFX_SUCCESS;
318
319 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
320 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
321 nrf_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
322 nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTTX);
323
324 if (p_cb->handler == NULL)
325 {
326 bool endtx;
327 bool txstopped;
328 do
329 {
330 endtx = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
331 txstopped = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
332 }
333 while ((!endtx) && (!txstopped));
334
335 if (txstopped)
336 {
337 err_code = NRFX_ERROR_FORBIDDEN;
338 }
339 p_cb->tx_buffer_length = 0;
340 }
341
342 NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
343 return err_code;
344 }
345
nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)346 bool nrfx_uarte_tx_in_progress(nrfx_uarte_t const * p_instance)
347 {
348 return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
349 }
350
nrfx_uarte_rx(nrfx_uarte_t const * p_instance,uint8_t * p_data,size_t length)351 nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance,
352 uint8_t * p_data,
353 size_t length)
354 {
355 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
356
357 NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
358 NRFX_ASSERT(p_data);
359 NRFX_ASSERT(length > 0);
360 NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));
361
362 nrfx_err_t err_code;
363
364 // EasyDMA requires that transfer buffers are placed in DataRAM,
365 // signal error if the are not.
366 if (!nrfx_is_in_ram(p_data))
367 {
368 err_code = NRFX_ERROR_INVALID_ADDR;
369 NRFX_LOG_WARNING("Function: %s, error code: %s.",
370 __func__,
371 NRFX_LOG_ERROR_STRING_GET(err_code));
372 return err_code;
373 }
374
375 bool second_buffer = false;
376
377 if (p_cb->handler)
378 {
379 nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
380 NRF_UARTE_INT_ENDRX_MASK);
381 }
382 if (p_cb->rx_buffer_length != 0)
383 {
384 if (p_cb->rx_secondary_buffer_length != 0)
385 {
386 if (p_cb->handler)
387 {
388 nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
389 NRF_UARTE_INT_ENDRX_MASK);
390 }
391 err_code = NRFX_ERROR_BUSY;
392 NRFX_LOG_WARNING("Function: %s, error code: %s.",
393 __func__,
394 NRFX_LOG_ERROR_STRING_GET(err_code));
395 return err_code;
396 }
397 second_buffer = true;
398 }
399
400 if (!second_buffer)
401 {
402 p_cb->rx_buffer_length = length;
403 p_cb->p_rx_buffer = p_data;
404 p_cb->rx_secondary_buffer_length = 0;
405 }
406 else
407 {
408 p_cb->p_rx_secondary_buffer = p_data;
409 p_cb->rx_secondary_buffer_length = length;
410 }
411
412 NRFX_LOG_INFO("Transfer rx_len: %d.", length);
413
414 err_code = NRFX_SUCCESS;
415
416 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
417 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
418 nrf_uarte_rx_buffer_set(p_instance->p_reg, p_data, length);
419 if (!second_buffer)
420 {
421 nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTRX);
422 }
423 else
424 {
425 nrf_uarte_shorts_enable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
426 }
427
428 if (m_cb[p_instance->drv_inst_idx].handler == NULL)
429 {
430 bool endrx;
431 bool rxto;
432 bool error;
433 do {
434 endrx = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
435 rxto = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_RXTO);
436 error = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
437 } while ((!endrx) && (!rxto) && (!error));
438
439 m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0;
440
441 if (error)
442 {
443 err_code = NRFX_ERROR_INTERNAL;
444 }
445
446 if (rxto)
447 {
448 err_code = NRFX_ERROR_FORBIDDEN;
449 }
450 }
451 else
452 {
453 nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK |
454 NRF_UARTE_INT_ENDRX_MASK);
455 }
456 NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
457 return err_code;
458 }
459
nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)460 bool nrfx_uarte_rx_ready(nrfx_uarte_t const * p_instance)
461 {
462 return nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX);
463 }
464
nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)465 uint32_t nrfx_uarte_errorsrc_get(nrfx_uarte_t const * p_instance)
466 {
467 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ERROR);
468 return nrf_uarte_errorsrc_get_and_clear(p_instance->p_reg);
469 }
470
rx_done_event(uarte_control_block_t * p_cb,size_t bytes,uint8_t * p_data)471 static void rx_done_event(uarte_control_block_t * p_cb,
472 size_t bytes,
473 uint8_t * p_data)
474 {
475 nrfx_uarte_event_t event;
476
477 event.type = NRFX_UARTE_EVT_RX_DONE;
478 event.data.rxtx.bytes = bytes;
479 event.data.rxtx.p_data = p_data;
480
481 p_cb->handler(&event, p_cb->p_context);
482 }
483
tx_done_event(uarte_control_block_t * p_cb,size_t bytes)484 static void tx_done_event(uarte_control_block_t * p_cb,
485 size_t bytes)
486 {
487 nrfx_uarte_event_t event;
488
489 event.type = NRFX_UARTE_EVT_TX_DONE;
490 event.data.rxtx.bytes = bytes;
491 event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
492
493 p_cb->tx_buffer_length = 0;
494
495 p_cb->handler(&event, p_cb->p_context);
496 }
497
nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)498 void nrfx_uarte_tx_abort(nrfx_uarte_t const * p_instance)
499 {
500 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
501
502 nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
503 nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPTX);
504 if (p_cb->handler == NULL)
505 {
506 while (!nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED))
507 {}
508 }
509 NRFX_LOG_INFO("TX transaction aborted.");
510 }
511
nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)512 void nrfx_uarte_rx_abort(nrfx_uarte_t const * p_instance)
513 {
514 uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
515
516 // Short between ENDRX event and STARTRX task must be disabled before
517 // aborting transmission.
518 if (p_cb->rx_secondary_buffer_length != 0)
519 {
520 nrf_uarte_shorts_disable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
521 }
522 nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STOPRX);
523 NRFX_LOG_INFO("RX transaction aborted.");
524 }
525
uarte_irq_handler(NRF_UARTE_Type * p_uarte,uarte_control_block_t * p_cb)526 static void uarte_irq_handler(NRF_UARTE_Type * p_uarte,
527 uarte_control_block_t * p_cb)
528 {
529 if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR))
530 {
531 nrfx_uarte_event_t event;
532
533 nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR);
534
535 event.type = NRFX_UARTE_EVT_ERROR;
536 event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(p_uarte);
537 event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(p_uarte);
538 event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
539
540 // Abort transfer.
541 p_cb->rx_buffer_length = 0;
542 p_cb->rx_secondary_buffer_length = 0;
543
544 p_cb->handler(&event, p_cb->p_context);
545 }
546 else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX))
547 {
548 nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX);
549 size_t amount = nrf_uarte_rx_amount_get(p_uarte);
550 // If the transfer was stopped before completion, amount of transfered bytes
551 // will not be equal to the buffer length. Interrupted transfer is ignored.
552 if (amount == p_cb->rx_buffer_length)
553 {
554 if (p_cb->rx_secondary_buffer_length != 0)
555 {
556 uint8_t * p_data = p_cb->p_rx_buffer;
557 nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX);
558 p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
559 p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
560 p_cb->rx_secondary_buffer_length = 0;
561 rx_done_event(p_cb, amount, p_data);
562 }
563 else
564 {
565 p_cb->rx_buffer_length = 0;
566 rx_done_event(p_cb, amount, p_cb->p_rx_buffer);
567 }
568 }
569 }
570
571 if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO))
572 {
573 nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO);
574
575 if (p_cb->rx_buffer_length != 0)
576 {
577 p_cb->rx_buffer_length = 0;
578 // In case of using double-buffered reception both variables storing buffer length
579 // have to be cleared to prevent incorrect behaviour of the driver.
580 p_cb->rx_secondary_buffer_length = 0;
581 rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer);
582 }
583 }
584
585 if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX))
586 {
587 nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX);
588 if (p_cb->tx_buffer_length != 0)
589 {
590 tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte));
591 }
592 }
593 }
594
595 #if NRFX_CHECK(NRFX_UARTE0_ENABLED)
nrfx_uarte_0_irq_handler(void)596 void nrfx_uarte_0_irq_handler(void)
597 {
598 uarte_irq_handler(NRF_UARTE0, &m_cb[NRFX_UARTE0_INST_IDX]);
599 }
600 #endif
601
602 #if NRFX_CHECK(NRFX_UARTE1_ENABLED)
nrfx_uarte_1_irq_handler(void)603 void nrfx_uarte_1_irq_handler(void)
604 {
605 uarte_irq_handler(NRF_UARTE1, &m_cb[NRFX_UARTE1_INST_IDX]);
606 }
607 #endif
608
609 #if NRFX_CHECK(NRFX_UARTE2_ENABLED)
nrfx_uarte_2_irq_handler(void)610 void nrfx_uarte_2_irq_handler(void)
611 {
612 uarte_irq_handler(NRF_UARTE2, &m_cb[NRFX_UARTE2_INST_IDX]);
613 }
614 #endif
615
616 #if NRFX_CHECK(NRFX_UARTE3_ENABLED)
nrfx_uarte_3_irq_handler(void)617 void nrfx_uarte_3_irq_handler(void)
618 {
619 uarte_irq_handler(NRF_UARTE3, &m_cb[NRFX_UARTE3_INST_IDX]);
620 }
621 #endif
622
623 #endif // NRFX_CHECK(NRFX_UARTE_ENABLED)
624