Skip to content

Commit 1fdc5d2

Browse files
committed
[p2] Only restore handler if one was backed up.
Return error if overriding handler multiple times.
1 parent 9121cf4 commit 1fdc5d2

File tree

2 files changed

+30
-20
lines changed

2 files changed

+30
-20
lines changed

hal/src/rtl872x/interrupts_hal.cpp

+23-20
Original file line numberDiff line numberDiff line change
@@ -258,36 +258,39 @@ int hal_interrupt_set_direct_handler(IRQn_Type irqn, hal_interrupt_direct_handle
258258
return 1;
259259
}
260260

261+
int error = 0;
261262
int32_t state = HAL_disable_irq();
262263

263264
if (handler == nullptr && (flags & HAL_INTERRUPT_DIRECT_FLAG_RESTORE)) {
264-
// Restore
265+
// Restore old handler only if one was backed up
265266
uint32_t old_handler = hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)];
266-
__NVIC_SetVector(irqn, (uint32_t)old_handler);
267-
268-
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = 0;
269-
} else {
270-
271-
// If there is currently a backup: Return error
272-
if(hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)]){
273-
return 1;
267+
if (old_handler) {
268+
__NVIC_SetVector(irqn, (uint32_t)old_handler);
269+
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = 0;
274270
}
275-
276-
// If there is a current handler, back it up
277-
uint32_t current_handler = __NVIC_GetVector(irqn);
278-
if (current_handler) {
279-
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = current_handler;
271+
} else {
272+
// If there is currently a handler backup: Return error
273+
if (hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)]) {
274+
error = SYSTEM_ERROR_NOT_SUPPORTED;
275+
} else {
276+
// If there is a current handler, back it up
277+
uint32_t current_handler = __NVIC_GetVector(irqn);
278+
if (current_handler) {
279+
hal_interrupts_handler_backup[IRQN_TO_IDX(irqn)] = current_handler;
280+
}
280281
}
281282
}
282283

283-
if (flags & HAL_INTERRUPT_DIRECT_FLAG_DISABLE) {
284-
// Disable
285-
//__NVIC_DisableIRQ(irqn); // actually disable the interrupt (ie like systick!?)
286-
} else if (flags & HAL_INTERRUPT_DIRECT_FLAG_ENABLE) {
287-
__NVIC_SetVector(irqn, (uint32_t)handler);
284+
if (!error) {
285+
if (flags & HAL_INTERRUPT_DIRECT_FLAG_DISABLE) {
286+
// Disable
287+
__NVIC_DisableIRQ(irqn);
288+
} else if (flags & HAL_INTERRUPT_DIRECT_FLAG_ENABLE) {
289+
__NVIC_SetVector(irqn, (uint32_t)handler);
290+
}
288291
}
289292

290293
HAL_enable_irq(state);
291294

292-
return 0;
295+
return error;
293296
}

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)