25 start.pulseUs = _bitPeriodUs;
32 data.level = (
byte & (1 <<
bit));
33 data.pulseUs = _bitPeriodUs;
42 stop.pulseUs = _bitPeriodUs;
51 Logger::debug(
"[NRZCodec] decodeEdge: level=%s, duration=%d us",
61 if (!_inFrame && _preamble->preambleLength() == 0) {
73 Logger::debug(
"Long pulse detected: %d us, splitting into %d edges",
78 if (decodeEdgeInternal(_bitPeriodUs, level,
result)) {
90 if (
edges[0].level !=
false) {
91 Logger::error(
"Invalid start bit: expected LOW, got HIGH: duration=%d us",
97 for (
int i = 0; i < 8; ++i) {
98 if (edges[i + 1].level) {
107 for (
int s = 0; s < _stopBits; ++s) {
108 if (edges[9 + s].level !=
true) {
109 Logger::error(
"Stop bit %d: 0, duration=%d us", s, edges[9 + s].pulseUs);
112 Logger::debug(
"Stop bit %d: 1, duration=%d us", s, edges[9 + s].pulseUs);
122 _decodeEdgeStream.
clear();
135 uint8_t getStopBits()
const {
return _stopBits; }
141 bool bitMatch(uint32_t duration,
bool bit)
const {
142 uint32_t expectedDuration = _bitPeriodUs;
143 return (duration >= expectedDuration - (_bitPeriodUs / 2)) &&
144 (duration <= expectedDuration + (_bitPeriodUs / 2));
147 virtual bool decodeEdgeInternal(uint32_t durationUs,
bool level, uint8_t& result) {
149 assert(_decodeEdgeStream.
capacity() > 0);
153 Logger::debug(
"Idle gap detected: %d us, resetting decoder", durationUs);
158 OutputEdge newEdge{level, durationUs};
159 assert(_preamble !=
nullptr);
161 if (_preamble->preambleLength() == 0) {
163 _decodeEdgeStream.
clear();
167 }
else if (_preamble->
detect(newEdge)) {
170 _decodeEdgeStream.
clear();
179 bool rc = decodeByte(_decodeEdgeStream, result);
181 _decodeEdgeStream.
clear();
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 error(const char *format,...)
Log an error message with formatting.
NRZ (Non-Return-to-Zero) codec for serial-like encoding/decoding with start/stop bit framing.
int getEndOfFrameDelayUs() override
bool getIdleLevel() const override
Provides the initial ldle state (low or hith)
CodecEnum getCodecType() const override
size_t getEdgeCount() const override
Get the number of protocol symbols (bits, pulses, etc.) per encoded byte.
size_t encode(uint8_t byte, Vector< OutputEdge > &output) override
Fill output vector with protocol-specific OutputSpec(s) for a byte.
void reset() override
Reset the internal state of the codec.
bool decodeEdge(uint32_t durationUs, bool level, uint8_t &result) override
Edge-based decoding for protocol-agnostic RX drivers.
Abstract base class for preamble detection and generation.
virtual bool detect(const OutputEdge &edge)
Detects if the incoming edge matches the expected preamble pattern.
Small, header-only vector replacement for non-STL environments.
size_t capacity() const
Current allocated capacity.
void clear()
Remove all elements.
void push_back(const T &value)
Add element to end of vector.
size_t size() const
Number of elements in vector.
Specifies a single IR signal segment for protocol-agnostic transmission.