You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
6.5 KiB
137 lines
6.5 KiB
//
|
|
// Created by zwsd
|
|
//
|
|
|
|
#pragma once
|
|
#include <map>
|
|
|
|
#include "basic.hpp"
|
|
#include "sdk/os/zos.hpp"
|
|
#include "sdk\components\zprotocols\zcancmder\zcancmder_protocol.hpp"
|
|
|
|
#define ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
|
|
auto *cmdheader = (Cmdheader_t *)m_txbuf; \
|
|
auto *cmd = (varcmdid##_cmd_t *)cmdheader->data; \
|
|
cmdheader->cmdid = MODULE_CMDID(varcmdid); \
|
|
cmdheader->subcmdid = SUBCMDID(varcmdid); \
|
|
cmdheader->packetType = zcr::kpt_cmd; \
|
|
static_assert(sizeof(varcmdid##_cmd_t) <= sizeof(m_txbuf), "m_txbuf is too small"); \
|
|
cmd->id = m_id;
|
|
|
|
#define ZCAN_SEND_CMD_WITH_STATUS_CB(varcmdid, overtime, ...) \
|
|
ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
|
|
__VA_ARGS__ \
|
|
int32_t errorcode = m_cancmder->sendCmdWithStatusCb((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), getindexcache(varcmdid), overtime, status_cb); \
|
|
return errorcode;
|
|
|
|
#define ZCAN_SEND_CMD(varcmdid, ack, overtime, ...) \
|
|
ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
|
|
__VA_ARGS__ \
|
|
int32_t errorcode = m_cancmder->sendCmd((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), (uint8_t *)&ack, sizeof(ack), overtime); \
|
|
return errorcode;
|
|
|
|
#define ZCAN_SEND_CMD_NO_ACK(varcmdid, overtime, ...) \
|
|
ZCAN_SEND_CMD_PREFIX(varcmdid, overtime) \
|
|
__VA_ARGS__ \
|
|
int32_t errorcode = m_cancmder->sendCmdNoAck((uint8_t *)m_txbuf, sizeof(*cmdheader) + sizeof(*cmd), overtime); \
|
|
return errorcode;
|
|
|
|
namespace iflytop {
|
|
using namespace std;
|
|
typedef function<void(CanPacketRxBuffer *report)> zcan_commnader_master_onpacket_t;
|
|
|
|
class ZCanCommnaderMasterListener {
|
|
public:
|
|
zcan_commnader_master_onpacket_t on_ack;
|
|
zcan_commnader_master_onpacket_t on_cmd_exec_status_report;
|
|
zcan_commnader_master_onpacket_t on_report;
|
|
};
|
|
|
|
class ZCanCommnaderMaster : 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发送方法的返回值
|
|
|
|
#define CAN_PACKET_RX_BUFFER_NUM 5
|
|
CanPacketRxBuffer m_canPacketRxBuffer[CAN_PACKET_RX_BUFFER_NUM];
|
|
|
|
int txPacketInterval_ms = 0;
|
|
|
|
ZThread m_loopThread;
|
|
|
|
map<uint16_t, ZCanCommnaderMasterListener> m_on_packet_map;
|
|
zmutex m_on_packet_map_lock;
|
|
uint16_t m_index_off = 0;
|
|
|
|
public:
|
|
ZCanCommnaderMaster() {}
|
|
CFG *createCFG();
|
|
void init(CFG *cfg);
|
|
|
|
int32_t sendCmd(uint8_t *packet, size_t len, uint8_t *rxbuf, size_t rxbuflen, int overtime_ms);
|
|
int32_t sendCmdNoAck(uint8_t *packet, size_t len, int overtime_ms);
|
|
int32_t sendCmdWithStatusCb(uint8_t *packet, size_t len, uint16_t &packetindex, int overtime_ms, action_cb_status_t status_cb);
|
|
|
|
int32_t sendPacketBlock(uint8_t *packet, size_t len, uint16_t &packetindex, uint8_t *rxbuf, size_t rxbuflen, int overtime_ms, zcan_commnader_master_onpacket_t onReport);
|
|
void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; }
|
|
|
|
public:
|
|
virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can);
|
|
virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can);
|
|
|
|
private:
|
|
void loop();
|
|
|
|
uint8_t getDeviceId() { return m_config->deviceId; }
|
|
void sendPacket(uint8_t *packet, size_t len);
|
|
void regListener(uint16_t index, //
|
|
zcan_commnader_master_onpacket_t onack, //
|
|
zcan_commnader_master_onpacket_t on_cmd_exec_status_report, //
|
|
zcan_commnader_master_onpacket_t on_report);
|
|
void unregListener(uint16_t index);
|
|
void callListener(CanPacketRxBuffer *report);
|
|
void unregListenerAckCB(uint16_t index);
|
|
bool isListenerReg(uint16_t index);
|
|
int getListenerNum();
|
|
uint16_t generateFreeIndex();
|
|
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
|
|
|
|
HAL_StatusTypeDef initializeFilter();
|
|
HAL_StatusTypeDef activateRxIT();
|
|
HAL_StatusTypeDef deactivateRxIT();
|
|
bool getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/);
|
|
|
|
size_t safe_memcpy(void *dst, size_t dst_max_size, void *src, size_t src_len);
|
|
|
|
void initCanPacketRxBuffer(CanPacketRxBuffer *buf, uint16_t id);
|
|
CanPacketRxBuffer *allocCanPacketRxBufferInIRQ(uint16_t id);
|
|
CanPacketRxBuffer *findCanPacketRxBufferInIRQ(uint16_t id);
|
|
void freeCanPacketRxBuffer(uint16_t id);
|
|
void processReadyPacket(CanPacketRxBuffer *buf);
|
|
};
|
|
|
|
} // namespace iflytop
|