fix overflow and mute

This commit is contained in:
2026-04-14 09:36:27 +03:00
parent ad1e16cfda
commit 8631f23b53
9 changed files with 466 additions and 69 deletions

View File

@ -72,15 +72,32 @@ public:
//////////////////////////////////////////////////////////////////////////
private:
enum class RxBriefReason : uint8_t
{
MuteBegin = 1,
MuteEnd = 2,
RawOverflow = 3,
FilterOverflow = 4,
HoldOverflow = 5,
Glitch = 6,
Timing = 7,
Preamble = 8,
Sync = 9,
BufferOverflow = 10,
Timeout = 11,
Crc = 12,
Ok = 13
};
bool isRejectAvailable = false;
uint8_t rejectPackSize = 0;
uint8_t rejectBuffer[dataByteSizeMax]{};
ErrorsStruct errors;
bool isAvailable = false;
uint16_t packSize;
uint16_t crcValue;
volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика
uint16_t packSize = 0;
uint16_t crcValue = 0;
volatile uint16_t isPairSending = 0; // Число активных TX, временно глушащих этот RX.
volatile bool isRecive = false; // Флаг приёма
volatile bool isPreamb = false; // флаг начальной последовости
volatile bool isSubBufferOverflow = false;
@ -107,6 +124,8 @@ private:
RingBuffer<FrontStorage, subBufferSize> subBuffer;
/** Очередь фронтов после потокового анти-глитча; tick() читает из неё при включённом фильтре. */
RingBuffer<FrontStorage, subBufferSize> filteredSubBuffer;
IR_Encoder *pairMuteEncoders[IR_PAIR_MUTE_MAX_ENCODERS]{};
uint8_t pairMuteEncoderCount = 0;
static constexpr uint8_t kPulseFilterHoldCap = 6;
FrontStorage pulseFilterHoldEdges[kPulseFilterHoldCap]{};
uint8_t pulseFilterHoldCount = 0;
@ -143,6 +162,17 @@ private:
volatile bool edgeTrace_overflow = false;
#endif
#if IR_RX_BRIEF_LOG
volatile bool rxBriefMuteBeginPending = false;
volatile uint32_t rxBriefMuteBeginUs = 0;
volatile bool rxBriefMuteEndPending = false;
volatile uint32_t rxBriefMuteEndUs = 0;
volatile uint16_t rxBriefMuteEndCount = 0;
volatile uint16_t rxBriefMuteBlockedEdges = 0;
volatile uint16_t rxBriefRawOverflowDrops = 0;
volatile uint32_t rxBriefRawOverflowLastUs = 0;
#endif
////////////////////////////////////////////////////////////////////////
uint8_t dataBuffer[dataByteSizeMax]{0}; // Буффер данных
volatile uint32_t prevRise, prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов
@ -163,7 +193,7 @@ private:
int16_t bufBitPos = 0; // Позиция для записи бита в буффер
private:
bool isReciveRaw;
bool isReciveRaw = false;
void listenStart();
void checkTimeout(); //
/** Один сырой фронт из subBuffer -> потоковый holdback-антиглитч. */
@ -173,6 +203,8 @@ bool isReciveRaw;
void pulseFilterShiftLeft(uint8_t n);
void pulseFilterReset();
static uint32_t absDiffU32(uint32_t a, uint32_t b);
bool registerPairMuteEncoder(IR_Encoder *enc);
void refreshPairMuteState();
uint32_t preambleJitterTolUs(uint32_t baselineUs) const;
bool preambleRisePeriodCoarseOk(uint32_t periodUs) const;
void preambleResetToIdle();
@ -187,10 +219,10 @@ bool isReciveRaw;
////////////////////////////////////////////////////////////////////////
bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации
uint16_t i_dataBuffer; // Счётчик буфера данных
uint16_t i_dataBuffer = 0; // Счётчик буфера данных
uint16_t nextControlBit = bitPerByte; // Метка для смены флага isData; uint16_t нужен для длинных кадров (>24 байт total)
uint8_t i_syncBit; // Счётчик битов синхронизации
uint8_t err_syncBit; // Счётчик ошибок синхронизации
uint8_t i_syncBit = 0; // Счётчик битов синхронизации
uint8_t err_syncBit = 0; // Счётчик ошибок синхронизации
/// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация
/// @param packTraceInvertFix если true — в IRDEBUG_SERIAL_PACK бит в трассе пишется как `0`/`1` (исправление по фронтам)
@ -205,6 +237,14 @@ bool isReciveRaw;
/// @return Результат
uint16_t ceil_div(uint16_t val, uint16_t divider);
#if IR_RX_BRIEF_LOG
static const __FlashStringHelper *rxBriefReasonTag(RxBriefReason reason);
void rxBriefLog(RxBriefReason reason, uint16_t a = 0, uint16_t b = 0, uint32_t tUs = 0);
void rxBriefNoteMuteBlockedIsr(uint32_t tUs);
void rxBriefNoteRawOverflowIsr(uint32_t tUs);
void rxBriefFlushDeferredIsrLogs();
#endif
#ifdef IRDEBUG
uint32_t wrCounter;
inline void errPulse(uint8_t pin, uint8_t count);