// // Created by zwsd // #pragma once #include "a8000_protocol/protocol.hpp" #include "sdk/components/api/zi_module.hpp" #include "sdk/os/zos.hpp" #include "type/zcan_rx_frame.hpp" #include "type/zcan_rx_frame_pool.hpp" #include "type/zcan_rx_frame_queue.hpp" #ifdef HAL_CAN_MODULE_ENABLED namespace iflytop { using namespace zcr; class IZCanRxProcesser { public: virtual bool filterPacket(ZcanRxframe *rx) = 0; virtual void processRxPacket(ZcanRxframe *rx) = 0; }; class ZCanReceiver : 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; // }; 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发送方法的返回值 uint8_t txbuff[128]; IZCanRxProcesser *rxprocesser; ZcanRxframePool m_rxFramePool; // 接收数据池 ZcanRxframeQueue m_pendingMsgQueue; // 接收数据队列 ZcanRxframe *curRxBuf = nullptr; // 当前接收数据 int txPacketInterval_ms = 0; zmutex m_lock; int8_t m_reportIndex = 0; public: ZCanReceiver() {} CFG *createCFG(uint8_t deviceId); void initialize(CFG *cfg); uint8_t getDeviceId() { return m_config->deviceId; } void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; } virtual void registerListener(IZCanRxProcesser *listener); virtual int32_t sendBufAck(zcr_cmd_header_t *rx_cmd_header, uint8_t *data, int32_t len); virtual int32_t sendAck(zcr_cmd_header_t *rx_cmd_header, int32_t *ackvar, int32_t nack); virtual int32_t sendErrorAck(zcr_cmd_header_t *rx_cmd_header, int32_t errorcode); virtual int32_t triggerEvent(zcr_cmd_header_t *cmd_header, uint8_t *data, int32_t len); void loop(); public: virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can); virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can); private: void sendPacket(uint8_t *packet, size_t len); bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems); void processRx(); HAL_StatusTypeDef initializeFilter(); HAL_StatusTypeDef activateRxIT(); HAL_StatusTypeDef deactivateRxIT(); bool getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/); }; } // namespace iflytop #endif