You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.1 KiB

#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);
}
}