/** * @file qdx_protocol.h * @brief Communication Protocol 2.0 Structures and Constants * * Platform-independent header for CH32 MCU and other systems. * All structures use 1-byte alignment. Focuses on safe uint8_t * serialization and avoiding hardware faults from unaligned access. */ #ifndef QDX_PROTOCOL_H #define QDX_PROTOCOL_H #include /* ============================================================ * Protocol Constants * ============================================================ */ #define PROTO_MAGIC 0x55AA /* Frame Header Magic */ #define PROTO_VERSION 0x20 /* Protocol Version v2.0 */ /* Message Classes (Class) */ #define CLASS_CONTROL 0x01 /* Configuration / Control */ #define CLASS_DATA 0x02 /* Real-time Data Report */ #define CLASS_RESPONSE 0x03 /* ACK / NACK / Error */ #define CLASS_SYSTEM 0x04 /* Handshake / Heartbeat / Sync */ /* TLV Types */ #define TYPE_HANDSHAKE 0x01 #define TYPE_HEARTBEAT 0x02 #define TYPE_SYNC_TIME 0x03 #define TYPE_DEVID_ASSIGN 0x05 #define TYPE_TEMP_FRAME 0x10 #define TYPE_RAW_FRAME 0x11 #define TYPE_CONFIG_COMMON 0x20 #define TYPE_CONFIG_2D 0x22 #define TYPE_CONFIG_1D 0x23 #define TYPE_ACK_PAYLOAD 0x30 #define TYPE_DETECTION_RESULT 0x40 /* Flags */ #define FLAG_PRIORITY_MASK 0x03 #define FLAG_COMPRESSED 0x04 #define FLAG_ENCRYPTED 0x08 #define FLAG_ACK_REQ 0x10 #define FLAG_LAST_FRAGMENT 0x20 /* Frame Structure Sizes */ #define HEADER_SIZE 16 /* FrameHeader_t size */ #define TLV_HEADER_SIZE 3 /* TLV_t size (Type + Length) */ #define CRC_SIZE 2 /* CRC16 size */ /* Fragmentation limit */ #define MAX_FRAGMENT_PAYLOAD 1400 /* Error Codes */ #define ERR_NONE 0x0000 #define ERR_CRC 0x1001 #define ERR_VERSION 0x1002 #define ERR_LENGTH 0x1003 #define ERR_AUTH 0x2001 #define ERR_BUSY 0x2002 #define ERR_DEV_ID_CONFLICT 0x2003 #define ERR_PARAM 0x3001 /* ============================================================ * Internal Protocol Structures (Packed to 1 byte) * ============================================================ */ #pragma pack(push, 1) /** * @brief Frame Header (16 bytes) */ typedef struct { uint16_t Magic; uint8_t Version; uint16_t Length; uint16_t Sequence; uint32_t Timestamp; uint8_t Source; uint16_t DevID; uint8_t Class; uint8_t Flags; } FrameHeader_t; /** * @brief TLV Header (3 bytes) */ typedef struct { uint8_t Type; uint16_t Length; } TLV_t; /** * @brief Handshake (46 bytes) */ typedef struct { uint16_t ProtocolVersion; uint8_t DeviceUUID[16]; uint8_t AuthToken[16]; char HardwareVersion[8]; char FirmwareVersion[8]; uint32_t Capabilities; } Handshake_t; /** * @brief Heartbeat (6 bytes) */ typedef struct { uint32_t UpTime; uint8_t CpuLoad; uint8_t MemUsage; } Heartbeat_t; /** * @brief ACK Payload (5 bytes) */ typedef struct { uint16_t AckSeq; uint8_t Status; uint16_t ErrorCode; } Ack_t; /** * @brief Device ID Assignment (4 bytes) */ typedef struct { uint16_t NewDevID; uint16_t Reserved; } DevIDAssignment_t; /** * @brief Temperature Frame Header (18 bytes) */ typedef struct { uint32_t FrameNumber; uint16_t Width; uint16_t Height; int16_t MinTemp; int16_t MaxTemp; int16_t AvgTemp; int16_t RoiTemp; uint8_t FrameType; uint8_t Status; uint8_t Is2D; uint8_t Reserved; } TemperatureFrameHeader_t; /** * @brief 1D Temperature Point (4 bytes) */ typedef struct { uint16_t TimeOffset; uint16_t Temperature; } TempPoint1D_t; /** * @brief Detection Result (8 bytes) */ typedef struct { uint32_t FrameNumber; uint8_t Result; uint8_t Reserved[3]; } DetectionResult_t; /** * @brief Common Configuration */ typedef struct { char PipelineId[16]; uint8_t PipelineType; uint8_t WorkMode; uint8_t ConfigTag; uint8_t StrictnessLevel; uint8_t IsCustomMode; uint8_t Reserved[2]; } ConfigCommon_t; /** * @brief 2D Configuration */ typedef struct { uint8_t Enabled; uint8_t IsLive; uint16_t DeviceId; uint16_t Width; uint16_t Height; uint8_t Fps; uint32_t Exposure; uint8_t AutoExposure; uint8_t MaskEnabled; int16_t MaskThreshold; uint16_t MaskWidth; uint16_t MaskHeight; int16_t Angle; uint16_t TargetWidth; uint16_t TargetHeight; uint8_t TriggerMode; uint8_t TriggerGpioLine; uint16_t TriggerDelayMs; uint8_t TriggerBurstCount; uint16_t TriggerInternalIntervalMs; int16_t TriggerTemperatureThreshold; uint16_t TriggerDebounceIntervalMs; uint8_t TriggerCondition; uint16_t TriggerRoiX; uint16_t TriggerRoiY; uint16_t TriggerRoiW; uint16_t TriggerRoiH; uint16_t NGioDelay; uint8_t OutputGpioLine; uint8_t AlarmGpioLine; uint16_t AlarmHoldMs; uint8_t StoreNgImagesOnly; uint8_t TrainingEnabled; uint16_t TrainingSampleThreshold; uint16_t ProcessingTimeoutMs; uint8_t MaxProcessingQueueSize; uint8_t Reserved; } Config2D_t; /** * @brief 1D Configuration */ typedef struct { uint8_t Enabled; uint8_t RunMode; uint8_t TriggerType; uint16_t BufferSize; int16_t TriggerTempLimit; uint16_t StartPointsToRemove; uint16_t ReferenceLength; uint16_t HighTimerLimit; uint16_t TimerCLimit; uint8_t NgCountLimit; uint16_t LSizeStart; uint16_t RSizeStart; uint16_t NGioDelay; uint8_t OutputGpioLine; uint8_t AlarmGpioLine; uint16_t AlarmHoldMs; } Config1D_t; #pragma pack(pop) /* ============================================================ * Application Level Business Structures * ============================================================ */ /** * @brief Raw Image Buffer provided by capture module */ typedef struct { uint16_t *pData; uint16_t Width; uint16_t Height; uint32_t FrameNumber; } RawImageBuffer_t; /** * @brief Preprocessing result metadata */ typedef struct { uint8_t *pValidData; uint32_t DataLength; uint16_t ValidWidth; uint16_t ValidHeight; int16_t MinTemp; int16_t MaxTemp; int16_t AvgTemp; int16_t RoiTemp; uint8_t Status; uint32_t FrameNumber; } PreprocessResult_t; /** * @brief Buffer wrapper for Zero-Copy TCP packet building */ typedef struct { uint8_t *pBuffer; uint32_t TotalCapacity; uint32_t HeadOffset; /* Reserved header space for envelope */ uint32_t ValidPayloadLen; } TcpTxBuffer_t; /* System global config hook types */ typedef void (*ConfigUpdateCallback_t)(const ConfigCommon_t *common, const Config2D_t *cfg2d, const Config1D_t *cfg1d); typedef void (*DetectionResultCallback_t)(uint32_t frameNumber, uint8_t resultStatus); /* ============================================================ * Protocol Utility Function Declarations * ============================================================ */ /* Calculate Modbus CRC16 */ uint16_t qdx_crc16_modbus(const uint8_t *data, int len); /* Shift-safe write: 16-bit little-endian */ void qdx_write_u16_le(uint8_t *buf, uint16_t val); /* Shift-safe write: 32-bit little-endian */ void qdx_write_u32_le(uint8_t *buf, uint32_t val); /* Shift-safe read: 16-bit little-endian */ uint16_t qdx_read_u16_le(const uint8_t *buf); /* Shift-safe read: 32-bit little-endian */ uint32_t qdx_read_u32_le(const uint8_t *buf); /** * @brief Build a complete protocol frame using safe byte shifts. */ int qdx_build_frame(uint8_t *buf, uint8_t msg_class, uint8_t tlv_type, const uint8_t *payload, uint16_t payload_len, uint16_t dev_id, uint16_t seq, uint32_t timestamp, uint8_t flags); /** * @brief In-place frame build: 仅填写帧头并追加 CRC,不拷贝 payload。 * 用于零拷贝场景,payload(含 TLV)已在 buf[HEADER_SIZE] 处就位。 */ int qdx_build_frame_inplace(uint8_t *buf, uint8_t msg_class, uint16_t payload_len, uint16_t dev_id, uint16_t seq, uint32_t timestamp, uint8_t flags); /** * @brief Build a fragmented payload frame (No TLV wrapper). */ int qdx_build_fragment_frame(uint8_t *buf, uint8_t msg_class, const uint8_t *chunk, uint16_t chunk_len, uint16_t dev_id, uint16_t seq, uint32_t timestamp, uint8_t flags); #endif /* QDX_PROTOCOL_H */