7 changed files with 655 additions and 3 deletions
-
3components/dwin/dwin_screen.cpp
-
4components/eq_20_asb_motor/eq20_servomotor.hpp
-
73components/zcancmder/cmd.hpp
-
343components/zcancmder/zcanreceiver.cpp
-
122components/zcancmder/zcanreceiver.hpp
-
67components/zcancmder_module/zcan_basic_order_module.cpp
-
46components/zcancmder_module/zcan_basic_order_module.hpp
@ -0,0 +1,73 @@ |
|||||
|
#pragma once
|
||||
|
#include "sdk/os/zos.hpp"
|
||||
|
|
||||
|
namespace iflytop { |
||||
|
namespace zcr { |
||||
|
|
||||
|
typedef struct { |
||||
|
uint16_t packetindex; |
||||
|
uint16_t cmdid; |
||||
|
uint8_t subcmdid; |
||||
|
uint8_t packetType; |
||||
|
uint8_t data[]; |
||||
|
} Cmdheader_t; |
||||
|
|
||||
|
typedef enum { |
||||
|
kpt_cmd = 0, |
||||
|
kpt_ack = 1, |
||||
|
kpt_error_ack = 2, |
||||
|
kpt_status_report = 3, |
||||
|
} PacketType_t; |
||||
|
|
||||
|
typedef enum { |
||||
|
kcmd_ping = 0, |
||||
|
kcmd_read_io = 1, |
||||
|
kcmd_set_io = 2, |
||||
|
kcmd_readadc_raw = 3, |
||||
|
|
||||
|
kcmd_m211887_operation = 1000, // 维萨拉臭氧传感器
|
||||
|
kcmd_read_presure_sensor = 1001, // 压力传感器
|
||||
|
kcmd_triple_warning_light_ctl = 1002, // 三色警示灯控制
|
||||
|
kcmd_high_power_electrical_ctl = 1003, // 大功率电源控制
|
||||
|
kcmd_peristaltic_pump_ctl = 1004, // 液泵控制
|
||||
|
kcmd_read_huacheng_pressure_sensor = 1005, // 华诚压力传感器
|
||||
|
} CmdID_t; |
||||
|
} // namespace zcr
|
||||
|
} // namespace iflytop
|
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t boardid; |
||||
|
} kcmd_ping_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t boardid; |
||||
|
} kcmd_ping_ack_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t ioid; |
||||
|
} kcmd_read_io_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t ioid; |
||||
|
uint8_t val; |
||||
|
} kcmd_read_io_ack_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t ioid; |
||||
|
uint8_t val; |
||||
|
} kcmd_set_io_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t ioid; |
||||
|
uint8_t val; |
||||
|
} kcmd_set_io_ack_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t sensorid; |
||||
|
} kcmd_readadc_raw_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t sensorid; |
||||
|
uint8_t __p; // padding
|
||||
|
int32_t val; |
||||
|
} kcmd_readadc_raw_ack_t; |
@ -0,0 +1,343 @@ |
|||||
|
#include "zcanreceiver.hpp"
|
||||
|
|
||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
|
#include <stdio.h>
|
||||
|
#include <stdlib.h>
|
||||
|
#include <string.h>
|
||||
|
using namespace iflytop; |
||||
|
using namespace zcr; |
||||
|
|
||||
|
#define TAG "ZCanCmder"
|
||||
|
|
||||
|
#define OVER_TIME_MS 5
|
||||
|
|
||||
|
uint16_t CanPacketRxBuffer::get_packetindex() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->packetindex; |
||||
|
} |
||||
|
uint16_t CanPacketRxBuffer::get_cmdid() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->cmdid; |
||||
|
} |
||||
|
uint8_t CanPacketRxBuffer::get_subcmdid() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->subcmdid; |
||||
|
} |
||||
|
uint8_t CanPacketRxBuffer::get_packetType() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->packetType; |
||||
|
} |
||||
|
uint8_t *CanPacketRxBuffer::get_data() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->data; |
||||
|
} |
||||
|
uint16_t CanPacketRxBuffer::get_datalen() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return rxdataSize - sizeof(Cmdheader_t); |
||||
|
} |
||||
|
|
||||
|
bool CanPacketRxBuffer::iscmd(CmdID_t id, uint8_t subcmdid) { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader->cmdid == (uint16_t)id && cmdheader->subcmdid == subcmdid; |
||||
|
} |
||||
|
|
||||
|
Cmdheader_t* CanPacketRxBuffer::get_cmdheader() { |
||||
|
Cmdheader_t *cmdheader = (Cmdheader_t *)rxdata; |
||||
|
return cmdheader; |
||||
|
} |
||||
|
|
||||
|
ZCanCmder::CFG *ZCanCmder::createCFG(uint8_t deviceId) { |
||||
|
CFG *cfg = new CFG(); |
||||
|
ZASSERT(cfg != NULL); |
||||
|
cfg->deviceId = deviceId; |
||||
|
#ifdef STM32F103xB
|
||||
|
cfg->canHandle = &hcan; |
||||
|
#else
|
||||
|
cfg->canHandle = &hcan1; |
||||
|
#endif
|
||||
|
cfg->canFilterIndex0 = 0; |
||||
|
cfg->maxFilterNum = 7; |
||||
|
cfg->rxfifoNum = CAN_RX_FIFO0; |
||||
|
return cfg; |
||||
|
} |
||||
|
void ZCanCmder::init(CFG *cfg) { |
||||
|
HAL_StatusTypeDef hal_status; |
||||
|
m_config = cfg; |
||||
|
|
||||
|
/**
|
||||
|
* @brief 初始化CAN |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* @brief 初始化消息接收buf |
||||
|
*/ |
||||
|
m_canPacketRxBuffer[0].dataIsReady = false; |
||||
|
m_canPacketRxBuffer[0].id = 1; // 只接收来自主机的消息
|
||||
|
m_canPacketRxBuffer[0].m_canPacketNum = 0; |
||||
|
|
||||
|
/**
|
||||
|
* @brief 初始化过滤器 |
||||
|
*/ |
||||
|
hal_status = initializeFilter(); |
||||
|
if (hal_status != HAL_OK) { |
||||
|
ZLOGE(TAG, "start can initializeFilter fail\r\n"); |
||||
|
return; |
||||
|
} |
||||
|
/**
|
||||
|
* @brief 启动CAN |
||||
|
*/ |
||||
|
hal_status = HAL_CAN_Start(m_config->canHandle); // 开启CAN
|
||||
|
if (hal_status != HAL_OK) { |
||||
|
ZLOGE(TAG, "start can fail\r\n"); |
||||
|
return; |
||||
|
} |
||||
|
/**
|
||||
|
* @brief 监听回调 |
||||
|
*/ |
||||
|
ZCanIRQDispatcher::instance().regListener(this); |
||||
|
HAL_StatusTypeDef status = activateRxIT(); |
||||
|
if (status != HAL_OK) { |
||||
|
ZLOGE(TAG, "activateRxIT fail\r\n"); |
||||
|
return; |
||||
|
} |
||||
|
// ZHALCORE::getInstance()->regPeriodJob([this](ZHALCORE::Context &context) { loop(); }, 0);
|
||||
|
} |
||||
|
HAL_StatusTypeDef ZCanCmder::initializeFilter() { |
||||
|
/**
|
||||
|
* @brief ID区帧格式 |
||||
|
* [ 27:0 ] |
||||
|
* [ STDID ] [ EXTID ] |
||||
|
* [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0] |
||||
|
* 优先级 属性 帧类型 目标ID 源ID |
||||
|
*/ |
||||
|
HAL_StatusTypeDef HAL_Status; |
||||
|
CAN_FilterTypeDef sFilterConfig; |
||||
|
|
||||
|
uint32_t filterId; |
||||
|
uint32_t mask; |
||||
|
|
||||
|
memset(&sFilterConfig, 0, sizeof(sFilterConfig)); |
||||
|
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 设为MASK模式
|
||||
|
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
|
||||
|
sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // 关联过滤器到rxfifoNum
|
||||
|
sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
|
||||
|
sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
|
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* 接收所有消息 * |
||||
|
*******************************************************************************/ |
||||
|
filterId = (0); //
|
||||
|
mask = (0); //
|
||||
|
sFilterConfig.FilterBank = m_config->canFilterIndex0; //
|
||||
|
sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
|
||||
|
sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
|
||||
|
sFilterConfig.FilterIdLow = filterId & 0xffff; //
|
||||
|
sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
|
||||
|
HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig); |
||||
|
if (HAL_Status != HAL_OK) { |
||||
|
ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail"); |
||||
|
return HAL_Status; |
||||
|
} |
||||
|
ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3); |
||||
|
return HAL_Status; |
||||
|
} |
||||
|
|
||||
|
void ZCanCmder::registerListener(ZCanCmderListener *listener) { m_listenerList.push_back(listener); } |
||||
|
void ZCanCmder::regListener(zcan_cmder_listener_t listener) { m_listenerList2.push_back(listener); } |
||||
|
void ZCanCmder::sendPacket(uint8_t *packet, size_t len) { |
||||
|
/**
|
||||
|
* @brief |
||||
|
*/ |
||||
|
int npacket = len / 8 + (len % 8 == 0 ? 0 : 1); |
||||
|
if (npacket > 255) { |
||||
|
ZLOGE(TAG, "sendPacket fail, len:%d", len); |
||||
|
return; |
||||
|
} |
||||
|
int finalpacketlen = len % 8 == 0 ? 8 : len % 8; |
||||
|
|
||||
|
for (uint8_t i = 0; i < npacket; i++) { |
||||
|
bool suc = false; |
||||
|
if (i == npacket - 1) { |
||||
|
suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS); |
||||
|
} else { |
||||
|
suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS); |
||||
|
} |
||||
|
if (!suc) { |
||||
|
ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ZCanCmder::sendAck(Cmdheader_t *cmdheader, uint8_t *data, size_t len) { |
||||
|
Cmdheader_t *txheader = (Cmdheader_t *)txbuff; |
||||
|
memcpy(txheader, cmdheader, sizeof(Cmdheader_t)); |
||||
|
txheader->packetType = kpt_ack; |
||||
|
memcpy(txheader->data, data, len); |
||||
|
sendPacket(txbuff, sizeof(Cmdheader_t) + len); |
||||
|
} |
||||
|
|
||||
|
void ZCanCmder::sendErrorAck(Cmdheader_t *cmdheader, int16_t errcode) { |
||||
|
Cmdheader_t *txheader = (Cmdheader_t *)txbuff; |
||||
|
memcpy(txheader, cmdheader, sizeof(Cmdheader_t)); |
||||
|
txheader->packetType = kpt_error_ack; |
||||
|
sendPacket(txbuff, sizeof(Cmdheader_t) + 2); |
||||
|
} |
||||
|
|
||||
|
bool ZCanCmder::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) { |
||||
|
CAN_TxHeaderTypeDef pHeader; |
||||
|
uint8_t aData[8] /*8byte table*/; |
||||
|
uint32_t txMailBox = 0; |
||||
|
|
||||
|
uint32_t enterticket = zos_get_tick(); |
||||
|
|
||||
|
memset(&pHeader, 0, sizeof(pHeader)); |
||||
|
memset(aData, 0, sizeof(aData)); |
||||
|
pHeader.StdId = 0x00; |
||||
|
pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex; |
||||
|
pHeader.IDE = CAN_ID_EXT; |
||||
|
pHeader.RTR = CAN_RTR_DATA; |
||||
|
pHeader.DLC = len; |
||||
|
pHeader.TransmitGlobalTime = DISABLE; |
||||
|
|
||||
|
memcpy(aData, packet, len); |
||||
|
|
||||
|
m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox); |
||||
|
if (m_lastTransmitStatus != HAL_OK) { |
||||
|
ZLOGE(TAG, "HAL_CAN_AddTxMessage fail"); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) { |
||||
|
if (zos_haspassedms(enterticket) > (uint32_t)overtimems) { |
||||
|
m_lastTransmitStatus = HAL_TIMEOUT; |
||||
|
HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox); |
||||
|
return false; |
||||
|
} |
||||
|
// m_os->sleepMS(1);
|
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool ZCanCmder::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) { |
||||
|
/**
|
||||
|
* @brief 读取当前FIFO中缓存了多少帧的数据 |
||||
|
*/ |
||||
|
uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum); |
||||
|
if (level == 0) { |
||||
|
return false; |
||||
|
} |
||||
|
HAL_StatusTypeDef HAL_RetVal; |
||||
|
HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData); |
||||
|
if (HAL_OK == HAL_RetVal) { |
||||
|
// 处理接收到的can总线数据
|
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
void ZCanCmder::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) { |
||||
|
/**
|
||||
|
* @brief 中断上下文 |
||||
|
*/ |
||||
|
// ZLOG_INFO("%s\n", __FUNCTION__);
|
||||
|
// printf("------------------%s\n", __FUNCTION__);
|
||||
|
if (canHandle != m_config->canHandle) { |
||||
|
return; |
||||
|
} |
||||
|
/**
|
||||
|
* @brief 处理can接收到消息 |
||||
|
*/ |
||||
|
CAN_RxHeaderTypeDef pHeader; |
||||
|
uint8_t aData[8] /*8byte table*/; |
||||
|
while (getRxMessage(&pHeader, aData)) { |
||||
|
/**
|
||||
|
* @brief 消息格式 |
||||
|
* |
||||
|
* [2] [3bit] [8bit] [8bit] [8bit] |
||||
|
* , from frameNum frameId |
||||
|
*/ |
||||
|
uint8_t from = (pHeader.ExtId >> 16 & 0xFF); |
||||
|
uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8; |
||||
|
uint8_t frameId = (pHeader.ExtId & 0x00FF); |
||||
|
CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0]; |
||||
|
if (from != rxbuf->id) { |
||||
|
// 目前只接收来自主机的消息
|
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (rxbuf->dataIsReady) { |
||||
|
// 上次接收到的消息还没有来的急处理
|
||||
|
continue; |
||||
|
} |
||||
|
/**
|
||||
|
* @TODO:判断是否丢包 |
||||
|
*/ |
||||
|
if (frameId == 0) { |
||||
|
rxbuf->m_canPacketNum = 0; |
||||
|
} |
||||
|
|
||||
|
if (rxbuf->m_canPacketNum < 255) { |
||||
|
rxbuf->m_canPacket[rxbuf->m_canPacketNum].pHeader = pHeader; |
||||
|
memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8); |
||||
|
rxbuf->m_canPacketNum++; |
||||
|
} |
||||
|
if (nframe == frameId + 1) { |
||||
|
rxbuf->dataIsReady = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// deactivateRxIT();
|
||||
|
} |
||||
|
void ZCanCmder::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) { |
||||
|
if (canHandle != m_config->canHandle) { |
||||
|
return; |
||||
|
} |
||||
|
ZLOGE(TAG, "onCAN_Error\r\n"); |
||||
|
} |
||||
|
void ZCanCmder::loop() { |
||||
|
CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0]; |
||||
|
if (rxbuf->dataIsReady) { |
||||
|
int dataoff = 0; |
||||
|
for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) { |
||||
|
memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC); |
||||
|
dataoff += rxbuf->m_canPacket[i].pHeader.DLC; |
||||
|
} |
||||
|
rxbuf->rxdataSize = dataoff; |
||||
|
|
||||
|
for (auto &var : m_listenerList) { |
||||
|
var->onRceivePacket(rxbuf); |
||||
|
} |
||||
|
|
||||
|
for (auto &var : m_listenerList2) { |
||||
|
var(rxbuf); |
||||
|
} |
||||
|
|
||||
|
rxbuf->dataIsReady = false; |
||||
|
} |
||||
|
} |
||||
|
HAL_StatusTypeDef ZCanCmder::activateRxIT() { |
||||
|
HAL_StatusTypeDef hal_status = HAL_ERROR; |
||||
|
if (m_config->rxfifoNum == CAN_RX_FIFO0) { |
||||
|
hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING); |
||||
|
} else if (m_config->rxfifoNum == CAN_RX_FIFO1) { |
||||
|
hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING); |
||||
|
} else { |
||||
|
ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n"); |
||||
|
return hal_status; |
||||
|
} |
||||
|
return hal_status; |
||||
|
} |
||||
|
HAL_StatusTypeDef ZCanCmder::deactivateRxIT() { |
||||
|
HAL_StatusTypeDef hal_status = HAL_ERROR; |
||||
|
if (m_config->rxfifoNum == CAN_RX_FIFO0) { |
||||
|
hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING); |
||||
|
} else if (m_config->rxfifoNum == CAN_RX_FIFO1) { |
||||
|
hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING); |
||||
|
} else { |
||||
|
ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n"); |
||||
|
return hal_status; |
||||
|
} |
||||
|
return hal_status; |
||||
|
} |
||||
|
|
||||
|
#endif
|
@ -0,0 +1,122 @@ |
|||||
|
//
|
||||
|
// Created by zwsd
|
||||
|
//
|
||||
|
|
||||
|
#pragma once
|
||||
|
#include "cmd.hpp"
|
||||
|
#include "sdk/os/zos.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, uint8_t subcmdid); |
||||
|
|
||||
|
template <typename T> |
||||
|
T *get_data_as() { |
||||
|
return (T *)get_data(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
class ZCanCmderListener { |
||||
|
public: |
||||
|
virtual void onRceivePacket(CanPacketRxBuffer *rxcmd) = 0; |
||||
|
}; |
||||
|
|
||||
|
typedef function<void(CanPacketRxBuffer *rxcmd)> 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[1000]; |
||||
|
|
||||
|
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<ZCanCmderListener *> m_listenerList; |
||||
|
list<zcan_cmder_listener_t> m_listenerList2; |
||||
|
CanPacketRxBuffer m_canPacketRxBuffer[1]; |
||||
|
|
||||
|
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 sendAck(Cmdheader_t *rxcmdheader, uint8_t *data, size_t len); |
||||
|
void sendErrorAck(Cmdheader_t *rxcmdheader, int16_t errcode); |
||||
|
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems); |
||||
|
uint8_t getDeviceId() { return m_config->deviceId; } |
||||
|
|
||||
|
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
|
@ -0,0 +1,67 @@ |
|||||
|
#include "zcan_basic_order_module.hpp"
|
||||
|
|
||||
|
#include <stdio.h>
|
||||
|
#include <string.h>
|
||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
|
|
||||
|
using namespace iflytop; |
||||
|
using namespace zcr; |
||||
|
|
||||
|
void ZCanBasicOrderModule::initialize(ZCanCmder* zcanReceiver) { |
||||
|
zcanReceiver->registerListener(this); |
||||
|
m_zcanReceiver = zcanReceiver; |
||||
|
} |
||||
|
|
||||
|
void ZCanBasicOrderModule::regInputCtl(readfn_t fn) { m_readfn = fn; } |
||||
|
void ZCanBasicOrderModule::regOutCtl(writefn_t fn) { m_writefn = fn; } |
||||
|
void ZCanBasicOrderModule::regReadAdcVal(readadcval_t fn) { m_readadcval = fn; } |
||||
|
|
||||
|
void ZCanBasicOrderModule::onRceivePacket(CanPacketRxBuffer* rxbuf) { |
||||
|
if (rxbuf->iscmd(kcmd_ping, 0)) { |
||||
|
kcmd_ping_t* pingcmd = rxbuf->get_data_as<kcmd_ping_t>(); |
||||
|
kcmd_ping_ack_t* ack = (kcmd_ping_ack_t*)txbuff; |
||||
|
|
||||
|
if (pingcmd->boardid == m_zcanReceiver->getDeviceId()) { |
||||
|
ack->boardid = pingcmd->boardid; |
||||
|
m_zcanReceiver->sendAck(rxbuf->get_cmdheader(), txbuff, sizeof(kcmd_ping_ack_t)); |
||||
|
return; |
||||
|
} |
||||
|
} else if (rxbuf->iscmd(kcmd_read_io, 0)) { |
||||
|
kcmd_read_io_t* cmd = rxbuf->get_data_as<kcmd_read_io_t>(); |
||||
|
kcmd_read_io_ack_t* ack = (kcmd_read_io_ack_t*)txbuff; |
||||
|
bool val = false; |
||||
|
|
||||
|
if (m_readfn && m_readfn(cmd->ioid, val)) { |
||||
|
ack->ioid = cmd->ioid; |
||||
|
ack->val = val; |
||||
|
m_zcanReceiver->sendAck(rxbuf->get_cmdheader(), txbuff, sizeof(kcmd_read_io_ack_t)); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
} else if (rxbuf->iscmd(kcmd_set_io, 0)) { |
||||
|
kcmd_set_io_t* cmd = rxbuf->get_data_as<kcmd_set_io_t>(); |
||||
|
kcmd_set_io_ack_t ack; |
||||
|
bool val = cmd->val; |
||||
|
if (m_writefn && m_writefn(cmd->ioid, val)) { |
||||
|
ack.ioid = cmd->ioid; |
||||
|
ack.val = val; |
||||
|
m_zcanReceiver->sendAck(rxbuf->get_cmdheader(), (uint8_t*)&ack, sizeof(ack)); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
} else if (rxbuf->iscmd(kcmd_readadc_raw, 0)) { |
||||
|
kcmd_readadc_raw_t* cmd = rxbuf->get_data_as<kcmd_readadc_raw_t>(); |
||||
|
kcmd_readadc_raw_ack_t ack; |
||||
|
int32_t val = 0; |
||||
|
if (m_readadcval && m_readadcval(cmd->sensorid, val)) { |
||||
|
ack.sensorid = cmd->sensorid; |
||||
|
ack.val = val; |
||||
|
m_zcanReceiver->sendAck(rxbuf->get_cmdheader(), (uint8_t*)&ack, sizeof(ack)); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ZCanBasicOrderModule::loop() {} |
||||
|
|
||||
|
#endif
|
@ -0,0 +1,46 @@ |
|||||
|
//
|
||||
|
// Created by zwsd
|
||||
|
//
|
||||
|
|
||||
|
#pragma once
|
||||
|
//
|
||||
|
#include "sdk/os/zos.hpp"
|
||||
|
#include "sdk\components\zcancmder\zcanreceiver.hpp"
|
||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
|
|
||||
|
namespace iflytop { |
||||
|
class ZCanBasicOrderModule : public ZCanCmderListener { |
||||
|
public: |
||||
|
private: |
||||
|
ZCanCmder* m_zcanReceiver; |
||||
|
|
||||
|
typedef function<bool(uint8_t id, bool& val)> readfn_t; |
||||
|
typedef function<bool(uint8_t id, bool val)> writefn_t; |
||||
|
typedef function<bool(uint8_t id, int32_t& val)> readadcval_t; |
||||
|
|
||||
|
readfn_t m_readfn; |
||||
|
writefn_t m_writefn; |
||||
|
readadcval_t m_readadcval; |
||||
|
|
||||
|
uint8_t txbuff[32]; |
||||
|
|
||||
|
public: |
||||
|
ZCanBasicOrderModule(/* args */) {} |
||||
|
~ZCanBasicOrderModule() {} |
||||
|
|
||||
|
public: |
||||
|
void initialize(ZCanCmder* zcanReceiver); |
||||
|
|
||||
|
void regInputCtl(readfn_t fn); |
||||
|
void regOutCtl(writefn_t fn); |
||||
|
void regReadAdcVal(readadcval_t fn); |
||||
|
|
||||
|
public: |
||||
|
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf); |
||||
|
|
||||
|
private: |
||||
|
void loop(); |
||||
|
}; |
||||
|
} // namespace iflytop
|
||||
|
|
||||
|
#endif
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue