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