Browse Source

add zcanmodules

master
zhaohe 2 years ago
parent
commit
9ad9341868
  1. 4
      chip/marco.h
  2. 67
      components/modbus/modbus_basic.cpp
  3. 28
      components/modbus/modbus_basic.hpp
  4. 108
      components/modbus/modbus_block_host.cpp
  5. 27
      components/modbus/modbus_block_host.hpp
  6. 4
      components/single_axis_motor_control_v2/i_iflytop_can_slave_module.cpp
  7. 79
      components/zcan_module/zcan_basic_order_module.cpp
  8. 43
      components/zcan_module/zcan_basic_order_module.hpp
  9. 105
      components/zcan_module/zcan_high_power_electrical_ctl_module.cpp
  10. 47
      components/zcan_module/zcan_high_power_electrical_ctl_module.hpp
  11. 0
      components/zcan_module/zcan_m211887_module_manager.cpp
  12. 45
      components/zcan_module/zcan_m211887_module_manager.hpp
  13. 57
      components/zcan_module/zcan_pressure_sensor_module.cpp
  14. 45
      components/zcan_module/zcan_pressure_sensor_module.hpp
  15. 63
      components/zcan_module/zcan_pump_ctrl_module.cpp
  16. 45
      components/zcan_module/zcan_pump_ctrl_module.hpp
  17. 68
      components/zcan_module/zcan_trigle_warning_light_ctl_module.cpp
  18. 45
      components/zcan_module/zcan_trigle_warning_light_ctl_module.hpp
  19. 29
      components/zcanreceiver/cmd.hpp
  20. 10
      components/zcanreceiver/zcanreceiver.cpp
  21. 14
      components/zcanreceiver/zcanreceiver.hpp

4
chip/marco.h

@ -1,6 +1,6 @@
#pragma once
#ifndef ZARRAY_SIZE
#define ZARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define ZARRAY_SIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
#endif
#define ZMAX(a, b) ((a) > (b) ? (a) : (b))
#define ZMIN(a, b) ((a) < (b) ? (a) : (b))
@ -42,4 +42,4 @@
#endif
#ifndef UINT64_MAX
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
#endif
#endif

67
components/modbus/modbus_basic.cpp

@ -0,0 +1,67 @@
/**
* Modbus
* | add(1byte) | functionCode(1byte) | ...data... | crc1(1byte) | crc2(2byte)|
*
*
*
*
*/
#include "modbus_basic.hpp"
#include <stdint.h>
// CRC_16高8位数据区
#define ASSERT(con) \
while (!(con)) { \
}
static const uint8_t auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};
// CRC低位字节值表
static const uint8_t auchCRCLo[] = { // CRC_16低8位数据区
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA,
0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15,
0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35,
0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA,
0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7,
0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E,
0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
/*CRC16查表计算函数*/
uint16_t modbus_gen_crc16(uint8_t *puckMsg, uint8_t usDataLen) {
volatile uint8_t uchCRCHi = 0xFF; // 高CRC字节初始化
volatile uint8_t uchCRCLo = 0xFF; // 低CRC 字节初始化
volatile uint32_t uIndex; // CRC循环中的索引
// 传输消息缓冲区
while (usDataLen--) {
// 计算CRC
uIndex = uchCRCLo ^ *puckMsg++;
uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex];
uchCRCHi = auchCRCLo[uIndex];
}
// 返回结果,高位在前
return (uchCRCLo << 8 | uchCRCHi);
}
void modbus_pack_crc_to_packet(uint8_t *puckMsg, uint8_t packetlen) {
uint16_t crc = modbus_gen_crc16(puckMsg, packetlen - 2);
puckMsg[packetlen - 2] = crc >> 8;
puckMsg[packetlen - 1] = crc;
}
/*函数功能:用于校验接收到的信息是否有误
message是接收到的待校验消息length是消息字节的长度
TrueFalse
CRC校验校验接收的信息是否正确*/
bool modbus_checkcrc16(uint8_t *message, uint8_t length) { return (modbus_gen_crc16(message, length) == 0x00) ? true : false; }

