Skip to content

Commit a0224ed

Browse files
author
Marcus Chang
committed
Fix interrupt initialization for NRF52 series
In some cases the UARTE interrupt would be enabled with pending interrupts. This commit ensures that interrupts are only enabled from a known state.
1 parent 226e799 commit a0224ed

File tree

1 file changed

+28
-43
lines changed

1 file changed

+28
-43
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ static void nordic_nrf5_uart_swi_rx_1(void)
429429
static void nordic_nrf5_uart_event_handler_endtx(int instance)
430430
{
431431
/* Disable ENDTX event again. */
432-
nordic_nrf5_uart_register[instance]->INTEN &= ~NRF_UARTE_INT_ENDTX_MASK;
432+
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
433433

434434
/* Release mutex. As the owner this call is safe. */
435435
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
@@ -455,7 +455,7 @@ static void nordic_nrf5_uart_event_handler_endtx(int instance)
455455
static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance)
456456
{
457457
/* Disable ENDTX interrupt. */
458-
nordic_nrf5_uart_register[instance]->INTEN &= ~NRF_UARTE_INT_ENDTX_MASK;
458+
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
459459

460460
/* Set Tx done and reset Tx mode to be not asynchronous. */
461461
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
@@ -753,29 +753,6 @@ static void nordic_nrf5_uart1_handler(void)
753753
* |___/
754754
*/
755755

756-
/**
757-
* @brief Enable UARTE interrupts.
758-
*
759-
* Translates instance to UARTE register.
760-
* Set IRQ priority to highest to avoid Rx overflow.
761-
*
762-
* @param[in] instance The instance
763-
*/
764-
static void nordic_nrf5_uart_irq_enable(int instance)
765-
{
766-
if (instance == 0) {
767-
768-
nrf_drv_common_irq_enable(UARTE0_UART0_IRQn, APP_IRQ_PRIORITY_HIGHEST);
769-
}
770-
771-
#if UART1_ENABLED
772-
else if (instance == 1) {
773-
774-
nrf_drv_common_irq_enable(UARTE1_IRQn, APP_IRQ_PRIORITY_HIGHEST);
775-
}
776-
#endif
777-
}
778-
779756
/**
780757
* @brief Configure UARTE based on serial object settings.
781758
*
@@ -840,9 +817,9 @@ static void nordic_nrf5_uart_configure_object(serial_t *obj)
840817
static void nordic_nrf5_uart_configure_rx(int instance)
841818
{
842819
/* Disable interrupts during confiration. */
843-
nordic_nrf5_uart_register[instance]->INTEN &= ~(NRF_UARTE_INT_RXSTARTED_MASK |
844-
NRF_UARTE_INT_ENDRX_MASK |
845-
NRF_UARTE_INT_RXDRDY_MASK);
820+
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
821+
NRF_UARTE_INT_ENDRX_MASK |
822+
NRF_UARTE_INT_RXDRDY_MASK);
846823

847824
/* Clear FIFO buffer. */
848825
nrf_atfifo_clear(nordic_nrf5_uart_state[instance].fifo);
@@ -867,9 +844,9 @@ static void nordic_nrf5_uart_configure_rx(int instance)
867844
nordic_nrf5_uart_state[instance].rx_asynch = false;
868845

869846
/* Enable interrupts again. */
870-
nordic_nrf5_uart_register[instance]->INTEN |= (NRF_UARTE_INT_RXSTARTED_MASK |
871-
NRF_UARTE_INT_ENDRX_MASK |
872-
NRF_UARTE_INT_RXDRDY_MASK);
847+
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
848+
NRF_UARTE_INT_ENDRX_MASK |
849+
NRF_UARTE_INT_RXDRDY_MASK);
873850
}
874851

875852
#if DEVICE_SERIAL_ASYNCH
@@ -881,9 +858,9 @@ static void nordic_nrf5_uart_configure_rx(int instance)
881858
static void nordic_nrf5_uart_configure_rx_asynch(int instance)
882859
{
883860
/* Disable Rx related interrupts. */
884-
nordic_nrf5_uart_register[instance]->INTEN &= ~(NRF_UARTE_INT_RXSTARTED_MASK |
885-
NRF_UARTE_INT_ENDRX_MASK |
886-
NRF_UARTE_INT_RXDRDY_MASK);
861+
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_RXSTARTED_MASK |
862+
NRF_UARTE_INT_ENDRX_MASK |
863+
NRF_UARTE_INT_RXDRDY_MASK);
887864

