Files
OptoTest/OpticalChannelTester/Receiver.h

65 lines
2.2 KiB
C++

#pragma once
#include <Arduino.h>
#include <esp_idf_version.h>
#include <driver/gpio.h>
#include "Config.h"
#include "Core.h"
#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
#define OPTICAL_USE_MCPWM_CAPTURE 1
#include <driver/mcpwm_cap.h>
#else
#define OPTICAL_USE_MCPWM_CAPTURE 0
#endif
class PulseReceiver {
public:
bool begin();
bool start(uint32_t expectedHz, float expectedDutyPct);
void stop();
void resetStream();
size_t readPeriods(PulsePeriod *periods, size_t capacity, TickType_t waitTicks = 0);
uint32_t takeDroppedItems();
uint32_t tickHz() const;
uint32_t pulseTickHz() const { return tickHz(); }
uint32_t plannedTickHz(uint32_t expectedHz, float expectedDutyPct) const;
uint32_t plannedPulseTickHz(uint32_t expectedHz, float expectedDutyPct) const {
return plannedTickHz(expectedHz, expectedDutyPct);
}
uint16_t receiveChunkSymbols() const { return 1; }
bool highRateBackend() const { return OPTICAL_USE_MCPWM_CAPTURE; }
private:
struct Edge { uint32_t tick; uint8_t rising; };
struct TimedEdge { uint64_t tick; bool rising; };
bool consumeEdge(const Edge &edge, PulsePeriod &period);
bool nextOrderedEdge(Edge &edge, TickType_t waitTicks);
TimedEdge extendEdge(const Edge &edge);
#if OPTICAL_USE_MCPWM_CAPTURE
static bool IRAM_ATTR onCapture(mcpwm_cap_channel_handle_t,
const mcpwm_capture_event_data_t *, void *);
mcpwm_cap_timer_handle_t captureTimer_ = nullptr;
mcpwm_cap_channel_handle_t risingChannel_ = nullptr;
mcpwm_cap_channel_handle_t fallingChannel_ = nullptr;
uint32_t captureResolutionHz_ = 0;
#else
static void IRAM_ATTR onGpio(void *ctx);
uint32_t cpuTickHz_ = 0;
#endif
QueueHandle_t queue_ = nullptr;
Edge reorderEdge_ = {};
bool haveReorderEdge_ = false;
volatile uint32_t droppedItems_ = 0;
volatile bool running_ = false;
uint32_t expectedHz_ = 0;
float expectedDutyPct_ = 50.0f;
bool polarityKnown_ = false, activeStartRising_ = false;
TimedEdge syncEdges_[3] = {};
uint8_t syncEdgeCount_ = 0;
bool waitingForActiveEnd_ = true;
uint64_t activeStart_ = 0, activeEnd_ = 0;
bool haveRawTick_ = false;
uint32_t lastRawTick_ = 0;
uint64_t tickEpoch_ = 0;
};