28
components/modbus/modbus_basic.hpp

@ -0,0 +1,28 @@
#pragma ocne
#include <stdbool.h>
#include <stdint.h>
/**
* @brief CRC16校验码
*
* @param puckMsg
* @param usDataLen (CRC16)
* @return uint16_t
*/
uint16_t modbus_gen_crc16(uint8_t *puckMsg, uint8_t usDataLen);
/**
* @brief CRC16校验码添加到数据包中
*
* @param puckMsg CRC16
* @param packetlen
*/
void modbus_pack_crc_to_packet(uint8_t *puckMsg, uint8_t packetlen);
/**
* @brief CRC16校验码
*
* @param message
* @param length (CRC16)
* @return true
* @return false
*/
bool modbus_checkcrc16(uint8_t *message, uint8_t length);

108
components/modbus/modbus_block_host.cpp

@ -0,0 +1,108 @@
#include "modbus_block_host.hpp"
#include "modbus_basic.hpp"
using namespace iflytop;
#define DEBUG 1
ModbusBlockHost::ModbusBlockHost() {}
ModbusBlockHost::~ModbusBlockHost() {}
void ModbusBlockHost::initialize(UART_HandleTypeDef *huart) {}
void ModbusBlockHost::cleanRxBuff() { //
HAL_StatusTypeDef status;
do {
status = HAL_UART_Receive(huart, rxbuff, 1, 1);
} while (status == HAL_OK);
}
void ModbusBlockHost::uarttx(uint8_t *buff, size_t len) {
#if DEBUG
printf("uarttx:\n");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
#endif
HAL_UART_Transmit(huart, buff, len, 1000);
}
bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) {
HAL_StatusTypeDef status;
status = HAL_UART_Receive(huart, buff, len, overtimems);
#if DEBUG
if (status == HAL_OK) {
printf("uartrx:");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
}
#endif
return status == HAL_OK;
}
bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) {
txbuff[0] = slaveAddr;
txbuff[1] = 0x03;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = 0x01;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
status = uartrx(rxbuff, 7, overtimems);
if (status && modbus_checkcrc16(rxbuff, 7)) {
*regVal = rxbuff[3] << 8 | rxbuff[4];
return true;
}
return false;
}
bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
txbuff[0] = slaveAddr;
txbuff[1] = 0x06;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = regVal >> 8;
txbuff[5] = regVal & 0xff;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
status = uartrx(rxbuff, 8, overtimems);
if (status && modbus_checkcrc16(rxbuff, 8)) {
return true;
}
return false;
}
bool ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
txbuff[0] = slaveAddr;
txbuff[1] = 0x10;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = 0x01;
txbuff[6] = 0x02; // 字节数
txbuff[7] = regVal >> 8;
txbuff[8] = regVal & 0xff;
modbus_pack_crc_to_packet(txbuff, 9 + 2);
cleanRxBuff();
uarttx(txbuff, 9 + 2);
bool status;
status = uartrx(rxbuff, 8, overtimems);
if (status && modbus_checkcrc16(rxbuff, 8)) {
return true;
}
return false;
}

27
components/modbus/modbus_block_host.hpp

@ -0,0 +1,27 @@
#pragma ocne
#include "sdk/hal/zhal.hpp"
//
namespace iflytop {
class ModbusBlockHost {
UART_HandleTypeDef *huart;
uint8_t txbuff[32];
uint8_t rxbuff[32];
public:
ModbusBlockHost();
~ModbusBlockHost();
void initialize(UART_HandleTypeDef *huart);
bool readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems);
bool writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems);
bool writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems);
private:
void cleanRxBuff();
void uarttx(uint8_t *buff, size_t len);
bool uartrx(uint8_t *buff, size_t len, int overtimems);
};
} // namespace iflytop

4
components/single_axis_motor_control_v2/i_iflytop_can_slave_module.cpp

