Skip to content

Commit 4bb84fd

Browse files
author
Marcus Chang
committed
Change NRF52 series UART to only use one SWI channel
This fixes conflicts with the SoftDevice.
1 parent cfb99d6 commit 4bb84fd

File tree

3 files changed

+64
-60
lines changed

3 files changed

+64
-60
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ The table must be placed in a C compilation file.
143143
Because each DMA buffer must be at least 5 bytes deep, each buffer is automatically flushed after a certain idle period to ensure low latency and correctness. This idle timeout is implemented using 2 of the 4 channels on RTC instance 2. This leaves RTC0 for the SoftDevice and RTC1 for Mbed tickers.
144144

145145

146-
#### SWI2, SWI3, SWI4, and SWI5
146+
#### SWI0
147147

148-
To minimize the time spend in the highest priority interrupt handler all callbacks to the user provided IRQ handlers are deferred through Software Interrupts running at lowest priority. SWI 2-5 are reserved by the serial implementation.
148+
To minimize the time spend in the highest priority interrupt handler all callbacks to the user provided IRQ handlers are deferred through Software Interrupts running at lowest priority. SWI0 is reserved by the serial implementation.
149149

150150

151151
#### Asserts
@@ -156,13 +156,14 @@ The SDK file `mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_14_2/librari
156156
The assert handler is defined in mbed-os/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5x/source/btle/btle.cpp : assert_nrf_callback() which forwards assert failures to thye mbed error() handler.
157157

158158

159-
160159
#### Limitations
161160

162161
* The UARTE hardware only supports 8-bit, None/Even parity, and 1 stop bit.
163162
* The asynchronous read and write implementation currently only support 255 byte transfers.
164163
* The EasyDMA hardware can only read from RAM, which means all Tx buffers must reside in RAM. If a Tx buffer residing in flash is passed to the asynchronous write function, the function will try to copy the Tx buffer to a temporary internal buffer and transmit the data from there.
165164
* It is not possible to do an asynchronous write from flash and receive non-asynchronously at the same time since the non-asynchronous receive buffer is being used as the temporary transmission buffer.
165+
* The driver will flush the DMA buffer after a configurable timeout. During this process the UART will be halted and therefor unable to receive data. Hardware flow control should be enabled to avoid missing any data during this window.
166+
166167

167168
## SoftDevice
168169

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/mbed_lib.json

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
"value": 8
1919
}
2020
},
21+
"macros": [
22+
"SWI_DISABLE0"
23+
],
2124
"target_overrides": {
2225
"DELTA_DFBM_NQ620": {
2326
"target.macros_add": [
2427
"CONFIG_GPIO_AS_PINRESET",
25-
"SWI_DISABLE0",
2628
"NRF52_PAN_12",
2729
"NRF52_PAN_15",
2830
"NRF52_PAN_20",
@@ -45,7 +47,6 @@
4547
"MTB_LAIRD_BL652": {
4648
"target.macros_add": [
4749
"CONFIG_GPIO_AS_PINRESET",
48-
"SWI_DISABLE0",
4950
"NRF52_PAN_12",
5051
"NRF52_PAN_15",
5152
"NRF52_PAN_20",
@@ -67,7 +68,6 @@
6768
"MTB_UBLOX_NINA_B1": {
6869
"target.macros_add": [
6970
"CONFIG_GPIO_AS_PINRESET",
70-
"SWI_DISABLE0",
7171
"NRF52_PAN_12",
7272
"NRF52_PAN_15",
7373
"NRF52_PAN_20",
@@ -87,7 +87,6 @@
8787
"NRF52_DK": {
8888
"target.macros_add": [
8989
"CONFIG_GPIO_AS_PINRESET",
90-
"SWI_DISABLE0",
9190
"NRF52_PAN_12",
9291
"NRF52_PAN_15",
9392
"NRF52_PAN_20",
@@ -108,7 +107,6 @@
108107
"RBLAB_BLENANO2": {
109108
"target.macros_add": [
110109
"CONFIG_GPIO_AS_PINRESET",
111-
"SWI_DISABLE0",
112110
"NRF52_PAN_12",
113111
"NRF52_PAN_15",
114112
"NRF52_PAN_20",
@@ -128,7 +126,6 @@
128126
"UBLOX_EVA_NINA": {
129127
"target.macros_add": [
130128
"CONFIG_GPIO_AS_PINRESET",
131-
"SWI_DISABLE0",
132129
"NRF52_PAN_12",
133130
"NRF52_PAN_15",
134131
"NRF52_PAN_20",
@@ -148,7 +145,6 @@
148145
"UBLOX_EVK_NINA_B1": {
149146
"target.macros_add": [
150147
"CONFIG_GPIO_AS_PINRESET",
151-
"SWI_DISABLE0",
152148
"NRF52_PAN_12",
153149
"NRF52_PAN_15",
154150
"NRF52_PAN_20",
@@ -169,7 +165,6 @@
169165
"VBLUNO52": {
170166
"target.macros_add": [
171167
"CONFIG_GPIO_AS_PINRESET",
172-
"SWI_DISABLE0",
173168
"NRF52_PAN_12",
174169
"NRF52_PAN_15",
175170
"NRF52_PAN_20",
@@ -190,7 +185,6 @@
190185
"NRF52840_DK": {
191186
"target.macros_add": [
192187
"CONFIG_GPIO_AS_PINRESET",
193-
"SWI_DISABLE0",
194188
"NRF52_ERRATA_20"
195189
],
196190
"target.console-uart-flow-control": "RTSCTS"

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,6 @@
122122
*/
123123
#define RTC_FREQUENCY 32768
124124

125-
/**
126-
* SWI IRQ numbers
127-
*/
128-
#define UARTE0_SWI_TX_IRQ SWI2_EGU2_IRQn
129-
#define UARTE0_SWI_RX_IRQ SWI3_EGU3_IRQn
130-
#define UARTE1_SWI_TX_IRQ SWI4_EGU4_IRQn
131-
#define UARTE1_SWI_RX_IRQ SWI5_EGU5_IRQn
132-
133125
/***
134126
* _______ _ __
135127
* |__ __| | | / _|
@@ -238,6 +230,14 @@ NRF_ATFIFO_DEF(nordic_nrf5_uart_fifo_0, uint8_t, UART0_FIFO_BUFFER_SIZE);
238230
NRF_ATFIFO_DEF(nordic_nrf5_uart_fifo_1, uint8_t, UART1_FIFO_BUFFER_SIZE);
239231
#endif
240232

233+
/**
234+
* SWI IRQ mask.
235+
*/
236+
static uint8_t nordic_nrf5_uart_swi_mask_tx_0 = 0;
237+
static uint8_t nordic_nrf5_uart_swi_mask_rx_0 = 0;
238+
static uint8_t nordic_nrf5_uart_swi_mask_tx_1 = 0;
239+
static uint8_t nordic_nrf5_uart_swi_mask_rx_1 = 0;
240+
241241
/**
242242
* Global variables expected by mbed_retarget.cpp for STDOUT.
243243
*/
@@ -411,16 +411,6 @@ static void nordic_nrf5_uart_callback_handler(uint32_t instance)
411411
}
412412
}
413413

414-
static void nordic_nrf5_uart_swi_rx_0(void)
415-
{
416-
nordic_nrf5_uart_callback_handler(0);
417-
}
418-
419-
static void nordic_nrf5_uart_swi_rx_1(void)
420-
{
421-
nordic_nrf5_uart_callback_handler(1);
422-
}
423-
424414
/**
425415
* @brief SWI interrupt handler for when the Tx buffer has been transmitted.
426416
*
@@ -477,33 +467,55 @@ static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance)
477467
}
478468
#endif
479469

480-
static void nordic_nrf5_uart_swi_tx_0(void)
470+
static void nordic_nrf5_uart_swi0(void)
481471
{
472+
if (nordic_nrf5_uart_swi_mask_tx_0) {
473+
474+
nordic_nrf5_uart_swi_mask_tx_0 = 0;
475+
482476
#if DEVICE_SERIAL_ASYNCH
483-
if (nordic_nrf5_uart_state[0].tx_asynch) {
477+
if (nordic_nrf5_uart_state[0].tx_asynch) {
484478

485-
nordic_nrf5_uart_event_handler_endtx_asynch(0);
486-
} else
479+
nordic_nrf5_uart_event_handler_endtx_asynch(0);
480+
} else
487481
#endif
488-
{
489-
nordic_nrf5_uart_event_handler_endtx(0);
482+
{
483+
nordic_nrf5_uart_event_handler_endtx(0);
484+
}
490485
}
491-
}
486+
487+
if (nordic_nrf5_uart_swi_mask_rx_0) {
488+
489+
nordic_nrf5_uart_swi_mask_rx_0 = 0;
490+
491+
nordic_nrf5_uart_callback_handler(0);
492+
}
493+
492494

493495
#if UART1_ENABLED
494-
static void nordic_nrf5_uart_swi_tx_1(void)
495-
{
496+
if (nordic_nrf5_uart_swi_mask_tx_1) {
497+
498+
nordic_nrf5_uart_swi_mask_tx_1 = 0;
499+
496500
#if DEVICE_SERIAL_ASYNCH
497-
if (nordic_nrf5_uart_state[1].tx_asynch) {
501+
if (nordic_nrf5_uart_state[1].tx_asynch) {
498502

499-
nordic_nrf5_uart_event_handler_endtx_asynch(1);
500-
} else
503+
nordic_nrf5_uart_event_handler_endtx_asynch(1);
504+
} else
501505
#endif
502-
{
503-
nordic_nrf5_uart_event_handler_endtx(1);
506+
{
507+
nordic_nrf5_uart_event_handler_endtx(1);
508+
}
509+
}
510+
511+
if (nordic_nrf5_uart_swi_mask_rx_1) {
512+
513+
nordic_nrf5_uart_swi_mask_rx_1 = 0;
514+
515+
nordic_nrf5_uart_callback_handler(1);
504516
}
505-
}
506517
#endif
518+
}
507519

508520
/**
509521
* @brief Trigger Tx SWI.
@@ -514,12 +526,14 @@ static void nordic_swi_tx_trigger(int instance)
514526
{
515527
if (instance == 0) {
516528

517-
NVIC_SetPendingIRQ(UARTE0_SWI_TX_IRQ);
529+
nordic_nrf5_uart_swi_mask_tx_0 = 1;
530+
NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
518531
}
519532
#if UART1_ENABLED
520533
else if (instance == 1) {
521534

522-
NVIC_SetPendingIRQ(UARTE1_SWI_TX_IRQ);
535+
nordic_nrf5_uart_swi_mask_tx_1 = 1;
536+
NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
523537
}
524538
#endif
525539
}
@@ -533,12 +547,16 @@ static void nordic_swi_rx_trigger(int instance)
533547
{
534548
if (instance == 0) {
535549

536-
NVIC_SetPendingIRQ(UARTE0_SWI_RX_IRQ);
550+
nordic_nrf5_uart_swi_mask_rx_0 = 1;
551+
NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
537552
}
553+
#if UART1_ENABLED
538554
else if (instance == 1) {
539555

540-
NVIC_SetPendingIRQ(UARTE1_SWI_RX_IRQ);
556+
nordic_nrf5_uart_swi_mask_rx_1 = 1;
557+
NVIC_SetPendingIRQ(SWI0_EGU0_IRQn);
541558
}
559+
#endif
542560
}
543561

544562
/***
@@ -990,17 +1008,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
9901008
nrf_rtc_task_trigger(NRF_RTC2, NRF_RTC_TASK_START);
9911009

9921010
/* Enable interrupts for SWI. */
993-
NVIC_SetVector(UARTE0_SWI_TX_IRQ, (uint32_t) nordic_nrf5_uart_swi_tx_0);
994-
NVIC_SetVector(UARTE0_SWI_RX_IRQ, (uint32_t) nordic_nrf5_uart_swi_rx_0);
995-
nrf_drv_common_irq_enable(UARTE0_SWI_TX_IRQ, APP_IRQ_PRIORITY_LOWEST);
996-
nrf_drv_common_irq_enable(UARTE0_SWI_RX_IRQ, APP_IRQ_PRIORITY_LOWEST);
997-
998-
#if UART1_ENABLED
999-
NVIC_SetVector(UARTE1_SWI_TX_IRQ, (uint32_t) nordic_nrf5_uart_swi_tx_1);
1000-
NVIC_SetVector(UARTE1_SWI_RX_IRQ, (uint32_t) nordic_nrf5_uart_swi_rx_1);
1001-
nrf_drv_common_irq_enable(UARTE1_SWI_TX_IRQ, APP_IRQ_PRIORITY_LOWEST);
1002-
nrf_drv_common_irq_enable(UARTE1_SWI_RX_IRQ, APP_IRQ_PRIORITY_LOWEST);
1003-
#endif
1011+
NVIC_SetVector(SWI0_EGU0_IRQn, (uint32_t) nordic_nrf5_uart_swi0);
1012+
nrf_drv_common_irq_enable(SWI0_EGU0_IRQn, APP_IRQ_PRIORITY_LOWEST);
10041013

10051014
/* Initialize FIFO buffer for UARTE0. */
10061015
NRF_ATFIFO_INIT(nordic_nrf5_uart_fifo_0);

0 commit comments

Comments
 (0)