Skip to content

Commit 2693832

Browse files
authored
Merge pull request #2486 from particle-iot/fix/sc-106749/interrupts
[p2] fixes INTERRUPTS_01_isisr_willpreempt_servicedirqn test
2 parents 263bd32 + 8f75cdc commit 2693832

File tree

3 files changed

+29
-14
lines changed

3 files changed

+29
-14
lines changed

hal/inc/interrupts_hal.h

-6
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,6 @@ int hal_interrupt_set_direct_handler(IRQn_Type irqn, hal_interrupt_direct_handle
111111

112112
#ifdef USE_STDPERIPH_DRIVER
113113

114-
#if defined(STM32F10X_MD) || defined(STM32F10X_HD)
115-
#include "stm32f10x.h"
116-
#elif defined(STM32F2XX)
117-
#include "stm32f2xx.h"
118-
#endif // defined(STM32F10X_MD) || defined(STM32F10X_HD)
119-
120114
#ifdef nRF52840
121115
#include <nrf52840.h>
122116
#endif /* nRF52840 */

hal/src/rtl872x/interrupts_hal.cpp

+22-8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern "C" {
2727
#include "pinmap_impl.h"
2828
#include "gpio_hal.h"
2929
#include "check.h"
30+
#include "scope_guard.h"
3031

3132
#if HAL_PLATFORM_IO_EXTENSION && MODULE_FUNCTION != MOD_FUNC_BOOTLOADER
3233
#if HAL_PLATFORM_MCP23S17
@@ -36,6 +37,7 @@ using namespace particle;
3637
#endif
3738

3839
extern uintptr_t link_ram_interrupt_vectors_location[];
40+
static uint32_t hal_interrupts_handler_backup[MAX_VECTOR_TABLE_NUM] = {};
3941

4042
namespace {
4143

@@ -258,23 +260,35 @@ int hal_interrupt_set_direct_handler(IRQn_Type irqn, hal_interrupt_direct_handle
258260
}
259261

260262
int32_t state = HAL_disable_irq();
261-
volatile uint32_t* isrs = (volatile uint32_t*)&link_ram_interrupt_vectors_location;
263+
264+
SCOPE_GUARD ({
265+
HAL_enable_irq(state);
266+
});
262267

263268
if (handler == nullptr && (flags & HAL_INTERRUPT_DIRECT_FLAG_RESTORE)) {
264-
// Restore
265-
// HAL_Core_Restore_Interrupt(irqn);
269+
// Restore old handler only if one was backed up
270+
uint32_t old_handler = hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)];
271+
if (old_handler) {
272+
__NVIC_SetVector(irqn, (uint32_t)old_handler);
273+
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = 0;
274+
}
266275
} else {
267-
isrs[IRQN_TO_IDX(irqn)] = (uint32_t)handler;
276+
// If there is currently a handler backup: Return error
277+
CHECK_FALSE(hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)], SYSTEM_ERROR_ALREADY_EXISTS);
278+
279+
// If there is a current handler, back it up
280+
uint32_t current_handler = __NVIC_GetVector(irqn);
281+
if (current_handler) {
282+
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = current_handler;
283+
}
268284
}
269285

270286
if (flags & HAL_INTERRUPT_DIRECT_FLAG_DISABLE) {
271287
// Disable
272-
// sd_nvic_DisableIRQ(irqn);
288+
__NVIC_DisableIRQ(irqn);
273289
} else if (flags & HAL_INTERRUPT_DIRECT_FLAG_ENABLE) {
274-
// sd_nvic_EnableIRQ(irqn);
290+
__NVIC_SetVector(irqn, (uint32_t)handler);
275291
}
276292

277-
HAL_enable_irq(state);
278-
279293
return 0;
280294
}

user/tests/wiring/no_fixture/interrupts.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,11 @@ test(INTERRUPTS_01_isisr_willpreempt_servicedirqn)
4747
assertFalse(hal_interrupt_will_preempt(SysTick_IRQn, SysTick_IRQn));
4848
assertTrue(hal_interrupt_will_preempt(NonMaskableInt_IRQn, SysTick_IRQn));
4949
assertFalse(hal_interrupt_will_preempt(SysTick_IRQn, NonMaskableInt_IRQn));
50+
51+
#if HAL_PLATFORM_RTL872X
52+
// Using arbitrary interrupt
53+
assertTrue(attachInterruptDirect(I2C0_IRQ, []() {return;}));
54+
assertFalse(attachInterruptDirect(I2C0_IRQ, []() {return;}));
55+
assertTrue(detachInterruptDirect(I2C0_IRQ));
56+
#endif
5057
}

0 commit comments

Comments
 (0)