@ -268,7 +268,7 @@ icps::error_t IIflytopCanSlaveModule::onHostRegisterWriteEvent(IflytopCanProtoco
*/
icps::error_t err;
int regoff = writeEvent->reg->add - m_regStart;
for (size_t i = 0; i < m_configParaNum; i++) {
for (int i = 0; i < m_configParaNum; i++) {
if (m_configParas[i].getRegAddOff() == regoff) {
err = m_configParas[i].processIflytopCanRegisterWriteEvent(writeEvent);
ZLOGI(m_name, "update Config %d %d", m_configParas[i].getRegAddOff(), writeEvent->newvalue);
@ -276,7 +276,7 @@ icps::error_t IIflytopCanSlaveModule::onHostRegisterWriteEvent(IflytopCanProtoco
}
}
for (size_t i = 0; i < m_actionNum; i++) {
for (int i = 0; i < m_actionNum; i++) {
if (m_action[i].getRegAddOff() == regoff) {
/**
* @brief

79
components/zcan_module/zcan_basic_order_module.cpp

@ -0,0 +1,79 @@
#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(ZCanReceiver* 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::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) { //
Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
if (cmdheader->cmdid == kcmd_ping && cmdheader->subcmdid == 0) {
/**
* @brief
* cmd : b0:boardid
* ack : b0:boardid
* ack_datalen : 1
*/
if (cmdheader->data[0] == m_zcanReceiver->getDeviceId()) {
//
Cmdheader_t* txheader = (Cmdheader_t*)txbuff;
memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
txheader->packetType = kpt_ack;
txheader->data[0] = cmdheader->data[0];
m_zcanReceiver->sendPacket(txbuff, sizeof(Cmdheader_t) + 1);
return;
}
} else if (cmdheader->cmdid == kcmd_read_io && cmdheader->subcmdid == 0) {
/**
* @brief
* cmd : b0:ioid
* ack : b0:ioid b1:ioval
* ack_datalen : 2
*/
uint8_t ioid = cmdheader->data[0];
bool val = 0;
if (m_readfn && m_readfn(ioid, val)) {
//
Cmdheader_t* txheader = (Cmdheader_t*)txbuff;
memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
txheader->packetType = kpt_ack;
txheader->data[0] = cmdheader->data[0];
txheader->data[1] = val;
m_zcanReceiver->sendPacket(txbuff, sizeof(Cmdheader_t) + 2);
return;
}
} else if (cmdheader->cmdid == kcmd_set_io && cmdheader->subcmdid == 0) {
/**
* @brief
* cmd : b0:ioid b1:ioval
* ack : b0:ioid b1:ioval
* ack_datalen : 2
*/
uint8_t ioid = cmdheader->data[0];
bool val = cmdheader->data[1];
if (m_writefn && m_writefn(ioid, val)) {
Cmdheader_t* txheader = (Cmdheader_t*)txbuff;
memcpy(txheader, cmdheader, sizeof(Cmdheader_t));
txheader->packetType = kpt_ack;
txheader->data[0] = cmdheader->data[0];
txheader->data[1] = cmdheader->data[1];
m_zcanReceiver->sendPacket(txbuff, sizeof(Cmdheader_t) + 2);
return;
}
}
}
void ZCanBasicOrderModule::loop() {}
#endif

43
components/zcan_module/zcan_basic_order_module.hpp

@ -0,0 +1,43 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanBasicOrderModule : public ZCanRceiverListener {
public:
private:
ZCanReceiver* m_zcanReceiver;
typedef function<bool(uint8_t id, bool& val)> readfn_t;
typedef function<bool(uint8_t id, bool val)> writefn_t;
readfn_t m_readfn;
writefn_t m_writefn;
uint8_t txbuff[32];
public:
ZCanBasicOrderModule(/* args */) {}
~ZCanBasicOrderModule() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void regInputCtl(readfn_t fn);
void regOutCtl(writefn_t fn);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
private:
void loop();
};
} // namespace iflytop
#endif

105
components/zcan_module/zcan_high_power_electrical_ctl_module.cpp

@ -0,0 +1,105 @@
#include "zcan_high_power_electrical_ctl_module.hpp"
#include <stdio.h>
#include <string.h>
#ifdef HAL_CAN_MODULE_ENABLED
using namespace iflytop;
using namespace zcr;
#define TAG "ZCanHighPowerElectricalCtlModule"
void ZCanHighPowerElectricalCtlModule::initialize(ZCanReceiver* zcanReceiver) {
zcanReceiver->registerListener(this);
m_zcanReceiver = zcanReceiver;
}
void ZCanHighPowerElectricalCtlModule::pushElectricAppliance(int id, setswitchfn_t m_set_safe_switch, setswitchfn_t m_set_power_switch,
getcurrentfn_t m_get_current) {
ZASSERT(m_set_safe_switch != NULL);
ZASSERT(m_set_power_switch != NULL);
ZASSERT(m_get_current != NULL);
ElectricAppliance* appliance = new ElectricAppliance();
ZASSERT(appliance != NULL);
appliance->id = id;
appliance->m_set_safe_switch = m_set_safe_switch;
appliance->m_set_power_switch = m_set_power_switch;
appliance->m_get_current = m_get_current;
m_electricAppliances.push_back(appliance);
}
ZCanHighPowerElectricalCtlModule::ElectricAppliance* ZCanHighPowerElectricalCtlModule::find(int id) {
for (auto it = m_electricAppliances.begin(); it != m_electricAppliances.end(); it++) {
if ((*it)->id == id) {
return *it;
}
}
return NULL;
}
void ZCanHighPowerElectricalCtlModule::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) { //
//
Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
if (cmdheader->cmdid == kcmd_high_power_electrical_ctl && cmdheader->subcmdid == 0) {
/**
* @brief (0)
* cmd : b0:id b1:switchstatus
* ack : b0:boardid b1:switchstatus
* ack_datalen : 2
*/
uint8_t id = cmdheader->data[0];
bool swicthval = cmdheader->data[1];
ElectricAppliance* appliance = find(id);
if (appliance) {
appliance->m_set_power_switch(swicthval);
uint8_t txbuff[2] = {id, swicthval};
m_zcanReceiver->sendAck(cmdheader, txbuff, 2);
ZLOGI(TAG, "set power switch %d %d", id, swicthval);
return;
}
}
if (cmdheader->cmdid == kcmd_high_power_electrical_ctl && cmdheader->subcmdid == 1) {
/**
* @brief
* cmd : b0:id b1:switchstatus
* ack : b0:boardid b1:switchstatus
* ack_datalen : 2
*/
uint8_t id = cmdheader->data[0];
bool swicthval = cmdheader->data[1];
ElectricAppliance* appliance = find(id);
if (appliance) {
appliance->m_set_power_switch(swicthval);
uint8_t txbuff[2] = {id, swicthval};
m_zcanReceiver->sendAck(cmdheader, txbuff, 2);
ZLOGI(TAG, "set safe switch %d %d", id, swicthval);
return;
}
}
if (cmdheader->cmdid == kcmd_high_power_electrical_ctl && cmdheader->subcmdid == 3) {
/**
* @brief
* cmd : b0:id
* ack : b0:boardid b2-5 current
* ack_datalen : 2
*/
uint8_t id = cmdheader->data[0];
ElectricAppliance* appliance = find(id);
if (appliance) {
uint8_t txbuff[2 + 4] = {0};
txbuff[0] = id;
*(int32_t*)(&txbuff[2]) = appliance->m_get_current();
m_zcanReceiver->sendAck(cmdheader, txbuff, sizeof(txbuff));
return;
}
}
}
#endif

47
components/zcan_module/zcan_high_power_electrical_ctl_module.hpp

@ -0,0 +1,47 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanHighPowerElectricalCtlModule : public ZCanRceiverListener {
public:
typedef function<void(bool)> setswitchfn_t;
typedef function<int32_t()> getcurrentfn_t; // 读取工作电流 ma
class ElectricAppliance {
public:
int id;
setswitchfn_t m_set_safe_switch;
setswitchfn_t m_set_power_switch;
getcurrentfn_t m_get_current; // 0.1A
};
private:
ZCanReceiver* m_zcanReceiver;
list<ElectricAppliance*> m_electricAppliances;
public:
ZCanHighPowerElectricalCtlModule(/* args */) {}
~ZCanHighPowerElectricalCtlModule() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void pushElectricAppliance(int id, setswitchfn_t m_set_safe_switch, setswitchfn_t m_set_power_switch, getcurrentfn_t m_get_current);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
ElectricAppliance* find(int id);
private:
void loop();
};
} // namespace iflytop
#endif

0
components/zcan_module/zcan_m211887_module_manager.cpp

45
components/zcan_module/zcan_m211887_module_manager.hpp

@ -0,0 +1,45 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanM211887ModuleManager : public ZCanRceiverListener {
public:
typedef function<void(uint8_t r, uint8_t g, uint8_t b, uint8_t beep)> WarningLightCtrlFn_t;
class Submodule {
public:
int id;
WarningLightCtrlFn_t ctrl_fn;
};
private:
ZCanReceiver* m_zcanReceiver;
list<Submodule*> m_submodules;
public:
ZCanM211887ModuleManager(/* args */) {}
~ZCanM211887ModuleManager() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void regSubmodule(int id, WarningLightCtrlFn_t fn);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
Submodule* find(int id);
private:
void loop();
};
} // namespace iflytop
#endif

