7 #include <esp32-hal-ledc.h> 10 #include <driver/ledc.h> 16 static const char *
const TAG =
"ledc.output";
19 static const int MAX_RES_BITS = LEDC_TIMER_BIT_MAX - 1;
20 #if SOC_LEDC_SUPPORT_HS_MODE 22 inline ledc_mode_t
get_speed_mode(uint8_t channel) {
return channel < 8 ? LEDC_HIGH_SPEED_MODE : LEDC_LOW_SPEED_MODE; }
27 inline ledc_mode_t
get_speed_mode(uint8_t) {
return LEDC_LOW_SPEED_MODE; }
30 static const int MAX_RES_BITS = 20;
36 const float max_div_num = ((1 << MAX_RES_BITS) - 1) / (low_frequency ? 32.0f : 256.0f);
37 return 80e6f / (max_div_num * float(1 << bit_depth));
41 ESP_LOGD(TAG,
"Calculating resolution bit-depth for frequency %f", frequency);
42 for (
int i = MAX_RES_BITS; i >= 1; i--) {
45 if (min_frequency <= frequency && frequency <= max_frequency) {
46 ESP_LOGD(TAG,
"Resolution calculated as %d", i);
55 ESP_LOGW(TAG,
"LEDC output hasn't been initialized yet!");
63 const uint32_t max_duty = (uint32_t(1) << this->
bit_depth_) - 1;
64 const float duty_rounded = roundf(state * max_duty);
65 auto duty =
static_cast<uint32_t
>(duty_rounded);
72 auto chan_num =
static_cast<ledc_channel_t
>(
channel_ % 8);
73 ledc_set_duty(speed_mode, chan_num, duty);
74 ledc_update_duty(speed_mode, chan_num);
87 auto timer_num =
static_cast<ledc_timer_t
>((
channel_ % 8) / 2);
88 auto chan_num =
static_cast<ledc_channel_t
>(
channel_ % 8);
92 ESP_LOGW(TAG,
"Frequency %f can't be achieved with any bit depth",
frequency_);
96 ledc_timer_config_t timer_conf{};
97 timer_conf.speed_mode = speed_mode;
98 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(
bit_depth_);
99 timer_conf.timer_num = timer_num;
101 timer_conf.clk_cfg = LEDC_AUTO_CLK;
102 ledc_timer_config(&timer_conf);
104 ledc_channel_config_t chan_conf{};
106 chan_conf.speed_mode = speed_mode;
107 chan_conf.channel = chan_num;
108 chan_conf.intr_type = LEDC_INTR_DISABLE;
109 chan_conf.timer_sel = timer_num;
111 chan_conf.hpoint = 0;
112 ledc_channel_config(&chan_conf);
118 ESP_LOGCONFIG(TAG,
"LEDC Output:");
119 LOG_PIN(
" Pin ", this->
pin_);
120 ESP_LOGCONFIG(TAG,
" LEDC Channel: %u", this->
channel_);
121 ESP_LOGCONFIG(TAG,
" Frequency: %.1f Hz", this->
frequency_);
126 if (!bit_depth_opt.has_value()) {
127 ESP_LOGW(TAG,
"Frequency %f can't be achieved with any bit depth", frequency);
135 #endif // USE_ARDUINO 138 ESP_LOGW(TAG,
"LEDC output hasn't been initialized yet!");
142 auto timer_num =
static_cast<ledc_timer_t
>((
channel_ % 8) / 2);
144 ledc_timer_config_t timer_conf{};
145 timer_conf.speed_mode = speed_mode;
146 timer_conf.duty_resolution =
static_cast<ledc_timer_bit_t
>(
bit_depth_);
147 timer_conf.timer_num = timer_num;
149 timer_conf.clk_cfg = LEDC_AUTO_CLK;
150 ledc_timer_config(&timer_conf);
virtual void turn_off()
Disable this binary output.
uint8_t next_ledc_channel
void update_frequency(float frequency) override
Dynamically change frequency at runtime.
virtual uint8_t get_pin() const =0
ledc_mode_t get_speed_mode(uint8_t channel)
void write_state(float state) override
Override FloatOutput's write_state.
void status_set_warning()
void setup() override
Setup LEDC.
void dump_config() override
float ledc_min_frequency_for_bit_depth(uint8_t bit_depth, bool low_frequency)
optional< uint8_t > ledc_bit_depth_for_frequency(float frequency)
float ledc_max_frequency_for_bit_depth(uint8_t bit_depth)
virtual bool is_inverted() const =0