mirror of
https://github.com/micropython/micropython.git
synced 2026-01-05 03:30:14 +01:00
esp32: Re-use allocated timer interrupts and simplify UART timer code.
If the interrupt is not freed but merely disabled, instead of reallocating it every time the timer is enabled again we can instead just re-enable it. That means we're no longer setting the handler every time, and we need to ensure it does not change. Doing so by adding an additional wrapper function does not only solve that problem, it also allows us to remove some code duplication and simplify how machine_uart uses the timer. Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
This commit is contained in:
committed by
Damien George
parent
bf909303ff
commit
2c2f0b292a
@@ -110,30 +110,19 @@ static const char *_parity_name[] = {"None", "1", "0"};
|
||||
{ MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_IRQ_RXIDLE) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_IRQ_BREAK), MP_ROM_INT(UART_IRQ_BREAK) }, \
|
||||
|
||||
static void uart_timer_callback(void *self_in) {
|
||||
machine_timer_obj_t *self = self_in;
|
||||
|
||||
uint32_t intr_status = timer_ll_get_intr_status(self->hal_context.dev);
|
||||
|
||||
if (intr_status & TIMER_LL_EVENT_ALARM(self->index)) {
|
||||
timer_ll_clear_intr_status(self->hal_context.dev, TIMER_LL_EVENT_ALARM(self->index));
|
||||
if (self->repeat) {
|
||||
timer_ll_enable_alarm(self->hal_context.dev, self->index, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_timer_callback(machine_timer_obj_t *timer) {
|
||||
// The UART object is referred here by the callback field.
|
||||
machine_uart_obj_t *uart = (machine_uart_obj_t *)self->callback;
|
||||
if (uart->rxidle_state == RXIDLE_ALERT) {
|
||||
machine_uart_obj_t *self = (machine_uart_obj_t *)timer->callback;
|
||||
if (self->rxidle_state == RXIDLE_ALERT) {
|
||||
// At the first call, just switch the state
|
||||
uart->rxidle_state = RXIDLE_ARMED;
|
||||
} else if (uart->rxidle_state == RXIDLE_ARMED) {
|
||||
self->rxidle_state = RXIDLE_ARMED;
|
||||
} else if (self->rxidle_state == RXIDLE_ARMED) {
|
||||
// At the second call, run the irq callback and stop the timer
|
||||
uart->rxidle_state = RXIDLE_STANDBY;
|
||||
uart->mp_irq_flags = UART_IRQ_RXIDLE;
|
||||
mp_irq_handler(uart->mp_irq_obj);
|
||||
self->rxidle_state = RXIDLE_STANDBY;
|
||||
self->mp_irq_flags = UART_IRQ_RXIDLE;
|
||||
mp_irq_handler(self->mp_irq_obj);
|
||||
mp_hal_wake_main_task_from_isr();
|
||||
machine_timer_disable(uart->rxidle_timer);
|
||||
machine_timer_disable(self->rxidle_timer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,9 +139,7 @@ static void uart_event_task(void *self_in) {
|
||||
if (self->mp_irq_trigger & UART_IRQ_RXIDLE) {
|
||||
if (self->rxidle_state != RXIDLE_INACTIVE) {
|
||||
if (self->rxidle_state == RXIDLE_STANDBY) {
|
||||
self->rxidle_timer->repeat = true;
|
||||
self->rxidle_timer->handle = NULL;
|
||||
machine_timer_enable(self->rxidle_timer, uart_timer_callback);
|
||||
machine_timer_enable(self->rxidle_timer);
|
||||
}
|
||||
}
|
||||
self->rxidle_state = RXIDLE_ALERT;
|
||||
@@ -553,11 +540,11 @@ static void uart_irq_configure_timer(machine_uart_obj_t *self, mp_uint_t trigger
|
||||
}
|
||||
self->rxidle_period = period;
|
||||
self->rxidle_timer->period = period;
|
||||
self->rxidle_timer->handler = uart_timer_callback;
|
||||
// The Python callback is not used. So use this
|
||||
// data field to hold a reference to the UART object.
|
||||
self->rxidle_timer->callback = self;
|
||||
self->rxidle_timer->repeat = true;
|
||||
self->rxidle_timer->handle = NULL;
|
||||
self->rxidle_state = RXIDLE_STANDBY;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user