57
components/zcan_module/zcan_pressure_sensor_module.cpp

@ -0,0 +1,57 @@
#include "zcan_pressure_sensor_module.hpp"
#include <stdio.h>
#include <string.h>
#ifdef HAL_CAN_MODULE_ENABLED
using namespace iflytop;
using namespace zcr;
#define TAG "ZCanPressureSensorModule"
void ZCanPressureSensorModule::initialize(ZCanReceiver* zcanReceiver) {
zcanReceiver->registerListener(this);
m_zcanReceiver = zcanReceiver;
}
void ZCanPressureSensorModule::regSubmodule(int id, readpresure_t fn) {
ZASSERT(fn != NULL);
Submodule* submodule = new Submodule();
ZASSERT(submodule != NULL);
submodule->id = id;
submodule->m_readpresure_fn = fn;
m_submodules.push_back(submodule);
}
void ZCanPressureSensorModule::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) {
Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
if (cmdheader->cmdid == kcmd_read_presure_sensor && cmdheader->subcmdid == 0) {
/**
* @brief (0)
* cmd : b0:sensorid
* ack : b0:boardid b2:5:presure pa
* ack_datalen : 6
*/
uint8_t id = cmdheader->data[0];
Submodule* subm = find(id);
if (subm) {
uint8_t txbuff[6] = {};
txbuff[0] = id;
*(int32_t*)(&txbuff[2]) = subm->m_readpresure_fn();
m_zcanReceiver->sendAck(cmdheader, txbuff, 6);
return;
}
}
}
ZCanPressureSensorModule::Submodule* ZCanPressureSensorModule::find(int id) {
for (auto it = m_submodules.begin(); it != m_submodules.end(); it++) {
if ((*it)->id == id) {
return *it;
}
}
return NULL;
}
#endif

