доработки всякие
This commit is contained in:
@@ -89,7 +89,7 @@ bool dutyWithin(float measured, float expected, float tolerance) {
|
||||
}
|
||||
|
||||
float effectiveTolerancePct(float configured) {
|
||||
return configured > 0.0f && configured <= 1.0001f ? 1.25f : configured;
|
||||
return configured;
|
||||
}
|
||||
|
||||
uint8_t choosePwmResolution(uint32_t frequencyHz, uint32_t sourceClockHz,
|
||||
@@ -166,14 +166,17 @@ bool chooseIntegerPwmConfig(uint32_t requestedHz, uint32_t sourceClockHz,
|
||||
}
|
||||
|
||||
FailReason validateResolution(uint32_t frequencyHz, float dutyPct, float accuracyPct,
|
||||
uint32_t captureHz, uint8_t pwmBits) {
|
||||
if (!frequencyHz || !captureHz || !pwmBits) return FailReason::RESOLUTION;
|
||||
uint32_t captureHz, uint8_t pwmBits,
|
||||
uint16_t averagingPeriods) {
|
||||
if (!frequencyHz || !captureHz || !pwmBits || !averagingPeriods)
|
||||
return FailReason::RESOLUTION;
|
||||
const float periodTicks = static_cast<float>(captureHz) / frequencyHz;
|
||||
const float activeTicks = periodTicks * dutyPct / 100.0f;
|
||||
const float inactiveTicks = periodTicks - activeTicks;
|
||||
if (periodTicks < 4.0f || activeTicks < 2.0f || inactiveTicks < 2.0f) return FailReason::RESOLUTION;
|
||||
const float timerPeriodError = 100.0f / periodTicks;
|
||||
const float timerDutyError = 100.0f / periodTicks;
|
||||
const float averagedTicks = periodTicks * averagingPeriods;
|
||||
const float timerPeriodError = 100.0f / averagedTicks;
|
||||
const float timerDutyError = 100.0f / averagedTicks;
|
||||
// Measurement uses the duty actually programmed into LEDC. A coarse PWM
|
||||
// step is not itself an error when the requested value (e.g. 50%) is exactly
|
||||
// representable; only the selected value's actual quantization matters.
|
||||
@@ -256,3 +259,60 @@ FailReason evaluatePeriodFast(const PulsePeriod &p, uint32_t tickHz,
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
FailReason evaluatePeriodWindow(uint64_t periodSum, uint64_t activeSum,
|
||||
uint32_t periodCount, uint32_t tickHz,
|
||||
float expectedHz, float expectedDuty,
|
||||
float tolerance,
|
||||
uint32_t minPeriod, uint32_t maxPeriod,
|
||||
uint8_t repeat,
|
||||
StageStats &s) {
|
||||
if (!periodSum || !periodCount || activeSum >= periodSum || !tickHz)
|
||||
return FailReason::EXTRA_EDGE;
|
||||
const float hz = static_cast<float>(
|
||||
static_cast<double>(tickHz) * periodCount / periodSum);
|
||||
const float duty = static_cast<float>(
|
||||
100.0 * static_cast<double>(activeSum) / periodSum);
|
||||
bool frequencyOk = periodWithin(hz, expectedHz, tolerance);
|
||||
if (!frequencyOk && maxPeriod == minPeriod + 1U) {
|
||||
// At a tolerance boundary, alternating adjacent RMT counts prove that the
|
||||
// result is quantization-limited. Accept only when a one-tick correction
|
||||
// toward the expected value returns the averaged frequency into tolerance.
|
||||
// Consecutive periods telescope into one first-to-last edge interval, so
|
||||
// the whole window has a one-tick endpoint uncertainty, not one tick per
|
||||
// period.
|
||||
uint64_t correctedPeriodSum = periodSum;
|
||||
if (hz > expectedHz) ++correctedPeriodSum;
|
||||
else if (periodSum > 1U) --correctedPeriodSum;
|
||||
const float correctedHz = static_cast<float>(
|
||||
static_cast<double>(tickHz) * periodCount / correctedPeriodSum);
|
||||
frequencyOk = periodWithin(correctedHz, expectedHz, tolerance);
|
||||
}
|
||||
|
||||
bool dutyOk = dutyWithin(duty, expectedDuty, tolerance);
|
||||
if (!dutyOk) {
|
||||
// Unlike full periods, active intervals do not telescope: every pulse is
|
||||
// bounded by a different rising/falling edge pair. With slowly drifting
|
||||
// asynchronous clocks an entire short window can therefore quantize to
|
||||
// the same adjacent count (e.g. 41/80 for a true 50% duty). Apply one tick
|
||||
// per active interval even when minActive == maxActive.
|
||||
const bool dutyHigh = duty > expectedDuty;
|
||||
const uint64_t correctedActive = dutyHigh
|
||||
? (activeSum > periodCount ? activeSum - periodCount : 0U)
|
||||
: activeSum + periodCount;
|
||||
const float correctedDuty = static_cast<float>(
|
||||
100.0 * static_cast<double>(correctedActive) / periodSum);
|
||||
dutyOk = dutyWithin(correctedDuty, expectedDuty, tolerance);
|
||||
}
|
||||
|
||||
FailReason reason = !frequencyOk ? FailReason::PERIOD_OUT :
|
||||
(!dutyOk ? FailReason::DUTY_OUT : FailReason::NONE);
|
||||
if (reason != FailReason::NONE && s.reason == FailReason::NONE) {
|
||||
s.reason = reason;
|
||||
s.firstBadPeriod = s.periods >= periodCount ? s.periods - periodCount + 1U : 1U;
|
||||
s.firstBadRepeat = repeat;
|
||||
s.badFrequency = hz;
|
||||
s.badDuty = duty;
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user