1*150812a8SEvalZero /*
2*150812a8SEvalZero * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero * All rights reserved.
4*150812a8SEvalZero *
5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero *
8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero * list of conditions and the following disclaimer.
10*150812a8SEvalZero *
11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero * documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero *
15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero * software without specific prior written permission.
18*150812a8SEvalZero *
19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero */
31*150812a8SEvalZero
32*150812a8SEvalZero #include <nrfx.h>
33*150812a8SEvalZero
34*150812a8SEvalZero #if NRFX_CHECK(NRFX_UART_ENABLED)
35*150812a8SEvalZero
36*150812a8SEvalZero #if !NRFX_CHECK(NRFX_UART0_ENABLED)
37*150812a8SEvalZero #error "No enabled UART instances. Check <nrfx_config.h>."
38*150812a8SEvalZero #endif
39*150812a8SEvalZero
40*150812a8SEvalZero #include <nrfx_uart.h>
41*150812a8SEvalZero #include "prs/nrfx_prs.h"
42*150812a8SEvalZero #include <hal/nrf_gpio.h>
43*150812a8SEvalZero
44*150812a8SEvalZero #define NRFX_LOG_MODULE UART
45*150812a8SEvalZero #include <nrfx_log.h>
46*150812a8SEvalZero
47*150812a8SEvalZero #define EVT_TO_STR(event) \
48*150812a8SEvalZero (event == NRF_UART_EVENT_ERROR ? "NRF_UART_EVENT_ERROR" : \
49*150812a8SEvalZero "UNKNOWN EVENT")
50*150812a8SEvalZero
51*150812a8SEvalZero
52*150812a8SEvalZero #define TX_COUNTER_ABORT_REQ_VALUE UINT32_MAX
53*150812a8SEvalZero
54*150812a8SEvalZero typedef struct
55*150812a8SEvalZero {
56*150812a8SEvalZero void * p_context;
57*150812a8SEvalZero nrfx_uart_event_handler_t handler;
58*150812a8SEvalZero uint8_t const * p_tx_buffer;
59*150812a8SEvalZero uint8_t * p_rx_buffer;
60*150812a8SEvalZero uint8_t * p_rx_secondary_buffer;
61*150812a8SEvalZero size_t tx_buffer_length;
62*150812a8SEvalZero size_t rx_buffer_length;
63*150812a8SEvalZero size_t rx_secondary_buffer_length;
64*150812a8SEvalZero volatile size_t tx_counter;
65*150812a8SEvalZero volatile size_t rx_counter;
66*150812a8SEvalZero volatile bool tx_abort;
67*150812a8SEvalZero bool rx_enabled;
68*150812a8SEvalZero nrfx_drv_state_t state;
69*150812a8SEvalZero } uart_control_block_t;
70*150812a8SEvalZero static uart_control_block_t m_cb[NRFX_UART_ENABLED_COUNT];
71*150812a8SEvalZero
apply_config(nrfx_uart_t const * p_instance,nrfx_uart_config_t const * p_config)72*150812a8SEvalZero static void apply_config(nrfx_uart_t const * p_instance,
73*150812a8SEvalZero nrfx_uart_config_t const * p_config)
74*150812a8SEvalZero {
75*150812a8SEvalZero if (p_config->pseltxd != NRF_UART_PSEL_DISCONNECTED)
76*150812a8SEvalZero {
77*150812a8SEvalZero nrf_gpio_pin_set(p_config->pseltxd);
78*150812a8SEvalZero nrf_gpio_cfg_output(p_config->pseltxd);
79*150812a8SEvalZero }
80*150812a8SEvalZero if (p_config->pselrxd != NRF_UART_PSEL_DISCONNECTED)
81*150812a8SEvalZero {
82*150812a8SEvalZero nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL);
83*150812a8SEvalZero }
84*150812a8SEvalZero
85*150812a8SEvalZero nrf_uart_baudrate_set(p_instance->p_reg, p_config->baudrate);
86*150812a8SEvalZero nrf_uart_configure(p_instance->p_reg, p_config->parity, p_config->hwfc);
87*150812a8SEvalZero nrf_uart_txrx_pins_set(p_instance->p_reg, p_config->pseltxd, p_config->pselrxd);
88*150812a8SEvalZero if (p_config->hwfc == NRF_UART_HWFC_ENABLED)
89*150812a8SEvalZero {
90*150812a8SEvalZero if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED)
91*150812a8SEvalZero {
92*150812a8SEvalZero nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL);
93*150812a8SEvalZero }
94*150812a8SEvalZero if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED)
95*150812a8SEvalZero {
96*150812a8SEvalZero nrf_gpio_pin_set(p_config->pselrts);
97*150812a8SEvalZero nrf_gpio_cfg_output(p_config->pselrts);
98*150812a8SEvalZero }
99*150812a8SEvalZero nrf_uart_hwfc_pins_set(p_instance->p_reg, p_config->pselrts, p_config->pselcts);
100*150812a8SEvalZero }
101*150812a8SEvalZero }
102*150812a8SEvalZero
interrupts_enable(nrfx_uart_t const * p_instance,uint8_t interrupt_priority)103*150812a8SEvalZero static void interrupts_enable(nrfx_uart_t const * p_instance,
104*150812a8SEvalZero uint8_t interrupt_priority)
105*150812a8SEvalZero {
106*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
107*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);
108*150812a8SEvalZero nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_TXDRDY |
109*150812a8SEvalZero NRF_UART_INT_MASK_RXTO);
110*150812a8SEvalZero NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg),
111*150812a8SEvalZero interrupt_priority);
112*150812a8SEvalZero NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
113*150812a8SEvalZero }
114*150812a8SEvalZero
interrupts_disable(nrfx_uart_t const * p_instance)115*150812a8SEvalZero static void interrupts_disable(nrfx_uart_t const * p_instance)
116*150812a8SEvalZero {
117*150812a8SEvalZero nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
118*150812a8SEvalZero NRF_UART_INT_MASK_TXDRDY |
119*150812a8SEvalZero NRF_UART_INT_MASK_ERROR |
120*150812a8SEvalZero NRF_UART_INT_MASK_RXTO);
121*150812a8SEvalZero NRFX_IRQ_DISABLE(nrfx_get_irq_number((void *)p_instance->p_reg));
122*150812a8SEvalZero }
123*150812a8SEvalZero
pins_to_default(nrfx_uart_t const * p_instance)124*150812a8SEvalZero static void pins_to_default(nrfx_uart_t const * p_instance)
125*150812a8SEvalZero {
126*150812a8SEvalZero /* Reset pins to default states */
127*150812a8SEvalZero uint32_t txd;
128*150812a8SEvalZero uint32_t rxd;
129*150812a8SEvalZero uint32_t rts;
130*150812a8SEvalZero uint32_t cts;
131*150812a8SEvalZero
132*150812a8SEvalZero txd = nrf_uart_tx_pin_get(p_instance->p_reg);
133*150812a8SEvalZero rxd = nrf_uart_rx_pin_get(p_instance->p_reg);
134*150812a8SEvalZero rts = nrf_uart_rts_pin_get(p_instance->p_reg);
135*150812a8SEvalZero cts = nrf_uart_cts_pin_get(p_instance->p_reg);
136*150812a8SEvalZero nrf_uart_txrx_pins_disconnect(p_instance->p_reg);
137*150812a8SEvalZero nrf_uart_hwfc_pins_disconnect(p_instance->p_reg);
138*150812a8SEvalZero
139*150812a8SEvalZero if (txd != NRF_UART_PSEL_DISCONNECTED)
140*150812a8SEvalZero {
141*150812a8SEvalZero nrf_gpio_cfg_default(txd);
142*150812a8SEvalZero }
143*150812a8SEvalZero if (rxd != NRF_UART_PSEL_DISCONNECTED)
144*150812a8SEvalZero {
145*150812a8SEvalZero nrf_gpio_cfg_default(rxd);
146*150812a8SEvalZero }
147*150812a8SEvalZero if (cts != NRF_UART_PSEL_DISCONNECTED)
148*150812a8SEvalZero {
149*150812a8SEvalZero nrf_gpio_cfg_default(cts);
150*150812a8SEvalZero }
151*150812a8SEvalZero if (rts != NRF_UART_PSEL_DISCONNECTED)
152*150812a8SEvalZero {
153*150812a8SEvalZero nrf_gpio_cfg_default(rts);
154*150812a8SEvalZero }
155*150812a8SEvalZero }
156*150812a8SEvalZero
nrfx_uart_init(nrfx_uart_t const * p_instance,nrfx_uart_config_t const * p_config,nrfx_uart_event_handler_t event_handler)157*150812a8SEvalZero nrfx_err_t nrfx_uart_init(nrfx_uart_t const * p_instance,
158*150812a8SEvalZero nrfx_uart_config_t const * p_config,
159*150812a8SEvalZero nrfx_uart_event_handler_t event_handler)
160*150812a8SEvalZero {
161*150812a8SEvalZero NRFX_ASSERT(p_config);
162*150812a8SEvalZero uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
163*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
164*150812a8SEvalZero
165*150812a8SEvalZero if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
166*150812a8SEvalZero {
167*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
168*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
169*150812a8SEvalZero __func__,
170*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
171*150812a8SEvalZero return err_code;
172*150812a8SEvalZero }
173*150812a8SEvalZero
174*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
175*150812a8SEvalZero static nrfx_irq_handler_t const irq_handlers[NRFX_UART_ENABLED_COUNT] = {
176*150812a8SEvalZero #if NRFX_CHECK(NRFX_UART0_ENABLED)
177*150812a8SEvalZero nrfx_uart_0_irq_handler,
178*150812a8SEvalZero #endif
179*150812a8SEvalZero };
180*150812a8SEvalZero if (nrfx_prs_acquire(p_instance->p_reg,
181*150812a8SEvalZero irq_handlers[p_instance->drv_inst_idx]) != NRFX_SUCCESS)
182*150812a8SEvalZero {
183*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
184*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
185*150812a8SEvalZero __func__,
186*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
187*150812a8SEvalZero return err_code;
188*150812a8SEvalZero }
189*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_PRS_ENABLED)
190*150812a8SEvalZero
191*150812a8SEvalZero apply_config(p_instance, p_config);
192*150812a8SEvalZero
193*150812a8SEvalZero p_cb->handler = event_handler;
194*150812a8SEvalZero p_cb->p_context = p_config->p_context;
195*150812a8SEvalZero
196*150812a8SEvalZero if (p_cb->handler)
197*150812a8SEvalZero {
198*150812a8SEvalZero interrupts_enable(p_instance, p_config->interrupt_priority);
199*150812a8SEvalZero }
200*150812a8SEvalZero
201*150812a8SEvalZero nrf_uart_enable(p_instance->p_reg);
202*150812a8SEvalZero p_cb->rx_buffer_length = 0;
203*150812a8SEvalZero p_cb->rx_secondary_buffer_length = 0;
204*150812a8SEvalZero p_cb->rx_enabled = false;
205*150812a8SEvalZero p_cb->tx_buffer_length = 0;
206*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_INITIALIZED;
207*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
208*150812a8SEvalZero __func__,
209*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
210*150812a8SEvalZero return err_code;
211*150812a8SEvalZero }
212*150812a8SEvalZero
nrfx_uart_uninit(nrfx_uart_t const * p_instance)213*150812a8SEvalZero void nrfx_uart_uninit(nrfx_uart_t const * p_instance)
214*150812a8SEvalZero {
215*150812a8SEvalZero uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
216*150812a8SEvalZero
217*150812a8SEvalZero nrf_uart_disable(p_instance->p_reg);
218*150812a8SEvalZero
219*150812a8SEvalZero if (p_cb->handler)
220*150812a8SEvalZero {
221*150812a8SEvalZero interrupts_disable(p_instance);
222*150812a8SEvalZero }
223*150812a8SEvalZero
224*150812a8SEvalZero pins_to_default(p_instance);
225*150812a8SEvalZero
226*150812a8SEvalZero #if NRFX_CHECK(NRFX_PRS_ENABLED)
227*150812a8SEvalZero nrfx_prs_release(p_instance->p_reg);
228*150812a8SEvalZero #endif
229*150812a8SEvalZero
230*150812a8SEvalZero p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
231*150812a8SEvalZero p_cb->handler = NULL;
232*150812a8SEvalZero NRFX_LOG_INFO("Instance uninitialized: %d.", p_instance->drv_inst_idx);
233*150812a8SEvalZero }
234*150812a8SEvalZero
tx_byte(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)235*150812a8SEvalZero static void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
236*150812a8SEvalZero {
237*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
238*150812a8SEvalZero uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter];
239*150812a8SEvalZero p_cb->tx_counter++;
240*150812a8SEvalZero nrf_uart_txd_set(p_uart, txd);
241*150812a8SEvalZero }
242*150812a8SEvalZero
tx_blocking(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)243*150812a8SEvalZero static bool tx_blocking(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
244*150812a8SEvalZero {
245*150812a8SEvalZero while (p_cb->tx_counter < p_cb->tx_buffer_length)
246*150812a8SEvalZero {
247*150812a8SEvalZero // Wait until the transmitter is ready to accept a new byte.
248*150812a8SEvalZero // Exit immediately if the transfer has been aborted.
249*150812a8SEvalZero while (!nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
250*150812a8SEvalZero {
251*150812a8SEvalZero if (p_cb->tx_abort)
252*150812a8SEvalZero {
253*150812a8SEvalZero return false;
254*150812a8SEvalZero }
255*150812a8SEvalZero }
256*150812a8SEvalZero
257*150812a8SEvalZero tx_byte(p_uart, p_cb);
258*150812a8SEvalZero }
259*150812a8SEvalZero
260*150812a8SEvalZero return true;
261*150812a8SEvalZero }
262*150812a8SEvalZero
nrfx_uart_tx(nrfx_uart_t const * p_instance,uint8_t const * p_data,size_t length)263*150812a8SEvalZero nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
264*150812a8SEvalZero uint8_t const * p_data,
265*150812a8SEvalZero size_t length)
266*150812a8SEvalZero {
267*150812a8SEvalZero uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
268*150812a8SEvalZero NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
269*150812a8SEvalZero NRFX_ASSERT(p_data);
270*150812a8SEvalZero NRFX_ASSERT(length > 0);
271*150812a8SEvalZero
272*150812a8SEvalZero nrfx_err_t err_code;
273*150812a8SEvalZero
274*150812a8SEvalZero if (nrfx_uart_tx_in_progress(p_instance))
275*150812a8SEvalZero {
276*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
277*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
278*150812a8SEvalZero __func__,
279*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
280*150812a8SEvalZero return err_code;
281*150812a8SEvalZero }
282*150812a8SEvalZero p_cb->tx_buffer_length = length;
283*150812a8SEvalZero p_cb->p_tx_buffer = p_data;
284*150812a8SEvalZero p_cb->tx_counter = 0;
285*150812a8SEvalZero p_cb->tx_abort = false;
286*150812a8SEvalZero
287*150812a8SEvalZero NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
288*150812a8SEvalZero NRFX_LOG_DEBUG("Tx data:");
289*150812a8SEvalZero NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
290*150812a8SEvalZero p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));
291*150812a8SEvalZero
292*150812a8SEvalZero err_code = NRFX_SUCCESS;
293*150812a8SEvalZero
294*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
295*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX);
296*150812a8SEvalZero
297*150812a8SEvalZero tx_byte(p_instance->p_reg, p_cb);
298*150812a8SEvalZero
299*150812a8SEvalZero if (p_cb->handler == NULL)
300*150812a8SEvalZero {
301*150812a8SEvalZero if (!tx_blocking(p_instance->p_reg, p_cb))
302*150812a8SEvalZero {
303*150812a8SEvalZero // The transfer has been aborted.
304*150812a8SEvalZero err_code = NRFX_ERROR_FORBIDDEN;
305*150812a8SEvalZero }
306*150812a8SEvalZero else
307*150812a8SEvalZero {
308*150812a8SEvalZero // Wait until the last byte is completely transmitted.
309*150812a8SEvalZero while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY))
310*150812a8SEvalZero {}
311*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
312*150812a8SEvalZero }
313*150812a8SEvalZero p_cb->tx_buffer_length = 0;
314*150812a8SEvalZero }
315*150812a8SEvalZero
316*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
317*150812a8SEvalZero return err_code;
318*150812a8SEvalZero }
319*150812a8SEvalZero
nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)320*150812a8SEvalZero bool nrfx_uart_tx_in_progress(nrfx_uart_t const * p_instance)
321*150812a8SEvalZero {
322*150812a8SEvalZero return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0);
323*150812a8SEvalZero }
324*150812a8SEvalZero
rx_enable(nrfx_uart_t const * p_instance)325*150812a8SEvalZero static void rx_enable(nrfx_uart_t const * p_instance)
326*150812a8SEvalZero {
327*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
328*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
329*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
330*150812a8SEvalZero }
331*150812a8SEvalZero
rx_byte(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)332*150812a8SEvalZero static void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
333*150812a8SEvalZero {
334*150812a8SEvalZero if (!p_cb->rx_buffer_length)
335*150812a8SEvalZero {
336*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
337*150812a8SEvalZero // Byte received when buffer is not set - data lost.
338*150812a8SEvalZero (void) nrf_uart_rxd_get(p_uart);
339*150812a8SEvalZero return;
340*150812a8SEvalZero }
341*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY);
342*150812a8SEvalZero p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart);
343*150812a8SEvalZero p_cb->rx_counter++;
344*150812a8SEvalZero }
345*150812a8SEvalZero
nrfx_uart_rx(nrfx_uart_t const * p_instance,uint8_t * p_data,size_t length)346*150812a8SEvalZero nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
347*150812a8SEvalZero uint8_t * p_data,
348*150812a8SEvalZero size_t length)
349*150812a8SEvalZero {
350*150812a8SEvalZero uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
351*150812a8SEvalZero
352*150812a8SEvalZero NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
353*150812a8SEvalZero NRFX_ASSERT(p_data);
354*150812a8SEvalZero NRFX_ASSERT(length > 0);
355*150812a8SEvalZero
356*150812a8SEvalZero nrfx_err_t err_code;
357*150812a8SEvalZero
358*150812a8SEvalZero bool second_buffer = false;
359*150812a8SEvalZero
360*150812a8SEvalZero if (p_cb->handler)
361*150812a8SEvalZero {
362*150812a8SEvalZero nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
363*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
364*150812a8SEvalZero }
365*150812a8SEvalZero if (p_cb->rx_buffer_length != 0)
366*150812a8SEvalZero {
367*150812a8SEvalZero if (p_cb->rx_secondary_buffer_length != 0)
368*150812a8SEvalZero {
369*150812a8SEvalZero if (p_cb->handler)
370*150812a8SEvalZero {
371*150812a8SEvalZero nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
372*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
373*150812a8SEvalZero }
374*150812a8SEvalZero err_code = NRFX_ERROR_BUSY;
375*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
376*150812a8SEvalZero __func__,
377*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
378*150812a8SEvalZero return err_code;
379*150812a8SEvalZero }
380*150812a8SEvalZero second_buffer = true;
381*150812a8SEvalZero }
382*150812a8SEvalZero
383*150812a8SEvalZero if (!second_buffer)
384*150812a8SEvalZero {
385*150812a8SEvalZero p_cb->rx_buffer_length = length;
386*150812a8SEvalZero p_cb->p_rx_buffer = p_data;
387*150812a8SEvalZero p_cb->rx_counter = 0;
388*150812a8SEvalZero p_cb->rx_secondary_buffer_length = 0;
389*150812a8SEvalZero }
390*150812a8SEvalZero else
391*150812a8SEvalZero {
392*150812a8SEvalZero p_cb->p_rx_secondary_buffer = p_data;
393*150812a8SEvalZero p_cb->rx_secondary_buffer_length = length;
394*150812a8SEvalZero }
395*150812a8SEvalZero
396*150812a8SEvalZero NRFX_LOG_INFO("Transfer rx_len: %d.", length);
397*150812a8SEvalZero
398*150812a8SEvalZero if ((!p_cb->rx_enabled) && (!second_buffer))
399*150812a8SEvalZero {
400*150812a8SEvalZero rx_enable(p_instance);
401*150812a8SEvalZero }
402*150812a8SEvalZero
403*150812a8SEvalZero if (p_cb->handler == NULL)
404*150812a8SEvalZero {
405*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);
406*150812a8SEvalZero
407*150812a8SEvalZero bool rxrdy;
408*150812a8SEvalZero bool rxto;
409*150812a8SEvalZero bool error;
410*150812a8SEvalZero do
411*150812a8SEvalZero {
412*150812a8SEvalZero do
413*150812a8SEvalZero {
414*150812a8SEvalZero error = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_ERROR);
415*150812a8SEvalZero rxrdy = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
416*150812a8SEvalZero rxto = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXTO);
417*150812a8SEvalZero } while ((!rxrdy) && (!rxto) && (!error));
418*150812a8SEvalZero
419*150812a8SEvalZero if (error || rxto)
420*150812a8SEvalZero {
421*150812a8SEvalZero break;
422*150812a8SEvalZero }
423*150812a8SEvalZero rx_byte(p_instance->p_reg, p_cb);
424*150812a8SEvalZero } while (p_cb->rx_buffer_length > p_cb->rx_counter);
425*150812a8SEvalZero
426*150812a8SEvalZero p_cb->rx_buffer_length = 0;
427*150812a8SEvalZero if (error)
428*150812a8SEvalZero {
429*150812a8SEvalZero err_code = NRFX_ERROR_INTERNAL;
430*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
431*150812a8SEvalZero __func__,
432*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
433*150812a8SEvalZero return err_code;
434*150812a8SEvalZero }
435*150812a8SEvalZero
436*150812a8SEvalZero if (rxto)
437*150812a8SEvalZero {
438*150812a8SEvalZero err_code = NRFX_ERROR_FORBIDDEN;
439*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
440*150812a8SEvalZero __func__,
441*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
442*150812a8SEvalZero return err_code;
443*150812a8SEvalZero }
444*150812a8SEvalZero
445*150812a8SEvalZero if (p_cb->rx_enabled)
446*150812a8SEvalZero {
447*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
448*150812a8SEvalZero }
449*150812a8SEvalZero else
450*150812a8SEvalZero {
451*150812a8SEvalZero // Skip stopping RX if driver is forced to be enabled.
452*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
453*150812a8SEvalZero }
454*150812a8SEvalZero }
455*150812a8SEvalZero else
456*150812a8SEvalZero {
457*150812a8SEvalZero nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
458*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
459*150812a8SEvalZero }
460*150812a8SEvalZero err_code = NRFX_SUCCESS;
461*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
462*150812a8SEvalZero return err_code;
463*150812a8SEvalZero }
464*150812a8SEvalZero
nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)465*150812a8SEvalZero bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)
466*150812a8SEvalZero {
467*150812a8SEvalZero return nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
468*150812a8SEvalZero }
469*150812a8SEvalZero
nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)470*150812a8SEvalZero void nrfx_uart_rx_enable(nrfx_uart_t const * p_instance)
471*150812a8SEvalZero {
472*150812a8SEvalZero if (!m_cb[p_instance->drv_inst_idx].rx_enabled)
473*150812a8SEvalZero {
474*150812a8SEvalZero rx_enable(p_instance);
475*150812a8SEvalZero m_cb[p_instance->drv_inst_idx].rx_enabled = true;
476*150812a8SEvalZero }
477*150812a8SEvalZero }
478*150812a8SEvalZero
nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)479*150812a8SEvalZero void nrfx_uart_rx_disable(nrfx_uart_t const * p_instance)
480*150812a8SEvalZero {
481*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
482*150812a8SEvalZero m_cb[p_instance->drv_inst_idx].rx_enabled = false;
483*150812a8SEvalZero }
484*150812a8SEvalZero
nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)485*150812a8SEvalZero uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance)
486*150812a8SEvalZero {
487*150812a8SEvalZero nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR);
488*150812a8SEvalZero return nrf_uart_errorsrc_get_and_clear(p_instance->p_reg);
489*150812a8SEvalZero }
490*150812a8SEvalZero
rx_done_event(uart_control_block_t * p_cb,size_t bytes,uint8_t * p_data)491*150812a8SEvalZero static void rx_done_event(uart_control_block_t * p_cb,
492*150812a8SEvalZero size_t bytes,
493*150812a8SEvalZero uint8_t * p_data)
494*150812a8SEvalZero {
495*150812a8SEvalZero nrfx_uart_event_t event;
496*150812a8SEvalZero
497*150812a8SEvalZero event.type = NRFX_UART_EVT_RX_DONE;
498*150812a8SEvalZero event.data.rxtx.bytes = bytes;
499*150812a8SEvalZero event.data.rxtx.p_data = p_data;
500*150812a8SEvalZero
501*150812a8SEvalZero p_cb->handler(&event, p_cb->p_context);
502*150812a8SEvalZero }
503*150812a8SEvalZero
tx_done_event(uart_control_block_t * p_cb,size_t bytes)504*150812a8SEvalZero static void tx_done_event(uart_control_block_t * p_cb,
505*150812a8SEvalZero size_t bytes)
506*150812a8SEvalZero {
507*150812a8SEvalZero nrfx_uart_event_t event;
508*150812a8SEvalZero
509*150812a8SEvalZero event.type = NRFX_UART_EVT_TX_DONE;
510*150812a8SEvalZero event.data.rxtx.bytes = bytes;
511*150812a8SEvalZero event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer;
512*150812a8SEvalZero
513*150812a8SEvalZero p_cb->tx_buffer_length = 0;
514*150812a8SEvalZero
515*150812a8SEvalZero p_cb->handler(&event, p_cb->p_context);
516*150812a8SEvalZero }
517*150812a8SEvalZero
nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)518*150812a8SEvalZero void nrfx_uart_tx_abort(nrfx_uart_t const * p_instance)
519*150812a8SEvalZero {
520*150812a8SEvalZero uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
521*150812a8SEvalZero
522*150812a8SEvalZero p_cb->tx_abort = true;
523*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
524*150812a8SEvalZero if (p_cb->handler)
525*150812a8SEvalZero {
526*150812a8SEvalZero tx_done_event(p_cb, p_cb->tx_counter);
527*150812a8SEvalZero }
528*150812a8SEvalZero
529*150812a8SEvalZero NRFX_LOG_INFO("TX transaction aborted.");
530*150812a8SEvalZero }
531*150812a8SEvalZero
nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)532*150812a8SEvalZero void nrfx_uart_rx_abort(nrfx_uart_t const * p_instance)
533*150812a8SEvalZero {
534*150812a8SEvalZero nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
535*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
536*150812a8SEvalZero nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
537*150812a8SEvalZero
538*150812a8SEvalZero NRFX_LOG_INFO("RX transaction aborted.");
539*150812a8SEvalZero }
540*150812a8SEvalZero
uart_irq_handler(NRF_UART_Type * p_uart,uart_control_block_t * p_cb)541*150812a8SEvalZero static void uart_irq_handler(NRF_UART_Type * p_uart,
542*150812a8SEvalZero uart_control_block_t * p_cb)
543*150812a8SEvalZero {
544*150812a8SEvalZero if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) &&
545*150812a8SEvalZero nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR))
546*150812a8SEvalZero {
547*150812a8SEvalZero nrfx_uart_event_t event;
548*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR);
549*150812a8SEvalZero NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR));
550*150812a8SEvalZero nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
551*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
552*150812a8SEvalZero if (!p_cb->rx_enabled)
553*150812a8SEvalZero {
554*150812a8SEvalZero nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
555*150812a8SEvalZero }
556*150812a8SEvalZero event.type = NRFX_UART_EVT_ERROR;
557*150812a8SEvalZero event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart);
558*150812a8SEvalZero event.data.error.rxtx.bytes = p_cb->rx_buffer_length;
559*150812a8SEvalZero event.data.error.rxtx.p_data = p_cb->p_rx_buffer;
560*150812a8SEvalZero
561*150812a8SEvalZero // Abort transfer.
562*150812a8SEvalZero p_cb->rx_buffer_length = 0;
563*150812a8SEvalZero p_cb->rx_secondary_buffer_length = 0;
564*150812a8SEvalZero
565*150812a8SEvalZero p_cb->handler(&event,p_cb->p_context);
566*150812a8SEvalZero }
567*150812a8SEvalZero else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) &&
568*150812a8SEvalZero nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY))
569*150812a8SEvalZero {
570*150812a8SEvalZero rx_byte(p_uart, p_cb);
571*150812a8SEvalZero if (p_cb->rx_buffer_length == p_cb->rx_counter)
572*150812a8SEvalZero {
573*150812a8SEvalZero if (p_cb->rx_secondary_buffer_length)
574*150812a8SEvalZero {
575*150812a8SEvalZero uint8_t * p_data = p_cb->p_rx_buffer;
576*150812a8SEvalZero size_t rx_counter = p_cb->rx_counter;
577*150812a8SEvalZero
578*150812a8SEvalZero // Switch to secondary buffer.
579*150812a8SEvalZero p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
580*150812a8SEvalZero p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
581*150812a8SEvalZero p_cb->rx_secondary_buffer_length = 0;
582*150812a8SEvalZero p_cb->rx_counter = 0;
583*150812a8SEvalZero rx_done_event(p_cb, rx_counter, p_data);
584*150812a8SEvalZero }
585*150812a8SEvalZero else
586*150812a8SEvalZero {
587*150812a8SEvalZero if (!p_cb->rx_enabled)
588*150812a8SEvalZero {
589*150812a8SEvalZero nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
590*150812a8SEvalZero }
591*150812a8SEvalZero nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
592*150812a8SEvalZero NRF_UART_INT_MASK_ERROR);
593*150812a8SEvalZero p_cb->rx_buffer_length = 0;
594*150812a8SEvalZero rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
595*150812a8SEvalZero }
596*150812a8SEvalZero }
597*150812a8SEvalZero }
598*150812a8SEvalZero
599*150812a8SEvalZero if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
600*150812a8SEvalZero {
601*150812a8SEvalZero if (p_cb->tx_counter < p_cb->tx_buffer_length &&
602*150812a8SEvalZero !p_cb->tx_abort)
603*150812a8SEvalZero {
604*150812a8SEvalZero tx_byte(p_uart, p_cb);
605*150812a8SEvalZero }
606*150812a8SEvalZero else
607*150812a8SEvalZero {
608*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
609*150812a8SEvalZero if (p_cb->tx_buffer_length)
610*150812a8SEvalZero {
611*150812a8SEvalZero tx_done_event(p_cb, p_cb->tx_buffer_length);
612*150812a8SEvalZero }
613*150812a8SEvalZero }
614*150812a8SEvalZero }
615*150812a8SEvalZero
616*150812a8SEvalZero if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO))
617*150812a8SEvalZero {
618*150812a8SEvalZero nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO);
619*150812a8SEvalZero
620*150812a8SEvalZero // RXTO event may be triggered as a result of abort call. In th
621*150812a8SEvalZero if (p_cb->rx_enabled)
622*150812a8SEvalZero {
623*150812a8SEvalZero nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX);
624*150812a8SEvalZero }
625*150812a8SEvalZero if (p_cb->rx_buffer_length)
626*150812a8SEvalZero {
627*150812a8SEvalZero p_cb->rx_buffer_length = 0;
628*150812a8SEvalZero rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
629*150812a8SEvalZero }
630*150812a8SEvalZero }
631*150812a8SEvalZero }
632*150812a8SEvalZero
633*150812a8SEvalZero #if NRFX_CHECK(NRFX_UART0_ENABLED)
nrfx_uart_0_irq_handler(void)634*150812a8SEvalZero void nrfx_uart_0_irq_handler(void)
635*150812a8SEvalZero {
636*150812a8SEvalZero uart_irq_handler(NRF_UART0, &m_cb[NRFX_UART0_INST_IDX]);
637*150812a8SEvalZero }
638*150812a8SEvalZero #endif
639*150812a8SEvalZero
640*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_UART_ENABLED)
641