#ifndef DEVICE_CANFD_H #define DEVICE_CANFD_H #include /** @brief CANFD 状态报文的数据长度,单位字节。 */ #define CANFD_STATUS_DLEN 12U /** * @brief CANFD 通信模块。 * @note 负责 GPIO/模式控制、波特率配置、异步接收缓存与状态帧发送。 */ class CanFd { public: /** * @brief CANFD 运行诊断统计信息。 * @note 记录发送、接收、错误计数以及最近一次收发报文的关键信息。 */ struct Diag { uint32_t tx_count; /**< @brief 成功发送的报文计数。 */ uint32_t rx_count; /**< @brief 成功接收的报文计数。 */ uint32_t error_count; /**< @brief 发送失败或检测到的错误计数。 */ uint32_t last_rx_id; /**< @brief 最近一次接收报文的标识符。 */ uint32_t last_tx_id; /**< @brief 最近一次发送报文的标识符。 */ uint8_t last_payload_length; /**< @brief 最近一次收发报文的数据长度。 */ uint8_t last_rx_fd_flag; /**< @brief 最近一次接收报文的 FD 帧标志。 */ uint8_t last_rx_brs; /**< @brief 最近一次接收报文的波特率切换标志。 */ uint8_t last_rx_esi; /**< @brief 最近一次接收报文的错误状态指示位。 */ }; /** * @brief CANFD 状态发送载荷。 * @note 当前保持协议兼容,仅包含温度与供电相关字段;VIN_ADC 单独在诊断打印中输出。 */ struct StatusPayload { uint16_t temp_raw; /**< @brief 内部温度通道原始 ADC 数值。 */ uint16_t vref_raw; /**< @brief 内部参考电压通道原始 ADC 数值。 */ float vdda; /**< @brief 根据内部参考电压换算得到的 MCU 供电电压,单位 V。 */ float temperature; /**< @brief 根据温度通道换算得到的芯片温度,单位 ℃。 */ }; static void init(); static void poll(); static void prepareStatus(const StatusPayload *status); static void sendPrepared(); static bool hasRxFrame(); static bool consumeRxFrame(uint32_t *id, uint8_t *data, uint8_t *length); static const Diag *diag(); static void setNormalMode(); static void setSilentMode(); static void onRx0Interrupt(); private: struct RxFrame { uint32_t id; uint8_t data[64]; uint8_t length; uint8_t valid; }; static void initGpio(); static void filterAcceptAll(); static void initNominalTiming(); static void initFdMode(); static void buildStatusFrame(const StatusPayload *status); static Diag s_diag; static RxFrame s_rxFrame; }; using canfd_diag_t = CanFd::Diag; using canfd_status_payload_t = CanFd::StatusPayload; #endif /* DEVICE_CANFD_H */