6#if defined(USE_RTL87XX) && !defined(CLANG_TIDY)
10#include <ArduinoPrivate.h>
11#ifndef USE_LIBRETINY_VARIANT_RTL8720C
18static const char *
const TAG =
"remote_transmitter";
25#ifdef USE_LIBRETINY_VARIANT_RTL8720C
26static constexpr uint32_t ENVELOPE_TIMER_ID = TIMER6;
31static uint8_t s_pwm_tick_sources[] = {GTimer1, GTimer2, GTimer3, GTimer4, GTimer5, GTimer6, 0xff};
32static gtimer_t s_envelope_timer;
33static bool s_envelope_timer_ready =
false;
36static void IRAM_ATTR envelope_timer_isr(
uint32_t arg) {
37 reinterpret_cast<RemoteTransmitterComponent *
>(arg)->advance_envelope_isr();
45 if (info ==
nullptr || !pinSupported(info, PIN_PWM)) {
47 ESP_LOGE(TAG,
"Pin %u is not PWM-capable", this->
pin_->
get_pin());
51 auto *pwm =
new pwmout_t();
53 pwmout_init(pwm,
static_cast<PinName
>(info->gpio));
54#ifdef USE_LIBRETINY_VARIANT_RTL8720C
57 ESP_LOGE(TAG,
"PWM init failed on pin %u", this->
pin_->
get_pin());
65 hal_pwm_comm_tick_source_list(s_pwm_tick_sources);
67 pwmout_period_us(pwm, 26);
69#ifdef USE_LIBRETINY_VARIANT_RTL8720C
70 if (!s_envelope_timer_ready) {
71 gtimer_init(&s_envelope_timer, ENVELOPE_TIMER_ID);
72 s_envelope_timer_ready =
true;
80 "Remote Transmitter:\n"
81 " Carrier Duty: %u%%",
83#ifdef USE_LIBRETINY_VARIANT_RTL8720C
84 ESP_LOGCONFIG(TAG,
" Non-blocking: %s", YESNO(this->
non_blocking_));
86 LOG_PIN(
" Pin: ", this->
pin_);
90 if (this->
pwm_ ==
nullptr)
92#ifdef USE_LIBRETINY_VARIANT_RTL8720C
96 pwmout_write(
static_cast<pwmout_t *
>(this->
pwm_), (value != this->
pin_->
is_inverted()) ? 1.0f : 0.0f);
99#ifdef USE_LIBRETINY_VARIANT_RTL8720C
109 float space_duty = 0.0f;
111 mark_duty = 1.0f - mark_duty;
119 const uint32_t period = std::max(
uint32_t(1), (1000000UL + carrier_frequency / 2) / carrier_frequency);
120 pwmout_period_us(
static_cast<pwmout_t *
>(this->
pwm_), period);
129 gtimer_start_one_shout(&s_envelope_timer, duration_us, (
void *) envelope_timer_isr, (
uint32_t)
this);
147 if (this->
pwm_ ==
nullptr) {
148 ESP_LOGW(TAG,
"Cannot send: PWM not initialized");
151 ESP_LOGD(TAG,
"Sending remote code");
156 float space_duty = 0.0f;
158 mark_duty = 1.0f - mark_duty;
161 auto *pwm =
static_cast<pwmout_t *
>(this->
pwm_);
164 const uint32_t period = std::max(
uint32_t(1), (1000000UL + carrier_frequency / 2) / carrier_frequency);
165 pwmout_period_us(pwm, period);
169 const UBaseType_t saved_priority = uxTaskPriorityGet(
nullptr);
170 for (
uint32_t i = 0; i < send_times; i++) {
174 vTaskPrioritySet(
nullptr, configMAX_PRIORITIES - 1);
179 const bool is_mark = item > 0;
181 pwmout_write(pwm, is_mark ? mark_duty : space_duty);
186 pwmout_write(pwm, space_duty);
187 vTaskPrioritySet(
nullptr, saved_priority);
188 if (i + 1 < send_times) {
192 while ((int32_t) (gap_end -
micros()) > 0) {
void feed_wdt()
Feed the task watchdog.
void mark_failed()
Mark this component as failed.
void disable_loop()
Disable this component's loop.
virtual uint8_t get_pin() const =0
virtual bool is_inverted() const =0
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
uint32_t get_carrier_frequency() const
const RawTimings & get_data() const
RemoteTransmitData temp_
Use same vector for all transmits, avoids many allocations.
void send_internal(uint32_t send_times, uint32_t send_wait) override
bool envelope_ready_() const
void write_envelope_level_(bool mark)
Trigger complete_trigger_
void stop_envelope_timer_()
uint32_t current_carrier_frequency_
Trigger transmit_trigger_
void await_target_time_()
void prepare_carrier_(uint32_t carrier_frequency)
void digital_write(bool value)
void arm_one_shot_(uint32_t duration_us)
uint8_t carrier_duty_percent_
void dump_config() override
uint32_t IRAM_ATTR HOT micros()
Application App
Global storage of Application pointer - only one Application can exist.