mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-09-22 21:09:36 +00:00
Analyzer plug
This commit is contained in:
135
Analyzer/raw/IR_Fox/src/IrFoxDecoder.h
Normal file
135
Analyzer/raw/IR_Fox/src/IrFoxDecoder.h
Normal file
@ -0,0 +1,135 @@
|
||||
#pragma once
|
||||
|
||||
#include "IrFoxProtocolConstants.h"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
enum IrFoxFrameType : uint8_t
|
||||
{
|
||||
IRF_FT_DATA_BIT = 1,
|
||||
IRF_FT_SYNC_BIT = 2,
|
||||
IRF_FT_PACKET_OK = 3,
|
||||
IRF_FT_PACKET_CRC_FAIL = 4,
|
||||
IRF_FT_OVERFLOW = 5,
|
||||
IRF_FT_ABORT = 6,
|
||||
IRF_FT_PREAMBLE = 7,
|
||||
};
|
||||
|
||||
/** WithBubble — вызвать on_bit; Quiet — только обновить состояние (для пакета битов с одного фронта). */
|
||||
enum class IrFoxEmitBitMode : uint8_t
|
||||
{
|
||||
WithBubble,
|
||||
Quiet,
|
||||
};
|
||||
|
||||
struct IrFoxEmitBit
|
||||
{
|
||||
int64_t start_sample;
|
||||
int64_t end_sample;
|
||||
uint8_t frame_type;
|
||||
uint64_t bit_value;
|
||||
uint64_t bit_index;
|
||||
uint8_t mflags;
|
||||
bool invert_fix;
|
||||
uint8_t err_low;
|
||||
uint8_t err_high;
|
||||
uint8_t err_other;
|
||||
/** Подпись бабла: "0", "1" или склейка "001"; пусто — смотреть bit_value. */
|
||||
char bubble_text[32]{};
|
||||
};
|
||||
|
||||
struct IrFoxEmitPacket
|
||||
{
|
||||
int64_t start_sample;
|
||||
int64_t end_sample;
|
||||
bool crc_ok;
|
||||
uint8_t pack_size;
|
||||
uint8_t err_low;
|
||||
uint8_t err_high;
|
||||
uint8_t err_other;
|
||||
uint8_t data_bytes[irfox::kDataByteSizeMax];
|
||||
};
|
||||
|
||||
using IrFoxOnBit = std::function<void(const IrFoxEmitBit&)>;
|
||||
using IrFoxOnPacket = std::function<void(const IrFoxEmitPacket&)>;
|
||||
|
||||
class IrFoxDecoder
|
||||
{
|
||||
public:
|
||||
void reset();
|
||||
void processEdge(uint64_t sample, bool rising, uint32_t sample_rate_hz, const IrFoxOnBit& on_bit,
|
||||
const IrFoxOnPacket& on_pkt);
|
||||
void flushEnd(uint64_t last_sample, uint32_t sample_rate_hz, const IrFoxOnBit& on_bit, const IrFoxOnPacket& on_pkt);
|
||||
|
||||
private:
|
||||
static uint16_t ceil_div_u16(uint16_t val, uint16_t divider);
|
||||
static uint8_t crc8(const uint8_t* data, uint8_t start, uint8_t end, uint8_t poly);
|
||||
bool crc_check(uint8_t len, uint16_t& crc_out);
|
||||
|
||||
void first_rx();
|
||||
void listen_start(double t_us);
|
||||
void check_timeout(double t_us);
|
||||
void write_to_buffer(bool bit, bool pack_trace_invert_fix, uint64_t cell_start_s, uint64_t cell_end_s,
|
||||
const IrFoxOnBit& on_bit, const IrFoxOnPacket& on_pkt,
|
||||
IrFoxEmitBitMode emit_mode = IrFoxEmitBitMode::WithBubble);
|
||||
|
||||
double sample_to_us(uint64_t sample, uint32_t fs) const { return double(sample) * 1e6 / double(fs); }
|
||||
|
||||
// --- state (mirror IR_DecoderRaw) ---
|
||||
uint8_t data_buffer[irfox::kDataByteSizeMax]{};
|
||||
uint8_t err_low_signal = 0;
|
||||
uint8_t err_high_signal = 0;
|
||||
uint8_t err_other = 0;
|
||||
|
||||
bool is_available = false;
|
||||
uint16_t pack_size = 0;
|
||||
uint16_t crc_value = 0;
|
||||
bool is_recive = false;
|
||||
bool is_recive_raw = false;
|
||||
bool is_preamb = false;
|
||||
bool is_buffer_overflow = false;
|
||||
bool is_wrong_pack = false;
|
||||
|
||||
uint32_t rise_sync_time_us = irfox::kBitTimeUs;
|
||||
|
||||
double prev_rise_us = 0;
|
||||
double prev_fall_us = 0;
|
||||
uint64_t prev_rise_sample = 0;
|
||||
uint64_t prev_fall_sample = 0;
|
||||
/** Сэмпл предыдущего нарастающего фронта до обновления на текущем тике (граница ячейки бита, см. IR_DecoderRaw::tick). */
|
||||
uint64_t rise_period_anchor_sample_ = 0;
|
||||
uint64_t preamble_bubble_start_sample_ = 0;
|
||||
bool preamble_bubble_start_valid_ = false;
|
||||
bool trim_first_data_bit_cell_ = false;
|
||||
|
||||
double last_edge_time_us = 0;
|
||||
uint64_t last_edge_sample = 0;
|
||||
double last_processed_edge_us = 0;
|
||||
bool have_last_processed = false;
|
||||
|
||||
void fill_err_snapshot(IrFoxEmitBit& e) const
|
||||
{
|
||||
e.err_low = err_low_signal;
|
||||
e.err_high = err_high_signal;
|
||||
e.err_other = err_other;
|
||||
}
|
||||
|
||||
uint32_t rise_period_us = 0;
|
||||
uint32_t high_time_us = 0;
|
||||
uint32_t low_time_us = 0;
|
||||
|
||||
int8_t high_count = 0;
|
||||
int8_t low_count = 0;
|
||||
int8_t all_count = 0;
|
||||
|
||||
uint16_t wrong_counter = 0;
|
||||
int8_t preamb_front_counter = 0;
|
||||
int16_t buf_bit_pos = 0;
|
||||
bool is_data = true;
|
||||
uint16_t i_data_buffer = 0;
|
||||
uint8_t next_control_bit = irfox::kBitPerByte;
|
||||
uint8_t i_sync_bit = 0;
|
||||
uint8_t err_sync_bit = 0;
|
||||
uint16_t error_counter = 0;
|
||||
uint8_t msg_type_receive = 0;
|
||||
};
|
||||
Reference in New Issue
Block a user