45
components/zcan_module/zcan_pressure_sensor_module.hpp

@ -0,0 +1,45 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanPressureSensorModule : public ZCanRceiverListener {
public:
typedef function<int32_t()> readpresure_t;
class Submodule {
public:
int id;
readpresure_t m_readpresure_fn;
};
private:
ZCanReceiver* m_zcanReceiver;
list<Submodule*> m_submodules;
public:
ZCanPressureSensorModule(/* args */) {}
~ZCanPressureSensorModule() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void regSubmodule(int id, readpresure_t fn);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
Submodule* find(int id);
private:
void loop();
};
} // namespace iflytop
#endif

63
components/zcan_module/zcan_pump_ctrl_module.cpp

@ -0,0 +1,63 @@
#include "zcan_pump_ctrl_module.hpp"
#include <stdio.h>
#include <string.h>
#ifdef HAL_CAN_MODULE_ENABLED
using namespace iflytop;
using namespace zcr;
#define TAG "ZCanPumpCtrlModule"
void ZCanPumpCtrlModule::initialize(ZCanReceiver* zcanReceiver) {
zcanReceiver->registerListener(this);
m_zcanReceiver = zcanReceiver;
}
void ZCanPumpCtrlModule::regSubmodule(int id, pumprun_t fn) {
ZASSERT(fn != NULL);
Submodule* submodule = new Submodule();
ZASSERT(submodule != NULL);
submodule->id = id;
submodule->m_pumprun_fn = fn;
m_submodules.push_back(submodule);
}
void ZCanPumpCtrlModule::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) {
Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
if (cmdheader->cmdid == kcmd_peristaltic_pump_ctl && cmdheader->subcmdid == 0) {
/**
* @brief (0)
* cmd:
* [0]:ID
* [2:3]:acc [4:5]:rpm
* ack : b0:pumpid
* ack_datalen : 1
*/
uint8_t id = cmdheader->data[0];
Submodule* subm = find(id);
if (subm) {
int16_t acc = *(int16_t*)(&cmdheader->data[2]);
int16_t rpm = *(int16_t*)(&cmdheader->data[4]);
subm->m_pumprun_fn(acc, rpm);
uint8_t txbuff[1] = {};
txbuff[0] = id;
m_zcanReceiver->sendAck(cmdheader, txbuff, sizeof(txbuff));
return;
}
}
}
ZCanPumpCtrlModule::Submodule* ZCanPumpCtrlModule::find(int id) {
for (auto it = m_submodules.begin(); it != m_submodules.end(); it++) {
if ((*it)->id == id) {
return *it;
}
}
return NULL;
}
#endif

