ESPHome 2025.5.0
Loading...
Searching...
No Matches
rp2040_pwm.cpp
Go to the documentation of this file.
1#ifdef USE_RP2040
2
3#include "rp2040_pwm.h"
6#include "esphome/core/log.h"
8
9#include <hardware/clocks.h>
10#include <hardware/gpio.h>
11#include <hardware/pwm.h>
12#include <cmath>
13
14namespace esphome {
15namespace rp2040_pwm {
16
17static const char *const TAG = "rp2040_pwm";
18
20 ESP_LOGCONFIG(TAG, "Setting up RP2040 PWM Output...");
21
22 this->setup_pwm_();
23}
24
26 pwm_config config = pwm_get_default_config();
27
28 uint32_t clock = clock_get_hz(clk_sys);
29 float divider = ceil(clock / (4096 * this->frequency_)) / 16.0f;
30 if (divider < 1.0f) {
31 divider = 1.0f;
32 }
33 uint16_t wrap = clock / divider / this->frequency_ - 1;
34 this->wrap_ = wrap;
35 ESP_LOGD(TAG, "divider=%.5f, wrap=%d, clock=%d", divider, wrap, clock);
36
37 pwm_config_set_clkdiv(&config, divider);
38 pwm_config_set_wrap(&config, wrap);
39 pwm_init(pwm_gpio_to_slice_num(this->pin_->get_pin()), &config, true);
40}
41
43 ESP_LOGCONFIG(TAG, "RP2040 PWM:");
44 LOG_PIN(" Pin: ", this->pin_);
45 ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_);
46 LOG_FLOAT_OUTPUT(this);
47}
49 this->last_output_ = state;
50
51 // Also check pin inversion
52 if (this->pin_->is_inverted()) {
53 state = 1.0f - state;
54 }
55
56 if (this->frequency_changed_) {
57 this->setup_pwm_();
58 this->frequency_changed_ = false;
59 }
60
61 gpio_set_function(this->pin_->get_pin(), GPIO_FUNC_PWM);
62 pwm_set_gpio_level(this->pin_->get_pin(), state * this->wrap_);
63}
64
65} // namespace rp2040_pwm
66} // namespace esphome
67
68#endif
virtual uint8_t get_pin() const =0
virtual bool is_inverted() const =0
void write_state(float state) override
float last_output_
Cache last output level for dynamic frequency updating.
Definition rp2040_pwm.h:39
void setup() override
Initialize pin.
bool state
Definition fan.h:0
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7