Files
OptoTest/OpticalChannelTester/Core.h

95 lines
3.0 KiB
C

#pragma once
#include <stdint.h>
#include <stddef.h>
enum class Role : uint8_t { SOLO, MASTER, SLAVE };
enum class FailReason : uint8_t {
NONE, NO_SIGNAL, PERIOD_OUT, DUTY_OUT, EXTRA_EDGE, GLITCH, LOST_EDGE,
DATA_LOSS, LINK_LOST, UNSUPPORTED, RESOLUTION, ABORTED
};
const char *roleName(Role role);
const char *failName(FailReason reason);
struct Settings {
uint16_t version;
uint8_t role;
uint8_t startIndex;
uint8_t endIndex;
uint8_t accuracyIndex;
uint8_t timeIndex;
uint8_t dutyIndex;
uint32_t checksum;
};
struct TestParams {
uint32_t startHz;
uint32_t endHz;
float accuracyPct;
uint32_t testTimeMs;
uint8_t dutyPct;
};
struct PulsePeriod {
uint64_t startTick;
uint32_t periodTicks;
uint32_t activeTicks;
};
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;
uint16_t divider;
uint8_t bits;
};
uint32_t settingsChecksum(const Settings &s);
uint32_t frequencyPointCount(uint32_t startHz, uint32_t endHz);
uint32_t frequencyAt(uint32_t startHz, uint32_t endHz, 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 chooseIntegerPwmConfig(uint32_t requestedHz, uint32_t sourceClockHz,
uint8_t maxBits, uint8_t dutyPct,
IntegerPwmConfig &config);
FailReason validateResolution(uint32_t frequencyHz, float dutyPct, float accuracyPct,
uint32_t captureResolutionHz, uint8_t pwmBits);
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);