3#include "pulse/tools/RingBuffer.h"
33 _rxState = WAIT_START;
45 start.pulseUs = _bitPeriodUs;
52 if (
byte & (1 <<
bit)) {
54 data.pulseUs = _bitPeriodUs / 2;
57 data.pulseUs = _bitPeriodUs / 2;
62 data.pulseUs = _bitPeriodUs;
72 stop.pulseUs = _bitPeriodUs;
83 Logger::debug(
"[RZCodec] decodeEdge: level=%s, duration=%d us",
111 enum { WAIT_START, DATA_BITS, STOP_BITS } _rxState = WAIT_START;
112 uint8_t _rxDataBitCount = 0;
113 uint8_t _rxStopBitCount = 0;
116 bool isValidPeriod(uint32_t pulse, uint32_t target,
117 uint32_t tolerance)
const {
118 return abs((
int)pulse - (
int)target) < (int)tolerance;
122 bool handleFrameStart(
bool level, uint32_t durationUs) {
123 OutputEdge newEdge{level, durationUs};
125 if (_preamble->preambleLength() == 0) {
126 _decodeEdgeStream.
clear();
130 }
else if (_preamble->
detect(newEdge)) {
132 _decodeEdgeStream.
clear();
141 bool handleInFrameDecoding(uint32_t durationUs,
bool level, uint8_t& result) {
144 _edgeBuffer.write({level, durationUs});
145 Logger::debug(
"Reconstructed edge: level=%s, duration=%d us",
146 level ?
"HIGH" :
"LOW", durationUs);
147 }
else if (!level && durationUs >= _bitPeriodUs) {
148 int n = durationUs / _bitPeriodUs;
149 Logger::debug(
"Reconstructed %d edges: level=LOW, duration=%d us", n,
151 for (
int i = 0; i < n; ++i) {
152 _edgeBuffer.write({
false, _bitPeriodUs});
155 Logger::debug(
"Ignored edge: level=LOW, duration=%d us", durationUs);
160 while (!_edgeBuffer.isEmpty()) {
162 _edgeBuffer.read(edge);
171 _rxState = DATA_BITS;
179 _byte |= (1 << _rxDataBitCount);
180 Logger::debug(
"Decoded data bit 1 at pos=%d", _rxDataBitCount);
182 Logger::debug(
"Decoded data bit 0 at pos=%d", _rxDataBitCount);
184 if (++_rxDataBitCount == 8) {
185 _rxState = STOP_BITS;
196 if (++_rxStopBitCount >= _stopBits) {
199 _rxState = WAIT_START;
Abstract base class for IR protocol encoding and decoding.
virtual void reset()
Reset the internal state of the codec.
static void debug(const char *format,...)
Log a debug message with formatting.
static void warning(const char *format,...)
Log a warning message with formatting.
Abstract base class for preamble detection and generation.
virtual bool detect(const OutputEdge &edge)
Detects if the incoming edge matches the expected preamble pattern.
bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result) override
Edge-based decoding for protocol-agnostic RX drivers.
size_t getEdgeCount() const override
Get the number of protocol symbols (bits, pulses, etc.) per encoded byte.
CodecEnum getCodecType() const override
size_t encode(uint8_t byte, Vector< OutputEdge > &output) override
Fill output vector with protocol-specific OutputSpec(s) for a byte.
int getEndOfFrameDelayUs() override
void reset() override
Reset the internal state of the codec.
bool getIdleLevel() const override
Provides the initial ldle state (low or hith)
Small, header-only vector replacement for non-STL environments.
void clear()
Remove all elements.
void push_back(const T &value)
Add element to end of vector.
Specifies a single IR signal segment for protocol-agnostic transmission.