Browse Source

merge

master
zhaohe 2 years ago
parent
commit
a79bbff03a
  1. 2
      chip/api/zi_api.hpp
  2. 15
      chip/api/zi_pwm_ctrl.hpp
  3. 12
      chip/api/zi_temperature.hpp
  4. 15
      components/api/zi_uart_sender.hpp
  5. 126
      components/modbus/modbus_basic.hpp
  6. 90
      components/modbus/modbus_client.cpp
  7. 44
      components/modbus/modbus_client.hpp
  8. 280
      components/modbus/modbus_processer.cpp
  9. 43
      components/modbus/modbus_processer.hpp
  10. 63
      components/sub_modbus_module/sub_modbus_board_initer.cpp
  11. 26
      components/sub_modbus_module/sub_modbus_board_initer.hpp
  12. 5
      components/subcanmodule/zcancmder_subboard_initer.cpp
  13. 8
      components/subcanmodule/zcancmder_subboard_initer.hpp
  14. 2
      components/tmc/basic/tmc_ic_interface.hpp
  15. 22
      components/tmc/ic/ztmc5130.cpp
  16. 1
      components/tmc/ic/ztmc5130.hpp
  17. 80
      components/zcancmder/zcan_board_module.cpp
  18. 19
      components/zcancmder/zcan_board_module.hpp

2
chip/api/zi_api.hpp

@ -1,3 +1,5 @@
#pragma once
#include "zi_adc.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
#include "zi_temperature.hpp"
#include "zi_pwm_ctrl.hpp"

15
chip/api/zi_pwm_ctrl.hpp

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
namespace iflytop {
using namespace std;
class ZIPWMCtrl {
public:
virtual ~ZIPWMCtrl(){};
virtual int32_t set_pwm_duty(int32_t duty) = 0;
virtual int32_t set_pwm_freq(int32_t freq) = 0;
virtual int32_t get_pwm_duty() = 0;
virtual int32_t get_pwm_freq() = 0;
};
} // namespace iflytop

12
chip/api/zi_temperature.hpp

@ -0,0 +1,12 @@
#pragma once
#include <stdint.h>
namespace iflytop {
using namespace std;
class ZITemperatureSensor {
public:
virtual ~ZITemperatureSensor(){};
virtual int32_t getTemperature(int32_t& sensorval) = 0;
};
} // namespace iflytop

15
components/api/zi_uart_sender.hpp

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#include <functional>
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
namespace iflytop {
using namespace std;
class ZIUartSender {
public:
virtual ~ZIUartSender() {}
virtual void send(const uint8_t *data, size_t len) = 0;
};
} // namespace iflytop

126
components/modbus/modbus_basic.hpp

