diff --git a/arch/xtensa/src/esp32s2/esp32s2_oneshot.c b/arch/xtensa/src/esp32s2/esp32s2_oneshot.c index ced51d210f..70c2596837 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_oneshot.c +++ b/arch/xtensa/src/esp32s2/esp32s2_oneshot.c @@ -85,20 +85,15 @@ static int esp32s2_oneshot_handler(int irq, void *context, void *arg); static int esp32s2_oneshot_handler(int irq, void *context, void *arg) { int ret = OK; - struct esp32s2_oneshot_s *oneshot = - (struct esp32s2_oneshot_s *)arg; + struct esp32s2_oneshot_s *oneshot = (struct esp32s2_oneshot_s *)arg; + oneshot_handler_t handler; + void *handler_arg; - DEBUGASSERT(oneshot != NULL && oneshot->handler != NULL); + DEBUGASSERT(oneshot != NULL); + DEBUGASSERT(oneshot->handler != NULL); tmrinfo("Oneshot handler triggered\n"); - /* Stop timer - * Note: It's not necessary to disable the alarm because - * it automatically disables each time it expires. - */ - - ESP32S2_TIM_STOP(oneshot->tim); - /* Disable interrupts */ ESP32S2_TIM_DISABLEINT(oneshot->tim); @@ -107,20 +102,25 @@ static int esp32s2_oneshot_handler(int irq, void *context, void *arg) ret = ESP32S2_TIM_SETISR(oneshot->tim, NULL, NULL); - /* Call the callback */ - - oneshot->handler((void *)oneshot->arg); - - /* Restore state */ - - oneshot->running = false; - oneshot->handler = NULL; - oneshot->arg = NULL; - /* Clear the Interrupt */ ESP32S2_TIM_ACKINT(oneshot->tim); + /* The timer is no longer running */ + + oneshot->running = false; + + /* Forward the event, clearing out any vestiges */ + + handler = (oneshot_handler_t)oneshot->handler; + oneshot->handler = NULL; + handler_arg = (void *)oneshot->arg; + oneshot->arg = NULL; + + /* Call the callback */ + + handler(handler_arg); + return ret; } diff --git a/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c b/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c index 935779d1f8..78954b1001 100644 --- a/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c +++ b/arch/xtensa/src/esp32s2/esp32s2_oneshot_lowerhalf.c @@ -114,20 +114,26 @@ static void esp32s2_oneshot_lh_handler(void *arg) { struct esp32s2_oneshot_lowerhalf_s *priv = (struct esp32s2_oneshot_lowerhalf_s *)arg; + oneshot_callback_t callback; + FAR void *cb_arg; DEBUGASSERT(priv != NULL); DEBUGASSERT(priv->callback != NULL); tmrinfo("Oneshot LH handler triggered\n"); - /* Call the callback */ - - priv->callback(&priv->lh, priv->arg); - - /* Restore state */ + /* Sample and nullify BEFORE executing callback (in case the callback + * restarts the oneshot). + */ + callback = priv->callback; + cb_arg = priv->arg; priv->callback = NULL; - priv->arg = NULL; + priv->arg = NULL; + + /* Then perform the callback */ + + callback(&priv->lh, cb_arg); } /****************************************************************************