888865
/* Clear Rx related events. */
889866
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_RXSTARTED);
@@ -897,7 +874,7 @@ static void nordic_nrf5_uart_configure_rx_asynch(int instance)
897874
nordic_nrf5_uart_state[instance].rx_asynch = true;
898875

899876
/* Enable Rx interrupt. */
900-
nordic_nrf5_uart_register[instance]->INTEN |= NRF_UARTE_INT_ENDRX_MASK;
877+
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDRX_MASK);
901878
}
902879
#endif
903880

@@ -1004,7 +981,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
1004981
NRF_RTC_INT_COMPARE0_MASK |
1005982
NRF_RTC_INT_COMPARE1_MASK);
1006983

1007-
/* Enable RTC2 IRQ. Priority is set to lowest so that the UARTE ISR can interrupt it. */
984+
/* Enable RTC2 IRQ. Priority is set to highest so that the UARTE ISR can't interrupt it. */
1008985
nrf_drv_common_irq_enable(RTC2_IRQn, APP_IRQ_PRIORITY_HIGHEST);
1009986

1010987
/* Start RTC2. According to the datasheet the added power consumption is neglible so
@@ -1032,9 +1009,13 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
10321009
/* Initialize owner to NULL. */
10331010
nordic_nrf5_uart_state[0].owner = NULL;
10341011

1035-
/* Enable interrupts for UARTE0. */
1012+
/* Clear any old events and enable interrupts for UARTE0. */
1013+
nrf_uarte_int_disable(nordic_nrf5_uart_register[0], NRF_UARTE_INT_RXSTARTED_MASK |
1014+
NRF_UARTE_INT_ENDRX_MASK |
1015+
NRF_UARTE_INT_RXDRDY_MASK);
1016+
10361017
NVIC_SetVector(UARTE0_UART0_IRQn, (uint32_t) nordic_nrf5_uart0_handler);
1037-
nordic_nrf5_uart_irq_enable(0);
1018+
nrf_drv_common_irq_enable(UARTE0_UART0_IRQn, APP_IRQ_PRIORITY_HIGHEST);
10381019

10391020
#if UART1_ENABLED
10401021
/* Initialize FIFO buffer for UARTE1. */
@@ -1044,9 +1025,13 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
10441025
/* Initialize owner to NULL. */
10451026
nordic_nrf5_uart_state[1].owner = NULL;
10461027

1047-
/* Enable interrupts for UARTE1. */
1028+
/* Clear any old events and enable interrupts for UARTE1. */
1029+
nrf_uarte_int_disable(nordic_nrf5_uart_register[1], NRF_UARTE_INT_RXSTARTED_MASK |
1030+
NRF_UARTE_INT_ENDRX_MASK |
1031+
NRF_UARTE_INT_RXDRDY_MASK);
1032+
10481033
NVIC_SetVector(UARTE1_IRQn, (uint32_t) nordic_nrf5_uart1_handler);
1049-
nordic_nrf5_uart_irq_enable(1);
1034+
nrf_drv_common_irq_enable(UARTE1_IRQn, APP_IRQ_PRIORITY_HIGHEST);
10501035
#endif
10511036
}
10521037

@@ -1472,7 +1457,7 @@ void serial_putc(serial_t *obj, int character)
14721457

14731458
/* Clear ENDTX event and enable interrupts. */
14741459
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
1475-
nordic_nrf5_uart_register[instance]->INTEN |= NRF_UARTE_INT_ENDTX_MASK;
1460+
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
14761461

14771462
/* Trigger DMA transfer. */
14781463
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
@@ -1632,7 +1617,7 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx
16321617

16331618
/* Clear Tx event and enable Tx interrupts. */
16341619
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
1635-
nordic_nrf5_uart_register[instance]->INTEN |= NRF_UARTE_INT_ENDTX_MASK;
1620+
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
16361621

16371622
/* Set Tx DMA buffer. */
16381623
nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[obj->serial.instance],
@@ -1771,7 +1756,7 @@ void serial_tx_abort_asynch(serial_t *obj)
17711756
int instance = obj->serial.instance;
17721757

17731758
/* Disable ENDTX interrupts. */
1774-
nordic_nrf5_uart_register[instance]->INTEN &= ~NRF_UARTE_INT_ENDTX_MASK;
1759+
nrf_uarte_int_disable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
17751760

17761761
/* Clear ENDTX event. */
17771762
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);

0 commit comments

Comments
 (0)