@ -1,7 +1,133 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
/**
* @brief
*
* dep:
* basic_type.h
*
*
* TODO:
*
* 0x04
* 0x10
*
*/
/*定义Modbus的操作功能码,支持01、02、03、04、05、06、15、16功能码*/
typedef enum {
// ReadCoilStatus 读线圈状态(读多个输出位的状态)
ModbusOrder01 = 0x01,
// ReadInputStatus 读输入位状态(读多个输入位的状态)
ModbusOrder02 = 0x02,
// ReadHoldingRegister 读保持寄存器(读多个保持寄存器的数值)
ModbusOrder03 = 0x03,
// ReadInputRegister 读输入寄存器(读多个输入寄存器的数值)
ModbusOrder04 = 0x04,
// WriteSingleCoil 强制单个线圈(强制单个输出位的状态)
ModbusOrder05 = 0x05,
// WriteSingleRegister 预制单个寄存器(设定一个寄存器的数值)
ModbusOrder06 = 0x06,
// WriteMultipleCoil 强制多个线圈(强制多个输出位的状态)
ModbusOrder0F = 0x0F,
// WriteMultipleRegister 预制多个寄存器(设定多个寄存器的数值)
ModbusOrder10 = 0x10,
// ReadFileRecord 读文件记录
ModbusOrder14 = 0x14,
// WriteFileRecord 写文件记录
ModbusOrder15 = 0x15,
// MaskWriteRegister 屏蔽写寄存器
ModbusOrder16 = 0x16,
// ReadWriteMultiRegister 读写多个寄存器
ModbusOrder17 = 0x17,
// ReadDeviceID读设备识别码
ModbusOrder2B = 0x2B,
} ModbusFunctionCode;
/*定义接收到指令检测错误时的错误码*/
typedef enum {
Modbus_OK = 0x00,
InvalidFunctionCode = 0x01, // 不合法功能代码
IllegalDataAddress = 0x02, // 非法的数据地址
IllegalDataValues = 0x03, // 非法的数据值或者范围
SlaveFailure = 0x04, // 从站设备故障
Acknowledgement = 0x05, // 确认
SlaveDeviceBusy = 0x06, // 从属设备忙
MemoryParityError = 0x08, // 存储奇偶性差错
GatewayDisabled = 0x0A, // 不可用网关路径
GatewayResponseFailed = 0x0B // 网关目标设备响应失败
} ModbusStatus;
typedef struct {
uint8_t deviceid;
ModbusFunctionCode functionCode;
union {
/**********read************/
struct {
uint16_t startbit; // bit
uint16_t numbit; // bit
} O01; // ReadCoilStatus
struct {
uint16_t startbit; // bit
uint16_t numbit; // bit
} O02; // ReadInputStatus
struct {
uint16_t startreg; // byte
uint16_t numreg; // reg(一个reg==16bit)
} O03; // ReadInputStatus
struct {
uint16_t startreg; // byte
uint16_t numreg; // reg(一个reg==16bit)
} O04; // ReadInputStatus
/**********write************/
struct {
uint16_t startbit; // bit
uint16_t numbit; // bit
uint8_t bytenum;
uint8_t *bit;
} O0F; // WriteMultipleCoil
struct {
uint16_t startreg; // byte
uint16_t numreg; // byte
uint8_t bytenum; // numreg*2
uint8_t *reg;
} O10; // WriteMultipleCoil
} d;
} ModbusMasterData_t;
typedef struct {
ModbusFunctionCode functionCode;
uint8_t deviceId;
union {
/**********read_receipt************/
struct {
uint8_t bytenum; // bit
uint8_t *byte_table;
} O01; // ReadCoilStatus
struct {
uint8_t bytenum; // byte_table
uint8_t *byte_table;
} O02; // ReadInputStatus
struct {
uint8_t bytenum; // byte
uint8_t *reg;
} O03; // ReadInputStatus
struct {
uint8_t bytenum; // byte
uint8_t *reg;
} O04; // ReadInputStatus
/**********write_receipt************/
struct {
uint16_t startbit;
uint16_t bitnum; // bit
} O0F; // WriteMultipleCoil-->对应01
struct {
uint16_t startreg;
uint16_t regnum; // byte
} O10; // --->对应03
} d;
} ModbusSlaveData_t;
/**
* @brief CRC16校验码
*

90
components/modbus/modbus_client.cpp

@ -0,0 +1,90 @@
#include "modbus_client.hpp"
#include <string.h>
#include "modbus_basic.hpp"
#include "sdk\os\delay.hpp"
using namespace iflytop;
static uint8_t modbus_rx_buf[255];
static uint8_t modbus_tx_buf[255];
static bool modbus_rx_is_ready = false;
static int modbus_rx_size = 0;
static void modbux_tx(uint8_t* rx, uint16_t len) { ModulebusClient::Inst()->sendpacket(rx, len); }
static void modbux_process_rx(modbus_processer_context_t* context) { ModulebusClient::Inst()->process_rx_packet(context); }
void ModulebusClient::init(ZIUartReceiver* receiver, ZIUartSender* sender, int deviceId, //
on_reg_read_t regreadcb, //
on_reg_write_t regwritecb) {
static modbus_processer_t s_modbus_processer = {};
s_modbus_processer.modbus_device_id = deviceId;
s_modbus_processer.modbus_processer_rx_buf = modbus_rx_buf;
s_modbus_processer.modbus_processer_rx_buf_size = sizeof(modbus_rx_buf);
s_modbus_processer.modbus_processer_tx_buf = modbus_tx_buf;
s_modbus_processer.modbus_processer_tx_buf_size = sizeof(modbus_tx_buf);
s_modbus_processer.tx = modbux_tx;
s_modbus_processer.process_rx = modbux_process_rx;
m_receiver = receiver;
m_sender = sender;
m_deviceId = deviceId;
m_regreadcb = regreadcb;
m_regwritecb = regwritecb;
modbus_processer_init(&s_modbus_processer);
receiver->startRx([this](uint8_t* data, size_t len) { //
if (modbus_rx_is_ready) return;
if (len > 255) return;
memcpy(modbus_rx_buf, data, len);
modbus_rx_size = len;
modbus_rx_is_ready = true;
});
}
void ModulebusClient::loop() {
if (modbus_rx_is_ready) {
modbus_processer_process_data(modbus_rx_buf, modbus_rx_size);
modbus_rx_is_ready = false;
}
}
void ModulebusClient::sendpacket(uint8_t* data, uint16_t len) { m_sender->send(data, len); }
void ModulebusClient::process_rx_packet(modbus_processer_context_t* context) {
ModbusFunctionCode fcode = modbus_get_function_code(context);
if (fcode == ModbusOrder10) {
/**
* @brief »ù±¾GPIOд
*/
uint16_t startreg = context->rx->d.O10.startreg;
uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg;
uint16_t regnum = context->rx->d.O10.numreg;
for (int i = 0; i < regnum; i++) {
int32_t regoff = i + startreg;
if (m_regwritecb) {
m_regwritecb(regoff, modbus_get_reg_10(context, regoff));
}
}
} else if (fcode == ModbusOrder03) {
uint16_t startreg = context->rx->d.O03.startreg;
uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg;
uint16_t regnum = context->rx->d.O03.numreg;
for (int i = 0; i < regnum; i++) {
int32_t regoff = i + startreg;
uint16_t regval = 0;
if (m_regreadcb) {
m_regreadcb(regoff, regval);
}
modbus_set_tx_reg_03(context, regoff, regval);
}
}
if (fcode == ModbusOrder10) {
modbus_send_10(context, Modbus_OK);
} else if (fcode == ModbusOrder03) {
modbus_send_03(context, Modbus_OK);
}
}

