Files
OptoTest/OpticalChannelTester/Pwm.cpp
2026-08-05 16:49:05 +03:00

40 lines
1.6 KiB
C++

#include "Pwm.h"
#include "Config.h"
void PwmGenerator::begin() { pinMode(GPIO_PWM, OUTPUT); stop(); }
bool PwmGenerator::start(uint32_t hz, uint8_t dutyPct, ActualPwm &a) {
stop();
uint8_t bits = LEDC_MAX_BITS;
while (bits > 1 && static_cast<uint64_t>(hz) * (1ULL << bits) > 80000000ULL) --bits;
if (!ledcAttachChannel(GPIO_PWM, hz, bits, LEDC_CHANNEL)) return false;
const uint32_t top = (1UL << bits) - 1UL;
const uint32_t duty = (static_cast<uint64_t>(top) * 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 / top, bits};
running_ = true;
return true;
}
bool PwmGenerator::preview(uint32_t hz, uint8_t dutyPct, ActualPwm &a) {
stop();
uint8_t bits = LEDC_MAX_BITS;
while (bits > 1 && static_cast<uint64_t>(hz) * (1ULL << bits) > 80000000ULL) --bits;
if (!ledcAttachChannel(GPIO_PWM, hz, bits, LEDC_CHANNEL)) return false;
ledcWriteChannel(LEDC_CHANNEL, 0); // query hardware without emitting test pulses
const uint32_t actualHz = ledcReadFreq(GPIO_PWM);
const uint32_t top = (1UL << bits) - 1UL;
const uint32_t duty = (static_cast<uint64_t>(top) * dutyPct + 50U) / 100U;
a = {hz, actualHz, 100.0f * duty / top, bits};
ledcDetach(GPIO_PWM); pinMode(GPIO_PWM, OUTPUT); digitalWrite(GPIO_PWM, PWM_SAFE_LEVEL);
return actualHz != 0;
}
void PwmGenerator::stop() {
if (running_) ledcDetach(GPIO_PWM);
pinMode(GPIO_PWM, OUTPUT); digitalWrite(GPIO_PWM, PWM_SAFE_LEVEL);
running_ = false;
}