diff --git a/src/Comms/AuxDevice.cpp b/src/Comms/AuxDevice.cpp index d232646ef..99961711f 100644 --- a/src/Comms/AuxDevice.cpp +++ b/src/Comms/AuxDevice.cpp @@ -42,7 +42,10 @@ void AuxDevice::SetMode(AuxMode p_mode) noexcept #if SUPPORT_MODBUS_RTU uart->SetOnTxEndedCallback((p_mode == AuxMode::device) ? GlobalTxEndedCallback : nullptr, CallbackParameter(this)); #endif - uart->begin(baudRate); + AsyncSerial::UARTModes config = AsyncSerial::Mode_8N1; + if (serialParity == SerialParity::even) { config = AsyncSerial::Mode_8E1; } + else if (serialParity == SerialParity::odd) { config = AsyncSerial::Mode_8O1; } + uart->begin(baudRate, config); mode = p_mode; } } diff --git a/src/Comms/AuxDevice.h b/src/Comms/AuxDevice.h index e8ec93129..bcac73859 100644 --- a/src/Comms/AuxDevice.h +++ b/src/Comms/AuxDevice.h @@ -31,11 +31,14 @@ class AsyncSerial; class AuxDevice { public: + enum class SerialParity : uint8_t { none = 0, even, odd }; + AuxDevice() noexcept; void Init(AsyncSerial *p_uart, uint32_t p_baudRate) noexcept; bool IsEnabledForGCodeIo() const noexcept { return mode == AuxMode::raw || mode == AuxMode::panelDue; } void SetMode(AuxMode p_mode) noexcept; + void SetSerialParity(SerialParity p_parity) noexcept { serialParity = p_parity; } // applied on next SetMode; affects device/Modbus mode only void SetBaudRate(uint32_t p_baudRate) noexcept { baudRate = p_baudRate; } // must call SetMode after calling this to actually change the baud rate void Disable() noexcept; AuxMode GetMode() const noexcept { return mode; } @@ -91,6 +94,8 @@ class AuxDevice uint32_t baudRate; AuxMode mode = AuxMode::disabled; // whether disabled, raw, PanelDue mode or Modbus RTU mode + SerialParity serialParity = SerialParity::none; // device/Modbus serial parity: none=8N1, even=8E1, odd=8O1 + #if SUPPORT_MODBUS_RTU IoPort txNotRx; // port used to switch the RS485 port between transmit and receive uint8_t *_ecv_array receivedData; diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 72e30816b..41871d8b7 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -2303,6 +2303,14 @@ GCodeResult Platform::HandleM575(GCodeBuffer& gb, const StringRef& reply) THROWS } } # endif + // Serial parity for device/Modbus mode. Always applied so that omitting F restores + // the pre-existing behaviour (no parity, 8N1) rather than keeping a previous setting. + switch (gb.Seen('F') ? gb.GetLimitedUIValue('F', 3) : 0) + { + case 1: dev.SetSerialParity(AuxDevice::SerialParity::even); break; + case 2: dev.SetSerialParity(AuxDevice::SerialParity::odd); break; + default: dev.SetSerialParity(AuxDevice::SerialParity::none); break; + } # endif }