44
components/modbus/modbus_client.hpp

@ -0,0 +1,44 @@
#pragma once
#include "modbus_processer.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\api\zi_uart_sender.hpp"
#include "sdk\components\cmdscheduler\cmd_scheduler_v2.hpp"
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
#include "sdk\components\zcancmder\zcan_board_module.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#include "sdk\components\zprotocol_helper\micro_computer_module_device_script_cmder_paser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_event_bus_sender.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_parser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_manager.hpp"
namespace iflytop {
typedef function<void(uint16_t regadd, uint16_t& val)> on_reg_read_t;
typedef function<void(uint16_t regadd, uint16_t val)> on_reg_write_t;
class ModulebusClient {
ZIUartReceiver* m_receiver;
ZIUartSender* m_sender;
int m_deviceId;
on_reg_read_t m_regreadcb;
on_reg_write_t m_regwritecb;
ModulebusClient() {}
public:
static ModulebusClient* Inst() {
static ModulebusClient instance;
return &instance;
}
void init(ZIUartReceiver* receiver, ZIUartSender* sender, int deviceId, //
on_reg_read_t regreadcb, //
on_reg_write_t regwritecb);
void loop();
public:
void process_rx_packet(modbus_processer_context_t* context);
void sendpacket(uint8_t* data, uint16_t len);
};
} // namespace iflytop

280
components/modbus/modbus_processer.cpp

