Browse Source

update

transmit_disinfection
zhaohe 12 months ago
parent
commit
54ccfa2fd5
  1. BIN
      hmp110/HMM100-Datasheet-B210813ZH.pdf
  2. BIN
      hmp110/HMP110 DOC247480-A Simplified Models.zip
  3. BIN
      hmp110/HMP110-Datasheet-B210852ZH.pdf
  4. BIN
      hmp110/HMP60-and-HMP110-Series-User-Guide-M211060EN-L.pdf
  5. 118
      hmp110/hmp110.cpp
  6. 71
      hmp110/hmp110.hpp
  7. BIN
      hpp272/HPP272-使用说明书.pdf
  8. 8
      hpp272/README.md
  9. 71
      hpp272/hpp272.cpp
  10. 79
      hpp272/hpp272.hpp
  11. BIN
      hpp272/过氧化氢传感器读取.zip
  12. 67
      modbus/modbus_basic.cpp
  13. 28
      modbus/modbus_basic.hpp
  14. 202
      modbus/modbus_block_host.cpp
  15. 31
      modbus/modbus_block_host.hpp
  16. 107
      preportional_valve/preportional_valve_ctrl.cpp
  17. 49
      preportional_valve/preportional_valve_ctrl.hpp
  18. BIN
      pxx_pressure_sensor_driver/DP600--RS485通讯说明书V0.1.docx
  19. BIN
      pxx_pressure_sensor_driver/HCP300新说明书.pdf
  20. BIN
      pxx_pressure_sensor_driver/P100标准MODBUS RTU通讯协议.pdf
  21. 244
      pxx_pressure_sensor_driver/pxx_pressure_sensor_bus.cpp
  22. 75
      pxx_pressure_sensor_driver/pxx_pressure_sensor_bus.hpp
  23. 6
      stm32basic.hpp
  24. 153
      sys_mgr.cpp
  25. 51
      sys_mgr.hpp
  26. BIN
      tmc/TMC5130A_datasheet_rev1.20 (1).pdf
  27. 19
      tmcdriver/tmc/tmc_type.h
  28. 67
      tmcdriver/tmc51x0/reg/TMC5130_Constants.h
  29. 1475
      tmcdriver/tmc51x0/reg/TMC5130_Fields.h
  30. 74
      tmcdriver/tmc51x0/reg/TMC5130_Register.h
  31. 59
      tmcdriver/tmc51x0/reg/TMC5130_Type.h
  32. 439
      tmcdriver/tmc51x0/tmc51x0.cpp
  33. 125
      tmcdriver/tmc51x0/tmc51x0.hpp
  34. 429
      zcanreceiver/zcanreceiver.cpp
  35. 48
      zcanreceiver/zcanreceiver.hpp
  36. 350
      zcanreceiver_old/zcanreceiver.cpp
  37. 116
      zcanreceiver_old/zcanreceiver.hpp
  38. 1
      zsdk.hpp

BIN
hmp110/HMM100-Datasheet-B210813ZH.pdf

BIN
hmp110/HMP110 DOC247480-A Simplified Models.zip

BIN
hmp110/HMP110-Datasheet-B210852ZH.pdf

BIN
hmp110/HMP60-and-HMP110-Series-User-Guide-M211060EN-L.pdf

118
hmp110/hmp110.cpp

@ -1,118 +0,0 @@
#include "hmp110.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
using namespace iflytop;
#define TAG "HMP110"
void HMP110::init(ModbusBlockHost* modbusBlockHost) {
m_modbusBlockHost = modbusBlockHost;
m_id = 240;
m_cache_lock.init();
m_chlock.init();
}
bool HMP110::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, int overtimems) { //
zlock_guard lck(m_chlock);
// ZLOGI(TAG, "=============== readReg03 %d %d", slaveAddr, regAddr);
bool ret = m_modbusBlockHost->readReg03(slaveAddr, regAddr, regVal, overtimems);
// ZLOGI(TAG, "=============== END%d", ret);
return ret;
}
bool HMP110::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, int regNum, int overtimems) { //
zlock_guard lck(m_chlock);
// ZLOGI(TAG, "=============== readReg03Muti %d %d %d", slaveAddr, regAddr, regNum);
bool ret = m_modbusBlockHost->readReg03Muti(slaveAddr, regAddr, regVal, regNum, overtimems);
// ZLOGI(TAG, "=============== END%d", ret);
return ret;
}
bool HMP110::ping(int id) {
int16_t val = 0;
return readReg03(id, 0x1F00, (uint16_t*)&val, 300);
}
void HMP110::setid(int32_t id) { m_id = id; }
void HMP110::read_calibration_date(int32_t* year, int32_t* month, int32_t* day) { // TODO
*year = 1;
*month = 2;
*day = 3;
}
int32_t HMP110::read_errorcode() {
int16_t val = 0;
bool suc = readReg03(m_id, 0x0200, (uint16_t*)&val, 300);
if (!suc) {
return -1;
}
if (val == 1) {
return 0;
}
uint16_t ecodebuf[2];
suc = readReg03Muti(m_id, 0x0203, ecodebuf, 2, 300);
uint32_t ecode = ecodebuf[0] | (((uint32_t)ecodebuf[1]) << 16);
return ecode;
}
bool HMP110::read_reg(int32_t add, uint16_t* val, size_t len) {
// ZLOGI(TAG, "read_reg %x %d", add, len);
bool suc = readReg03Muti(m_id, add, val, len, 300);
// if (suc)
// for (size_t i = 0; i < len; i++) {
// ZLOGI(TAG, "val[%d] = %d", i, val[i]);
// }
// else
// ZLOGE(TAG, "read_reg failed");
return suc;
}
bool HMP110::read_sensor_data(hmp110_sensordata_t* sensordata) {
uint16_t buf[7];
bool suc = readReg03Muti(m_id, 0x0100, buf, 7, 300);
if (!suc) {
return false;
}
sensordata->rh = buf[0];
sensordata->temp = buf[1];
sensordata->df_ptemp = buf[2];
sensordata->ah = buf[3];
sensordata->mr = buf[4];
sensordata->wet_bulb_temp = buf[5];
sensordata->enthalpy = buf[6];
return true;
}
void HMP110::updateSensorDataAndErrorcode() {
bool suc = read_sensor_data(&m_rdbuf);
osDelay(100);
int32_t errorcode = read_errorcode();
if (errorcode != 0) {
ZLOGE(TAG, "errorcode: %d", errorcode);
}
if (!suc) {
ZLOGE(TAG, "read_sensor_data failed");
errorcode = -1;
}
{
zlock_guard lck(m_cache_lock);
m_cachedata = m_rdbuf;
m_cache_errorcode = errorcode;
}
}
int32_t HMP110::read_cache_errorcode() {
zlock_guard lck(m_cache_lock);
return m_cache_errorcode;
}
bool HMP110::read_cache_sensor_data(hmp110_sensordata_t* sensordata) {
zlock_guard lck(m_cache_lock);
*sensordata = m_cachedata;
return true;
}

71
hmp110/hmp110.hpp

@ -1,71 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdio.h>
#include "stm32basic/modbus/modbus_block_host.hpp"
#include "stm32basic/zsdk.hpp"
namespace iflytop {
#define PXX_PRESSURE_SENSOR_NUM 10
class HMP110 {
public:
#pragma pack(1)
typedef struct {
int16_t rh; // Relative humidity %RH * 10
int16_t temp; // Temperature °C * 10
int16_t df_ptemp; // Dew/frost point temperature °C * 10
int16_t ah; // Absolute humidity g/m3 * 10
int16_t mr; // Mixing ratio g/kg * 10
int16_t wet_bulb_temp; // Wet-bulb temperature °C * 10
int16_t enthalpy; // Enthalpy kJ/kg * 10
} hmp110_sensordata_t;
#pragma pack()
private:
/***********************************************************************************************************************
* DATA *
***********************************************************************************************************************/
ModbusBlockHost* m_modbusBlockHost = NULL;
int32_t m_id = 0;
zmutex m_lock;
hmp110_sensordata_t m_rdbuf;
hmp110_sensordata_t m_cachedata;
int32_t m_cache_errorcode = 0;
zmutex m_cache_lock;
zmutex m_chlock;
public:
/***********************************************************************************************************************
* FUNC *
***********************************************************************************************************************/
void init(ModbusBlockHost* modbusBlockHost);
bool ping(int id);
bool ping();
void setid(int32_t id);
void read_calibration_date(int32_t* year, int32_t* month, int32_t* day); // TODO
int32_t read_errorcode(); // ret == -1 表明设备不在线
bool read_reg(int32_t add, uint16_t* val, size_t len);
bool read_sensor_data(hmp110_sensordata_t* sensordata);
void updateSensorDataAndErrorcode();
int32_t read_cache_errorcode();
bool read_cache_sensor_data(hmp110_sensordata_t* sensordata);
public:
bool readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, int overtimems);
bool readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal, int regNum, int overtimems);
};
} // namespace iflytop

BIN
hpp272/HPP272-使用说明书.pdf

8
hpp272/README.md

@ -1,8 +0,0 @@
```
注意事项:
1. 串口停止位是2位
2. 波特率19200
3. 默认ID 240
```

71
hpp272/hpp272.cpp

@ -1,71 +0,0 @@
#include "hpp272.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
using namespace iflytop;
#define TAG "HPP272"
void HPP272::init(ModbusBlockHost* modbusBlockHost) {
m_modbusBlockHost = modbusBlockHost;
m_id = 240;
m_cache_lock.init();
}
bool HPP272::ping(int id) {
int16_t val = 0;
return m_modbusBlockHost->readReg03(id, 0x1F00, (uint16_t*)&val, 100);
}
void HPP272::setid(int32_t id) { m_id = id; }
void HPP272::read_calibration_date(int32_t* year, int32_t* month, int32_t* day) { // TODO
*year = 0;
*month = 0;
*day = 0;
}
int32_t HPP272::read_errorcode() {
int16_t val = 0;
bool suc = m_modbusBlockHost->readReg03(m_id, 0x0200, (uint16_t*)&val, 100);
if (!suc) {
return -1;
}
// 0 = Status OK.
// 1 = Critical error,maintenance needed.
// 2 = Error, device may recover automatically.
// 4 = Warning.
// 8 = Notification.
// 16 = Calibration enabled
return val;
}
bool HPP272::read_reg(int32_t add, uint16_t* val, size_t len) { return m_modbusBlockHost->readReg03Muti(m_id, add, val, len, 100); }
bool HPP272::read_sensor_data(hpp272_data_t* sensordata) { //
return m_modbusBlockHost->readReg03Muti(m_id, 0x0100, (uint16_t*)sensordata, sizeof(*sensordata) / 2, 100);
}
void HPP272::updateSensorDataAndErrorcode() {
if (!read_sensor_data(&m_readbuf)) {
return;
}
int32_t errorcode = read_errorcode();
{
zlock_guard lck(m_cache_lock);
m_cachedata = m_readbuf;
m_cache_errorcode = errorcode;
}
}
int32_t HPP272::read_cache_errorcode() {
zlock_guard lck(m_cache_lock);
return m_cache_errorcode;
}
bool HPP272::read_cache_sensor_data(hpp272_data_t* sensordata) {
zlock_guard lck(m_cache_lock);
*sensordata = m_cachedata;
return true;
}

79
hpp272/hpp272.hpp

