Skip to content

Commit

Permalink
Implemented M260.4
Browse files Browse the repository at this point in the history
Also added receive data variable support to M260[.0]
  • Loading branch information
dc42 committed Nov 26, 2024
1 parent 1f54bb5 commit 86388be
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 120 deletions.
107 changes: 76 additions & 31 deletions src/Comms/AuxDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,40 @@ GCodeResult AuxDevice::ReadModbusRegisters(uint8_t p_slaveAddress, uint8_t p_fun
return GCodeResult::ok;
}

GCodeResult AuxDevice::ModbusRawTransaction(uint8_t p_slaveAddress, const uint8_t *_ecv_array rawDataOut, size_t numOut, uint8_t *_ecv_array rawDataIn, size_t numIn) noexcept
{
if (!mutex.Take(BusAvailableTimeout))
{
return GCodeResult::error;
}

uart->ClearTransmitBuffer();
uart->DisableTransmit();
crc.Reset(ModbusCrcInit);
bytesTransmitted = 0;

slaveAddress = p_slaveAddress;
ModbusWriteByte(slaveAddress);
function = ModbusFunction::generic;
while (numOut != 0)
{
ModbusWriteByte(*rawDataOut++);
--numOut;
}
uart->write((uint8_t)crc.Get());
uart->write((uint8_t)(crc.Get() >> 8));

txNotRx.WriteDigital(true); // set port to transmit
delay(CalcTransmissionTime(4)); // Modbus specifies a 3.5 character interval
uart->ClearReceiveBuffer();
uart->EnableTransmit();
whenStartedTransmitting = millis();

bytesExpected = numIn + 3;
receivedData = rawDataIn;
return GCodeResult::ok;
}

// Check whether the Modbus operation completed.
GCodeResult AuxDevice::CheckModbusResult() noexcept
{
Expand All @@ -339,48 +373,59 @@ GCodeResult AuxDevice::CheckModbusResult() noexcept

// If we get here then we received sufficient bytes for a valid reply
crc.Reset(ModbusCrcInit);
if (ModbusReadByte() == slaveAddress && ModbusReadByte() == (uint8_t)function)
if (ModbusReadByte() == slaveAddress)
{
switch(function)
if (function == ModbusFunction::generic)
{
case ModbusFunction::writeSingleCoil:
case ModbusFunction::writeSingleRegister:
case ModbusFunction::writeMultipleCoils:
case ModbusFunction::writeMultipleRegisters:
if (ModbusReadWord() == startRegister && ModbusReadWord() == numRegistersOrDataWord)
for (size_t i = 0; i + 3 < bytesExpected; ++i)
{
return ReleaseMutexAndCheckCrc();
*receivedData++ = ModbusReadByte();
}
break;

case ModbusFunction::readCoils:
case ModbusFunction::readDiscreteInputs:
if (ModbusReadByte() == (numRegistersOrDataWord + 7u)/8u)
return ReleaseMutexAndCheckCrc();
}
else if (ModbusReadByte() == (uint8_t)function)
{
switch(function)
{
for (size_t i = 0; i < (numRegistersOrDataWord + 7u)/8u; ++i)
case ModbusFunction::writeSingleCoil:
case ModbusFunction::writeSingleRegister:
case ModbusFunction::writeMultipleCoils:
case ModbusFunction::writeMultipleRegisters:
if (ModbusReadWord() == startRegister && ModbusReadWord() == numRegistersOrDataWord)
{
*receivedData++ = ModbusReadByte();
return ReleaseMutexAndCheckCrc();
}
return ReleaseMutexAndCheckCrc();
}
break;
break;

case ModbusFunction::readInputRegisters:
case ModbusFunction::readHoldingRegisters:
if (ModbusReadByte() == 2 * numRegistersOrDataWord)
{
while (numRegistersOrDataWord != 0)
case ModbusFunction::readCoils:
case ModbusFunction::readDiscreteInputs:
if (ModbusReadByte() == (numRegistersOrDataWord + 7u)/8u)
{
*(uint16_t*)receivedData = ModbusReadWord();
receivedData += sizeof(uint16_t);
--numRegistersOrDataWord;
for (size_t i = 0; i < (numRegistersOrDataWord + 7u)/8u; ++i)
{
*receivedData++ = ModbusReadByte();
}
return ReleaseMutexAndCheckCrc();
}
return ReleaseMutexAndCheckCrc();
}
break;
break;

default:
break;
case ModbusFunction::readInputRegisters:
case ModbusFunction::readHoldingRegisters:
if (ModbusReadByte() == 2 * numRegistersOrDataWord)
{
while (numRegistersOrDataWord != 0)
{
*(uint16_t*)receivedData = ModbusReadWord();
receivedData += sizeof(uint16_t);
--numRegistersOrDataWord;
}
return ReleaseMutexAndCheckCrc();
}
break;

default:
break;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/Comms/AuxDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class AuxDevice
GCodeResult SendModbusRegisters(uint8_t p_slaveAddress, uint8_t p_function, uint16_t p_startRegister, uint16_t p_numRegisters, const uint8_t *_ecv_array data) noexcept;
GCodeResult ReadModbusRegisters(uint8_t p_slaveAddress, uint8_t p_function, uint16_t p_startRegister, uint16_t p_numRegisters, uint8_t *_ecv_array data) noexcept
pre(function == 3 || function == 4);
GCodeResult ModbusRawTransaction(uint8_t p_slaveAddress, const uint8_t *_ecv_array rawDataOut, size_t numOut, uint8_t *_ecv_array rawDataIn, size_t numIn) noexcept;
GCodeResult CheckModbusResult() noexcept;

void TxEndedCallback() noexcept;
Expand Down
6 changes: 4 additions & 2 deletions src/Comms/Modbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <cstdint>

// Modbus RTU function codes
enum class ModbusFunction : uint8_t
enum class ModbusFunction : uint16_t
{
readCoils = 0x01,
readDiscreteInputs = 0x02,
Expand All @@ -22,7 +22,9 @@ enum class ModbusFunction : uint8_t
writeMultipleCoils = 0x0F,
writeMultipleRegisters = 0x10,
readDeviceId1 = 0x0E,
readDeviceId2 = 0x2B
readDeviceId2 = 0x2B,

generic = 0x100
};

#endif /* SRC_COMMS_MODBUS_H_ */
12 changes: 11 additions & 1 deletion src/GCodes/GCodeBuffer/GCodeBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ uint32_t GCodeBuffer::GetUIValue() THROWS(GCodeException)
return PARSER_OPERATION(GetUIValue());
}

// Get an unsigned integer value, throw if >= limit
// Get an unsigned integer value, throw if >= limit or the parameter letter is not seen
uint32_t GCodeBuffer::GetLimitedUIValue(char c, uint32_t minValue, uint32_t maxValuePlusOne) THROWS(GCodeException)
{
MustSee(c);
Expand Down Expand Up @@ -1392,6 +1392,16 @@ void GCodeBuffer::ThrowGCodeException(const char *_ecv_array msg, uint32_t param
throw GCodeException(this, column, msg, param);
}

[[noreturn]] void GCodeBuffer::ThrowGCodeException(const char *_ecv_array msg, const char *_ecv_array param) const THROWS(GCodeException)
{
const int column =
#if HAS_SBC_INTERFACE
(isBinaryBuffer) ? -1 :
#endif
stringParser.GetColumn();
throw GCodeException(this, column, msg, param);
}

#if SUPPORT_COORDINATE_ROTATION

bool GCodeBuffer::DoingCoordinateRotation() const noexcept
Expand Down
1 change: 1 addition & 0 deletions src/GCodes/GCodeBuffer/GCodeBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ class GCodeBuffer final INHERIT_OBJECT_MODEL

[[noreturn]] void ThrowGCodeException(const char *_ecv_array msg) const THROWS(GCodeException);
[[noreturn]] void ThrowGCodeException(const char *_ecv_array msg, uint32_t param) const THROWS(GCodeException);
[[noreturn]] void ThrowGCodeException(const char *_ecv_array msg, const char *_ecv_array param) const THROWS(GCodeException);

#if SUPPORT_COORDINATE_ROTATION
bool DoingCoordinateRotation() const noexcept;
Expand Down
Loading

0 comments on commit 86388be

Please sign in to comment.