45
components/zcan_module/zcan_pump_ctrl_module.hpp

@ -0,0 +1,45 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanPumpCtrlModule : public ZCanRceiverListener {
public:
typedef function<void(int16_t acc, int16_t rpm)> pumprun_t;
class Submodule {
public:
int id;
pumprun_t m_pumprun_fn;
};
private:
ZCanReceiver* m_zcanReceiver;
list<Submodule*> m_submodules;
public:
ZCanPumpCtrlModule(/* args */) {}
~ZCanPumpCtrlModule() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void regSubmodule(int id, pumprun_t fn);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
Submodule* find(int id);
private:
void loop();
};
} // namespace iflytop
#endif

68
components/zcan_module/zcan_trigle_warning_light_ctl_module.cpp

@ -0,0 +1,68 @@
#include "zcan_trigle_warning_light_ctl_module.hpp"
#include <stdio.h>
#include <string.h>
#ifdef HAL_CAN_MODULE_ENABLED
using namespace iflytop;
using namespace zcr;
#define TAG "ZCanTrigleWarningLightCtlModule"
void ZCanTrigleWarningLightCtlModule::initialize(ZCanReceiver* zcanReceiver) {
zcanReceiver->registerListener(this);
m_zcanReceiver = zcanReceiver;
}
void ZCanTrigleWarningLightCtlModule::regSubmodule(int id, WarningLightCtrlFn_t fn) {
ZASSERT(fn != NULL);
Submodule* submodule = new Submodule();
ZASSERT(submodule != NULL);
submodule->id = id;
submodule->ctrl_fn = fn;
m_submodules.push_back(submodule);
}
void ZCanTrigleWarningLightCtlModule::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) {
Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
if (cmdheader->cmdid == kcmd_triple_warning_light_ctl && cmdheader->subcmdid == 0) {
/**
* @brief 0:
* cmd:
* [0]:SENSORID
* [2]:
* [3]:
* [4]:绿
* [5]:
* ack : b0:id
* ack_datalen : 1
*/
uint8_t id = cmdheader->data[0];
Submodule* subm = find(id);
if (subm) {
uint8_t r = cmdheader->data[2];
uint8_t g = cmdheader->data[3];
uint8_t b = cmdheader->data[4];
uint8_t beep = cmdheader->data[5];
subm->ctrl_fn(r, g, b, beep);
uint8_t txbuff[1] = {};
txbuff[0] = id;
m_zcanReceiver->sendAck(cmdheader, txbuff, sizeof(txbuff));
return;
}
}
}
ZCanTrigleWarningLightCtlModule::Submodule* ZCanTrigleWarningLightCtlModule::find(int id) {
for (auto it = m_submodules.begin(); it != m_submodules.end(); it++) {
if ((*it)->id == id) {
return *it;
}
}
return NULL;
}
#endif

