// // Created by zwsd // #pragma once #include "sdk/os/zos.hpp" #include "sdk\components\zprotocols\zcancmder\zcancmder_protocol.hpp" namespace iflytop { namespace zcr { typedef enum { kpacketHeader = 0, kpacketData = 1, kpacketTail = 2, } packet_type_t; class CANPacket { public: CAN_RxHeaderTypeDef pHeader; uint8_t aData[8]; /*8byte table*/ }; }; // namespace zcr using namespace zcr; class CanPacketRxBuffer { public: uint16_t id = 0; CANPacket m_canPacket[256] = {0}; // 用于接收can消息 uint8_t m_canPacketNum = 0; bool dataIsReady = false; uint8_t rxdata[2000] = {0}; int rxdataSize = 0; public: uint16_t get_packetindex(); uint16_t get_cmdid(); uint8_t get_subcmdid(); uint8_t get_packetType(); uint8_t *get_data(); uint16_t get_datalen(); Cmdheader_t *get_cmdheader(); bool iscmd(CmdID_t id); template T *get_data_as() { return (T *)get_data(); } }; class ZCanCmderListener { public: virtual void onRceivePacket(CanPacketRxBuffer *rxcmd) = 0; }; typedef function zcan_cmder_listener_t; class ZCanCmder : public ZCanIRQListener { public: class CFG { public: uint8_t deviceId; // /******************************************************************************* * CANConfig * *******************************************************************************/ CAN_HandleTypeDef *canHandle; // 默认使用CAN1 int canFilterIndex0; // 过滤器0 接收,发给自身的消息 int maxFilterNum; // 使用的过滤器数量,最大值14,默认为7 int rxfifoNum; // 使用的FIFO,默认使用FIFO0 int packetRxOvertime_ms; // }; uint8_t txbuff[2100]; public: class LoopJobContext { public: bool hasDoneSomething; }; private: CFG *m_config = NULL; // 配置 bool m_canOnRxDataFlag = false; // 是否有数据接收,用于从中断上下文转移到MainLoop上下文 uint32_t m_lastPacketTicket = 0; // 上一次接收到消息的时间,用于判断与主机是否断开连接 HAL_StatusTypeDef m_lastTransmitStatus; // 上次调用can发送方法的返回值 list m_listenerList; list m_listenerList2; CanPacketRxBuffer m_canPacketRxBuffer[1]; int txPacketInterval_ms = 0; public: ZCanCmder() {} CFG *createCFG(uint8_t deviceId); void init(CFG *cfg); void registerListener(ZCanCmderListener *listener); void regListener(zcan_cmder_listener_t listener); void sendPacket(uint8_t *packet, size_t len); void sendExecStatusReport(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len); void sendStatusReport(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len); void sendAck(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len); void sendErrorAck(Cmdheader_t *cmdheader, uint16_t id, uint32_t errcode); bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems); uint8_t getDeviceId() { return m_config->deviceId; } void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; } void loop(); public: virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can); virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can); private: HAL_StatusTypeDef initializeFilter(); HAL_StatusTypeDef activateRxIT(); HAL_StatusTypeDef deactivateRxIT(); bool getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/); }; } // namespace iflytop