Allow setting htop for ledc (#6340)

This commit is contained in:
Gagootron 2024-03-20 09:17:32 +01:00 committed by GitHub
parent b95a7f6438
commit b0db7319f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 26 additions and 2 deletions

View file

@ -96,6 +96,12 @@ esp_err_t configure_timer_frequency(ledc_mode_t speed_mode, ledc_timer_t timer_n
}
#endif
#ifdef USE_ESP_IDF
constexpr int ledc_angle_to_htop(float angle, uint8_t bit_depth) {
return static_cast<int>(angle * ((1U << bit_depth) - 1) / 360.);
}
#endif // USE_ESP_IDF
void LEDCOutput::write_state(float state) {
if (!initialized_) {
ESP_LOGW(TAG, "LEDC output hasn't been initialized yet!");
@ -117,7 +123,8 @@ void LEDCOutput::write_state(float state) {
#ifdef USE_ESP_IDF
auto speed_mode = get_speed_mode(channel_);
auto chan_num = static_cast<ledc_channel_t>(channel_ % 8);
ledc_set_duty(speed_mode, chan_num, duty);
int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_);
ledc_set_duty_with_hpoint(speed_mode, chan_num, duty, hpoint);
ledc_update_duty(speed_mode, chan_num);
#endif
}
@ -143,8 +150,10 @@ void LEDCOutput::setup() {
this->status_set_error();
return;
}
int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_);
ESP_LOGV(TAG, "Configured frequency %f with a bit depth of %u bits", this->frequency_, this->bit_depth_);
ESP_LOGV(TAG, "Angle of %.1f° results in hpoint %u", this->phase_angle_, hpoint);
ledc_channel_config_t chan_conf{};
chan_conf.gpio_num = pin_->get_pin();
@ -153,7 +162,7 @@ void LEDCOutput::setup() {
chan_conf.intr_type = LEDC_INTR_DISABLE;
chan_conf.timer_sel = timer_num;
chan_conf.duty = inverted_ == pin_->is_inverted() ? 0 : (1U << bit_depth_);
chan_conf.hpoint = 0;
chan_conf.hpoint = hpoint;
ledc_channel_config(&chan_conf);
initialized_ = true;
this->status_clear_error();
@ -165,6 +174,7 @@ void LEDCOutput::dump_config() {
LOG_PIN(" Pin ", this->pin_);
ESP_LOGCONFIG(TAG, " LEDC Channel: %u", this->channel_);
ESP_LOGCONFIG(TAG, " PWM Frequency: %.1f Hz", this->frequency_);
ESP_LOGCONFIG(TAG, " Phase angle: %.1f°", this->phase_angle_);
ESP_LOGCONFIG(TAG, " Bit depth: %u", this->bit_depth_);
ESP_LOGV(TAG, " Max frequency for bit depth: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_));
ESP_LOGV(TAG, " Min frequency for bit depth: %f",

View file

@ -19,6 +19,7 @@ class LEDCOutput : public output::FloatOutput, public Component {
void set_channel(uint8_t channel) { this->channel_ = channel; }
void set_frequency(float frequency) { this->frequency_ = frequency; }
void set_phase_angle(float angle) { this->phase_angle_ = angle; }
/// Dynamically change frequency at runtime
void update_frequency(float frequency) override;
@ -35,6 +36,7 @@ class LEDCOutput : public output::FloatOutput, public Component {
InternalGPIOPin *pin_;
uint8_t channel_{};
uint8_t bit_depth_{};
float phase_angle_{0.0f};
float frequency_{};
float duty_{0.0f};
bool initialized_ = false;

View file

@ -3,6 +3,7 @@ from esphome.components import output
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import (
CONF_PHASE_ANGLE,
CONF_CHANNEL,
CONF_FREQUENCY,
CONF_ID,
@ -46,6 +47,9 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency,
cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15),
cv.Optional(CONF_PHASE_ANGLE): cv.All(
cv.only_with_esp_idf, cv.angle, cv.float_range(min=0.0, max=360.0)
),
}
).extend(cv.COMPONENT_SCHEMA)
@ -58,6 +62,8 @@ async def to_code(config):
if CONF_CHANNEL in config:
cg.add(var.set_channel(config[CONF_CHANNEL]))
cg.add(var.set_frequency(config[CONF_FREQUENCY]))
if CONF_PHASE_ANGLE in config:
cg.add(var.set_phase_angle(config[CONF_PHASE_ANGLE]))
@automation.register_action(

View file

@ -2,9 +2,12 @@ output:
- platform: ledc
id: light_output_1
pin: 1
channel: 0
- platform: ledc
id: light_output_2
pin: 2
channel: 1
phase_angle: 180°
light:
- platform: cwww

View file

@ -2,9 +2,12 @@ output:
- platform: ledc
id: light_output_1
pin: 12
channel: 0
- platform: ledc
id: light_output_2
pin: 13
channel: 1
phase_angle: 180°
light:
- platform: cwww