mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 15:08:10 +01:00
Calculate PWM wrap dynamically whenever the frequency is changed (#4294)
fixes https://github.com/esphome/issues/issues/3841
This commit is contained in:
parent
27185265f6
commit
a45646af1b
2 changed files with 11 additions and 3 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <hardware/clocks.h>
|
#include <hardware/clocks.h>
|
||||||
#include <hardware/gpio.h>
|
#include <hardware/gpio.h>
|
||||||
#include <hardware/pwm.h>
|
#include <hardware/pwm.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace rp2040_pwm {
|
namespace rp2040_pwm {
|
||||||
|
@ -23,8 +24,14 @@ void RP2040PWM::setup() {
|
||||||
|
|
||||||
void RP2040PWM::setup_pwm_() {
|
void RP2040PWM::setup_pwm_() {
|
||||||
pwm_config config = pwm_get_default_config();
|
pwm_config config = pwm_get_default_config();
|
||||||
pwm_config_set_clkdiv(&config, clock_get_hz(clk_sys) / (255.0f * this->frequency_));
|
|
||||||
pwm_config_set_wrap(&config, 254);
|
uint32_t clock = clock_get_hz(clk_sys);
|
||||||
|
float divider = ceil(clock / (4096 * this->frequency_)) / 16.0f;
|
||||||
|
uint16_t wrap = clock / divider / this->frequency_ - 1;
|
||||||
|
this->wrap_ = wrap;
|
||||||
|
|
||||||
|
pwm_config_set_clkdiv(&config, divider);
|
||||||
|
pwm_config_set_wrap(&config, wrap);
|
||||||
pwm_init(pwm_gpio_to_slice_num(this->pin_->get_pin()), &config, true);
|
pwm_init(pwm_gpio_to_slice_num(this->pin_->get_pin()), &config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +55,7 @@ void HOT RP2040PWM::write_state(float state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_set_function(this->pin_->get_pin(), GPIO_FUNC_PWM);
|
gpio_set_function(this->pin_->get_pin(), GPIO_FUNC_PWM);
|
||||||
pwm_set_gpio_level(this->pin_->get_pin(), state * 255.0f);
|
pwm_set_gpio_level(this->pin_->get_pin(), state * this->wrap_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace rp2040_pwm
|
} // namespace rp2040_pwm
|
||||||
|
|
|
@ -34,6 +34,7 @@ class RP2040PWM : public output::FloatOutput, public Component {
|
||||||
|
|
||||||
InternalGPIOPin *pin_;
|
InternalGPIOPin *pin_;
|
||||||
float frequency_{1000.0};
|
float frequency_{1000.0};
|
||||||
|
uint16_t wrap_{65535};
|
||||||
/// Cache last output level for dynamic frequency updating
|
/// Cache last output level for dynamic frequency updating
|
||||||
float last_output_{0.0};
|
float last_output_{0.0};
|
||||||
bool frequency_changed_{false};
|
bool frequency_changed_{false};
|
||||||
|
|
Loading…
Reference in a new issue