#include "Pwm.h" #include "Config.h" #include "Core.h" void PwmGenerator::begin() { // Match LEDC_SOURCE_CLOCK_HZ and make the timer calculation deterministic. ledcSetClockSource(LEDC_USE_XTAL_CLK); pinMode(GPIO_PWM, OUTPUT); stop(); } bool PwmGenerator::start(uint32_t hz, uint8_t dutyPct, ActualPwm &a) { stop(); const uint8_t bits = choosePwmResolution(hz, LEDC_SOURCE_CLOCK_HZ, LEDC_MAX_BITS); if (!bits) return false; if (!ledcAttachChannel(GPIO_PWM, hz, bits, LEDC_CHANNEL)) return false; const uint32_t levels = 1UL << bits; const uint32_t duty = (static_cast(levels) * dutyPct + 50U) / 100U; if (!ledcWriteChannel(LEDC_CHANNEL, duty)) { ledcDetach(GPIO_PWM); return false; } const uint32_t actualHz = ledcReadFreq(GPIO_PWM); if (!actualHz) { ledcDetach(GPIO_PWM); return false; } a = {hz, actualHz, 100.0f * duty / levels, bits}; running_ = true; return true; } void PwmGenerator::stop() { if (running_) ledcDetach(GPIO_PWM); pinMode(GPIO_PWM, OUTPUT); digitalWrite(GPIO_PWM, PWM_SAFE_LEVEL); running_ = false; }