@ -1,79 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdio.h>
#include "base/config_service.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
#include "stm32basic/zsdk.hpp"
namespace iflytop {
#define PXX_PRESSURE_SENSOR_NUM 10
class HPP272 {
public:
#pragma pack(1)
typedef struct {
uint16_t hydrogen_peroxide_volume; // ppm 0x0100
uint16_t h2o_h2o2_rs; // %RS * 100
uint16_t temperature1; // °C * 100
uint16_t relative_humidity; // %RH * 100
uint16_t absolute_hydrogen_peroxide; // mg/m3
uint16_t h2o_h2o2dew_point_temperature; // °C * 100
uint16_t reserved1; //
uint16_t water_volume; // ppm
uint16_t water_vapor_pressure; // hpa
uint16_t absolute_humidity; // g/m3
uint16_t water_vapor_saturation_pressure_h2o; // hpa
uint16_t temperature2; // °C * 100
uint16_t h2o2_vapor_pressure; // hpa
uint16_t water_vapor_saturation_pressure_h2o_h2o2; // hpa
} hpp272_data_t;
#pragma pack()
private:
/***********************************************************************************************************************
* DATA *
***********************************************************************************************************************/
ModbusBlockHost* m_modbusBlockHost = NULL;
int32_t m_id = 0;
zmutex m_lock;
hpp272_data_t m_readbuf;
hpp272_data_t m_cachedata;
int32_t m_cache_errorcode = 0;
zmutex m_cache_lock;
public:
/***********************************************************************************************************************
* FUNC *
***********************************************************************************************************************/
/**
* @brief
*
* @param modbusBlockHost
*/
void init(ModbusBlockHost* modbusBlockHost);
bool ping(int id);
bool ping();
void setid(int32_t id);
void read_calibration_date(int32_t* year, int32_t* month, int32_t* day); // TODO
int32_t read_errorcode(); // see datasheet page83
bool read_reg(int32_t add, uint16_t* val, size_t len);
bool read_sensor_data(hpp272_data_t* sensordata);
void updateSensorDataAndErrorcode();
int32_t read_cache_errorcode();
bool read_cache_sensor_data(hpp272_data_t* sensordata);
public:
};
} // namespace iflytop

BIN
hpp272/过氧化氢传感器读取.zip

67
modbus/modbus_basic.cpp

@ -1,67 +0,0 @@
/**
* 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
modbus/modbus_basic.hpp

@ -1,28 +0,0 @@
#pragma once
#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);

202
modbus/modbus_block_host.cpp

@ -1,202 +0,0 @@
#include "modbus_block_host.hpp"
#include "modbus_basic.hpp"
using namespace iflytop;
#define PRV_DEBUG 0
ModbusBlockHost::ModbusBlockHost() {}
ModbusBlockHost::~ModbusBlockHost() {}
extern "C" {
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {}
}
void ModbusBlockHost::initialize(UART_HandleTypeDef *huart) {
this->huart = huart;
m_modbus_lock.init();
}
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) {
ZASSERT(len < sizeof(txbuff));
#if PRV_DEBUG
printf("uart_tx:\n");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
#endif
// HAL_UART_Transmit(huart, buff, len, 1000);
HAL_UART_DMAStop(huart);
HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(huart, buff, len);
ZASSERT(ret == HAL_OK);
// 等待DMA传输完成
while (true) {
if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) break;
}
return;
}
bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) {
HAL_StatusTypeDef status;
ZASSERT(len < sizeof(rxbuff));
status = HAL_UART_Receive_DMA(huart, buff, len);
if (status != HAL_OK) {
return false;
}
for (size_t i = 0; i < overtimems; i++) {
osDelay(3);
if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) {
#if PRV_DEBUG
if (status == HAL_OK) {
printf("uart_rx:");
for (size_t i = 0; i < len; i++) {
printf("%02x ", buff[i]);
}
printf("\n");
}
#endif
return true;
}
}
#if PRV_DEBUG
printf("uart_rx timeout\n");
#endif
HAL_UART_Abort(huart);
HAL_UART_DMAStop(huart);
return false;
}
bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) {
zlock_guard lck(m_modbus_lock);
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, 5 + 2, overtimems);
if (!status) {
return false;
}
if (!modbus_checkcrc16(rxbuff, 7)) {
ZLOGE("ModbusBlockHost", "crc error");
return false;
}
*regVal = (((uint16_t)(rxbuff[3])) << 8) | rxbuff[4];
return true;
}
// static const char *hex2str(uint8_t *buff, size_t len) {
// static char str[100];
// for (size_t i = 0; i < len; i++) {
// sprintf(str + i * 2, "%02x", buff[i]);
// }
// return str;
// }
bool ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) {
zlock_guard lck(m_modbus_lock);
txbuff[0] = slaveAddr;
txbuff[1] = 0x03;
txbuff[2] = regAddr >> 8;
txbuff[3] = regAddr & 0xff;
txbuff[4] = 0x00;
txbuff[5] = regNum;
modbus_pack_crc_to_packet(txbuff, 6 + 2);
cleanRxBuff();
uarttx(txbuff, 6 + 2);
bool status;
// 14*2 = 28
status = uartrx(rxbuff, 5 + regNum * 2, overtimems);
if (!status) {
return false;
}
if (!modbus_checkcrc16(rxbuff, 5 + regNum * 2)) {
ZLOGE("ModbusBlockHost", "crc error");
return false;
}
for (int i = 0; i < regNum; i++) {
regVal[i] = ((uint16_t)(rxbuff[3 + i * 2]) << 8) | rxbuff[4 + i * 2];
// int16_t val = regVal[i] ;
// ZLOGI("RX", "%d", val);
}
return true;
}
bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
zlock_guard lck(m_modbus_lock);
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) {
zlock_guard lck(m_modbus_lock);
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;
}

31
modbus/modbus_block_host.hpp

@ -1,31 +0,0 @@
#pragma once
//
#include "stm32basic/zbasic.h"
#include "../mutex.hpp"
namespace iflytop {
class ModbusBlockHost {
UART_HandleTypeDef *huart;
uint8_t txbuff[100];
uint8_t rxbuff[100];
zmutex m_modbus_lock;
public:
ModbusBlockHost();
~ModbusBlockHost();
void initialize(UART_HandleTypeDef *huart);
bool readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems);
bool readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, 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

107
preportional_valve/preportional_valve_ctrl.cpp

@ -1,107 +0,0 @@
#include "preportional_valve_ctrl.hpp"
#include "transmit_disfection_protocol/transmit_disfection_protocol.hpp"
using namespace iflytop;
using namespace zscanprotocol;
#define WORK_STATE_REG 0x0000
#define CTRL_STATE_REG 0x0001
#define POS_STATE_REG 0x0013
#define OVERTIME 30
#define TAG "PreportionalValveCtrl"
void PreportionalValveCtrl::initialize(UART_HandleTypeDef* huart) { m_modbusBlockHost.initialize(huart); }
int32_t PreportionalValveCtrl::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal) {
// 重发三次
for (size_t i = 0; i < 3; i++) {
int32_t err = m_modbusBlockHost.writeReg06(slaveAddr, regAddr, regVal, OVERTIME);
if (err == 0) return 0;
}
return err::kerr_subdevice_offline;
}
int32_t PreportionalValveCtrl::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal) {
// 重发三次
for (size_t i = 0; i < 3; i++) {
int32_t err = m_modbusBlockHost.readReg03(slaveAddr, regAddr, regVal, OVERTIME);
if (err == 0) return 0;
}
return err::kerr_subdevice_offline;
}
int32_t PreportionalValveCtrl::setValvePos(int32_t valueid, int32_t pos) { //
int32_t ret = 0;
if (valueid > 255 || valueid < 1) {
return err::kerr_invalid_param;
}
ret = writeReg06(valueid, CTRL_STATE_REG, pos);
if (!ret) return err::kerr_subdevice_offline;
m_last_set_valve_ticket = HAL_GetTick();
m_targetpos[valueid] = pos;
return 0;
}
int32_t PreportionalValveCtrl::getValvePos(int32_t valueid, int32_t* pos) {
int32_t ret = 0;
if (valueid > 255 || valueid < 1) {
return err::kerr_invalid_param;
}
uint16_t pos16 = 0;
ret = readReg03(valueid, POS_STATE_REG, &pos16);
if (!ret) return err::kerr_subdevice_offline;
*pos = pos16;
return 0;
}
int32_t PreportionalValveCtrl::getValveOrderPos(int32_t valueid, int32_t* pos) {
int32_t ret = 0;
if (valueid > 255 || valueid < 1) {
return err::kerr_invalid_param;
}
uint16_t pos16 = 0;
ret = readReg03(valueid, CTRL_STATE_REG, &pos16);
if (!ret) return err::kerr_subdevice_offline;
*pos = pos16;
return 0;
}
int32_t PreportionalValveCtrl::isBusy(int32_t valueid, int32_t* busy) {
#if 1
int32_t orderpos = 0;
int32_t pos = 0;
int32_t err = 0;
#if 0
err = getValveOrderPos(valueid, &orderpos);
if (err != 0) return err;
#endif
orderpos = m_targetpos[valueid];
err = getValvePos(valueid, &pos);
if (err != 0) return err;
if (abs(m_targetpos[valueid] - pos) <= 11) {
*busy = 0;
} else {
*busy = 1;
}
return 0;
#endif
}
int32_t PreportionalValveCtrl::getValveWorkState(int32_t valueid, int32_t* state) {
int32_t ret = 0;
if (valueid > 255 || valueid < 1) {
return err::kerr_invalid_param;
}
uint16_t state16 = 0;
ret = readReg03(valueid, WORK_STATE_REG, &state16);
if (!ret) return err::kerr_subdevice_offline;
*state = state16;
return 0;
}

49
preportional_valve/preportional_valve_ctrl.hpp

@ -1,49 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdio.h>
#include "base/config_service.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
#include "stm32basic/zsdk.hpp"
/**
* @brief
*
* https://iflytop1.feishu.cn/wiki/GQwCwHMqFiaJRwks80ncwaYKnSe
*/
namespace iflytop {
using namespace std;
class PreportionalValveCtrl {
public:
typedef enum {
kstate_stop = 0x0,
kstate_running_forward = 0xaa,
kstate_running_backward = 0xbb,
kstate_err_state = 0xea,
} work_state_t;
private:
/* data */
ModbusBlockHost m_modbusBlockHost;
int32_t val = 0;
uint32_t m_last_set_valve_ticket = 0;
uint16_t m_targetpos[255];
public:
PreportionalValveCtrl() {};
~PreportionalValveCtrl() {};
void initialize(UART_HandleTypeDef* huart);
int32_t setValvePos(int32_t valueid, int32_t pos);
int32_t getValvePos(int32_t valueid, int32_t* pos);
int32_t getValveOrderPos(int32_t valueid, int32_t* pos);
int32_t isBusy(int32_t valueid, int32_t* busy);
int32_t getValveWorkState(int32_t valueid, int32_t* state);
private:
int32_t writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal);
int32_t readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t* regVal);
};
} // namespace iflytop

BIN
pxx_pressure_sensor_driver/DP600--RS485通讯说明书V0.1.docx

BIN
pxx_pressure_sensor_driver/HCP300新说明书.pdf

BIN
pxx_pressure_sensor_driver/P100标准MODBUS RTU通讯协议.pdf

