Files
esp32-aldl/main/decoder.h
T
gronod 98d35a82e1
Build and Package Firmware / build (push) Failing after 2m0s
feat: add decoder module, host unit tests, and GitHub Actions CI pipeline
2026-06-12 14:04:58 +01:00

84 lines
2.3 KiB
C

#ifndef DECODER_H
#define DECODER_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#define LOGIC0_PULSE_US 1111u
#define LOGIC1_PULSE_US 4167u
#define THRESHOLD_US 2639u
#define MIN_VALID_US 300u
#define MERGE_THRESHOLD_US 8000u
#define MAX_VALID_US 13500u
#define MAX_SEPARATORS 12u
#define SYNC_ONES_NEEDED 8u
#define PAYLOAD_BYTES 25u
#define PC_GLITCH ((uint8_t)0)
#define PC_LOGIC_0 ((uint8_t)1)
#define PC_LOGIC_1 ((uint8_t)2)
#define PC_IDLE_GAP ((uint8_t)3)
#define PC_MERGED ((uint8_t)4)
#define DS_HUNT_SYNC ((uint8_t)0)
#define DS_AWAIT_START ((uint8_t)1)
#define DS_READ_BITS ((uint8_t)2)
struct BtFrame {
uint8_t data[PAYLOAD_BYTES];
uint8_t len;
};
struct DecoderContext {
uint8_t state;
uint8_t sync_count;
uint8_t bit_count;
uint8_t current_byte;
uint8_t byte_count;
uint8_t separator_count;
uint8_t frame[PAYLOAD_BYTES];
uint32_t frame_errors;
uint32_t frames_decoded;
uint32_t bytes_this_frame;
};
struct RingBuffer {
volatile uint32_t data[256];
volatile uint16_t head;
volatile uint16_t tail;
};
#define RB_MASK ((uint16_t)255u)
// Callbacks for hardware bridging (e.g. FreeRTOS queueing, hardware logging)
typedef void (*enqueue_frame_cb_t)(const uint8_t *frame_data, uint8_t len);
typedef void (*print_frame_cb_t)(uint32_t frames_decoded, const uint8_t *frame_data);
// Initialize decoder callbacks
void decoder_init(enqueue_frame_cb_t enqueue_cb, print_frame_cb_t print_cb);
// Core decoding interface
uint8_t classify_pulse(uint32_t us);
void reset_decoder(struct DecoderContext *ctx_ptr);
void process_pulse(struct DecoderContext *ctx_ptr, uint32_t pulse_us);
// Ring buffer inline helpers
static inline void rb_push(struct RingBuffer *rb_ptr, uint32_t v) {
uint16_t next = (rb_ptr->head + 1u) & RB_MASK;
if (next == rb_ptr->tail) return;
rb_ptr->data[rb_ptr->head] = v;
__asm__ __volatile__("" ::: "memory");
rb_ptr->head = next;
}
static inline bool rb_pop(struct RingBuffer *rb_ptr, uint32_t *out) {
if (rb_ptr->tail == rb_ptr->head) return false;
*out = rb_ptr->data[rb_ptr->tail];
__asm__ __volatile__("" ::: "memory");
rb_ptr->tail = (rb_ptr->tail + 1u) & RB_MASK;
return true;
}
#endif // DECODER_H