508 lines
22 KiB
C++
508 lines
22 KiB
C++
/*
|
||
Modbus Library for Arduino
|
||
Modbus public API implementation
|
||
Copyright (C) 2014 Andr<64> Sarmento Barbosa
|
||
2017-2021 Alexander Emelianov (a.m.emelianov@gmail.com)
|
||
*/
|
||
#pragma once
|
||
#include "Modbus.h"
|
||
|
||
template <class T>
|
||
class ModbusAPI : public T {
|
||
public:
|
||
// Alternative API
|
||
template <typename TYPEID>
|
||
uint16_t read(TYPEID id, TAddress reg, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t read(TYPEID id, TAddress reg, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t write(TYPEID id, TAddress reg, uint16_t value, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t write(TYPEID id, TAddress reg, bool value, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t write(TYPEID id, TAddress reg, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t write(TYPEID id, TAddress reg, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
/*
|
||
template <typename TYPEID>
|
||
uint16_t push(TYPEID id, TAddress to, TAddress from, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pull(TYPEID id, TAddress from, TAddress to, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
*/
|
||
// Classic API
|
||
bool Hregs(uint16_t offset, uint16_t* value, uint16_t numregs = 1) {return this->Reg(HREG(offset), value);}
|
||
bool Coils(uint16_t offset, bool* value, uint16_t numregs = 1) {return this->Reg(COIL(offset), value);}
|
||
bool Istss(uint16_t offset, bool* value, uint16_t numregs = 1) {return this->Reg(ISTS(offset), value);}
|
||
bool Iregs(uint16_t offset, uint16_t* value, uint16_t numregs = 1) {return this->Reg(IREG(offset), value);}
|
||
|
||
//bool addHreg(uint16_t offset, uint16_t* value, uint16_t numregs = 1) {return this->addReg(HREG(offset), value);}
|
||
//bool addCoil(uint16_t offset, bool* value, uint16_t numregs = 1) {return this->addReg(COIL(offset), value);}
|
||
//bool addIsts(uint16_t offset, bool* value, uint16_t numregs = 1) {return this->addReg(ISTS(offset), value);}
|
||
//bool addIreg(uint16_t offset, uint16_t* value, uint16_t numregs = 1) {return this->addReg(IREG(offset), value);}
|
||
|
||
bool addHreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
||
bool addCoil(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
||
bool addIsts(uint16_t offset, bool value = false, uint16_t numregs = 1);
|
||
bool addIreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
|
||
|
||
bool Hreg(uint16_t offset, uint16_t value);
|
||
bool Coil(uint16_t offset, bool value);
|
||
bool Ists(uint16_t offset, bool value);
|
||
bool Ireg(uint16_t offset, uint16_t value);
|
||
|
||
bool Coil(uint16_t offset);
|
||
bool Ists(uint16_t offset);
|
||
uint16_t Ireg(uint16_t offset);
|
||
uint16_t Hreg(uint16_t offset);
|
||
|
||
bool removeCoil(uint16_t offset, uint16_t numregs = 1);
|
||
bool removeIsts(uint16_t offset, uint16_t numregs = 1);
|
||
bool removeIreg(uint16_t offset, uint16_t numregs = 1);
|
||
bool removeHreg(uint16_t offset, uint16_t numregs = 1);
|
||
|
||
bool onGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool onSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
|
||
bool removeOnGetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnSetCoil(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnGetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnSetHreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnGetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnSetIsts(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnGetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
bool removeOnSetIreg(uint16_t offset, cbModbus cb = nullptr, uint16_t numregs = 1);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t writeCoil(TYPEID id, uint16_t offset, bool value, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t writeCoil(TYPEID id, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t readCoil(TYPEID id, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t writeHreg(TYPEID id, uint16_t offset, uint16_t value, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t writeHreg(TYPEID id, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t readIsts(TYPEID id, uint16_t offset, bool* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t readHreg(TYPEID id, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t readIreg(TYPEID id, uint16_t offset, uint16_t* value, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t pushCoil(TYPEID id, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pullCoil(TYPEID id, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pullIsts(TYPEID id, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pushHreg(TYPEID id, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pullHreg(TYPEID id, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pullIreg(TYPEID id, uint16_t from, uint16_t to, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t pullHregToIreg(TYPEID id, uint16_t offset, uint16_t startreg, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pullCoilToIsts(TYPEID id, uint16_t offset, uint16_t startreg, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pushIstsToCoil(TYPEID id, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t pushIregToHreg(TYPEID id, uint16_t to, uint16_t from, uint16_t numregs = 1, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t readFileRec(TYPEID slaveId, uint16_t fileNum, uint16_t startRec, uint16_t len, uint8_t* data, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t writeFileRec(TYPEID slaveId, uint16_t fileNum, uint16_t startRec, uint16_t len, uint8_t* data, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t maskHreg(TYPEID slaveId, uint16_t offset, uint16_t andMask, uint16_t orMask, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t readWriteHreg(TYPEID slaveId, uint16_t readOffset, uint16_t* readValue, uint16_t readNumregs, uint16_t writeOffset, uint16_t* writeValue, uint16_t writeNumregs, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
|
||
template <typename TYPEID>
|
||
uint16_t rawRequest(TYPEID ip, const uint8_t* data, uint16_t len, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t rawResponce(TYPEID ip, const uint8_t* data, uint16_t len, uint8_t unit = MODBUSIP_UNIT);
|
||
template <typename TYPEID>
|
||
uint16_t errorResponce(TYPEID ip, Modbus::FunctionCode fn, Modbus::ResultCode excode, uint8_t unit = MODBUSIP_UNIT);
|
||
};
|
||
|
||
// FNAME writeCoil, writeIsts, writeHreg, writeIreg
|
||
// REG COIL, ISTS, HREG, IREG
|
||
// FUNC Modbus function
|
||
// MAXNUM Register count limit
|
||
// VALTYPE bool, uint16_t
|
||
// VALUE
|
||
#define IMPLEMENT_WRITEREG(FNAME, REG, FUNC, VALUE, VALTYPE) \
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::FNAME(TYPEID ip, uint16_t offset, VALTYPE value, cbTransaction cb, uint8_t unit) { \
|
||
this->readSlave(offset, VALUE(value), Modbus::FUNC); \
|
||
return this->send(ip, REG(offset), cb, unit); \
|
||
}
|
||
IMPLEMENT_WRITEREG(writeCoil, COIL, FC_WRITE_COIL, COIL_VAL, bool)
|
||
IMPLEMENT_WRITEREG(writeHreg, HREG, FC_WRITE_REG, , uint16_t)
|
||
|
||
#define IMPLEMENT_WRITEREGS(FNAME, REG, FUNC, VALUE, MAXNUM, VALTYPE) \
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::FNAME(TYPEID ip, uint16_t offset, VALTYPE* value, uint16_t numregs, cbTransaction cb, uint8_t unit) { \
|
||
if (numregs < 0x0001 || numregs > MAXNUM) return false; \
|
||
this->VALUE(REG(offset), offset, numregs, Modbus::FUNC, value); \
|
||
return this->send(ip, REG(offset), cb, unit); \
|
||
}
|
||
IMPLEMENT_WRITEREGS(writeCoil, COIL, FC_WRITE_COILS, writeSlaveBits, MODBUS_MAX_BITS, bool)
|
||
IMPLEMENT_WRITEREGS(writeHreg, HREG, FC_WRITE_REGS, writeSlaveWords, MODBUS_MAX_WORDS, uint16_t)
|
||
|
||
#define IMPLEMENT_READREGS(FNAME, REG, FUNC, MAXNUM, VALTYPE) \
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::FNAME(TYPEID ip, uint16_t offset, VALTYPE* value, uint16_t numregs, cbTransaction cb, uint8_t unit) { \
|
||
if (numregs < 0x0001 || numregs > MAXNUM) return false; \
|
||
this->readSlave(offset, numregs, Modbus::FUNC); \
|
||
return this->send(ip, REG(offset), cb, unit, (uint8_t*)value); \
|
||
}
|
||
IMPLEMENT_READREGS(readCoil, COIL, FC_READ_COILS, MODBUS_MAX_BITS, bool)
|
||
IMPLEMENT_READREGS(readHreg, HREG, FC_READ_REGS, MODBUS_MAX_WORDS, uint16_t)
|
||
IMPLEMENT_READREGS(readIsts, ISTS, FC_READ_INPUT_STAT, MODBUS_MAX_BITS, bool)
|
||
IMPLEMENT_READREGS(readIreg, IREG, FC_READ_INPUT_REGS, MODBUS_MAX_WORDS, uint16_t)
|
||
|
||
#if defined(MODBUS_ADD_REG)
|
||
#define ADDREG(R) this->addReg(R(to), (uint16_t)0, numregs);
|
||
#else
|
||
#define ADDREG(R) ;
|
||
#endif
|
||
#define IMPLEMENT_PULL(FNAME, REG, FUNC, MAXNUM) \
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::FNAME(TYPEID ip, uint16_t from, uint16_t to, uint16_t numregs, cbTransaction cb, uint8_t unit) { \
|
||
if (numregs < 0x0001 || numregs > MAXNUM) return false; \
|
||
ADDREG(REG) \
|
||
this->readSlave(from, numregs, Modbus::FUNC); \
|
||
return this->send(ip, REG(to), cb, unit); \
|
||
}
|
||
IMPLEMENT_PULL(pullCoil, COIL, FC_READ_COILS, MODBUS_MAX_BITS)
|
||
IMPLEMENT_PULL(pullIsts, ISTS, FC_READ_INPUT_STAT, MODBUS_MAX_BITS)
|
||
IMPLEMENT_PULL(pullHreg, HREG, FC_READ_REGS, MODBUS_MAX_WORDS)
|
||
IMPLEMENT_PULL(pullIreg, IREG, FC_READ_INPUT_REGS, MODBUS_MAX_WORDS)
|
||
IMPLEMENT_PULL(pullHregToIreg, IREG, FC_READ_REGS, MODBUS_MAX_WORDS)
|
||
IMPLEMENT_PULL(pullCoilToIsts, ISTS, FC_READ_COILS, MODBUS_MAX_BITS)
|
||
|
||
#define IMPLEMENT_PUSH(FNAME, REG, FUNC, MAXNUM, FINT) \
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::FNAME(TYPEID ip, uint16_t to, uint16_t from, uint16_t numregs, cbTransaction cb, uint8_t unit) { \
|
||
if (numregs < 0x0001 || numregs > MAXNUM) return false; \
|
||
if (!this->searchRegister(REG(from))) return false; \
|
||
this->FINT(REG(from), to, numregs, Modbus::FUNC); \
|
||
return this->send(ip, REG(from), cb, unit); \
|
||
}
|
||
IMPLEMENT_PUSH(pushCoil, COIL, FC_WRITE_COILS, MODBUS_MAX_BITS, writeSlaveBits)
|
||
IMPLEMENT_PUSH(pushHreg, HREG, FC_WRITE_REGS, MODBUS_MAX_WORDS, writeSlaveWords)
|
||
IMPLEMENT_PUSH(pushIregToHreg, IREG, FC_WRITE_REGS, MODBUS_MAX_WORDS, writeSlaveWords)
|
||
IMPLEMENT_PUSH(pushIstsToCoil, ISTS, FC_WRITE_COILS, MODBUS_MAX_BITS, writeSlaveBits)
|
||
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::read(TYPEID id, TAddress reg, uint16_t* value, uint16_t numregs, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::HREG:
|
||
return readHreg(id, reg.address, value, numregs, cb, unit);
|
||
case TAddress::IREG:
|
||
return readIreg(id, reg.address, value, numregs, cb, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::read(TYPEID id, TAddress reg, bool* value, uint16_t numregs, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::COIL:
|
||
return readCoil(id, reg.address, value, numregs, cb, unit);
|
||
case TAddress::ISTS:
|
||
return readIsts(id, reg.address, value, numregs, cb, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::write(TYPEID id, TAddress reg, uint16_t value, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::COIL:
|
||
return writeCoil(id, reg.address, value, cb, unit);
|
||
case TAddress::HREG:
|
||
return writeHreg(id, reg.address, value, cb, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::write(TYPEID id, TAddress reg, bool value, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::COIL:
|
||
return writeCoil(id, reg.address, value, cb, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::write(TYPEID id, TAddress reg, uint16_t* value, uint16_t numregs, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::COIL:
|
||
return writeCoil(id, reg.address, value, numregs, cb, unit);
|
||
case TAddress::HREG:
|
||
return writeHreg(id, reg.address, value, numregs, cb, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::write(TYPEID id, TAddress reg, bool* value, uint16_t numregs, cbTransaction cb, uint8_t unit) {
|
||
switch (reg.type) {
|
||
case TAddress::COIL:
|
||
return writeCoil(id, reg.address, value, cb, numregs, unit);
|
||
default:
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
template <class T> \
|
||
bool ModbusAPI<T>::addHreg(uint16_t offset, uint16_t value, uint16_t numregs) {
|
||
return this->addReg(HREG(offset), value, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Hreg(uint16_t offset, uint16_t value) {
|
||
return this->Reg(HREG(offset), value);
|
||
}
|
||
template <class T> \
|
||
uint16_t ModbusAPI<T>::Hreg(uint16_t offset) {
|
||
return this->Reg(HREG(offset));
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeHreg(uint16_t offset, uint16_t numregs) {
|
||
return this->removeReg(HREG(offset), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::addCoil(uint16_t offset, bool value, uint16_t numregs) {
|
||
return this->addReg(COIL(offset), COIL_VAL(value), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::addIsts(uint16_t offset, bool value, uint16_t numregs) {
|
||
return this->addReg(ISTS(offset), ISTS_VAL(value), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::addIreg(uint16_t offset, uint16_t value, uint16_t numregs) {
|
||
return this->addReg(IREG(offset), value, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Coil(uint16_t offset, bool value) {
|
||
return this->Reg(COIL(offset), COIL_VAL(value));
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Ists(uint16_t offset, bool value) {
|
||
return this->Reg(ISTS(offset), ISTS_VAL(value));
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Ireg(uint16_t offset, uint16_t value) {
|
||
return this->Reg(IREG(offset), value);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Coil(uint16_t offset) {
|
||
return COIL_BOOL(this->Reg(COIL(offset)));
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::Ists(uint16_t offset) {
|
||
return ISTS_BOOL(this->Reg(ISTS(offset)));
|
||
}
|
||
template <class T> \
|
||
uint16_t ModbusAPI<T>::Ireg(uint16_t offset) {
|
||
return this->Reg(IREG(offset));
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeCoil(uint16_t offset, uint16_t numregs) {
|
||
return this->removeReg(COIL(offset), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeIsts(uint16_t offset, uint16_t numregs) {
|
||
return this->removeReg(ISTS(offset), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeIreg(uint16_t offset, uint16_t numregs) {
|
||
return this->removeReg(IREG(offset), numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onGet(COIL(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onSet(COIL(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onGet(HREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onSet(HREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onGet(ISTS(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onSet(ISTS(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onGet(IREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::onSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->onSet(IREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnGetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnGet(COIL(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnSetCoil(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnSet(COIL(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnGetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnGet(HREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnSetHreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnSet(HREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnGetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnGet(ISTS(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnSetIsts(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnSet(ISTS(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnGetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnGet(IREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
bool ModbusAPI<T>::removeOnSetIreg(uint16_t offset, cbModbus cb, uint16_t numregs) {
|
||
return this->removeOnSet(IREG(offset), cb, numregs);
|
||
}
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::readFileRec(TYPEID slaveId, uint16_t fileNum, uint16_t startRec, uint16_t len, uint8_t* data, cbTransaction cb, uint8_t unit) {
|
||
if (startRec > MODBUS_MAX_FILES) return 0;
|
||
if (!this->readSlaveFile(&fileNum, &startRec, &len, 1, Modbus::FC_READ_FILE_REC)) return 0;
|
||
return this->send(slaveId, NULLREG, cb, unit, data);
|
||
};
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::writeFileRec(TYPEID slaveId, uint16_t fileNum, uint16_t startRec, uint16_t len, uint8_t* data, cbTransaction cb, uint8_t unit) {
|
||
if (startRec > MODBUS_MAX_FILES) return 0;
|
||
if (!this->writeSlaveFile(&fileNum, &startRec, &len, 1, Modbus::FC_WRITE_FILE_REC, data)) return 0;
|
||
return this->send(slaveId, NULLREG, cb, unit);
|
||
};
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::maskHreg(TYPEID slaveId, uint16_t offset, uint16_t andMask, uint16_t orMask, cbTransaction cb, uint8_t unit) {
|
||
free(this->_frame);
|
||
this->_len = 7;
|
||
this->_frame = (uint8_t*) malloc(this->_len);
|
||
this->_frame[0] = Modbus::FC_MASKWRITE_REG;
|
||
this->_frame[1] = offset >> 8;
|
||
this->_frame[2] = offset & 0x00FF;
|
||
this->_frame[3] = andMask >> 8;
|
||
this->_frame[4] = andMask & 0x00FF;
|
||
this->_frame[5] = orMask >> 8;
|
||
this->_frame[6] = orMask & 0x00FF;
|
||
return this->send(slaveId, HREG(offset), cb, unit);
|
||
};
|
||
|
||
template <class T> \
|
||
template <typename TYPEID> \
|
||
uint16_t ModbusAPI<T>::readWriteHreg(TYPEID ip, \
|
||
uint16_t readOffset, uint16_t* readValue, uint16_t readNumregs, \
|
||
uint16_t writeOffset, uint16_t* writeValue, uint16_t writeNumregs, \
|
||
cbTransaction cb, uint8_t unit) {
|
||
const uint8_t _header = 10;
|
||
if (readNumregs < 0x0001 || readNumregs > MODBUS_MAX_WORDS || writeNumregs < 0x0001 || writeNumregs > 0X0079 || !readValue || !writeValue) return 0;
|
||
|
||
free(this->_frame);
|
||
this->_len = _header + 2 * writeNumregs;
|
||
this->_frame = (uint8_t*) malloc(this->_len);
|
||
if (!this->_frame) {
|
||
this->_reply = Modbus::REPLY_OFF;
|
||
return 0;
|
||
}
|
||
this->_frame[0] = Modbus::FC_READWRITE_REGS;
|
||
this->_frame[1] = readOffset >> 8;
|
||
this->_frame[2] = readOffset & 0x00FF;
|
||
this->_frame[3] = readNumregs >> 8;
|
||
this->_frame[4] = readNumregs & 0x00FF;
|
||
|
||
this->_frame[5] = writeOffset >> 8;
|
||
this->_frame[6] = writeOffset & 0x00FF;
|
||
this->_frame[7] = writeNumregs >> 8;
|
||
this->_frame[8] = writeNumregs & 0x00FF;
|
||
this->_frame[9] = this->_len - _header;
|
||
|
||
uint16_t* frame = (uint16_t*)(this->_frame + _header);
|
||
for (uint8_t i = 0; i < writeNumregs; i++) {
|
||
frame[i] = __swap_16(writeValue[i]);
|
||
}
|
||
return this->send(ip, HREG(readOffset), cb, unit, (uint8_t*)readValue);
|
||
};
|
||
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::rawRequest(TYPEID ip, \
|
||
const uint8_t* data, uint16_t len,
|
||
cbTransaction cb, uint8_t unit) {
|
||
free(this->_frame);
|
||
this->_frame = (uint8_t*)malloc(len);
|
||
if (!this->_frame)
|
||
return 0;
|
||
this->_len = len;
|
||
memcpy(this->_frame, data, len);
|
||
return this->send(ip, NULLREG, cb, unit);
|
||
};
|
||
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::rawResponce(TYPEID ip, \
|
||
const uint8_t* data, uint16_t len, uint8_t unit) {
|
||
free(this->_frame);
|
||
this->_frame = (uint8_t*)malloc(len);
|
||
if (!this->_frame)
|
||
return 0;
|
||
this->_len = len;
|
||
memcpy(this->_frame, data, len);
|
||
return this->send(ip, NULLREG, nullptr, unit, nullptr, false);
|
||
};
|
||
|
||
template <class T>
|
||
template <typename TYPEID>
|
||
uint16_t ModbusAPI<T>::errorResponce(TYPEID ip, Modbus::FunctionCode fn, Modbus::ResultCode excode, uint8_t unit) {
|
||
this->exceptionResponse(fn, excode);
|
||
return this->send(ip, NULLREG, nullptr, unit, nullptr, false);
|
||
}
|