244
pxx_pressure_sensor_driver/pxx_pressure_sensor_bus.cpp

@ -1,244 +0,0 @@
#include "pxx_pressure_sensor_bus.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
using namespace iflytop;
#define TAG "PxxSensor"
/**
* @brief
*
*
* p100_protocol
* 0x0000:
* p600_protocol
* 0x0018H:
*
*
*
* :
* : 500Hz5Hz
* : 20ms
*
* :
* 30ms
*/
#define OVERTIME_MS 50
static const char* protocolType2Str(PXXPressureSensorBus::protocol_type_t type) {
switch (type) {
case PXXPressureSensorBus::kp100_protocol:
return "P100";
case PXXPressureSensorBus::kdp600_protocol:
return "DP600";
case PXXPressureSensorBus::kothers_protocol:
return "OTHERS";
default:
return "UNKNOWN";
}
}
static const char* p100uint2Str(uint8_t uint) {
switch (uint) {
case 0:
return "Mpa";
case 1:
return "kpa";
case 2:
return "pa";
case 3:
return "bar";
case 4:
return "Mbar";
case 5:
return "kgcm2";
case 6:
return "psi";
case 7:
return "mh2o";
case 8:
return "mh2o";
default:
return "UNKNOWN";
}
}
/***********************************************************************************************************************
* GLOBAL *
***********************************************************************************************************************/
static osThreadId PxxPressureSensorThread;
static void onPxxPressureSensorThreadStart(void const* argument) { ((PXXPressureSensorBus*)argument)->threadFuncStart(); }
/***********************************************************************************************************************
* CLASS *
***********************************************************************************************************************/
bool PXXPressureSensorBus::pingDevice(int id) {
uint16_t add = 0;
bool suc = m_modbusBlockHost->readReg03(id, 0x0000, &add, OVERTIME_MS);
return suc;
}
bool PXXPressureSensorBus::tryProbeProtocolP100(int id, sensor_t* sensor) {
uint16_t add = 0;
bool suc = m_modbusBlockHost->readReg03(id, 0x0000, &add, OVERTIME_MS);
if (!suc) {
return false;
}
if (id != add) {
return false;
}
osDelay(10);
int16_t val[6] = {0};
suc = m_modbusBlockHost->readReg03Muti(id, 0x02, (uint16_t*)val, 5, 50);
if (!suc) {
return false;
}
sensor->p100_sensor_info.precision = val[1];
sensor->p100_sensor_info.pressure_unit = val[0];
sensor->p100_sensor_info.value = val[2];
sensor->p100_sensor_info.zero_point = val[3];
sensor->p100_sensor_info.range_full_point = val[4];
sensor->id = id;
sensor->type = kp100_protocol;
sensor->detected = true;
return true;
}
bool PXXPressureSensorBus::tryProbeProtocolDP600(int id, sensor_t* sensor) {
uint16_t add = 0;
bool suc = m_modbusBlockHost->readReg03(id, 0x0018, &add, OVERTIME_MS);
// ZLOGI(TAG, "tryProbeProtocolDP600 id:%d add:%d suc:%d", id, add, suc);
if (!suc) {
return false;
}
if (id != add) {
return false;
}
sensor->id = id;
sensor->type = kdp600_protocol;
sensor->detected = true;
return true;
}
void PXXPressureSensorBus::probeSensor() {
memset(sensors, 0, sizeof(sensors));
for (size_t i = 1; i < ZARRAY_SIZE(sensors); i++) {
osDelay(30);
bool pingSuc = false;
pingSuc = pingDevice(i);
ZLOGI(TAG, "pingDevice id:%d,%s", i, pingSuc ? "online" : "offline");
if (pingSuc) {
sensorNum++;
if (tryProbeProtocolP100(i, &sensors[i])) continue;
osDelay(30);
if (tryProbeProtocolDP600(i, &sensors[i])) continue;
sensors[i].id = i;
sensors[i].type = kothers_protocol;
sensors[i].detected = true;
} else {
}
}
/**
* @brief DUMP Sensor State
*/
ZLOGI(TAG, "detect pressure sensor list:(%d)", sensorNum);
for (size_t i = 0; i < ZARRAY_SIZE(sensors); i++) {
if (sensors[i].detected) {
if (sensors[i].type == kp100_protocol) {
ZLOGI(TAG, " Sensor[%d] id:%d ptype:%s precision:%d unit:%s zero:%d full:%d", i, sensors[i].id, //
protocolType2Str(sensors[i].type), //
sensors[i].p100_sensor_info.precision, //
p100uint2Str(sensors[i].p100_sensor_info.pressure_unit), //
sensors[i].p100_sensor_info.zero_point, //
sensors[i].p100_sensor_info.range_full_point);
} else {
ZLOGI(TAG, " Sensor[%d] id:%d ptype:%s detected:%d", i, sensors[i].id, protocolType2Str(sensors[i].type), sensors[i].detected);
}
}
}
ZLOGI(TAG, "end");
initedEnd = true;
}
void PXXPressureSensorBus::threadFuncStart() {
/**
* @brief
*/
probeSensor();
/**
* @brief
*/
while (true) {
//
for (size_t i = 0; i < ZARRAY_SIZE(sensors); i++) {
if (!sensors[i].detected) {
continue;
}
bool suc = false;
if (sensors[i].type == kp100_protocol) {
int16_t val = 0;
suc = m_modbusBlockHost->readReg03(i, 0x0004, (uint16_t*)&val, OVERTIME_MS);
{
zlock_guard l(m_lock);
if (suc) sensors[i].val = val;
sensors[i].online = suc;
}
} else if (sensors[i].type == kdp600_protocol) {
int16_t val = 0;
suc = m_modbusBlockHost->readReg03(i, 0x0000, (uint16_t*)&val, OVERTIME_MS);
{
zlock_guard l(m_lock);
if (suc) sensors[i].val = val;
sensors[i].online = suc;
}
} else {
{
zlock_guard l(m_lock);
sensors[i].online = false;
}
continue;
}
osDelay(50);
}
osDelay(50);
}
}
void PXXPressureSensorBus::init(UART_HandleTypeDef* huart) {
//
m_lock.init();
m_modbusBlockHost = new ModbusBlockHost(); //
m_modbusBlockHost->initialize(huart);
osThreadDef(PxxPressureSensorThread, onPxxPressureSensorThreadStart, osPriorityNormal, 0, 1024);
PxxPressureSensorThread = osThreadCreate(osThread(PxxPressureSensorThread), this);
while (!initedEnd) {
osDelay(10);
}
}
bool PXXPressureSensorBus::readData(int32_t id, int16_t* data) {
zlock_guard l(m_lock);
if (id < 0 || id >= ZARRAY_SIZE(sensors)) {
return false;
}
if (!sensors[id].online) {
return false;
}
*data = sensors[id].val;
return true;
}
void PXXPressureSensorBus::probe() {}

75
pxx_pressure_sensor_driver/pxx_pressure_sensor_bus.hpp

@ -1,75 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdio.h>
#include "base/config_service.hpp"
#include "stm32basic/modbus/modbus_block_host.hpp"
#include "stm32basic/zsdk.hpp"
namespace iflytop {
#define PXX_PRESSURE_SENSOR_NUM 10
class PXXPressureSensorBus {
public:
/***********************************************************************************************************************
* STRUCT *
***********************************************************************************************************************/
typedef enum {
kp100_protocol,
kdp600_protocol,
kothers_protocol,
} protocol_type_t;
typedef struct {
uint8_t precision; // 0,1,2,3
uint8_t pressure_unit; // 0:map,1:kpa,2:pa
int16_t value;
int16_t zero_point;
int16_t range_full_point;
} p100_sensor_info_t;
typedef struct {
uint16_t id;
protocol_type_t type;
bool detected;
bool online;
p100_sensor_info_t p100_sensor_info;
int32_t val;
} sensor_t;
private:
/***********************************************************************************************************************
* DATA *
***********************************************************************************************************************/
ModbusBlockHost* m_modbusBlockHost;
bool initedEnd = false;
zmutex m_lock;
public:
sensor_t sensors[PXX_PRESSURE_SENSOR_NUM] = {0};
int32_t sensorNum = 0;
public:
/***********************************************************************************************************************
* FUNC *
***********************************************************************************************************************/
void init(UART_HandleTypeDef *huart);
bool readData(int32_t id, int16_t* data);
private:
void probe();
public:
void threadFuncStart();
bool pingDevice(int id);
bool tryProbeProtocolP100(int id, sensor_t* sensor);
bool tryProbeProtocolDP600(int id, sensor_t* sensor);
void probeSensor();
};
} // namespace iflytop

6
stm32basic.hpp

@ -0,0 +1,6 @@
#pragma once
#include "zbasic.h"
#include "mutex.hpp"
#include "zadc.hpp"
#include "zspi.hpp"
#include "zgpio.hpp"

153
sys_mgr.cpp

