From ffb1ad288f29faed92e8591c38724ed5efba721e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 16 Sep 2026 18:32:13 -0500 Subject: [PATCH] [remote_receiver] Wake the main loop when the RMT callback stores a frame (#19102) --- .../remote_receiver/remote_receiver_rmt.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/esphome/components/remote_receiver/remote_receiver_rmt.cpp b/esphome/components/remote_receiver/remote_receiver_rmt.cpp index 4eebbbb16f1..e4ffd7e1105 100644 --- a/esphome/components/remote_receiver/remote_receiver_rmt.cpp +++ b/esphome/components/remote_receiver/remote_receiver_rmt.cpp @@ -1,5 +1,6 @@ #include "remote_receiver.h" #include "esphome/core/log.h" +#include "esphome/core/wake.h" #ifdef USE_ESP32 #include @@ -14,25 +15,32 @@ static constexpr uint32_t DEFAULT_BUFFER_SLOTS = 4; static bool IRAM_ATTR HOT rmt_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *event, void *arg) { RemoteReceiverComponentStore *store = (RemoteReceiverComponentStore *) arg; - rmt_rx_done_event_data_t *event_buffer = (rmt_rx_done_event_data_t *) (store->buffer + store->buffer_write); + const uint32_t buffer_write = store->buffer_write; + rmt_rx_done_event_data_t *event_buffer = (rmt_rx_done_event_data_t *) (store->buffer + buffer_write); uint32_t event_size = sizeof(rmt_rx_done_event_data_t); - uint32_t next_write = store->buffer_write + event_size + event->num_symbols * sizeof(rmt_symbol_word_t); + uint32_t next_write = buffer_write + event_size + event->num_symbols * sizeof(rmt_symbol_word_t); if (next_write + event_size + store->receive_size > store->buffer_size) { next_write = 0; } if (store->buffer_read - next_write < event_size + store->receive_size) { - next_write = store->buffer_write; + next_write = buffer_write; store->overflow = true; } if (event->num_symbols <= store->filter_symbols) { - next_write = store->buffer_write; + next_write = buffer_write; } store->error = rmt_receive(channel, (uint8_t *) store->buffer + next_write + event_size, store->receive_size, &store->config); event_buffer->num_symbols = event->num_symbols; event_buffer->received_symbols = event->received_symbols; + const bool stored = next_write != buffer_write; store->buffer_write = next_write; - return false; + // a stored frame is decoded, and a failed re-arm reported, on the next loop pass instead of + // waiting out the loop interval; filtered noise and dropped frames leave nothing to read + BaseType_t task_woken = pdFALSE; + if (stored || store->error != ESP_OK) + wake_loop_isrsafe(&task_woken); + return task_woken != pdFALSE; } void RemoteReceiverComponent::setup() {