[remote_transmitter] Fix repeat gap timing on LibreTiny Beken (#18585)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Keith Burzinski
2026-08-21 23:10:47 -05:00
committed by GitHub
co-authored by J. Nick Koston
parent 11ea819bc7
commit 8e9fb0f93c
3 changed files with 34 additions and 15 deletions
@@ -81,10 +81,14 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
ESP_LOGD(TAG, "Sending remote code"); ESP_LOGD(TAG, "Sending remote code");
uint32_t on_time, off_time; uint32_t on_time, off_time;
this->calculate_on_off_time_(this->temp_.get_carrier_frequency(), &on_time, &off_time); this->calculate_on_off_time_(this->temp_.get_carrier_frequency(), &on_time, &off_time);
this->target_time_ = 0;
this->transmit_trigger_.trigger(); this->transmit_trigger_.trigger();
for (uint32_t i = 0; i < send_times; i++) { for (uint32_t i = 0; i < send_times; i++) {
{
InterruptLock lock; InterruptLock lock;
// Re-anchor every iteration: timing must never span a lock boundary, as micros() can
// jump when interrupts are re-enabled between repeats (e.g. LibreTiny's Beken micros()
// discards its interrupt-lock correction, stretching the repeat gap by the lock duration)
this->target_time_ = 0;
for (int32_t item : this->temp_.get_data()) { for (int32_t item : this->temp_.get_data()) {
if (item > 0) { if (item > 0) {
const auto length = uint32_t(item); const auto length = uint32_t(item);
@@ -97,9 +101,17 @@ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t sen
} }
this->await_target_time_(); // wait for duration of last pulse this->await_target_time_(); // wait for duration of last pulse
this->pin_->digital_write(false); this->pin_->digital_write(false);
}
if (i + 1 < send_times) if (i + 1 < send_times) {
this->target_time_ += send_wait; // Wait out the repeat gap with interrupts enabled: wait_time is unbounded user config
// (previously this spin ran inside the next iteration's lock, disabling interrupts for
// the whole gap). Anchoring after the lock release keeps it exact on all platforms.
const uint32_t gap_end = micros() + send_wait;
while ((int32_t) (gap_end - micros()) > 0) {
App.feed_wdt();
}
}
} }
this->complete_trigger_.trigger(); this->complete_trigger_.trigger();
} }
@@ -72,7 +72,7 @@ class RemoteTransmitterComponent final : public remote_base::RemoteTransmitterBa
void space_(uint32_t usec); void space_(uint32_t usec);
void await_target_time_(); void await_target_time_();
uint32_t target_time_; uint32_t target_time_{0};
#endif #endif
#if defined(USE_ESP32) && SOC_RMT_SUPPORTED #if defined(USE_ESP32) && SOC_RMT_SUPPORTED
@@ -0,0 +1,7 @@
remote_transmitter:
id: xmitr
pin: GPIO26
carrier_duty_percent: 50%
packages:
buttons: !include common-buttons.yaml