@ -1,153 +0,0 @@
#include "sys_mgr.hpp"
#include <stdlib.h>
#include "zbasic.h"
using namespace iflytop;
#define TAG "SysMgr"
extern "C" {
/***********************************************************************************************************************
* STM32_CODE_ERROR *
***********************************************************************************************************************/
void SysMgr_on_Error_Handler() {
ZLOGE(TAG, "Error_Handler\n");
while (1) {
}
}
void SysMgr_on_assert_failed(uint8_t* file, uint32_t line) {
ZLOGE(TAG, "ASSERT: %s [%s:%d]\n", file, line);
while (1) {
}
}
extern uint8_t _end; /* Symbol defined in the linker script */
extern uint8_t _estack; /* Symbol defined in the linker script */
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
extern uint8_t* __sbrk_heap_end;
static size_t get_free_heap_size() {
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
const uint8_t* max_heap = (uint8_t*)stack_limit;
uint8_t* prev_heap_end;
return max_heap - __sbrk_heap_end;
// if (__sbrk_heap_end + incr > max_heap) {
// errno = ENOMEM;
// return (void*)-1;
// }
}
/***********************************************************************************************************************
* STM32_ERROR_IRQ *
***********************************************************************************************************************/
void SysMgr_on_NMI_Handler(void) { ZLOGI(TAG, "on NMI_Handler"); }
void SysMgr_on_HardFault_Handler(void) { ZLOGI(TAG, "on HardFault_Handler"); }
void SysMgr_on_MemManage_Handler(void) { ZLOGI(TAG, "on MemManage_Handler"); }
void SysMgr_on_BusFault_Handler(void) { ZLOGI(TAG, "on BusFault_Handler"); }
void SysMgr_on_UsageFault_Handler(void) { ZLOGI(TAG, "on UsageFault_Handler"); }
/***********************************************************************************************************************
* FREERTOS_ERROR *
***********************************************************************************************************************/
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char* pcTaskName) {
ZLOGE(TAG, "StackOverflowHook: %s\n", pcTaskName);
__disable_irq();
while (1) {
}
}
void vApplicationMallocFailedHook(void) {
ZLOGE(TAG, "MallocFailedHook\n");
__disable_irq();
while (1) {
}
}
}
SysMgr* SysMgr::ins() {
static SysMgr s_ins;
return &s_ins;
}
// void SysMgr::regTaskId(osThreadId id) {
// m_task[m_ntask].Id = id;
// m_ntask++;
// }
size_t SysMgr::osGetSysRunTime() { return HAL_GetTick(); }
UBaseType_t uxTaskGetSystemState(TaskStatus_t* const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t* const pulTotalRunTime);
void SysMgr::initedFinished() { //
static TaskStatus_t pxTaskStatusArray[SDK_MAX_TASK + 1];
UBaseType_t uxArraySize = SDK_MAX_TASK + 1;
uint32_t pulTotalRunTime;
m_ntask = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &pulTotalRunTime);
for (int i = 0; i < m_ntask; i++) {
m_task[i].Id = pxTaskStatusArray[i].xHandle;
}
ZASSERT_INFO(m_ntask < SDK_MAX_TASK, "task num is too large, please increase SDK_MAX_TASK");
}
size_t SysMgr::osGetMinimumEverFreeHeapSize() { return ::xPortGetMinimumEverFreeHeapSize(); }
size_t SysMgr::osGetFreeHeapSize() { return ::xPortGetFreeHeapSize(); }
size_t SysMgr::osGetTotalHeapSize() { return configTOTAL_HEAP_SIZE; }
size_t SysMgr::osGetFreeSysHeapSize() { return get_free_heap_size(); }
int32_t SysMgr::getTaskNum() { return m_ntask; }
void SysMgr::dumpSysInfo() {
zlog("---------------Heap Info--------------\n");
zlog("MinimumEverFreeHeapSize : %d\n", osGetMinimumEverFreeHeapSize());
zlog("RTOS FreeHeapSize : %d\n", osGetFreeHeapSize());
zlog("RTOS TotalHeapSize : %d\n", osGetTotalHeapSize());
zlog("Sys FreeHeap : %d\n", get_free_heap_size());
zlog("");
zlog("---------------Task Info--------------\n");
static char buf[40 * SDK_MAX_TASK]; // 40一个任务,最多支持10个任务
vTaskList(buf);
zlog("Name State Priority Stack Num\n");
zlog_raw(buf);
zlog("- TaskInfoEnd -\n");
}
uint32_t SysMgr::osTaskStackRemainingSize(osThreadId id) { return uxTaskGetStackHighWaterMark(id); }
const char* SysMgr::osTaskName(osThreadId id) { return pcTaskGetName(id); }
osThreadId SysMgr::osGetId(int offset) {
if (offset < m_ntask) {
return m_task[offset].Id;
}
return NULL;
}
void SysMgr::osTaskName(osThreadId id, char* name, int bufsize) {
strncpy(name, pcTaskGetName(id), bufsize);
name[bufsize - 1] = 0;
}
void SysMgr::osTaskStackRemainingSize(osThreadId id, uint16_t* remainsize) { *remainsize = uxTaskGetStackHighWaterMark(id); }
void SysMgr::osTaskPriority(osThreadId id, uint16_t* priority) { *priority = uxTaskPriorityGet(id); }
void SysMgr::osTaskGetState(osThreadId id, char* state) {
eTaskState task_state = eTaskGetState(id);
switch (task_state) {
case eRunning:
*state = 'X';
break;
case eReady:
*state = 'R';
break;
case eBlocked:
*state = 'B';
break;
case eSuspended:
*state = 'S';
break;
case eDeleted:
*state = 'D';
break;
default:
*state = '?';
break;
}
}

51
sys_mgr.hpp

@ -1,51 +0,0 @@
#pragma once
#include "cmsis_os.h"
#include "zbasic.h"
namespace iflytop {
class ZTaskInfo {
public:
osThreadId Id;
};
class SysMgr {
private:
/* data */
public:
ZTaskInfo m_task[30] = {0};
int m_ntask = 0;
static SysMgr* ins();
void initedFinished();
void dumpSysInfo();
size_t osGetSysRunTime();
/***********************************************************************************************************************
* HeapMgr *
***********************************************************************************************************************/
size_t osGetMinimumEverFreeHeapSize();
size_t osGetFreeHeapSize();
size_t osGetTotalHeapSize();
size_t osGetFreeSysHeapSize();
/***********************************************************************************************************************
* TaskInfo *
***********************************************************************************************************************/
osThreadId osGetId(int offset);
uint32_t osTaskStackRemainingSize(osThreadId id);
const char* osTaskName(osThreadId id);
void osTaskName(osThreadId id, char* name, int bufsize);
void osTaskStackRemainingSize(osThreadId id, uint16_t* remainsize);
void osTaskPriority(osThreadId id, uint16_t* priority);
void osTaskGetState(osThreadId id, char* state);
int32_t getTaskNum();
};
} // namespace iflytop

BIN
tmc/TMC5130A_datasheet_rev1.20 (1).pdf

19
tmcdriver/tmc/tmc_type.h

@ -1,19 +0,0 @@
#pragma once
typedef enum {
kmres_256 = 0x00,
kmres_128 = 0x01,
kmres_64 = 0x02,
kmres_32 = 0x03,
kmres_16 = 0x04,
kmres_8 = 0x05,
kmres_4 = 0x06,
kmres_2 = 0x07,
kmres_1 = 0x08,
} mres_type_t;
typedef enum {
kTMC4361A = 0x2,
kTMC2160AndTMC5160 = 0x30,
kTMC5130 = 0x11,
// kTMC5160 = 0x30,
} tmcic_id_t;

67
tmcdriver/tmc51x0/reg/TMC5130_Constants.h

@ -1,67 +0,0 @@
/*
* TMC5130_Constants.h
*
* Created on: 13.06.2018
* Author: LK
*/
#ifndef TMC_IC_TMC5130_TMC5130_CONSTANTS_H_
#define TMC_IC_TMC5130_TMC5130_CONSTANTS_H_
#define TMC5130_REGISTER_COUNT 128
#define TMC5130_MOTORS 1
#define TMC5130_WRITE_BIT 0x80
#define TMC5130_ADDRESS_MASK 0x7F
#define TMC5130_MAX_VELOCITY 8388096
#define TMC5130_MAX_ACCELERATION 65535
// ramp modes (Register TMC5161_RAMPMODE)
#define TMC5130_MODE_POSITION 0
#define TMC5130_MODE_VELPOS 1
#define TMC5130_MODE_VELNEG 2
#define TMC5130_MODE_HOLD 3
// limit switch mode bits (Register TMC5130_SWMODE)
#define TMC5130_SW_STOPL_ENABLE 0x0001
#define TMC5130_SW_STOPR_ENABLE 0x0002
#define TMC5130_SW_STOPL_POLARITY 0x0004
#define TMC5130_SW_STOPR_POLARITY 0x0008
#define TMC5130_SW_SWAP_LR 0x0010
#define TMC5130_SW_LATCH_L_ACT 0x0020
#define TMC5130_SW_LATCH_L_INACT 0x0040
#define TMC5130_SW_LATCH_R_ACT 0x0080
#define TMC5130_SW_LATCH_R_INACT 0x0100
#define TMC5130_SW_LATCH_ENC 0x0200
#define TMC5130_SW_SG_STOP 0x0400
#define TMC5130_SW_SOFTSTOP 0x0800
// Status bits (Register TMC5130_RAMPSTAT)
#define TMC5130_RS_STOPL 0x0001
#define TMC5130_RS_STOPR 0x0002
#define TMC5130_RS_LATCHL 0x0004
#define TMC5130_RS_LATCHR 0x0008
#define TMC5130_RS_EV_STOPL 0x0010
#define TMC5130_RS_EV_STOPR 0x0020
#define TMC5130_RS_EV_STOP_SG 0x0040
#define TMC5130_RS_EV_POSREACHED 0x0080
#define TMC5130_RS_VELREACHED 0x0100
#define TMC5130_RS_POSREACHED 0x0200
#define TMC5130_RS_VZERO 0x0400
#define TMC5130_RS_ZEROWAIT 0x0800
#define TMC5130_RS_SECONDMOVE 0x1000
#define TMC5130_RS_SG 0x2000
// Encoderbits (Register TMC5130_ENCMODE)
#define TMC5130_EM_DECIMAL 0x0400
#define TMC5130_EM_LATCH_XACT 0x0200
#define TMC5130_EM_CLR_XENC 0x0100
#define TMC5130_EM_NEG_EDGE 0x0080
#define TMC5130_EM_POS_EDGE 0x0040
#define TMC5130_EM_CLR_ONCE 0x0020
#define TMC5130_EM_CLR_CONT 0x0010
#define TMC5130_EM_IGNORE_AB 0x0008
#define TMC5130_EM_POL_N 0x0004
#define TMC5130_EM_POL_B 0x0002
#define TMC5130_EM_POL_A 0x0001
#endif /* TMC_IC_TMC5130_TMC5130_CONSTANTS_H_ */

1475
tmcdriver/tmc51x0/reg/TMC5130_Fields.h
File diff suppressed because it is too large
View File

74
tmcdriver/tmc51x0/reg/TMC5130_Register.h

@ -1,74 +0,0 @@
/*
* TMC5130_Register.h
*
* Created on: 30.09.2016
* Author: ed based on te
*/
#ifndef TMC5130_REGISTER_H
#define TMC5130_REGISTER_H
// ===== TMC5130 register set =====
#define TMC5130_GCONF 0x00
#define TMC5130_GSTAT 0x01
#define TMC5130_IFCNT 0x02
#define TMC5130_SLAVECONF 0x03
#define TMC5130_IOIN 0x04
#define TMC5130_X_COMPARE 0x05
#define TMC5130_IHOLD_IRUN 0x10
#define TMC5130_TPOWERDOWN 0x11
#define TMC5130_TSTEP 0x12
#define TMC5130_TPWMTHRS 0x13
#define TMC5130_TCOOLTHRS 0x14
#define TMC5130_THIGH 0x15
#define TMC5130_RAMPMODE 0x20
#define TMC5130_XACTUAL 0x21
#define TMC5130_VACTUAL 0x22
#define TMC5130_VSTART 0x23
#define TMC5130_A1 0x24
#define TMC5130_V1 0x25
#define TMC5130_AMAX 0x26
#define TMC5130_VMAX 0x27
#define TMC5130_DMAX 0x28
#define TMC5130_D1 0x2A
#define TMC5130_VSTOP 0x2B
#define TMC5130_TZEROWAIT 0x2C
#define TMC5130_XTARGET 0x2D
#define TMC5130_VDCMIN 0x33
#define TMC5130_SWMODE 0x34
#define TMC5130_RAMPSTAT 0x35
#define TMC5130_XLATCH 0x36
#define TMC5130_ENCMODE 0x38
#define TMC5130_XENC 0x39
#define TMC5130_ENC_CONST 0x3A
#define TMC5130_ENC_STATUS 0x3B
#define TMC5130_ENC_LATCH 0x3C
#define TMC5130_MSLUT0 0x60
#define TMC5130_MSLUT1 0x61
#define TMC5130_MSLUT2 0x62
#define TMC5130_MSLUT3 0x63
#define TMC5130_MSLUT4 0x64
#define TMC5130_MSLUT5 0x65
#define TMC5130_MSLUT6 0x66
#define TMC5130_MSLUT7 0x67
#define TMC5130_MSLUTSEL 0x68
#define TMC5130_MSLUTSTART 0x69
#define TMC5130_MSCNT 0x6A
#define TMC5130_MSCURACT 0x6B
#define TMC5130_CHOPCONF 0x6C
#define TMC5130_COOLCONF 0x6D
#define TMC5130_DCCTRL 0x6E
#define TMC5130_DRVSTATUS 0x6F
#define TMC5130_PWMCONF 0x70
#define TMC5130_PWMSTATUS 0x71
#define TMC5130_ENCM_CTRL 0x72
#define TMC5130_LOST_STEPS 0x73
#endif /* TMC5130_REGISTER_H */

