From 8636a282484ef25a39b3020a6020685baeb397be Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 24 Oct 2015 20:01:31 +0100 Subject: [PATCH] Clear interrupt flags selectively As discussed in #1294, every time a CC13xx/CC26xx RF interrupt fires, we clear all interrupt flags unconditionally. This may result in missed events. This patch fixes this bug by clearing only the flag that triggered the interrupt in the first place. Fixes #1294 --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 45387ab42..0553c58f6 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -478,8 +478,8 @@ cc26xx_rf_cpe1_isr(void) } } - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + /* Clear INTERNAL_ERROR interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF; ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -500,17 +500,25 @@ cc26xx_rf_cpe0_isr(void) ti_lib_int_master_disable(); if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) { + /* Clear the RX_ENTRY_DONE interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF; process_poll(&rf_core_process); } if(RF_CORE_DEBUG_CRC) { if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) { + /* Clear the RX_NOK interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF; rx_nok_isr(); } } - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & + (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) { + /* Clear the two TX-related interrupt flags */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5; + } + ti_lib_int_master_enable(); ENERGEST_OFF(ENERGEST_TYPE_IRQ);