mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Allow setting htop for ledc (#6340)
This commit is contained in:
parent
b95a7f6438
commit
b0db7319f9
5 changed files with 26 additions and 2 deletions
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue