ESPHome  2024.4.1
rp2040_pwm.cpp
Go to the documentation of this file.
1 #ifdef USE_RP2040
2 
3 #include "rp2040_pwm.h"
4 #include "esphome/core/defines.h"
5 #include "esphome/core/helpers.h"
6 #include "esphome/core/log.h"
7 #include "esphome/core/macros.h"
8 
9 #include <hardware/clocks.h>
10 #include <hardware/gpio.h>
11 #include <hardware/pwm.h>
12 #include <cmath>
13 
14 namespace esphome {
15 namespace rp2040_pwm {
16 
17 static 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 }
48 void HOT RP2040PWM::write_state(float state) {
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
void setup() override
Initialize pin.
Definition: rp2040_pwm.cpp:19
InternalGPIOPin * pin_
Definition: rp2040_pwm.h:35
virtual uint8_t get_pin() const =0
void write_state(float state) override
Definition: rp2040_pwm.cpp:48
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
float last_output_
Cache last output level for dynamic frequency updating.
Definition: rp2040_pwm.h:39
virtual bool is_inverted() const =0
bool state
Definition: fan.h:34