@ -0,0 +1,280 @@
#include "modbus_processer.hpp"
#include <stdbool.h>
#include <stdint.h>
/***********************485rx**************************/
// 接收到了多少数据
// volatile uint16_t s_modbus_uart_rx_off = 0;
// 当前是否正在处理接收到的数据
// volatile bool s_modbus_uart_rx_buf_is_processing = false;
/***********************485tx**************************/
static modbus_processer_t* g_processer;
#define GET_UINT16(uint8) (uint16_t)(((uint16_t)((uint8)[0]) << 8) + (uint8)[1])
void modbus_processer_process_data(uint8_t* rx, uint16_t len);
void modbus_processer_init(modbus_processer_t* processer) { g_processer = processer; }
void ModbusProcessRxData(uint8_t* rxraw, uint8_t length, ModbusMasterData_t* rxparsed) {
rxparsed->functionCode = (ModbusFunctionCode)rxraw[1];
if (rxraw[1] == ModbusOrder01 || rxraw[1] == ModbusOrder02 || rxraw[1] == ModbusOrder03 || rxraw[1] == ModbusOrder04) {
/**
* @brief
* 001
*/
rxparsed->d.O01.startbit = rxraw[2] * 256 + rxraw[3];
rxparsed->d.O01.numbit = rxraw[4] * 256 + rxraw[5];
} else if (rxraw[1] == ModbusOrder0F || rxraw[1] == ModbusOrder10) {
/**
* @brief
* 0F
*/
rxparsed->d.O0F.startbit = rxraw[2] * 256 + rxraw[3];
rxparsed->d.O0F.numbit = rxraw[4] * 256 + rxraw[5];
rxparsed->d.O0F.bytenum = rxraw[6];
rxparsed->d.O0F.bit = &rxraw[7];
} else {
/**
* @brief Not support now
*/
}
}
#define UINT16ToUINT8(u16d, u8addbegin) \
{ \
(u8addbegin)[0] = u16d >> 8; \
(u8addbegin)[1] = (uint8_t)u16d; \
}
void ModbusCreateTx_setReg(uint8_t* txbuffer, uint8_t length, uint16_t off, uint16_t regdata) {
if (3 + off * 2 > length - 2) {
return;
}
txbuffer[3 + off * 2] = regdata >> 8;
txbuffer[3 + off * 2 + 1] = (uint8_t)regdata;
}
void ModbusCreateTxData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, ModbusSlaveData_t* txdata) {
/**
* @brief TODO:txbuffer长度计算
*/
if (length < 4) return;
txbuffer[0] = txdata->deviceId;
txbuffer[1] = (uint8_t)txdata->functionCode;
*sendlength = 0;
volatile uint16_t _sendlength = 0;
volatile uint16_t i = 0;
if (txdata->functionCode == ModbusOrder01 || txdata->functionCode == ModbusOrder02 || txdata->functionCode == ModbusOrder03 || txdata->functionCode == ModbusOrder04) {
/**
* @brief 01,02 bit
*/
// 读取多个输出状态
// sendLen =
// add(1byte)+functionCode(1byte)+addNum(1)+crc(2) = 5+numbyte
volatile uint16_t numbyte = txdata->d.O01.bytenum;
_sendlength = 5 + numbyte;
if (length < _sendlength) return;
txbuffer[2] = txdata->d.O01.bytenum;
if (txdata->d.O01.byte_table != nullptr) {
for (i = 0; i < numbyte; i++) {
txbuffer[3 + i] = txdata->d.O01.byte_table[i];
}
}
} else if (txdata->functionCode == ModbusOrder0F || txdata->functionCode == ModbusOrder10) {
// 写入多个输出
// sendLen = add(1byte)+functionCode(1byte)+startAdd(2)+addNum(2)+crc(2) = 8
_sendlength = 8;
if (length < _sendlength) return;
UINT16ToUINT8(txdata->d.O0F.startbit, &txbuffer[2]);
UINT16ToUINT8(txdata->d.O0F.bitnum, &txbuffer[4]);
} else {
/**
* @brief Not support now
*/
}
// calculate crc
if (_sendlength > 2) {
modbus_pack_crc_to_packet(txbuffer, _sendlength);
}
*sendlength = _sendlength;
}
void ModbusCreateExceptionData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, uint8_t deviceid, uint8_t functioncode, ModbusStatus status) {
/**
* @brief TODO:txbuffer长度计算
*/
volatile uint16_t _sendlength = 0;
volatile uint16_t i = 0;
if (length < 4) return;
txbuffer[0] = deviceid;
txbuffer[1] = functioncode | 0x80;
txbuffer[2] = (uint8_t)status;
*sendlength = 0;
// sendLen = add(1byte)+functionCode(1byte)+exception(1)+crc(2) = 4
_sendlength = 4;
modbus_pack_crc_to_packet(txbuffer, _sendlength);
*sendlength = _sendlength;
return;
}
#if 0
void modbus_processer_try_process_data(void) {
/**
* @brief
* modbus协议3.5
*/
// bool receive_one_packet = false; // 因为keil报警告才注释
if (s_modbus_uart_rx_off != 0) {
uint16_t modbus_uart_rx_off_before = s_modbus_uart_rx_off;
g_processer->port_delay_us(g_processer->modbus_baundrate_one_packet_delay_us);
g_processer->port_enter_critical();
if (s_modbus_uart_rx_off == modbus_uart_rx_off_before) {
s_modbus_uart_rx_buf_is_processing = true;
}
g_processer->port_exit_critical();
if (s_modbus_uart_rx_buf_is_processing) {
modbus_processer_process_data(g_processer->modbus_processer_rx_buf, s_modbus_uart_rx_off);
g_processer->port_enter_critical();
s_modbus_uart_rx_off = 0;
s_modbus_uart_rx_buf_is_processing = false;
g_processer->port_exit_critical();
}
}
}
#endif
/***********************************************************************************************************************
* ==================================================modbus消息处理=================================================== *
***********************************************************************************************************************/
void modbus_processer_process_data(uint8_t* rx, uint16_t rxlen) {
/**
* @brief modbus接收完成以后在这里进行处理数据
*
*/
// 如果不是广播信息或者不是当前设备的信息,丢弃
if (rx[0] != 0 && rx[0] != g_processer->modbus_device_id) {
return;
}
// CRC校验失败
if (!modbus_checkcrc16(rx, rxlen)) {
return;
}
// if(functioncode)
static ModbusMasterData_t rxorder;
static ModbusSlaveData_t txorder;
// 将接受到的数据进行组包
ModbusProcessRxData(rx, rxlen, &rxorder);
// static uint16_t txsendlen = 0; // 因为keil报警告才注释
txorder.deviceId = g_processer->modbus_device_id;
// 功能码
txorder.functionCode = rxorder.functionCode;
modbus_processer_context_t context = {0};
context.tx = &txorder;
context.rx = &rxorder;
g_processer->process_rx(&context);
}
/***********************************************************************************************************************
* ======================================================Extern======================================================= *
***********************************************************************************************************************/
ModbusFunctionCode modbus_get_function_code(modbus_processer_context_t* context) { //
return context->tx->functionCode;
}
void modbus_set_tx_reg_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regdata) {
uint16_t off = regoff - context->rx->d.O03.startreg;
ModbusCreateTx_setReg(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, off, //
regdata);
}
void modbus_set_tx_regs_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t* regdata, int reglen) {
for (int i = 0; i < reglen; i++) {
modbus_set_tx_reg_03(context, regoff + i, regdata[i]);
}
}
uint16_t modbus_get_reg_10(modbus_processer_context_t* context, uint16_t regoff) {
uint16_t off = regoff - context->rx->d.O10.startreg;
uint8_t* data = context->rx->d.O10.reg;
if ((off + 1) * 2 <= context->rx->d.O10.bytenum) {
uint16_t u16 = GET_UINT16(&data[off * 2]);
return u16;
} else {
uint16_t u16 = data[off * 2];
return u16;
}
}
uint8_t* modbus_get_buf_10(modbus_processer_context_t* context, uint16_t regoff) {
uint16_t off = regoff - context->rx->d.O10.startreg;
uint8_t* data = context->rx->d.O10.reg;
return &data[off * 2];
}
bool modbus_if_register_exists_03(modbus_processer_context_t* context, uint16_t regoff) {
uint16_t startreg = context->rx->d.O03.startreg;
uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg;
return regoff >= startreg && regoff < endreg;
}
bool modbus_if_registers_exists_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regnum) { return (modbus_if_register_exists_03(context, regoff) && modbus_if_register_exists_03(context, regoff + regnum - 1)); }
bool modbus_if_register_exists_10(modbus_processer_context_t* context, uint16_t regoff) {
uint16_t startreg = context->rx->d.O10.startreg;
uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg;
return regoff >= startreg && regoff < endreg;
}
void modbus_send_03(modbus_processer_context_t* context, ModbusStatus modbus_status) {
uint16_t sendlegth = 0;
if (modbus_status == Modbus_OK) {
/**
* @brief
*/
context->tx->functionCode = context->rx->functionCode;
context->tx->deviceId = g_processer->modbus_device_id;
context->tx->d.O03.bytenum = context->rx->d.O03.numreg * 2;
context->tx->d.O03.reg = nullptr;
// 组成响应包
ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
// 包组成以后发送给服务端
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
} else {
// LOGD("error");
/**
* @brief
*/
// 处理异常情况
ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
g_processer->modbus_processer_tx_buf_size, //
&sendlegth, //
g_processer->modbus_device_id, //
context->rx->functionCode, //
modbus_status);
// 组包完成发送应答
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
}
}
void modbus_send_10(modbus_processer_context_t* context, ModbusStatus modbus_status) {
uint16_t sendlegth = 0;
if (modbus_status == Modbus_OK) {
context->tx->functionCode = context->rx->functionCode;
context->tx->deviceId = g_processer->modbus_device_id;
context->tx->d.O10.regnum = context->rx->d.O10.numreg;
context->tx->d.O10.startreg = context->rx->d.O10.startreg;
// 构造回执,并发送
ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
} else {
// 构造异常包并发送
ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
g_processer->modbus_processer_tx_buf_size, //
&sendlegth, //
g_processer->modbus_device_id, //
context->rx->functionCode, //
modbus_status);
g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
}
}

