#ifndef RADICK_RADAR_PROTOCOL_H #define RADICK_RADAR_PROTOCOL_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* RD-03D V1 multi-target UART protocol constants. */ #define RD03D_UART_BAUD_RATE 256000U #define RD03D_MAX_TARGETS 3U #define RD03D_TARGET_DATA_SIZE 8U #define RD03D_FRAME_HEADER_SIZE 4U #define RD03D_FRAME_TAIL_SIZE 2U #define RD03D_FRAME_SIZE 30U #define RD03D_CMD_ENABLE_SIZE 14U #define RD03D_CMD_MULTI_SIZE 12U #define RD03D_CMD_END_SIZE 12U extern const uint8_t rd03d_frame_header[RD03D_FRAME_HEADER_SIZE]; extern const uint8_t rd03d_frame_tail[RD03D_FRAME_TAIL_SIZE]; extern const uint8_t rd03d_cmd_enable[RD03D_CMD_ENABLE_SIZE]; extern const uint8_t rd03d_cmd_multi[RD03D_CMD_MULTI_SIZE]; extern const uint8_t rd03d_cmd_end[RD03D_CMD_END_SIZE]; typedef struct { int16_t x_mm; int16_t y_mm; int16_t speed_cm_s; uint16_t resolution_mm; bool valid; } rd03d_target_t; typedef struct { rd03d_target_t targets[RD03D_MAX_TARGETS]; } rd03d_frame_t; /* * The parser owns no dynamic memory and is safe to place in static storage or * on a task stack. Its fields are public so the same header works in ESP-IDF * and small host-side tests without an allocator or opaque platform handle. */ typedef struct { uint8_t buffer[RD03D_FRAME_SIZE]; size_t buffered; size_t header_matched; uint64_t bytes_received; uint32_t frames_decoded; uint32_t malformed_frames; } rd03d_parser_t; typedef void (*rd03d_frame_callback_t)(const rd03d_frame_t *frame, void *context); /* Decode the RD-03D's unusual sign/magnitude value (bit 15 means positive). */ int16_t rd03d_decode_sign_magnitude(uint8_t low, uint8_t high); /* Decode one complete frame. Returns false unless both header and tail match. */ bool rd03d_decode_frame(const uint8_t frame[RD03D_FRAME_SIZE], rd03d_frame_t *out); void rd03d_parser_init(rd03d_parser_t *parser); /* * Feed one byte. A complete decoded frame is copied to out (when non-NULL), * and true is returned. Noise and malformed frames are consumed internally. */ bool rd03d_parser_push(rd03d_parser_t *parser, uint8_t byte, rd03d_frame_t *out); /* * Feed an arbitrary UART chunk. The callback is invoked once per frame when * non-NULL; the return value always reports the number of decoded frames. */ size_t rd03d_parser_feed(rd03d_parser_t *parser, const uint8_t *data, size_t length, rd03d_frame_callback_t callback, void *context); #ifdef __cplusplus } #endif #endif /* RADICK_RADAR_PROTOCOL_H */