mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 00:48:19 +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/gpio.h>
|
||||
#include <hardware/pwm.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace esphome {
|
||||
namespace rp2040_pwm {
|
||||
|
@ -23,8 +24,14 @@ void RP2040PWM::setup() {
|
|||
|
||||
void RP2040PWM::setup_pwm_() {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -48,7 +55,7 @@ void HOT RP2040PWM::write_state(float state) {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -34,6 +34,7 @@ class RP2040PWM : public output::FloatOutput, public Component {
|
|||
|
||||
InternalGPIOPin *pin_;
|
||||
float frequency_{1000.0};
|
||||
uint16_t wrap_{65535};
|
||||
/// Cache last output level for dynamic frequency updating
|
||||
float last_output_{0.0};
|
||||
bool frequency_changed_{false};
|
||||
|
|
Loading…
Reference in a new issue