117 lines
4.0 KiB
C
117 lines
4.0 KiB
C
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
enum class Role : uint8_t { SOLO, MASTER, SLAVE };
|
|
enum class TestKind : uint8_t { OPTICAL, DRIVER };
|
|
enum class LightCode : uint8_t { HH, HL, LH, LL };
|
|
enum class FailReason : uint8_t {
|
|
NONE, NO_SIGNAL, PERIOD_OUT, DUTY_OUT, EXTRA_EDGE, GLITCH, LOST_EDGE,
|
|
DATA_LOSS, LINK_LOST, UNSUPPORTED, RESOLUTION, ABORTED,
|
|
ACK_MISSING, ACK_TIMING, DRIVER_FAULT, ACK_MERGED
|
|
};
|
|
|
|
const char *roleName(Role role);
|
|
const char *testKindName(TestKind kind);
|
|
const char *lightCodeName(LightCode code);
|
|
const char *failName(FailReason reason);
|
|
|
|
struct Settings {
|
|
uint16_t version;
|
|
uint8_t role;
|
|
uint8_t testKind;
|
|
uint8_t lightCode;
|
|
uint8_t frequencyIndex;
|
|
uint8_t maxPulseIndex;
|
|
uint8_t minPulseIndex;
|
|
uint8_t accuracyIndex;
|
|
uint8_t timeIndex;
|
|
uint16_t reserved;
|
|
uint32_t checksum;
|
|
};
|
|
|
|
struct TestParams {
|
|
uint32_t frequencyHz;
|
|
uint32_t maxPulseNs;
|
|
uint32_t minPulseNs;
|
|
float accuracyPct;
|
|
uint32_t testTimeMs;
|
|
};
|
|
|
|
struct PulsePeriod {
|
|
uint64_t startTick;
|
|
uint32_t periodTicks;
|
|
uint32_t activeTicks;
|
|
uint32_t activeTickHz;
|
|
};
|
|
|
|
struct StageStats {
|
|
uint32_t periods;
|
|
uint64_t periodSum;
|
|
uint64_t activeSum;
|
|
uint32_t minPeriod;
|
|
uint32_t maxPeriod;
|
|
uint32_t minActive;
|
|
uint32_t maxActive;
|
|
uint32_t firstBadPeriod;
|
|
uint8_t firstBadRepeat;
|
|
float badFrequency;
|
|
float badDuty;
|
|
uint32_t droppedItems;
|
|
FailReason reason;
|
|
void reset();
|
|
};
|
|
|
|
struct PeriodLimits {
|
|
uint32_t minPeriodTicks;
|
|
uint32_t maxPeriodTicks;
|
|
uint32_t minDutyX100;
|
|
uint32_t maxDutyX100;
|
|
};
|
|
|
|
struct IntegerPwmConfig {
|
|
uint32_t actualHz;
|
|
uint32_t dividerRaw;
|
|
uint32_t dutyCount;
|
|
uint32_t actualPulseNs;
|
|
uint8_t bits;
|
|
};
|
|
|
|
uint32_t settingsChecksum(const Settings &s);
|
|
bool txActiveLightOn(const Settings &s);
|
|
bool rxActiveLightOn(const Settings &s);
|
|
uint32_t pulseWidthPointCount(uint32_t maxPulseNs, uint32_t minPulseNs);
|
|
uint32_t pulseWidthAt(uint32_t maxPulseNs, uint32_t minPulseNs, uint32_t index);
|
|
uint64_t nominalStageUs(uint32_t frequencyHz, uint32_t sampleTimeMs, uint32_t settleCycles);
|
|
uint64_t nominalTotalUs(const TestParams &p, uint32_t settleCycles);
|
|
bool periodWithin(float measuredHz, float expectedHz, float tolerancePct);
|
|
bool dutyWithin(float measuredPct, float expectedPct, float tolerancePct);
|
|
float effectiveTolerancePct(float configuredPct);
|
|
uint8_t choosePwmResolution(uint32_t frequencyHz, uint32_t sourceClockHz,
|
|
uint8_t maxBits);
|
|
uint8_t chooseStablePwmResolution(uint32_t frequencyHz, uint32_t sourceClockHz,
|
|
uint8_t maxBits, uint8_t dutyPct);
|
|
bool choosePwmConfig(uint32_t requestedHz, uint32_t requestedPulseNs,
|
|
uint32_t sourceClockHz, uint8_t maxBits,
|
|
IntegerPwmConfig &config);
|
|
FailReason validateResolution(uint32_t frequencyHz, float dutyPct, float accuracyPct,
|
|
uint32_t periodResolutionHz, uint32_t pulseResolutionHz,
|
|
uint8_t pwmBits,
|
|
uint16_t averagingPeriods);
|
|
FailReason evaluatePeriod(const PulsePeriod &period, uint32_t tickHz, float expectedHz,
|
|
float expectedDuty, float tolerancePct, uint8_t repeat,
|
|
StageStats &stats);
|
|
bool makePeriodLimits(uint32_t expectedHz, float expectedDuty, float tolerancePct,
|
|
uint32_t tickHz, PeriodLimits &limits);
|
|
FailReason evaluatePeriodFast(const PulsePeriod &period, uint32_t tickHz,
|
|
const PeriodLimits &limits, uint8_t repeat,
|
|
StageStats &stats);
|
|
FailReason evaluatePeriodWindow(uint64_t periodSum, uint64_t activeSum,
|
|
uint32_t periodCount, uint32_t tickHz,
|
|
float expectedHz, float expectedDuty,
|
|
float tolerancePct,
|
|
uint32_t minPeriod, uint32_t maxPeriod,
|
|
uint8_t repeat,
|
|
StageStats &stats);
|