45
components/zcan_module/zcan_trigle_warning_light_ctl_module.hpp

@ -0,0 +1,45 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/hal/zhal.hpp"
//
#include "../zcanreceiver/zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZCanTrigleWarningLightCtlModule : public ZCanRceiverListener {
public:
typedef function<void(uint8_t r, uint8_t g, uint8_t b, uint8_t beep)> WarningLightCtrlFn_t;
class Submodule {
public:
int id;
WarningLightCtrlFn_t ctrl_fn;
};
private:
ZCanReceiver* m_zcanReceiver;
list<Submodule*> m_submodules;
public:
ZCanTrigleWarningLightCtlModule(/* args */) {}
~ZCanTrigleWarningLightCtlModule() {}
public:
void initialize(ZCanReceiver* zcanReceiver);
void regSubmodule(int id, WarningLightCtrlFn_t fn);
public:
virtual void onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len);
Submodule* find(int id);
private:
void loop();
};
} // namespace iflytop
#endif

29
components/zcanreceiver/cmd.hpp

@ -6,14 +6,33 @@ namespace zcr {
typedef struct {
uint16_t packetindex;
uint16_t cmdindex;
uint8_t subcmdindex;
uint16_t var0;
} cmdheader_t;
uint16_t cmdid;
uint8_t subcmdid;
uint8_t packetType;
uint8_t data[];
} Cmdheader_t;
typedef enum {
kpt_cmd = 0,
kpt_ack = 1,
kpt_status_report = 2,
} PacketType_t;
typedef enum {
kcmd_ping = 0,
kcmd_read_io = 1,
kcmd_set_io = 2,
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,
} CmdID_t;
} // namespace zcr
} // namespace iflytop
/**
* @brief
* @brief
*/

10
components/zcanreceiver/zcanreceiver.cpp

@ -132,6 +132,14 @@ void ZCanReceiver::sendPacket(uint8_t *packet, size_t len) {
}
}
void ZCanReceiver::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);
}
bool ZCanReceiver::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) {
CAN_TxHeaderTypeDef pHeader;
uint8_t aData[8] /*8byte table*/;
@ -229,7 +237,7 @@ void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandl
memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8);
rxbuf->m_canPacketNum++;
}
if (nframe == frameId+1) {
if (nframe == frameId + 1) {
rxbuf->dataIsReady = true;
}
}

14
components/zcanreceiver/zcanreceiver.hpp

@ -3,8 +3,8 @@
//
#pragma once
#include "cmd.hpp"
#include "sdk/hal/zhal.hpp"
namespace iflytop {
namespace zcr {
typedef enum {
@ -29,7 +29,6 @@ class CanPacketRxBuffer {
}; // namespace zcr
using namespace zcr;
class ZCanRceiverListener {
public:
virtual void onRceivePacket(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len) = 0;
@ -50,7 +49,8 @@ class ZCanReceiver : public ZCanIRQListener {
int packetRxOvertime_ms; //
};
uint8_t rxdata[255 * 8];
uint8_t rxdata[1000];
uint8_t txbuff[1000];
public:
class LoopJobContext {
@ -72,9 +72,11 @@ class ZCanReceiver : public ZCanIRQListener {
CFG *createCFG(uint8_t deviceId);
void init(CFG *cfg);
void registerListener(ZCanRceiverListener *listener);
void sendPacket(uint8_t *packet, size_t len);
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
void registerListener(ZCanRceiverListener *listener);
void sendPacket(uint8_t *packet, size_t len);
void sendAck(Cmdheader_t *cmdheader, uint8_t *data, size_t len);
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
uint8_t getDeviceId() { return m_config->deviceId; }
public:
virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can);

Loading…
Cancel
Save