43
components/modbus/modbus_processer.hpp

@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include "modbus_basic.hpp"
typedef struct {
ModbusMasterData_t* rx;
ModbusSlaveData_t* tx;
} modbus_processer_context_t;
typedef struct modbus_processer {
uint8_t modbus_device_id; // default 0x01;
uint8_t* modbus_processer_rx_buf;
uint8_t modbus_processer_rx_buf_size; //
uint8_t* modbus_processer_tx_buf;
uint8_t modbus_processer_tx_buf_size; //
/*************************************/
void (*tx)(uint8_t* rx, uint16_t len);
void (*process_rx)(modbus_processer_context_t* context);
} modbus_processer_t;
void modbus_processer_init(modbus_processer_t* processer);
void modbus_processer_push_data(uint8_t rxdata);
// void modbus_processer_try_process_data(void);
void modbus_processer_process_data(uint8_t* rx, uint16_t rxlen);
/***********************************************************************************************************************
* ====================================================¸¨Öú·½·¨==================================================== *
***********************************************************************************************************************/
ModbusFunctionCode modbus_get_function_code(modbus_processer_context_t* context);
void modbus_set_tx_reg_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regdata);
void modbus_set_tx_regs_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t* regdata, int reglen);
uint16_t modbus_get_reg_10(modbus_processer_context_t* context, uint16_t regoff);
bool modbus_if_register_exists_03(modbus_processer_context_t* context, uint16_t regoff);
bool modbus_if_registers_exists_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t reglen);
bool modbus_if_register_exists_10(modbus_processer_context_t* context, uint16_t regoff);
uint8_t* modbus_get_buf_10(modbus_processer_context_t* context, uint16_t regoff);
void modbus_send_03(modbus_processer_context_t* context, ModbusStatus modbus_status);
void modbus_send_10(modbus_processer_context_t* context, ModbusStatus modbus_status);

63
components/sub_modbus_module/sub_modbus_board_initer.cpp

@ -0,0 +1,63 @@
#include "sub_modbus_board_initer.hpp"
//
#include <stdio.h>
#include <string.h>
#include "project_configs.h"
using namespace iflytop;
#define TAG "main"
extern DMA_HandleTypeDef PC_DEBUG_UART_DMA_HANDLER;
extern DMA_HandleTypeDef PC_MODBUS_UART_DMA_HANDLER;
class UARTSender : public ZIUartSender {
UART_HandleTypeDef* m_huart;
public:
void init(UART_HandleTypeDef* huart) { m_huart = huart; }
virtual void send(const uint8_t* data, size_t len) { HAL_UART_Transmit(m_huart, (uint8_t*)data, len, 1000); }
};
void SubModbusBoardIniter::init(int deviceId, //
function<void()> subModuleIniter, //
on_reg_read_t regreadcb, //
on_reg_write_t regwritecb) {
chip_cfg_t chipcfg = {};
chipcfg.us_dleay_tim = &PC_SYS_DELAY_US_TIMER;
chipcfg.tim_irq_scheduler_tim = &PC_SYS_TIM_IRQ_SCHEDULER_TIMER;
chipcfg.huart = &PC_DEBUG_UART;
chipcfg.debuglight = PC_DEBUG_LIGHT_GPIO;
chip_init(&chipcfg);
zos_cfg_t zoscfg;
zos_init(&zoscfg);
ZLOGI(TAG, "boardId:%d", deviceId);
if (subModuleIniter) {
subModuleIniter();
}
static ZUARTDmaReceiver dmaUartReceiver;
static ZUARTDmaReceiver::hardware_config_t cfg = {
.huart = &PC_MODBUS_UART,
.dma_rx = &PC_MODBUS_UART_DMA_HANDLER,
.rxbuffersize = PC_MODBUS_UART_RX_BUF_SIZE,
.rxovertime_ms = 1,
};
dmaUartReceiver.initialize(&cfg);
static UARTSender uartSender;
uartSender.init(&PC_MODBUS_UART);
ModulebusClient::Inst()->init(&dmaUartReceiver, &uartSender, deviceId, regreadcb, regwritecb);
}
void SubModbusBoardIniter::loop() {
while (true) {
OSDefaultSchduler::getInstance()->loop();
ModulebusClient::Inst()->loop();
}
}

26
components/sub_modbus_module/sub_modbus_board_initer.hpp

@ -0,0 +1,26 @@
#pragma once
#include "sdk/os/zos.hpp"
#include "sdk\components\cmdscheduler\cmd_scheduler_v2.hpp"
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
#include "sdk\components\zcancmder\zcan_board_module.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#include "sdk\components\zprotocol_helper\micro_computer_module_device_script_cmder_paser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_event_bus_sender.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_parser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_manager.hpp"
//
#include "sdk\components\modbus\modbus_client.hpp"
namespace iflytop {
class SubModbusBoardIniter {
public:
void init(int deviceId, //
function<void()> subModuleIniter, //
on_reg_read_t regreadcb, //
on_reg_write_t regwritecb);
void loop();
private:
};
} // namespace iflytop

5
components/subcanmodule/zcancmder_subboard_initer.cpp

@ -70,9 +70,13 @@ void ZCancmderSubboardIniter::initmodule() {
ZCanBoardModule::hardware_config_t hcfg = {};
static_assert(ZARRAY_SIZE(hcfg.input) == ZARRAY_SIZE(m_cfg.input_gpio));
static_assert(ZARRAY_SIZE(hcfg.output) == ZARRAY_SIZE(m_cfg.output_gpio));
static_assert(ZARRAY_SIZE(hcfg.temperature_sensor) == ZARRAY_SIZE(m_cfg.temperature_sensor));
static_assert(ZARRAY_SIZE(hcfg.pwmctrl) == ZARRAY_SIZE(m_cfg.pwmctrl));
memcpy(&hcfg.input, &m_cfg.input_gpio, sizeof(m_cfg.input_gpio));
memcpy(&hcfg.output, &m_cfg.output_gpio, sizeof(m_cfg.output_gpio));
memcpy(&hcfg.temperature_sensor, &m_cfg.temperature_sensor, sizeof(m_cfg.temperature_sensor));
memcpy(&hcfg.pwmctrl, &m_cfg.pwmctrl, sizeof(m_cfg.pwmctrl));
boardmodule.initialize(get_module_id(0), &hcfg);
ziProtocolParser.registerModule(&boardmodule);
@ -86,7 +90,6 @@ void ZCancmderSubboardIniter::register_module(ZIModule* module) {
void ZCancmderSubboardIniter::loop() {
while (true) {
OSDefaultSchduler::getInstance()->loop();
zcanCmder.loop();
cmder.schedule();

8
components/subcanmodule/zcancmder_subboard_initer.hpp

@ -5,9 +5,9 @@
#include "sdk\components\zcancmder\zcan_board_module.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#include "sdk\components\zprotocol_helper\micro_computer_module_device_script_cmder_paser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_event_bus_sender.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_parser.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_manager.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\protocol_event_bus_sender.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
@ -15,8 +15,10 @@ class ZCancmderSubboardIniter {
public:
typedef struct {
int32_t deviceId;
ZGPIO::InputGpioCfg_t input_gpio[16];
ZGPIO::OutputGpioCfg_t output_gpio[16];
ZGPIO::InputGpioCfg_t input_gpio[32];
ZGPIO::OutputGpioCfg_t output_gpio[32];
ZITemperatureSensor* temperature_sensor[8];
ZIPWMCtrl* pwmctrl[8];
} cfg_t;
private:

2
components/tmc/basic/tmc_ic_interface.hpp

@ -59,6 +59,8 @@ class IStepperMotor {
virtual void setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) = 0;
virtual void setGlobalScale(uint8_t globalscale) = 0;
virtual void setScale(int32_t scale) = 0;
virtual void setScaleDenominator(int32_t scale) = 0;

22
components/tmc/ic/ztmc5130.cpp

@ -139,13 +139,17 @@ uint8_t TMC5130::reset() {
}
return 0;
}
int32_t TMC5130::getXACTUAL() { return to_user_pos(readInt(TMC5130_XACTUAL)); }
void TMC5130::setXACTUAL(int32_t value) { writeInt(TMC5130_XACTUAL, to_motor_pos(value)); }
int32_t TMC5130::getVACTUAL() { return to_user_pos(readInt(TMC5130_VACTUAL)); }
void TMC5130::setAcceleration(float accelerationpps2) { writeInt(TMC5130_AMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // 设置最大加速度
void TMC5130::setDeceleration(float accelerationpps2) { writeInt(TMC5130_DMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // 设置最大减速度
void TMC5130::setMotorShaft(bool reverse) { PRV_FIELD_WRITE(TMC5130_GCONF, TMC5130_SHAFT_MASK, TMC5130_SHAFT_SHIFT, reverse); }
void TMC5130::setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { writeInt(TMC5130_IHOLD_IRUN, (iholddelay << TMC5130_IHOLDDELAY_SHIFT) | (irun << TMC5130_IRUN_SHIFT) | (ihold << TMC5130_IHOLD_SHIFT)); }
int32_t TMC5130::getXACTUAL() { return to_user_pos(readInt(TMC5130_XACTUAL)); }
void TMC5130::setXACTUAL(int32_t value) { writeInt(TMC5130_XACTUAL, to_motor_pos(value)); }
int32_t TMC5130::getVACTUAL() { return to_user_pos(readInt(TMC5130_VACTUAL)); }
void TMC5130::setAcceleration(float accelerationpps2) { writeInt(TMC5130_AMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // 设置最大加速度
void TMC5130::setDeceleration(float accelerationpps2) { writeInt(TMC5130_DMAX, (int32_t)(to_motor_acc(accelerationpps2))); } // 设置最大减速度
void TMC5130::setMotorShaft(bool reverse) { PRV_FIELD_WRITE(TMC5130_GCONF, TMC5130_SHAFT_MASK, TMC5130_SHAFT_SHIFT, reverse); }
void TMC5130::setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { writeInt(TMC5130_IHOLD_IRUN, (iholddelay << TMC5130_IHOLDDELAY_SHIFT) | (irun << TMC5130_IRUN_SHIFT) | (ihold << TMC5130_IHOLD_SHIFT)); }
void TMC5130::setGlobalScale(uint8_t globalscale) {
// writeInt(TMC5130_GCONF, (readInt(TMC5130_GCONF) & ~TMC5130_SCALE_MASK) | (globalscale << TMC5130_SCALE_SHIFT));
}
uint32_t TMC5130::readICVersion() {
uint32_t chipID = PRV_FIELD_READ(TMC5130_IOIN, TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT);
return chipID;
@ -252,8 +256,8 @@ int32_t TMC5130::readInt(uint8_t address) {
return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4];
}
int32_t TMC5130::to_motor_acc(int32_t acc) { //
int32_t val = acc / 60.0 * m_onecirclepulse; // 65535
int32_t TMC5130::to_motor_acc(int32_t acc) { //
int32_t val = acc / 60.0 * m_onecirclepulse; // 65535
if (val > 65535) val = 65535;
return val;
}

1
components/tmc/ic/ztmc5130.hpp

@ -126,6 +126,7 @@ class TMC5130 : public IStepperMotor {
virtual void setDeceleration(float accelerationpps2);
void setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay);
void setGlobalScale(uint8_t globalscale);
// void setSubdivision(uint8_t subdivision);
void setMotorShaft(bool reverse); // 设置电机旋转方向

80
components/zcancmder/zcan_board_module.cpp

@ -47,6 +47,33 @@ int32_t ZCanBoardModule::module_xxx_reg(int32_t param_id, bool read, int32_t &va
PROCESS_REG(kreg_module_initflag, /* */ REG_GET(module_get_inited_flag()), module_set_inited_flag(val));
PROCESS_REG(kreg_module_output_state, /* */ REG_GET(readoutput()), ACTION_NONE);
PROCESS_REG(kreg_module_input_state, /* */ REG_GET(readinput()), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature0, readTemperature(0, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature1, readTemperature(1, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature2, readTemperature(2, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature3, readTemperature(3, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature4, readTemperature(4, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature5, readTemperature(5, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature6, readTemperature(6, val), ACTION_NONE);
PROCESS_REG(kreg_sensor_temperature7, readTemperature(7, val), ACTION_NONE);
PROCESS_REG(kreg_pwm0_duty, readPwmDuty(0, val), setPwmDuty(0, val));
PROCESS_REG(kreg_pwm1_duty, readPwmDuty(1, val), setPwmDuty(1, val));
PROCESS_REG(kreg_pwm2_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm3_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm4_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm5_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm6_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm7_duty, readPwmDuty(2, val), setPwmDuty(2, val));
PROCESS_REG(kreg_pwm0_freq, readPwmFreq(0, val), setPwmFreq(0, val));
PROCESS_REG(kreg_pwm1_freq, readPwmFreq(1, val), setPwmFreq(1, val));
PROCESS_REG(kreg_pwm2_freq, readPwmFreq(2, val), setPwmFreq(2, val));
PROCESS_REG(kreg_pwm3_freq, readPwmFreq(3, val), setPwmFreq(3, val));
PROCESS_REG(kreg_pwm4_freq, readPwmFreq(4, val), setPwmFreq(4, val));
PROCESS_REG(kreg_pwm5_freq, readPwmFreq(5, val), setPwmFreq(5, val));
PROCESS_REG(kreg_pwm6_freq, readPwmFreq(6, val), setPwmFreq(6, val));
default:
return err::kmodule_not_find_config_index;
break;
@ -79,4 +106,57 @@ int32_t ZCanBoardModule::readoutput() {
}
}
return outputval;
}
int32_t ZCanBoardModule::readTemperature(int32_t sensorId, int32_t &temperature_val) {
if (sensorId < 0 || sensorId >= ZARRAY_SIZE(temperature_sensor)) {
return err::kmodule_not_find_config_index;
}
if (temperature_sensor[sensorId] == nullptr) {
return err::kmodule_not_find_config_index;
}
return temperature_sensor[sensorId]->getTemperature(temperature_val);
}
int32_t ZCanBoardModule::readPwmDuty(int32_t pwmId, int32_t &duty) {
if (pwmId < 0 || pwmId >= ZARRAY_SIZE(m_cfg.pwmctrl)) {
return err::kmodule_not_find_config_index;
}
if (m_cfg.pwmctrl[pwmId] == nullptr) {
return err::kmodule_not_find_config_index;
}
duty = m_cfg.pwmctrl[pwmId]->get_pwm_duty();
return 0;
}
int32_t ZCanBoardModule::setPwmDuty(int32_t pwmId, int32_t duty) {
if (pwmId < 0 || pwmId >= ZARRAY_SIZE(m_cfg.pwmctrl)) {
return err::kmodule_not_find_config_index;
}
if (m_cfg.pwmctrl[pwmId] == nullptr) {
return err::kmodule_not_find_config_index;
}
m_cfg.pwmctrl[pwmId]->set_pwm_duty(duty);
return 0;
}
int32_t ZCanBoardModule::readPwmFreq(int32_t pwmId, int32_t &freq) {
if (pwmId < 0 || pwmId >= ZARRAY_SIZE(m_cfg.pwmctrl)) {
return err::kmodule_not_find_config_index;
}
if (m_cfg.pwmctrl[pwmId] == nullptr) {
return err::kmodule_not_find_config_index;
}
freq = m_cfg.pwmctrl[pwmId]->get_pwm_freq();
return 0;
}
int32_t ZCanBoardModule::setPwmFreq(int32_t pwmId, int32_t freq) {
if (pwmId < 0 || pwmId >= ZARRAY_SIZE(m_cfg.pwmctrl)) {
return err::kmodule_not_find_config_index;
}
if (m_cfg.pwmctrl[pwmId] == nullptr) {
return err::kmodule_not_find_config_index;
}
m_cfg.pwmctrl[pwmId]->set_pwm_freq(freq);
return 0;
}

19
components/zcancmder/zcan_board_module.hpp

@ -4,6 +4,10 @@
#pragma once
#include "sdk/os/zos.hpp"
//
#include "sdk/chip/api/zi_api.hpp"
#include "sdk/chip/api/zi_temperature.hpp"
#include "sdk\chip\api\zi_adc.hpp"
#include "sdk\components\zprotocols\zcancmder_v2\api\api.hpp"
/**
@ -29,8 +33,10 @@ using namespace std;
class ZCanBoardModule : public ZIModule {
public:
typedef struct {
ZGPIO::InputGpioCfg_t input[16];
ZGPIO::OutputGpioCfg_t output[16];
ZGPIO::InputGpioCfg_t input[32];
ZGPIO::OutputGpioCfg_t output[32];
ZITemperatureSensor *temperature_sensor[8];
ZIPWMCtrl *pwmctrl[8];
} hardware_config_t;
hardware_config_t m_cfg;
@ -42,6 +48,8 @@ class ZCanBoardModule : public ZIModule {
int32_t m_input_num = 0;
int32_t m_output_num = 0;
ZITemperatureSensor *temperature_sensor[8];
public:
virtual ~ZCanBoardModule() {}
@ -61,6 +69,13 @@ class ZCanBoardModule : public ZIModule {
int32_t module_xxx_reg(int32_t param_id, bool read, int32_t &param_value);
int32_t readinput();
int32_t readoutput();
int32_t readTemperature(int32_t sensorId, int32_t &temperature_val);
int32_t readPwmDuty(int32_t pwmId, int32_t &duty);
int32_t setPwmDuty(int32_t pwmId, int32_t duty);
int32_t readPwmFreq(int32_t pwmId, int32_t &freq);
int32_t setPwmFreq(int32_t pwmId, int32_t freq);
};
} // namespace iflytop
Loading…
Cancel
Save