Added STM32 platform for debugging and development
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
#include "RS485_driver.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <machine/endian.h>
|
||||
#ifdef ESP32
|
||||
#include <endian.h>
|
||||
#else
|
||||
#define be16toh(x) __bswap16(x)
|
||||
#define htobe16(x) __bswap16(x)
|
||||
#define htole16(x) x
|
||||
#endif
|
||||
|
||||
uint8_t data[][8] = {
|
||||
// ESP32-S3-POE-ETH-8DI-8RO Control Command (RS485 receiving data)
|
||||
@@ -37,14 +44,23 @@ namespace drivers
|
||||
//////////// RS485 ////////////
|
||||
////////////////////////////////
|
||||
|
||||
#ifdef ESP32
|
||||
RS485::RS485(const uint32_t baud, const SerialConfig conf)
|
||||
{
|
||||
log_i("Init serial port 1");
|
||||
LOG_INFO("Init serial port 1");
|
||||
m_serial = std::make_unique<HardwareSerial>(PORT); // RS485 is hardwired to serial port 1
|
||||
m_serial->begin(baud, conf);
|
||||
m_serial->setMode(UART_MODE_RS485_HALF_DUPLEX);
|
||||
}
|
||||
#else
|
||||
|
||||
RS485::RS485(const uint32_t baud)
|
||||
{
|
||||
LOG_INFO("Init serial port 1");
|
||||
m_serial = std::make_unique<HardwareSerial>(PORT); // RS485 is hardwired to serial port 1
|
||||
m_serial->begin(baud);
|
||||
}
|
||||
#endif
|
||||
const bool RS485::write(const std::vector<uint8_t> data)
|
||||
{
|
||||
return data.size() == m_serial->write(data.data(), data.size());
|
||||
@@ -75,17 +91,22 @@ namespace drivers
|
||||
////////////////////////////////
|
||||
//////////// MODBUS ////////////
|
||||
////////////////////////////////
|
||||
|
||||
#ifdef ESP32
|
||||
MODBUS::MODBUS(const uint32_t baud, const SerialConfig conf) : RS485::RS485(baud, conf)
|
||||
{
|
||||
log_i("Init MODBUS Master Mode");
|
||||
LOG_INFO("Init MODBUS Master Mode");
|
||||
}
|
||||
|
||||
#else
|
||||
MODBUS::MODBUS(const uint32_t baud) : RS485::RS485(baud)
|
||||
{
|
||||
LOG_INFO("Init MODBUS Master Mode");
|
||||
}
|
||||
#endif
|
||||
// Func 0x01
|
||||
const bool MODBUS::readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector<bool> &coils)
|
||||
{
|
||||
constexpr uint8_t func = 0x01;
|
||||
log_d("Read coils: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
LOG_DEBUG("Read coils: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
return readBinary(func, device, reg, num, coils);
|
||||
}
|
||||
|
||||
@@ -93,7 +114,7 @@ namespace drivers
|
||||
const bool MODBUS::readInputs(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<bool> &inputs)
|
||||
{
|
||||
constexpr uint8_t func = 0x01;
|
||||
log_d("Read multi inputs: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
LOG_DEBUG("Read multi inputs: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
return readBinary(func, device, reg, num, inputs);
|
||||
}
|
||||
|
||||
@@ -101,7 +122,7 @@ namespace drivers
|
||||
const bool MODBUS::readHoldingRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
||||
{
|
||||
constexpr uint8_t func = 0x03;
|
||||
log_d("Read multi holding registers: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
LOG_DEBUG("Read multi holding registers: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
return readInteger(func, device, reg, num, values);
|
||||
}
|
||||
|
||||
@@ -109,7 +130,7 @@ namespace drivers
|
||||
const bool MODBUS::readInputRegisters(const uint8_t device, const uint16_t reg, const uint8_t num, std::vector<uint16_t> &values)
|
||||
{
|
||||
constexpr uint8_t func = 0x04;
|
||||
log_d("Read multi input registers: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
LOG_DEBUG("Read multi input registers: dev[%02x], reg[%04x], num[%d]", device, reg, num);
|
||||
return readInteger(func, device, reg, num, values);
|
||||
}
|
||||
|
||||
@@ -117,7 +138,7 @@ namespace drivers
|
||||
const bool MODBUS::writeCoil(const uint8_t device, const uint16_t coil, const bool value)
|
||||
{
|
||||
constexpr uint8_t func = 0x05;
|
||||
log_d("Write single coil: dev[%02x], reg[%04x], val[...]", device, reg);
|
||||
LOG_DEBUG("Write single coil: dev[%02x], reg[%04x], val[...]", device, coil);
|
||||
return writeBinary(device, func, coil, 1, {value});
|
||||
}
|
||||
|
||||
@@ -125,7 +146,7 @@ namespace drivers
|
||||
const bool MODBUS::writeRegister(const uint8_t device, const uint16_t reg, const uint16_t value)
|
||||
{
|
||||
constexpr uint8_t func = 0x06;
|
||||
log_d("Write single register: dev[%02x], reg[%04x], val[%04x]", device, reg, value);
|
||||
LOG_DEBUG("Write single register: dev[%02x], reg[%04x], val[%04x]", device, reg, value);
|
||||
return writeInteger(device, func, reg, 1, {value});
|
||||
}
|
||||
|
||||
@@ -133,7 +154,7 @@ namespace drivers
|
||||
const bool MODBUS::writeCoils(const uint8_t device, const uint16_t coils, const std::vector<bool> &values)
|
||||
{
|
||||
constexpr uint8_t func = 0x0F;
|
||||
log_d("Write multi coils: dev[%02x], reg[%04x], val[...]", device, reg);
|
||||
LOG_DEBUG("Write multi coils: dev[%02x], reg[%04x], val[...]", device, coils);
|
||||
return writeBinary(device, func, coils, values.size(), values);
|
||||
}
|
||||
|
||||
@@ -141,7 +162,7 @@ namespace drivers
|
||||
const bool MODBUS::writeRegisters(const uint8_t device, const uint16_t reg, const std::vector<uint16_t> &values)
|
||||
{
|
||||
constexpr uint8_t func = 0x10;
|
||||
log_d("Write multi registers: dev[%02x], reg[%04x], val[...]", device, reg);
|
||||
LOG_DEBUG("Write multi registers: dev[%02x], reg[%04x], val[...]", device, reg);
|
||||
return writeInteger(device, func, reg, values.size(), values);
|
||||
}
|
||||
|
||||
@@ -153,22 +174,22 @@ namespace drivers
|
||||
{
|
||||
if (!write(singleRequest(device, func, reg, bits)))
|
||||
{
|
||||
log_e("Failed send readBinary command");
|
||||
LOG_ERROR("Failed send readBinary command");
|
||||
return false;
|
||||
}
|
||||
const uint16_t nRespDataBytes = 1 + (uint16_t)(bits / 8); // 1 bit for every coil, if not 8 mutiple padded with zeroes
|
||||
const uint16_t nRespDataBytes = 1 + (uint16_t)(bits / 8); // 1 bit for every coil, if not 8 mutiple padded with zeroes
|
||||
const uint16_t expectedRespLen = (RESP_HEADER_SIZE + RESP_CRC_SIZE) + nRespDataBytes; // device + function + nbytes + data[] + crc(16b)
|
||||
std::vector<uint8_t> response;
|
||||
if (!readN(expectedRespLen, response))
|
||||
{
|
||||
log_e("Failed receive readBinary response");
|
||||
LOG_ERROR("Failed receive readBinary response");
|
||||
return false;
|
||||
}
|
||||
|
||||
// element 2 of response has the response data bytes expected
|
||||
if (response.at(2) != nRespDataBytes)
|
||||
{
|
||||
log_e("Failed receive, data to short: bytes[%d], expected[%d]", response.at(2), nRespDataBytes);
|
||||
LOG_ERROR("Failed receive, data to short: bytes[%d], expected[%d]", response.at(2), nRespDataBytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -200,7 +221,7 @@ namespace drivers
|
||||
{
|
||||
if (!write(singleRequest(device, func, reg, num)))
|
||||
{
|
||||
log_e("Failed send readInteger command");
|
||||
LOG_ERROR("Failed send readInteger command");
|
||||
return false;
|
||||
}
|
||||
const uint16_t nRespDataBytes = num * sizeof(uint16_t);
|
||||
@@ -208,14 +229,14 @@ namespace drivers
|
||||
std::vector<uint8_t> response;
|
||||
if (!readN(expectedRespLen, response))
|
||||
{
|
||||
log_e("Failed receive readInteger response");
|
||||
LOG_ERROR("Failed receive readInteger response");
|
||||
return false;
|
||||
}
|
||||
|
||||
// element 2 of response has the response data bytes expected
|
||||
if (response.at(2) != nRespDataBytes)
|
||||
{
|
||||
log_e("Failed receive, data to short: bytes[%d], expected[%d]", response.at(2), nRespDataBytes);
|
||||
LOG_ERROR("Failed receive, data to short: bytes[%d], expected[%d]", response.at(2), nRespDataBytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -260,7 +281,7 @@ namespace drivers
|
||||
|
||||
if (!write(multiRequest(device, func, reg, bits, bitsOut)))
|
||||
{
|
||||
log_e("Failed send writeBinary command");
|
||||
LOG_ERROR("Failed send writeBinary command");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -268,7 +289,7 @@ namespace drivers
|
||||
std::vector<uint8_t> response;
|
||||
if (!readN(expectedRespLen, response))
|
||||
{
|
||||
log_e("Failed receive writeBinary response");
|
||||
LOG_ERROR("Failed receive writeBinary response");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -283,7 +304,7 @@ namespace drivers
|
||||
{
|
||||
if (!write(multiRequest(device, func, reg, num, in)))
|
||||
{
|
||||
log_e("Failed send writeInteger command");
|
||||
LOG_ERROR("Failed send writeInteger command");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -291,7 +312,7 @@ namespace drivers
|
||||
std::vector<uint8_t> response;
|
||||
if (!readN(expectedRespLen, response))
|
||||
{
|
||||
log_e("Failed receive writeInteger response");
|
||||
LOG_ERROR("Failed receive writeInteger response");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -371,7 +392,7 @@ namespace drivers
|
||||
// verify crc code
|
||||
if (highByte(computedCrc) != crcHi || lowByte(computedCrc) != crcLo)
|
||||
{
|
||||
log_e("Failed verify CRC code: comp[%04x], rec[%04x]", computedCrc, 0xFFFF & ((crcHi << 8) | crcLo));
|
||||
LOG_ERROR("Failed verify CRC code: comp[%04x], rec[%04x]", computedCrc, 0xFFFF & ((crcHi << 8) | crcLo));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <HardwareSerial.h> // Reference the ESP32 built-in serial port library
|
||||
#include <DebugLog.h>
|
||||
#include <Arduino.h>
|
||||
#include <HardwareSerial.h> // Reference the ESP32 built-in serial port library
|
||||
#include <CRC16.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -23,8 +24,11 @@ namespace drivers
|
||||
static const uint8_t PORT = 1;
|
||||
|
||||
public:
|
||||
#ifdef ESP32
|
||||
RS485(const uint32_t baud, const SerialConfig conf);
|
||||
|
||||
#else
|
||||
RS485(const uint32_t baud);
|
||||
#endif
|
||||
const bool write(const std::vector<uint8_t> data);
|
||||
const bool readAll(std::vector<uint8_t> &data);
|
||||
const bool readN(const uint16_t nBytes, std::vector<uint8_t> &data);
|
||||
@@ -61,7 +65,11 @@ namespace drivers
|
||||
typedef uint16_t crc_t;
|
||||
|
||||
public:
|
||||
#ifdef ESP32
|
||||
MODBUS(const uint32_t baud, const SerialConfig conf);
|
||||
#else
|
||||
MODBUS(const uint32_t baud);
|
||||
#endif
|
||||
|
||||
// Func 0x01
|
||||
const bool readCoils(const uint8_t device, const uint16_t reg, const uint16_t num, std::vector<bool> &coils);
|
||||
|
||||
Reference in New Issue
Block a user