4#include "AudioTools/CoreAudio/AudioPWM/PWMDriverBase.h"
5#include "driver/mcpwm.h"
92 is_timer_started =
false;
93 for (
int j = 0; j < pins.size(); j++) {
94 mcpwm_stop(pins[j].unit, pins[j].timer);
106 is_timer_started =
true;
116 if (audio_config.
channels > maxChannels()) {
117 LOGE(
"Only %d complementary channels supported", maxChannels());
118 audio_config.
channels = maxChannels();
120 bool has_pairs = audio_config.pins().size() >= (size_t)(audio_config.
channels * 2);
122 LOGW(
"Expected %d pins for %d complementary channels, got %d - assuming consecutive pin+1 as low-side", audio_config.
channels*2, audio_config.
channels, audio_config.pins().size());
125 for (
int j = 0; j < audio_config.
channels; j++) {
126 pins[j].unit = (mcpwm_unit_t)(j / 3);
127 pins[j].timer = (mcpwm_timer_t)(j % 3);
128 if (pins[j].unit > MCPWM_UNIT_1) { LOGE(
"Too many channels for MCPWM: %d", j);
break; }
130 pins[j].gpio_high = audio_config.pins()[j*2];
131 pins[j].gpio_low = audio_config.pins()[j*2 + 1];
133 pins[j].gpio_high = audio_config.pins()[j];
134 pins[j].gpio_low = pins[j].gpio_high + 1;
136 mcpwm_io_signals_t sigA = (mcpwm_io_signals_t)(MCPWM0A + (pins[j].timer * 2));
137 mcpwm_io_signals_t sigB = (mcpwm_io_signals_t)(MCPWM0B + (pins[j].timer * 2));
138 esp_err_t err = mcpwm_gpio_init(pins[j].unit, sigA, pins[j].gpio_high);
139 if (err != ESP_OK) LOGE(
"mcpwm_gpio_init high error=%d", (
int)err);
140 err = mcpwm_gpio_init(pins[j].unit, sigB, pins[j].gpio_low);
141 if (err != ESP_OK) LOGE(
"mcpwm_gpio_init low error=%d", (
int)err);
142 mcpwm_config_t cfg; cfg.frequency = audio_config.
pwm_frequency; cfg.cmpr_a = 0; cfg.cmpr_b = 0; cfg.counter_mode = MCPWM_UP_COUNTER; cfg.duty_mode = MCPWM_DUTY_MODE_0;
143 err = mcpwm_init(pins[j].unit, pins[j].timer, &cfg);
144 if (err != ESP_OK) LOGE(
"mcpwm_init error=%d", (
int)err);
147 uint32_t period_ticks = 80000000UL / audio_config.
pwm_frequency;
148 if (dead_ticks * 2 >= period_ticks) dead_ticks = period_ticks / 4;
149 if (dead_ticks > 0) {
150 err = mcpwm_deadtime_enable(pins[j].unit, pins[j].timer, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, dead_ticks, dead_ticks);
151 if (err != ESP_OK) LOGE(
"deadtime_enable error=%d", (
int)err);
154 LOGI(
"Complementary PWM ch=%d unit=%d timer=%d high=%d low=%d freq=%u dead_us=%u", j,(
int)pins[j].unit,(
int)pins[j].timer,pins[j].gpio_high,pins[j].gpio_low,(
unsigned)audio_config.
pwm_frequency,(
unsigned)audio_config.
dead_time_us);
161 timer.setCallbackParameter(
this);
162 timer.setIsSave(
false);
173 if (channel < 0 || channel >= pins.size())
return;
175 if (duty < 0) duty = 0;
else if (duty > 100) duty = 100;
176 mcpwm_set_duty(pins[channel].unit, pins[channel].timer, MCPWM_OPR_A, duty);
177 mcpwm_set_duty_type(pins[channel].unit, pins[channel].timer, MCPWM_OPR_A, MCPWM_DUTY_MODE_0);
180 mcpwm_set_duty(pins[channel].unit, pins[channel].timer, MCPWM_OPR_B, 100 - duty);
181 mcpwm_set_duty_type(pins[channel].unit, pins[channel].timer, MCPWM_OPR_B, MCPWM_DUTY_MODE_0);
188 uint32_t actual_timer_frequency = 0;
193 virtual int maxChannels() {
return 6; };
203#if defined(ESP32S2) || defined(ESP32S3)
204 switch (resolution) {
218 switch (resolution) {
235 if (drv !=
nullptr) {