59
tmcdriver/tmc51x0/reg/TMC5130_Type.h

@ -1,59 +0,0 @@
#pragma once
#include <stdint.h>
#include "TMC5130_Constants.h"
#include "TMC5130_Fields.h"
#include "TMC5130_Register.h"
namespace iflytop {
class TMC5130RampStat {
public:
uint32_t m_state;
typedef enum {
/**
* @brief
* R
* R+C
*/
ktmc5130_rs_stopl = TMC5130_RS_STOPL, // (R )
ktmc5130_rs_stopr = TMC5130_RS_STOPR, // (R )
ktmc5130_rs_latchl = TMC5130_RS_LATCHL, // (R+C)
ktmc5130_rs_latchr = TMC5130_RS_LATCHR, // (R+C)
ktmc5130_rs_ev_stopl = TMC5130_RS_EV_STOPL, // (R )
ktmc5130_rs_ev_stopr = TMC5130_RS_EV_STOPR, // (R )
ktmc5130_rs_ev_stop_sg = TMC5130_RS_EV_STOP_SG, // (R+C)
ktmc5130_rs_ev_posreached = TMC5130_RS_EV_POSREACHED, // (R+C)
ktmc5130_rs_velreached = TMC5130_RS_VELREACHED, // (R )
ktmc5130_rs_posreached = TMC5130_RS_POSREACHED, // (R )
ktmc5130_rs_vzero = TMC5130_RS_VZERO, // (R )
ktmc5130_rs_zerowait = TMC5130_RS_ZEROWAIT, // (R )
ktmc5130_rs_secondmove = TMC5130_RS_SECONDMOVE, // (R+C)
ktmc5130_rs_sg = TMC5130_RS_SG, // (R )
} ramp_stat_bit_t;
TMC5130RampStat(uint32_t state) : m_state(state) {}
bool isSetted(ramp_stat_bit_t bit) { return (m_state & bit) != 0; }
};
typedef struct {
uint32_t sg_result : 10;
uint32_t reserved0 : 5;
uint32_t fsactive : 1;
uint32_t cs_actual : 5;
uint32_t reserved1 : 3;
uint32_t stallguard : 1;
uint32_t ot : 1; // overtemperature flag
uint32_t otpw : 1; // overtemperature pre warning flag
uint32_t s2ga : 1; // short to ground indicator phase A
uint32_t s2gb : 1; // short to ground indicator phase B
uint32_t ola : 1; // open load indicator phase A
uint32_t olb : 1; // open load indicator phase B
uint32_t stst : 1; // standstill indicator
} TMC5130DevStatusReg_t;
typedef struct {
uint32_t reset : 1; //
uint32_t drv_err : 1; //
uint32_t uv_cp : 1;
} TMC5130GState_t;
} // namespace iflytop

439
tmcdriver/tmc51x0/tmc51x0.cpp

@ -1,439 +0,0 @@
#include "tmc51x0.hpp"
#include "reg/TMC5130_Constants.h"
#include "reg/TMC5130_Fields.h"
#include "reg/TMC5130_Register.h"
//
#include "stm32basic/mutex.hpp"
#include "stm32basic/zspi.hpp"
using namespace iflytop;
#if 0
// Register access permissions:
// 0x00: none (reserved)
// 0x01: read
// 0x02: write
// 0x03: read/write
// 0x13: read/write, separate functions/values for reading or writing
// 0x21: read, flag register (read to clear)
// 0x42: write, has hardware presets on reset
static const uint8_t tmc5130_defaultRegisterAccess[TMC5130_REGISTER_COUNT] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x03, 0x21, 0x01, 0x02, 0x13, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F
0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F
0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F
____, ____, ____, 0x02, 0x03, 0x21, 0x01, ____, 0x03, 0x03, 0x02, 0x21, 0x01, ____, ____, ____, // 0x30 - 0x3F
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F
0x42, 0x01, 0x02, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F
};
#endif
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
#define FIELD_SET(data, mask, shift, value) (data = (((data) & (~(mask))) | (((value) << (shift)) & (mask))))
#define FIELD_GET(data, mask, shift) (((data) & (mask)) >> (shift))
#define BYTE(value, n) (((value) >> ((n) << 3)) & 0xFF)
#define NIBBLE(value, n) (((value) >> ((n) << 2)) & 0x0F)
#define SHORT(value, n) (((value) >> ((n) << 4)) & 0xFFFF)
#define WORD(value, n) (((value) >> ((n) << 5)) & 0xFFFFFFFF)
#define TMC51x0_ADDRESS(x) ((x) & (TMC5130_ADDRESS_MASK))
#define TAG "TMC51X0"
void TMC51X0::initialize(TMC51X0Cfg cfg) {
m_cfg = cfg;
m_hspi = cfg.hspi;
ZLOGI(TAG, "SPI:%p CSPin:%s,enPIn:%s", cfg.hspi, pinname(cfg.csnpin), pinname(cfg.ennpin));
m_mutex.init();
m_csnpin.initAsOutput(m_cfg.csnpin, kxs_gpio_nopull, false, true);
m_ennpin.initAsOutput(m_cfg.ennpin, kxs_gpio_nopull, false, true);
enable(false);
stop();
writeInt(TMC5130_PWMCONF, 0x000500C8);
writeInt(TMC5130_CHOPCONF, 0x000100c3);
writeInt(TMC5130_IHOLD_IRUN, 0x00051A00);
writeInt(TMC5130_PWMCONF, 0x000401c8);
writeInt(TMC5130_XTARGET, 0);
writeInt(TMC5130_XACTUAL, 0x00000000);
writeInt(TMC5130_VACTUAL, 0x00000000);
writeInt(TMC5130_TZEROWAIT, 0);
setVstart(100);
setA1(30);
setAmax(50);
setV1(500);
setDmax(50);
setD1(30);
setVstop(100);
setTzerowait(100);
setIHOLD_IRUN(0, 30, 100);
enable(false);
}
/*******************************************************************************
* *
*******************************************************************************/
void TMC51X0::readWriteArray(uint8_t *data, size_t length) {
portENTER_CRITICAL();
m_csnpin.write(false);
HAL_SPI_TransmitReceive(m_hspi, data, data, length, 100);
m_csnpin.write(true);
portEXIT_CRITICAL();
}
void TMC51X0::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC5130_WRITE_BIT)), x1, x2, x3, x4};
readWriteArray(&data[0], 5);
}
void TMC51X0::writeInt(uint8_t address, int32_t value) { //
writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0));
}
void TMC51X0::writeField(uint8_t add, uint32_t mask, uint32_t shift, uint32_t value) {
uint32_t regval = readUInt(add);
regval = (regval & ~mask) | ((value << shift) & mask);
writeInt(add, regval);
}
int32_t TMC51X0::readInt(uint8_t address) {
/**
* @WARNING:
*
*/
address = TMC51x0_ADDRESS(address);
uint8_t data[5] = {0, 0, 0, 0, 0};
data[0] = address;
readWriteArray(&data[0], 5);
data[0] = address;
readWriteArray(&data[0], 5);
return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
}
uint32_t TMC51X0::readUInt(uint8_t address) {
int32_t val = readInt(address);
uint32_t ret;
memcpy(&ret, &val, sizeof(uint32_t));
return ret;
}
/***********************************************************************************************************************
* BASIC *
***********************************************************************************************************************/
bool TMC51X0::ping() {
zlock_guard lkg(m_mutex);
uint32_t regval = readUInt(TMC5130_IOIN);
uint32_t chipId = FIELD_GET(regval, TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT);
return chipId != 0;
}
void TMC51X0::enable(bool enable) {
zlock_guard lkg(m_mutex);
m_ennpin.write(!enable);
}
int32_t TMC51X0::to_motor_acc(int32_t acc) { //
int32_t val = acc / 60.0 * m_onecirclepulse; // 65535
if (val > 65535) val = 65535;
return val;
}
int32_t TMC51X0::to_motor_vel(int32_t vel) { //
int32_t val = vel / 60.0 * m_onecirclepulse;
if (val > 8388095 /*2^23-512*/) {
val = 8388095;
}
return val;
} // rpm
int32_t TMC51X0::to_motor_pos(int32_t pos) { //
int32_t val = pos * 1.0 / m_scale * m_scale_deceleration * m_onecirclepulse + 0.5;
return val;
} //
int32_t TMC51X0::to_user_pos(int32_t pos) { //
int32_t val = pos / m_onecirclepulse * m_scale / m_scale_deceleration + 0.5;
// ZLOGI("TMC5130", "to_user_pos %d,%d", pos, val);
return val;
} //
int32_t TMC51X0::to_user_vel(int32_t vel) { //
int32_t val = vel * 60.0 / m_onecirclepulse;
return val;
}
/***********************************************************************************************************************
* CTRL *
***********************************************************************************************************************/
void TMC51X0::stop() {
zlock_guard lkg(m_mutex);
rotate(0);
}
void TMC51X0::rotate(int32_t velocity) {
zlock_guard lkg(m_mutex);
velocity = to_motor_vel(velocity);
writeInt(TMC5130_VMAX, abs(velocity));
writeInt(TMC5130_RAMPMODE, (velocity >= 0) ? TMC5130_MODE_VELPOS : TMC5130_MODE_VELNEG);
}
void TMC51X0::moveTo(int32_t position, uint32_t velocityMax) {
zlock_guard lkg(m_mutex);
position = to_motor_pos(position);
velocityMax = to_motor_vel(velocityMax);
writeInt(TMC5130_RAMPMODE, TMC5130_MODE_POSITION);
writeInt(TMC5130_VMAX, velocityMax);
writeInt(TMC5130_XTARGET, position);
}
void TMC51X0::moveToEnd(int32_t direction, uint32_t velocityMax) {
zlock_guard lkg(m_mutex);
if (direction >= 0) {
writeInt(TMC5130_RAMPMODE, TMC5130_MODE_POSITION);
writeInt(TMC5130_VMAX, to_motor_vel(velocityMax));
writeInt(TMC5130_XTARGET, INT32_MAX / 1.5 - 1000);
} else {
writeInt(TMC5130_RAMPMODE, TMC5130_MODE_POSITION);
writeInt(TMC5130_VMAX, to_motor_vel(velocityMax));
writeInt(TMC5130_XTARGET, INT32_MIN / 1.5 + 1000);
}
}
void TMC51X0::moveBy(int32_t relativePosition, uint32_t velocityMax) { // determine actual position and add numbers of ticks to move
zlock_guard lkg(m_mutex);
int32_t pos = getXACTUAL();
int32_t target = pos + relativePosition;
moveTo(target, velocityMax);
}
/***********************************************************************************************************************
* GET STATE *
***********************************************************************************************************************/
int32_t TMC51X0::getXACTUAL() {
zlock_guard lkg(m_mutex);
return to_user_pos(readInt(TMC5130_XACTUAL));
}
int32_t TMC51X0::getVACTUAL() {
zlock_guard lkg(m_mutex);
return to_user_pos(readInt(TMC5130_VACTUAL));
}
int32_t TMC51X0::getEncVal() {
zlock_guard lkg(m_mutex);
int32_t enc_val = to_user_pos(readInt(TMC5130_XENC));
if (m_enc_resolution < 0) {
enc_val = -enc_val;
}
return enc_val;
}
TMC5130RampStat TMC51X0::getRampStat() {
zlock_guard lkg(m_mutex);
int32_t val = readInt(TMC5130_RAMPSTAT);
return TMC5130RampStat(val);
}
bool TMC51X0::isReachTarget(TMC5130RampStat *state) {
zlock_guard lkg(m_mutex);
int mode = readInt(TMC5130_RAMPMODE);
if (mode == TMC5130_MODE_POSITION) {
return state->isSetted(TMC5130RampStat::ktmc5130_rs_posreached);
} else {
return state->isSetted(TMC5130RampStat::ktmc5130_rs_vzero) && state->isSetted(TMC5130RampStat::ktmc5130_rs_velreached);
}
}
bool TMC51X0::isTMC5130() {
zlock_guard lkg(m_mutex);
uint32_t regval = readUInt(TMC5130_IOIN);
uint32_t chipId = FIELD_GET(regval, TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT);
return chipId == kTMC5130;
}
TMC5130DevStatusReg_t TMC51X0::getDevStatus() { // R 读后不清
zlock_guard lkg(m_mutex);
static_assert(sizeof(TMC5130DevStatusReg_t) == 4);
uint32_t value = readInt(TMC5130_DRVSTATUS);
TMC5130DevStatusReg_t val;
memcpy(&val, &value, sizeof(TMC5130DevStatusReg_t));
return val;
}
TMC5130GState_t TMC51X0::getGState() { // R+C 读后自动清除
zlock_guard lkg(m_mutex);
static_assert(sizeof(TMC5130GState_t) == 4);
uint32_t value = readInt(TMC5130_GSTAT);
TMC5130GState_t val;
memcpy(&val, &value, sizeof(TMC5130GState_t));
return val;
}
int32_t TMC51X0::readICVersion() {
zlock_guard lkg(m_mutex);
uint32_t regval = readUInt(TMC5130_IOIN);
uint32_t chipId = FIELD_GET(regval, TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT);
return chipId;
}
/***********************************************************************************************************************
* set state *
***********************************************************************************************************************/
void TMC51X0::setXACTUAL(int32_t value) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_XACTUAL, to_motor_pos(value));
}
void TMC51X0::setMotorShaft(bool reverse) {
zlock_guard lkg(m_mutex);
uint32_t regval = readUInt(TMC5130_GCONF);
FIELD_SET(regval, TMC5130_SHAFT_MASK, TMC5130_SHAFT_SHIFT, reverse ? 1 : 0);
writeInt(TMC5130_GCONF, regval);
// uint32_t readbak = readUInt(TMC5130_GCONF);
// ZLOGI(TAG, "%x,%x", regval, readbak);
}
void TMC51X0::setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_IHOLD_IRUN, (iholddelay << TMC5130_IHOLDDELAY_SHIFT) | (irun << TMC5130_IRUN_SHIFT) | (ihold << TMC5130_IHOLD_SHIFT));
}
void TMC51X0::setGlobalScale(uint8_t globalscale) {
#define TMC5160_GLOBAL_SCALER 0x0B
#define TMC5160_GLOBAL_SCALER_MASK 0xFF
#define TMC5160_GLOBAL_SCALER_SHIFT 0
zlock_guard lkg(m_mutex);
if (isTMC5130()) {
return;
}
if (globalscale == 0) {
globalscale = 0;
} else if (globalscale <= 31 && globalscale >= 1) {
globalscale = 32;
} else {
globalscale = globalscale;
}
writeInt(TMC5160_GLOBAL_SCALER, (readInt(TMC5160_GLOBAL_SCALER) & ~TMC5160_GLOBAL_SCALER_MASK) | (globalscale << TMC5160_GLOBAL_SCALER_SHIFT));
}
void TMC51X0::setScale(int32_t scale) {
zlock_guard lkg(m_mutex);
m_scale = scale;
}
void TMC51X0::setScaleDenominator(int32_t scale) {
zlock_guard lkg(m_mutex);
m_scale_deceleration = scale;
}
void TMC51X0::setVstart(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_VSTART, to_motor_vel(val));
}
void TMC51X0::setA1(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_A1, to_motor_acc(val));
}
void TMC51X0::setAmax(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_AMAX, to_motor_acc(val));
}
void TMC51X0::setV1(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_V1, to_motor_vel(val));
}
void TMC51X0::setDmax(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_DMAX, to_motor_acc(val));
}
void TMC51X0::setD1(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_D1, to_motor_acc(val));
}
void TMC51X0::setVstop(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_VSTOP, to_motor_vel(val));
}
void TMC51X0::setTzerowait(int32_t val) {
zlock_guard lkg(m_mutex);
writeInt(TMC5130_TZEROWAIT, val);
}
bool TMC51X0::setEncResolution(int32_t enc_resolution) {
zlock_guard lkg(m_mutex);
/**
* @brief
*
* 1.256
* 2.TMC5130_ENC_CONST是十进制模式
* 3.
*/
int32_t enc_resolution_tmp = enc_resolution * 4;
int16_t enc_const_integral = 0;
int16_t enc_const_fractional = 0;
switch (abs(enc_resolution_tmp)) {
case 1000:
enc_const_integral = 51;
enc_const_fractional = 0.2 * 10000;
break;
case 1024:
enc_const_integral = 50;
enc_const_fractional = 0 * 10000;
break;
case 4000:
enc_const_integral = 12;
enc_const_fractional = 0.8 * 10000;
break;
case 4096:
enc_const_integral = 12;
enc_const_fractional = 0.5 * 10000;
break;
case 16384:
enc_const_integral = 3;
enc_const_fractional = 0.125 * 10000;
break;
case 0:
m_enc_resolution = 0;
return true;
default:
return false;
break;
}
m_enc_resolution = enc_resolution;
uint32_t setval = 0;
uint8_t *psetval = (uint8_t *)&setval;
memcpy(psetval + 2, &enc_const_integral, 2);
memcpy(psetval, &enc_const_fractional, 2);
writeInt(TMC5130_ENCMODE, 0x1 << 10);
writeInt(TMC5130_ENC_CONST, setval);
return true;
}
void TMC51X0::setEncVal(int32_t enc_val) {
zlock_guard lkg(m_mutex);
int32_t enc_set_val = to_motor_pos(enc_val);
if (m_enc_resolution < 0) {
enc_set_val = -enc_set_val;
}
writeInt(TMC5130_XENC, enc_set_val);
}
/***********************************************************************************************************************
* reg operation *
***********************************************************************************************************************/
void TMC51X0::writeIntExt(uint8_t address, int32_t value) {
zlock_guard lkg(m_mutex);
writeInt(address, value);
}
int32_t TMC51X0::readIntExt(uint8_t address) {
zlock_guard lkg(m_mutex);
return readInt(address);
}

125
tmcdriver/tmc51x0/tmc51x0.hpp

@ -1,125 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32basic/zbasic.h"
#include "stm32basic/zgpio.hpp"
//
#include "../tmc/tmc_type.h"
#include "reg/TMC5130_Type.h"
#include "stm32basic/mutex.hpp"
namespace iflytop {
/**
* @brief
*
*
* 1. 6
* 2. AMAX有效
*
*/
class TMC51X0Cfg {
public:
SPI_HandleTypeDef *hspi = NULL;
Pin_t csnpin;
Pin_t ennpin;
TMC51X0Cfg(SPI_HandleTypeDef *hspi, Pin_t csnpin, Pin_t ennpin) : hspi(hspi), csnpin(csnpin), ennpin(ennpin) {}
TMC51X0Cfg() {}
};
class TMC51X0 {
protected:
TMC51X0Cfg m_cfg;
SPI_HandleTypeDef *m_hspi = NULL;
ZGPIO m_csnpin;
ZGPIO m_ennpin;
int32_t m_scale = 10000;
int32_t m_scale_deceleration = 1;
mres_type_t m_MRES = kmres_256;
double m_onecirclepulse = 51200;
int32_t m_enc_resolution = 0; // 编码器分辨率,默认只有在256细分的情况下有效
zmutex m_mutex;
bool m_driErr = false;
public:
void initialize(TMC51X0Cfg cfg);
private:
/*******************************************************************************
* *
*******************************************************************************/
void readWriteArray(uint8_t *data, size_t length);
void writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4);
void writeInt(uint8_t address, int32_t value);
void writeField(uint8_t add, uint32_t mask, uint32_t shift, uint32_t value);
int32_t readInt(uint8_t address);
uint32_t readUInt(uint8_t address);
public:
bool ping();
void enable(bool enable);
void setdriErr(bool val) { m_driErr = val; }
bool getdriErr() { return m_driErr; }
/***********************************************************************************************************************
* ctrl *
***********************************************************************************************************************/
void rotate(int32_t velocity);
void moveTo(int32_t position, uint32_t velocityMax);
void moveToEnd(int32_t direction, uint32_t velocityMax);
void moveBy(int32_t relativePosition, uint32_t velocityMax);
void stop();
/***********************************************************************************************************************
* get state *
***********************************************************************************************************************/
int32_t getXACTUAL(); // 当前位置
int32_t getVACTUAL(); // 当前速度
int32_t getEncVal(); // ENCVAL
TMC5130RampStat getRampStat();
TMC5130DevStatusReg_t getDevStatus(); // R 读后不清
TMC5130GState_t getGState(); // R+C 读后自动清除
int32_t readICVersion();
bool isReachTarget(TMC5130RampStat *state); // 是否到达目标位置
bool isTMC5130();
/***********************************************************************************************************************
* set state *
***********************************************************************************************************************/
void setXACTUAL(int32_t value); // 设置当前位置
void setMotorShaft(bool reverse);
void setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay);
void setGlobalScale(uint8_t globalscale); // ONLY for 5160
void setScale(int32_t scale);
void setScaleDenominator(int32_t scale);
void setVstart(int32_t val);
void setA1(int32_t val);
void setAmax(int32_t val);
void setV1(int32_t val);
void setDmax(int32_t val);
void setD1(int32_t val);
void setVstop(int32_t val);
void setTzerowait(int32_t val);
bool setEncResolution(int32_t enc_resolution);
void setEncVal(int32_t enc_val);
/***********************************************************************************************************************
* reg operation *
***********************************************************************************************************************/
void writeIntExt(uint8_t address, int32_t value);
int32_t readIntExt(uint8_t address);
private:
int32_t to_motor_acc(int32_t acc); // rpm/s^2
int32_t to_motor_vel(int32_t vel); // rpm
int32_t to_motor_pos(int32_t pos); //
int32_t to_user_pos(int32_t pos); //
int32_t to_user_vel(int32_t vel);
};
} // namespace iflytop

429
zcanreceiver/zcanreceiver.cpp

@ -1,429 +0,0 @@
#include "zcanreceiver.hpp"
#include "../mutex.hpp"
#include "stm32halport/stm32halport.hpp"
#define TAG "zcan"
#ifndef ENABLE_OLD_CAN_PROTOCOL
#define CANHANDLER &hcan1
#define CAN_FILTER_INDEX 0
#define CAN_MAX_FILTER_NUM 7
#define CAN_FIFO_NUM CAN_RX_FIFO0
#define OVER_TIME_MS 30
using namespace iflytop;
using namespace zscanprotocol;
using namespace transmit_disfection_protocol;
static uint8_t m_deviceId;
static zcanbus_on_rx_t m_rxlistener[30];
static uint32_t m_numListener = 0;
static zcanbus_on_connected_t m_connectedlistener;
static canrxbuffer_t m_rxbufcache;
static uint16_t reportIndex;
static uint8_t rxdata[200];
static uint8_t txbuff[200];
static uint32_t lastpacket_ticket;
static bool m_is_connected;
static uint8_t m_priority;
zmutex m_lock;
static void _oncanpacket(CAN_HandleTypeDef *hcan);
static void _processOneCanPacket(CAN_RxHeaderTypeDef *pHeader, uint8_t *aData);
static bool _getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/);
extern "C" {
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0CompleteCallback"); }
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1CompleteCallback"); }
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2CompleteCallback"); }
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0AbortCallback"); }
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1AbortCallback"); }
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2AbortCallback"); }
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { _oncanpacket(hcan); }
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo0FullCallback"); }
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1MsgPendingCallback"); }
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1FullCallback"); }
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_SleepCallback"); }
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_WakeUpFromRxMsgCallback"); }
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_ErrorCallback"); }
}
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
static void _oncanpacket(CAN_HandleTypeDef *hcan) {
if (CANHANDLER != hcan) return;
CAN_RxHeaderTypeDef pHeader;
uint8_t aData[8] /*8byte table*/;
while (_getRxMessage(&pHeader, aData)) {
_processOneCanPacket(&pHeader, aData);
}
}
static bool _getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) {
/**
* @brief FIFO中缓存了多少帧的数据
*/
uint32_t level = HAL_CAN_GetRxFifoFillLevel(CANHANDLER, CAN_FIFO_NUM);
if (level == 0) {
return false;
}
HAL_StatusTypeDef HAL_RetVal;
HAL_RetVal = HAL_CAN_GetRxMessage(CANHANDLER, CAN_FIFO_NUM, pHeader, aData);
if (HAL_OK == HAL_RetVal) {
// 处理接收到的can总线数据
return true;
}
return false;
}
static void _processOneCanPacket(CAN_RxHeaderTypeDef *pHeader, uint8_t *aData) {
/**
* @brief 12bit from,1bit emergency
*
* [1] [4bit] [8bit] [8bit] [4bit/4bit]
* , from to frameNum/frameId
*/
uint8_t from = (pHeader->ExtId & 0x00FF0000) >> 16;
uint8_t to = (pHeader->ExtId & 0x0000FF00) >> 8;
uint8_t nframe = (pHeader->ExtId & 0x000000F0) >> 4;
uint8_t frameId = (pHeader->ExtId & 0x0000000F);
// ZLOGI(TAG, "from:%d to:%d nframe:%d frameId:%d", from, to, nframe, frameId);
if (pHeader->IDE == CAN_ID_STD) {
return;
}
// 只接收主机消息
if (from != 1) {
return;
}
if (to != m_deviceId && to != 0xff) {
return;
}
// 上次接收到的消息还没有来的急处理
if (m_rxbufcache.dataIsReady) {
ZLOGI(TAG, "discard rx packet ,last packet not processed");
return;
}
if (frameId == 0) {
m_rxbufcache.canPacketNum = 0;
}
if (frameId != m_rxbufcache.canPacketNum) {
m_rxbufcache.canPacketNum = 0;
ZLOGI(TAG, "discard rx packet ,due to lost packet");
return;
}
if (m_rxbufcache.canPacketNum < ZARRAY_SIZE(m_rxbufcache.canPacket)) {
if (m_rxbufcache.canPacketNum == 0) {
m_rxbufcache.header = *pHeader;
m_rxbufcache.from = from;
m_rxbufcache.to = to;
}
m_rxbufcache.canPacket[m_rxbufcache.canPacketNum].datalen = pHeader->DLC;
memcpy(m_rxbufcache.canPacket[m_rxbufcache.canPacketNum].aData, aData, 8);
m_rxbufcache.canPacketNum++;
} else {
ZLOGI(TAG, "discard rx packet ,due to buffer full");
m_rxbufcache.canPacketNum = 0;
return;
}
if (nframe == frameId + 1) {
if (m_rxbufcache.canPacketNum != nframe) {
m_rxbufcache.canPacketNum = 0;
ZLOGI(TAG, "discard rx packet ,due to lost packet");
return;
} else {
m_rxbufcache.dataIsReady = true;
}
}
}
/***********************************************************************************************************************
* FUNC *
***********************************************************************************************************************/
static HAL_StatusTypeDef activateRxIT() {
HAL_StatusTypeDef hal_status = HAL_ERROR;
if (CAN_FIFO_NUM == CAN_RX_FIFO0) {
hal_status = HAL_CAN_ActivateNotification(CANHANDLER, CAN_IT_RX_FIFO0_MSG_PENDING);
} else if (CAN_FIFO_NUM == CAN_RX_FIFO1) {
hal_status = HAL_CAN_ActivateNotification(CANHANDLER, 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;
}
// static HAL_StatusTypeDef deactivateRxIT() {
// HAL_StatusTypeDef hal_status = HAL_ERROR;
// if (CAN_FIFO_NUM == CAN_RX_FIFO0) {
// hal_status = HAL_CAN_DeactivateNotification(CANHANDLER, CAN_IT_RX_FIFO0_MSG_PENDING);
// } else if (CAN_FIFO_NUM == CAN_RX_FIFO1) {
// hal_status = HAL_CAN_DeactivateNotification(CANHANDLER, 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 initializeFilter() {
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 = CAN_FIFO_NUM; // 关联过滤器到rxfifoNum
sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
sFilterConfig.SlaveStartFilterBank = CAN_MAX_FILTER_NUM; // slave filter start index
/*******************************************************************************
* *
*******************************************************************************/
filterId = (0); //
mask = (0); //
sFilterConfig.FilterBank = CAN_FILTER_INDEX; //
sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
sFilterConfig.FilterIdLow = filterId & 0xffff; //
sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
HAL_Status = HAL_CAN_ConfigFilter(CANHANDLER, &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 zcanbus_init(uint8_t deviceId) {
m_deviceId = deviceId;
HAL_StatusTypeDef hal_status;
m_rxbufcache.dataIsReady = false;
m_rxbufcache.id = 0; // 只接收来自主机的消息
m_rxbufcache.canPacketNum = 0;
hal_status = initializeFilter();
if (hal_status != HAL_OK) {
ZLOGE(TAG, "start can initializeFilter fail\r\n");
return;
}
hal_status = HAL_CAN_Start(CANHANDLER); // 开启CAN
if (hal_status != HAL_OK) {
ZLOGE(TAG, "start can fail\r\n");
return;
}
m_lock.init();
HAL_StatusTypeDef status = activateRxIT();
if (status != HAL_OK) {
ZLOGE(TAG, "activateRxIT fail\r\n");
ZASSERT(0);
return;
}
ZLOGI(TAG, "zcanbus init done");
}
void zcanbus_reglistener(zcanbus_on_rx_t rxlistener) {
ZASSERT(m_numListener < ZARRAY_SIZE(m_rxlistener));
m_rxlistener[m_numListener++] = rxlistener;
}
void zcanbus_reg_on_connected_listener(zcanbus_on_connected_t connectedlistener) { m_connectedlistener = connectedlistener; }
bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len) { return zcanbus_send_packet(to, packet, len, OVER_TIME_MS); }
static char *hex2str(uint8_t *data, size_t len) {
static char buf[200];
memset(buf, 0, sizeof(buf));
for (size_t i = 0; i < len; i++) {
sprintf(buf + i * 2, "%02x", data[i]);
}
return buf;
}
bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len, int overtimems) {
ZLOGI(TAG, "sendPacket to:%d, %s(%d)", to, hex2str(packet,len), len);
int npacket = len / 8 + (len % 8 == 0 ? 0 : 1);
if (npacket > 255) {
ZLOGE(TAG, "sendPacket fail, len:%d", len);
return false;
}
int finalpacketlen = len % 8 == 0 ? 8 : len % 8;
for (uint8_t i = 0; i < npacket; i++) {
bool suc = false;
if (i == npacket - 1) {
suc = zcanbus_send_sub_packet(to, npacket, i, packet + i * 8, finalpacketlen, overtimems);
} else {
suc = zcanbus_send_sub_packet(to, npacket, i, packet + i * 8, 8, overtimems);
}
if (!suc) {
// ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
return false;
}
}
return true;
}
// static const char *canpacket_dump(uint8_t *data, int size) {
// static char buf[20];
// memset(buf, 0, sizeof(buf));
// for (int i = 0; i < size; i++) {
// sprintf(buf + i * 2, "%02x", data[i]);
// }
// return buf;
// }
bool zcanbus_send_sub_packet(uint8_t to, 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 = zget_ticket();
memset(&pHeader, 0, sizeof(pHeader));
memset(aData, 0, sizeof(aData));
pHeader.StdId = 0x00;
pHeader.ExtId = (m_deviceId << 16) | (to << 8) | (npacket << 4) | (packetIndex);
pHeader.ExtId |= (m_priority & 0x0f) << 24;
pHeader.ExtId |= (0x01 << 28);
pHeader.IDE = CAN_ID_EXT;
pHeader.RTR = CAN_RTR_DATA;
pHeader.DLC = len;
pHeader.TransmitGlobalTime = DISABLE;
memcpy(aData, packet, len);
// ZLOGI(TAG, "tx %s", canpacket_dump(aData, len));
HAL_StatusTypeDef lastTransmitStatus = HAL_CAN_AddTxMessage(CANHANDLER, &pHeader, aData, &txMailBox);
if (lastTransmitStatus != HAL_OK) {
ZLOGE(TAG, "HAL_CAN_AddTxMessage fail");
return false;
}
while (HAL_CAN_IsTxMessagePending(CANHANDLER, txMailBox)) {
if (zhas_passedms(enterticket) > (uint32_t)overtimems) {
lastTransmitStatus = HAL_TIMEOUT;
HAL_CAN_AbortTxRequest(CANHANDLER, txMailBox);
return false;
}
zos_delay_ms(1);
}
return true;
}
bool zcanbus_send_ack(zcanbus_packet_t *rxpacket, uint8_t *param, size_t len) {
zlock_guard l(m_lock);
zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
txpacket->index = rxpacket->index;
txpacket->function_id = rxpacket->function_id;
txpacket->ptype = kreceipt;
if (param) memcpy(txpacket->params, param, len);
return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len);
}
bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, int32_t val) { return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val)); }
bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, bool _val) {
int32_t val = _val ? 1 : 0;
return zcanbus_send_ack(rxpacket, (uint8_t *)&val, sizeof(val));
}
bool zcanbus_send_errorack(zcanbus_packet_t *rxpacket, int32_t errcode) {
zlock_guard l(m_lock);
m_priority = kpriority_receipt;
zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
txpacket->index = rxpacket->index;
txpacket->function_id = rxpacket->function_id;
txpacket->ptype = kerror_receipt;
memcpy(txpacket->params, &errcode, sizeof(errcode));
return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + 4);
}
bool zcanbus_send_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
zlock_guard l(m_lock);
m_priority = kpriority_report;
zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
txpacket->index = reportIndex++;
txpacket->function_id = function_id;
txpacket->ptype = kreport;
memcpy(txpacket->params, param, len);
return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
}
bool zcanbus_send_emergency_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime) {
zlock_guard l(m_lock);
m_priority = kpriority_emergency_report;
zcanbus_packet_t *txpacket = (zcanbus_packet_t *)txbuff;
txpacket->index = reportIndex++;
txpacket->function_id = function_id;
txpacket->ptype = kreport;
memcpy(txpacket->params, param, len);
return zcanbus_send_packet(1 /*mainboard*/, (uint8_t *)&txpacket[0], sizeof(zcanbus_packet_t) + len, overtime);
}
static void process_rx_packet(canrxbuffer_t *canrxbuf, uint8_t *rx, size_t len) {
zcanbus_packet_t *packet = (zcanbus_packet_t *)rx;
lastpacket_ticket = zget_ticket();
if (!m_is_connected) {
m_is_connected = true;
if (m_connectedlistener) m_connectedlistener(true);
}
if (packet->ptype == kcmd) {
for (size_t i = 0; i < m_numListener; i++) {
m_rxlistener[i](canrxbuf->from, canrxbuf->to, rxdata, len);
}
}
}
void zcanbus_schedule() {
canrxbuffer_t *rxbuf = &m_rxbufcache;
uint16_t fromId = 0;
uint16_t toId = 0;
if (rxbuf->dataIsReady) {
int dataoff = 0;
// rxdata[0] = rxbuf->from;
// rxdata[1] = rxbuf->to;
for (size_t i = 0; i < rxbuf->canPacketNum; i++) {
memcpy(rxdata + dataoff, rxbuf->canPacket[i].aData, rxbuf->canPacket[i].datalen);
dataoff += rxbuf->canPacket[i].datalen;
ZASSERT(dataoff < ZARRAY_SIZE(rxdata));
}
process_rx_packet(rxbuf, rxdata, dataoff);
rxbuf->dataIsReady = false;
}
if (m_is_connected && zhas_passedms(lastpacket_ticket) > HEART_OVERTIME) {
m_is_connected = false;
if (m_connectedlistener) m_connectedlistener(false);
}
}
bool zcanbus_is_connected() { return m_is_connected; }
#endif

48
zcanreceiver/zcanreceiver.hpp

@ -1,48 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include "project_configs.h"
#include "stm32basic/zbasic.h"
#ifndef ENABLE_OLD_CAN_PROTOCOL
#include "transmit_disfection_protocol/transmit_disfection_protocol.hpp"
typedef void (*zcanbus_on_rx_t)(uint8_t from, uint8_t to, uint8_t *packet, size_t len);
typedef void (*zcanbus_on_connected_t)(bool connected);
typedef struct {
public:
uint8_t aData[8]; /*8byte table*/
uint8_t datalen;
} stm32_can_packet_t;
typedef struct {
public:
uint16_t id;
CAN_RxHeaderTypeDef header;
uint8_t from;
uint8_t to;
stm32_can_packet_t canPacket[20]; // 用于接收can消息
uint8_t canPacketNum = 0;
bool dataIsReady;
} canrxbuffer_t;
void zcanbus_init(uint8_t deviceId);
void zcanbus_reglistener(zcanbus_on_rx_t rxlistener);
void zcanbus_reg_on_connected_listener(zcanbus_on_connected_t connectedlistener);
void zcanbus_schedule();
bool zcanbus_is_connected();
bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len);
bool zcanbus_send_packet(uint8_t to, uint8_t *packet, size_t len, int overtimems);
bool zcanbus_send_sub_packet(uint8_t to, int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, uint8_t *param, size_t len);
bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, int32_t val);
bool zcanbus_send_ack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, bool _val);
bool zcanbus_send_errorack(iflytop::zscanprotocol::zcanbus_packet_t *rxpacket, int32_t errcode);
bool zcanbus_send_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime);
bool zcanbus_send_emergency_report(uint16_t function_id, uint8_t *param, size_t len, int32_t overtime);
#endif

350
zcanreceiver_old/zcanreceiver.cpp

@ -1,350 +0,0 @@
#include "zcanreceiver.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32basic/zbasic.h"
#define TAG "ZCanReceiver"
#define OVER_TIME_MS 100
#ifdef ENABLE_OLD_CAN_PROTOCOL
#include "stm32halport/stm32halport.hpp"
extern "C" {
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0CompleteCallback"); }
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1CompleteCallback"); }
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2CompleteCallback"); }
void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox0AbortCallback"); }
void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox1AbortCallback"); }
void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_TxMailbox2AbortCallback"); }
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { ZCanReceiver::ins()->STM32_HAL_onCAN_RxFifo0MsgPending(hcan); }
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo0FullCallback"); }
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1MsgPendingCallback"); }
void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_RxFifo1FullCallback"); }
void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_SleepCallback"); }
void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { ZLOGI(TAG, "HAL_CAN_WakeUpFromRxMsgCallback"); }
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { ZCanReceiver::ins()->STM32_HAL_onCAN_Error(hcan); }
}
ZCanReceiver *ZCanReceiver::ins() {
static ZCanReceiver ins;
return &ins;
}
ZCanReceiver::CFG *ZCanReceiver::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 ZCanReceiver::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;
}
HAL_StatusTypeDef status = activateRxIT();
if (status != HAL_OK) {
ZLOGE(TAG, "activateRxIT fail\r\n");
return;
}
}
HAL_StatusTypeDef ZCanReceiver::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 ZCanReceiver::registerListener(zcanbus_on_rx_t listener) { m_onRxData = listener; }
void ZCanReceiver::sendPacket(uint8_t *packet, size_t len, int overtime) {
/**
* @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, overtime);
} else {
suc = sendPacketSub(npacket, i, packet + i * 8, 8, overtime);
}
if (!suc) {
ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
return;
}
}
}
void ZCanReceiver::sendAck(transmit_disinfection_protocol_header_t *cmdheader, uint8_t *data, size_t len) {
transmit_disinfection_protocol_header_t *txheader = (transmit_disinfection_protocol_header_t *)txbuff;
memcpy(txheader, cmdheader, sizeof(transmit_disinfection_protocol_header_t));
txheader->packetType = kpt_ack;
memcpy(txheader->data, data, len);
sendPacket(txbuff, sizeof(transmit_disinfection_protocol_header_t) + len, OVER_TIME_MS);
}
void ZCanReceiver::sendErrorAck(transmit_disinfection_protocol_header_t *cmdheader, int16_t errcode) {
transmit_disinfection_protocol_header_t *txheader = (transmit_disinfection_protocol_header_t *)txbuff;
memcpy(txheader, cmdheader, sizeof(transmit_disinfection_protocol_header_t));
txheader->packetType = kpt_error_ack;
memcpy(txheader->data, &errcode, sizeof(errcode));
sendPacket(txbuff, sizeof(transmit_disinfection_protocol_header_t) + 2, OVER_TIME_MS);
}
void ZCanReceiver::sendReport(uint16_t cmdid, uint8_t subcmdid, uint8_t *attachments, size_t len) {
transmit_disinfection_protocol_header_t *txheader = (transmit_disinfection_protocol_header_t *)txbuff;
txheader->packetindex = report_index++;
txheader->cmdid = cmdid;
txheader->subcmdid = subcmdid;
txheader->packetType = kpt_status_report;
memcpy(txheader->data, attachments, len);
sendPacket(txbuff, sizeof(transmit_disinfection_protocol_header_t) + len, OVER_TIME_MS);
}
bool ZCanReceiver::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 = HAL_GetTick();
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 (zhas_passedms(enterticket) > (uint32_t)overtimems) {
m_lastTransmitStatus = HAL_TIMEOUT;
HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox);
return false;
}
// m_os->sleepMS(1);
}
return true;
}
bool ZCanReceiver::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 ZCanReceiver::registerListener(CanPacketRxBufferCB_t cb) { m_listenerCBList.push_back(cb); }
void ZCanReceiver::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];
// CAN_ID_STD
// CAN_ID_EXT
if (pHeader.IDE == CAN_ID_STD) {
// 只接收扩展帧数据帧
continue;
}
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;
rxbuf->maxFrameId = frameId;
}
}
// deactivateRxIT();
}
void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
if (canHandle != m_config->canHandle) {
return;
}
ZLOGE(TAG, "onCAN_Error\r\n");
}
void ZCanReceiver::loop() {
CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[0];
if (rxbuf->dataIsReady) {
int dataoff = 0;
for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) {
memcpy(rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].pHeader.DLC);
dataoff += rxbuf->m_canPacket[i].pHeader.DLC;
memset(&rxbuf->m_canPacket[i], 0, sizeof(rxbuf->m_canPacket[i]));
}
if (m_onRxData) {
m_onRxData(rxbuf, rxdata, dataoff);
}
for (auto &var : m_listenerCBList) {
if (var) var(rxbuf, rxdata, dataoff);
}
rxbuf->dataIsReady = false;
}
}
HAL_StatusTypeDef ZCanReceiver::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 ZCanReceiver::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
#endif

116
zcanreceiver_old/zcanreceiver.hpp

@ -1,116 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include <functional>
#include <list>
#include "project_configs.h"
#include "stm32basic/zbasic.h"
#ifdef ENABLE_OLD_CAN_PROTOCOL
#include "transmit_disinfection_protocol_v1/transmit_disinfection_protocol_v1.hpp"
namespace iflytop {
namespace zcr {
using namespace std;
typedef enum {
kpacketHeader = 0,
kpacketData = 1,
kpacketTail = 2,
} packet_type_t;
class CANPacket {
public:
CAN_RxHeaderTypeDef pHeader;
uint8_t aData[8]; /*8byte table*/
};
class CanPacketRxBuffer {
public:
uint16_t id;
CANPacket m_canPacket[256]; // 用于接收can消息
uint8_t m_canPacketNum = 0;
uint8_t maxFrameId = 0;
bool dataIsReady;
};
}; // namespace zcr
using namespace zcr;
typedef void (*zcanbus_on_rx_t)(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len);
typedef function<void(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len)> CanPacketRxBufferCB_t;
class ZCanReceiver {
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 rxdata[1000];
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发送方法的返回值
zcanbus_on_rx_t m_onRxData = NULL;
list<CanPacketRxBufferCB_t> m_listenerCBList;
CanPacketRxBuffer m_canPacketRxBuffer[1];
int report_index = 0;
public:
ZCanReceiver() {}
static ZCanReceiver *ins();
CFG *createCFG(uint8_t deviceId);
void init(CFG *cfg);
void registerListener(zcanbus_on_rx_t listener);
void registerListener(CanPacketRxBufferCB_t cb);
void sendPacket(uint8_t *packet, size_t len, int overtime);
void sendAck(transmit_disinfection_protocol_header_t *cmdheader, uint8_t *data, size_t len);
void sendErrorAck(transmit_disinfection_protocol_header_t *cmdheader, int16_t errcode);
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems);
void sendReport(uint16_t cmdid, uint8_t subcmdid, uint8_t *attachments, size_t len);
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
#endif

1
zsdk.hpp

@ -2,6 +2,5 @@
#define SDK_VERSION 2
#include "mutex.hpp"
#include "sys_mgr.hpp"
#include "zbasic.h"
#include "zgpio.hpp"
Loading…
Cancel
Save