I want to share the approach I took to abstract interrupts on a test RX app on an STM32 Nucleo board, using the NRF24L01+. Conceptually I want my "app code" to "wait" for an interrupt to be processed. I therefore want the ISR to "notify" the app. Here's how I do that, the mechanism seems to work well, it behaves as I expect but is there a downside? a better way?
Main app:
ISR:
The two support functions:
and
That "complete" flag is a flag on a small struct that's part of the device struct:
Main app:
C:
while (1)
{
nrf24_package.Action.WaitForRxInterrupt(&device, -1);
nrf24_package.Command.R_RX_PL_WID(&device, &width, &status);
nrf24_package.Command.R_RX_PAYLOAD(&device, buffer, width, &status); // TODO we should not need to pass payload_size
pulse_led(1); // lets us see messages are arriving
}
C:
void EXTI0_IRQHandler(void)
{
NrfReg_STATUS status;
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
nrf24_package.Read.STATUS(&device, &status);
if (status.RX_DR)
{
status.TX_DS = 0;
status.MAX_RT = 0;
nrf24_package.Write.STATUS(&device, status, &status);
nrf24_package.Action.ConfirmRxInterrupt(&device);
}
else
{
nrf24_hal_support.flash_red_led_forever(100); // shd never happen
}
}
C:
private void wait_for_interrupt(volatile NrfInterrupt_ptr state_ptr, int32_t max_spins)
{
state_ptr->spins = 0;
while (state_ptr->complete == 0)
{
state_ptr->spins++;
if (state_ptr->spins >= 0)
if (state_ptr->spins >= max_spins)
ApplicationFaultHandler(LIBNAME, "missing interrupt");
}
if (state_ptr->spins > state_ptr->max_so_far)
state_ptr->max_so_far = state_ptr->spins;
state_ptr->count++;
state_ptr->complete = 0;
}
C:
private void confirm_interrupt(volatile NrfInterrupt_ptr state_ptr)
{
state_ptr->complete = 1;
}
C:
struct nrf_interrupt
{
volatile uint32_t complete;
uint32_t spins;
uint32_t max_so_far;
uint32_t count;
};
Last edited: