добавлена бета проверка драйверов
This commit is contained in:
167
OpticalChannelTester/DriverTest.h
Normal file
167
OpticalChannelTester/DriverTest.h
Normal file
@@ -0,0 +1,167 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Receiver.h"
|
||||
|
||||
enum class DriverState : uint8_t {
|
||||
IDLE, SETTLING, RUNNING, SUBSAMPLE_DONE, PASS, FAIL
|
||||
};
|
||||
|
||||
struct DriverEdgeStats {
|
||||
uint32_t responses;
|
||||
uint32_t minDelayTicks;
|
||||
uint32_t maxDelayTicks;
|
||||
uint64_t delaySumTicks;
|
||||
uint32_t minResponseTicks;
|
||||
uint32_t maxResponseTicks;
|
||||
uint64_t responseSumTicks;
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct DriverStats {
|
||||
uint32_t inputEdges;
|
||||
uint32_t responses;
|
||||
uint32_t minDelayTicks;
|
||||
uint32_t maxDelayTicks;
|
||||
uint32_t minResponseTicks;
|
||||
uint32_t maxResponseTicks;
|
||||
uint32_t lastDelayTicks;
|
||||
uint32_t lastResponseTicks;
|
||||
uint32_t droppedItems;
|
||||
uint32_t unexpectedResponses;
|
||||
uint64_t errorElapsedTicks;
|
||||
uint32_t errorDelayTicks;
|
||||
uint32_t errorPulseTicks;
|
||||
bool errorDelayValid;
|
||||
bool errorPulseValid;
|
||||
DriverEdgeStats turnOn;
|
||||
DriverEdgeStats turnOff;
|
||||
FailReason reason;
|
||||
void reset();
|
||||
};
|
||||
|
||||
class DriverTest {
|
||||
public:
|
||||
explicit DriverTest(PulseReceiver &receiver) : receiver_(receiver) {}
|
||||
bool start(uint32_t frequencyHz, uint32_t pulseNs, float tolerancePct,
|
||||
uint32_t testTimeMs, uint8_t settleCycles,
|
||||
bool activeTxLightOn, bool activeRxLightOn);
|
||||
DriverState update() const { return state_; }
|
||||
void abort();
|
||||
void forceFail(FailReason reason);
|
||||
bool resumeSubsample();
|
||||
bool takeProgressUpdate();
|
||||
void printSummary() const;
|
||||
void printTrace() const;
|
||||
uint8_t progressStep() const { return currentStep_; }
|
||||
uint32_t tickHz() const { return captureHz_; }
|
||||
const DriverStats &stats() const { return publishedStats_; }
|
||||
|
||||
private:
|
||||
enum class Source : uint8_t { TX, RX };
|
||||
struct RawEvent { uint32_t tick; bool rising; Source source; };
|
||||
struct TimedEvent { uint64_t tick; bool rising; Source source; };
|
||||
struct PendingTx { uint64_t tick; bool lightOn; };
|
||||
struct Response {
|
||||
bool active;
|
||||
bool associated;
|
||||
uint64_t startTick;
|
||||
PendingTx tx;
|
||||
};
|
||||
struct TraceEvent {
|
||||
uint64_t tick;
|
||||
uint8_t source;
|
||||
uint8_t rising;
|
||||
uint8_t state;
|
||||
uint8_t pending;
|
||||
};
|
||||
|
||||
static void analyzerTaskEntry(void *context);
|
||||
static void pollTaskEntry(void *context);
|
||||
void analyzerTaskLoop();
|
||||
void pollTaskLoop();
|
||||
void processEvent(const TimedEvent &event);
|
||||
void processSettling(const TimedEvent &event);
|
||||
void processRunning(const TimedEvent &event);
|
||||
void processTx(const TimedEvent &event, bool lightOn);
|
||||
void processRx(const TimedEvent &event, bool activeNow);
|
||||
void expirePending(uint64_t now);
|
||||
void completeIfPossible(uint64_t now);
|
||||
bool addPending(uint64_t tick, bool lightOn);
|
||||
int8_t matchingPending(uint64_t rxTick) const;
|
||||
void removePending(uint8_t index);
|
||||
uint64_t mergeGuardTicks() const;
|
||||
void acceptAcknowledgement(uint64_t delay, uint64_t width, bool lightOn);
|
||||
void fail(FailReason reason, uint64_t tick = 0, uint64_t delay = 0,
|
||||
uint64_t pulseWidth = 0);
|
||||
void publishStats();
|
||||
void rememberTrace(const TimedEvent &event);
|
||||
bool armCapture();
|
||||
void requestCaptureStop();
|
||||
bool waitCaptureStopped(uint32_t timeoutMs);
|
||||
void clearCapture();
|
||||
void recordRaw(uint32_t tick, bool rising, Source source);
|
||||
size_t readRaw(TimedEvent *events, size_t capacity, TickType_t waitTicks);
|
||||
uint32_t takeDropped();
|
||||
uint64_t nsToTicks(uint32_t ns) const;
|
||||
uint64_t ticksToNs(uint64_t ticks) const;
|
||||
|
||||
static constexpr uint8_t MAX_PENDING = 8;
|
||||
static constexpr uint8_t SUBSAMPLE_COUNT = 10;
|
||||
static constexpr uint16_t RING_CAPACITY = 2048;
|
||||
static constexpr uint8_t TRACE_CAPACITY = 32;
|
||||
static_assert((RING_CAPACITY & (RING_CAPACITY - 1U)) == 0,
|
||||
"driver ring capacity must be a power of two");
|
||||
|
||||
PulseReceiver &receiver_;
|
||||
TaskHandle_t analyzerTask_ = nullptr;
|
||||
TaskHandle_t pollTask_ = nullptr;
|
||||
volatile DriverState state_ = DriverState::IDLE;
|
||||
DriverStats stats_ = {};
|
||||
DriverStats publishedStats_ = {};
|
||||
mutable portMUX_TYPE statsMux_ = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
RawEvent ring_[RING_CAPACITY] = {};
|
||||
volatile uint16_t ringWrite_ = 0;
|
||||
volatile uint16_t ringRead_ = 0;
|
||||
volatile uint32_t droppedItems_ = 0;
|
||||
volatile bool captureActive_ = false;
|
||||
volatile bool captureReady_ = false;
|
||||
volatile bool core0WdtDisabled_ = false;
|
||||
uint32_t captureHz_ = 0;
|
||||
uint32_t pollPeriodCycles_ = 0;
|
||||
uint32_t pollWindowBeforeCycles_ = 0;
|
||||
uint32_t pollWindowAfterCycles_ = 0;
|
||||
bool pollTxStartRawHigh_ = false;
|
||||
portMUX_TYPE pollMux_ = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
PendingTx pending_[MAX_PENDING] = {};
|
||||
uint8_t pendingCount_ = 0;
|
||||
Response response_ = {};
|
||||
uint64_t ackStartMaxTicks_ = 0;
|
||||
uint64_t faultLongTicks_ = 0;
|
||||
uint64_t shortCircuitTicks_ = 0;
|
||||
uint64_t stuckTicks_ = 0;
|
||||
uint64_t testTicks_ = 0;
|
||||
uint64_t subsampleTicks_ = 0;
|
||||
uint64_t measurementStartTick_ = 0;
|
||||
uint64_t deadlineTick_ = 0;
|
||||
uint64_t pointOriginTick_ = 0;
|
||||
uint64_t lastEventTick_ = 0;
|
||||
uint8_t settleCycles_ = 0;
|
||||
uint8_t settledCycles_ = 0;
|
||||
uint8_t completedSubsamples_ = 0;
|
||||
bool rxActiveRawHigh_ = true;
|
||||
bool rxActive_ = false;
|
||||
bool measurementClosed_ = false;
|
||||
bool havePointOrigin_ = false;
|
||||
bool haveRawTick_ = false;
|
||||
uint32_t lastRawTick_ = 0;
|
||||
uint64_t tickEpoch_ = 0;
|
||||
volatile uint8_t currentStep_ = 0;
|
||||
volatile bool progressUpdatePending_ = false;
|
||||
TraceEvent trace_[TRACE_CAPACITY] = {};
|
||||
uint8_t traceWrite_ = 0;
|
||||
uint8_t traceCount_ = 0;
|
||||
};
|
||||
Reference in New Issue
Block a user