- улушчено отображение на OLED - убраны настройки шага частоты и количества повторов - сделан перебор только реализуемых частот - увеличена точность, на 1МГц 1.25%, в остальных до 1% - точное измерение TOTAL TIME
67 lines
2.0 KiB
C++
67 lines
2.0 KiB
C++
#pragma once
|
|
#include <Arduino.h>
|
|
#include <esp_idf_version.h>
|
|
#include "Config.h"
|
|
#include "Core.h"
|
|
|
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
|
|
#define OPTICAL_USE_RMT_DMA 1
|
|
#include <driver/rmt_rx.h>
|
|
#else
|
|
#define OPTICAL_USE_RMT_DMA 0
|
|
#include <driver/gpio.h>
|
|
#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);
|
|
bool overflowed();
|
|
uint32_t takeDroppedItems();
|
|
uint32_t tickHz() const;
|
|
uint32_t plannedTickHz(uint32_t expectedHz, float expectedDutyPct) const;
|
|
uint16_t receiveChunkSymbols() const { return receiveChunkSymbols_; }
|
|
bool highRateBackend() const {
|
|
#if OPTICAL_USE_RMT_DMA && CONFIG_IDF_TARGET_ESP32S3
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
private:
|
|
struct Edge { uint32_t tick; uint8_t rising; };
|
|
bool consumeEdge(const Edge &edge, PulsePeriod &period);
|
|
|
|
#if OPTICAL_USE_RMT_DMA
|
|
static constexpr size_t BLOCK_SYMBOLS = RMT_MAX_RECEIVE_SYMBOLS;
|
|
struct SymbolBlock { uint16_t count; rmt_symbol_word_t symbols[BLOCK_SYMBOLS]; };
|
|
static bool IRAM_ATTR onRmt(rmt_channel_handle_t, const rmt_rx_done_event_data_t *, void *);
|
|
bool configureRmt(uint32_t resolutionHz);
|
|
bool nextRmtEdge(Edge &edge, TickType_t waitTicks);
|
|
rmt_channel_handle_t channel_ = nullptr;
|
|
uint32_t captureResolutionHz_ = 0;
|
|
rmt_symbol_word_t receiveBuffer_[RMT_MAX_RECEIVE_SYMBOLS];
|
|
uint16_t receiveChunkSymbols_ = 0;
|
|
SymbolBlock isrBlock_ = {};
|
|
SymbolBlock block_ = {};
|
|
uint16_t blockIndex_ = 0;
|
|
uint8_t phase_ = 0;
|
|
bool haveLevel_ = false;
|
|
bool level_ = false;
|
|
uint32_t rmtTick_ = 0;
|
|
#else
|
|
static void IRAM_ATTR onGpio(void *ctx);
|
|
uint32_t cpuTickHz_ = 0;
|
|
#endif
|
|
QueueHandle_t queue_ = nullptr;
|
|
volatile bool overflow_ = false;
|
|
volatile uint32_t droppedItems_ = 0;
|
|
bool running_ = false;
|
|
bool haveRise_ = false, haveFall_ = false, haveRawTick_ = false;
|
|
uint32_t lastRawTick_ = 0;
|
|
uint64_t tickEpoch_ = 0, rise_ = 0, fall_ = 0;
|
|
};
|