Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2020-04-20 17:39:53 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-04-20 17:39:53 +0300
commitf33d299919ca83729da74d4ebcef48c66d9a007d (patch)
tree03e39a6a2a0195e6d44bc119a8e5eab34047ebd2
parent669b2fb36307dbb57e3686f1eaa5b12f89f640f9 (diff)
Changes to PanelDue output code, add GpOut ports to OM
Suppress empty responses to PanelDue Discard responses that PanelDue indicates that it isn't interested in Added state.gpOut array Renamed sensors.inputs to sensors.gpIn and return null array element for unconfigured inputs
-rw-r--r--src/Endstops/EndstopsManager.cpp11
-rw-r--r--src/Endstops/EndstopsManager.h2
-rw-r--r--src/GCodes/GCodes.cpp2
-rw-r--r--src/GCodes/GCodes2.cpp4
-rw-r--r--src/GPIO/GpInPort.cpp146
-rw-r--r--src/GPIO/GpInPort.h (renamed from src/GPIO/GpioPorts.h)33
-rw-r--r--src/GPIO/GpOutPort.cpp (renamed from src/GPIO/GpioPorts.cpp)125
-rw-r--r--src/GPIO/GpOutPort.h47
-rw-r--r--src/Platform.cpp17
-rw-r--r--src/Platform.h10
-rw-r--r--src/RepRap.cpp32
-rw-r--r--src/RepRap.h1
-rw-r--r--src/Version.h2
13 files changed, 268 insertions, 164 deletions
diff --git a/src/Endstops/EndstopsManager.cpp b/src/Endstops/EndstopsManager.cpp
index e58d2db3..253961c6 100644
--- a/src/Endstops/EndstopsManager.cpp
+++ b/src/Endstops/EndstopsManager.cpp
@@ -62,12 +62,15 @@ constexpr ObjectModelArrayDescriptor EndstopsManager::filamentMonitorsArrayDescr
[] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue(FilamentMonitor::GetMonitorAlreadyLocked(context.GetLastIndex())); }
};
-constexpr ObjectModelArrayDescriptor EndstopsManager::inputsArrayDescriptor =
+constexpr ObjectModelArrayDescriptor EndstopsManager::gpinArrayDescriptor =
{
nullptr,
- [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return reprap.GetPlatform().GetNumInputsToReport(); },
+ [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return reprap.GetPlatform().GetNumGpInputsToReport(); },
[] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue
- { return ExpressionValue(&reprap.GetPlatform().GetGpInPort(context.GetLastIndex())); }
+ {
+ const GpInputPort& port = reprap.GetPlatform().GetGpInPort(context.GetLastIndex());
+ return (port.IsUnused()) ? ExpressionValue(nullptr) : ExpressionValue(&port);
+ }
};
constexpr ObjectModelArrayDescriptor EndstopsManager::probesArrayDescriptor =
@@ -85,7 +88,7 @@ constexpr ObjectModelTableEntry EndstopsManager::objectModelTable[] =
{ "analog", OBJECT_MODEL_FUNC_NOSELF(&sensorsArrayDescriptor), ObjectModelEntryFlags::live },
{ "endstops", OBJECT_MODEL_FUNC_NOSELF(&endstopsArrayDescriptor), ObjectModelEntryFlags::live },
{ "filamentMonitors", OBJECT_MODEL_FUNC_NOSELF(&filamentMonitorsArrayDescriptor), ObjectModelEntryFlags::live },
- { "inputs", OBJECT_MODEL_FUNC_NOSELF(&inputsArrayDescriptor), ObjectModelEntryFlags::live },
+ { "gpIn", OBJECT_MODEL_FUNC_NOSELF(&gpinArrayDescriptor), ObjectModelEntryFlags::live },
{ "probes", OBJECT_MODEL_FUNC_NOSELF(&probesArrayDescriptor), ObjectModelEntryFlags::live },
};
diff --git a/src/Endstops/EndstopsManager.h b/src/Endstops/EndstopsManager.h
index 4a36d0ea..91e50776 100644
--- a/src/Endstops/EndstopsManager.h
+++ b/src/Endstops/EndstopsManager.h
@@ -78,7 +78,7 @@ protected:
OBJECT_MODEL_ARRAY(sensors)
OBJECT_MODEL_ARRAY(endstops)
OBJECT_MODEL_ARRAY(filamentMonitors)
- OBJECT_MODEL_ARRAY(inputs)
+ OBJECT_MODEL_ARRAY(gpin)
OBJECT_MODEL_ARRAY(probes)
private:
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index ecb3b0bb..d321a3e2 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -3380,7 +3380,7 @@ void GCodes::HandleReplyPreserveResult(GCodeBuffer& gb, GCodeResult rslt, const
// Also check that this response was triggered by a gcode
if ( reply[0] == 0
&& ( (gb.MachineState().doingFileMacro && !gb.MachineState().waitingForAcknowledgement) // we must acknowledge M292
- || &gb == fileGCode || &gb == queuedGCode || &gb == triggerGCode || &gb == autoPauseGCode
+ || &gb == fileGCode || &gb == queuedGCode || &gb == triggerGCode || &gb == autoPauseGCode || &gb == auxGCode
)
)
{
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index db87a17a..c64490a8 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -1130,7 +1130,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
const uint32_t gpioPortNumber = gb.GetLimitedUIValue('P', MaxGpOutPorts);
gb.MustSee('S');
- result = platform.GetGpioPort(gpioPortNumber).WriteAnalog(gpioPortNumber, false, gb.GetPwmValue(), gb, reply);
+ result = platform.GetGpOutPort(gpioPortNumber).WriteAnalog(gpioPortNumber, false, gb.GetPwmValue(), gb, reply);
}
break;
@@ -2201,7 +2201,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
}
const float pwm = angleOrWidth * (ServoRefreshFrequency/1e6);
- result = platform.GetGpioPort(gpioPortNumber).WriteAnalog(gpioPortNumber, true, pwm, gb, reply);
+ result = platform.GetGpOutPort(gpioPortNumber).WriteAnalog(gpioPortNumber, true, pwm, gb, reply);
}
break;
diff --git a/src/GPIO/GpInPort.cpp b/src/GPIO/GpInPort.cpp
new file mode 100644
index 00000000..57bd7b4a
--- /dev/null
+++ b/src/GPIO/GpInPort.cpp
@@ -0,0 +1,146 @@
+/*
+ * GpInPort.cpp
+ *
+ * Created on: 11 Feb 2020
+ * Author: David
+ */
+
+#include "GpInPort.h"
+#include <GCodes/GCodeBuffer/GCodeBuffer.h>
+#include <RepRap.h>
+#include <Platform.h>
+
+#if SUPPORT_CAN_EXPANSION
+# include <CAN/CanInterface.h>
+# include <CAN/CanMessageGenericConstructor.h>
+#endif
+
+#if SUPPORT_OBJECT_MODEL
+
+// Object model table and functions
+// Note: if using GCC version 7.3.1 20180622 and lambda functions are used in this table, you must compile this file with option -std=gnu++17.
+// Otherwise the table will be allocated in RAM instead of flash, which wastes too much RAM.
+
+// Macro to build a standard lambda function that includes the necessary type conversions
+#define OBJECT_MODEL_FUNC(...) OBJECT_MODEL_FUNC_BODY(GpInputPort, __VA_ARGS__)
+#define OBJECT_MODEL_FUNC_IF(_condition,...) OBJECT_MODEL_FUNC_IF_BODY(GpInputPort, _condition,__VA_ARGS__)
+
+constexpr ObjectModelTableEntry GpInputPort::objectModelTable[] =
+{
+ // Within each group, these entries must be in alphabetical order
+ // Return 'value' as an integer, not a boolean, because we may allow analog inputs in future
+ { "value", OBJECT_MODEL_FUNC((int32_t)((self->GetState()) ? 1 : 0)), ObjectModelEntryFlags::live },
+};
+
+constexpr uint8_t GpInputPort::objectModelTableDescriptor[] = { 1, 1 };
+
+DEFINE_GET_OBJECT_MODEL_TABLE(GpInputPort)
+
+#endif
+
+bool GpInputPort::GetState() const noexcept
+{
+ // Temporary implementation until we use interrupts to track input pin state changes
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ return currentState;
+ }
+#endif
+ return port.Read();
+}
+
+// Return true if the port is not configured
+bool GpInputPort::IsUnused() const noexcept
+{
+ return
+#if SUPPORT_CAN_EXPANSION
+ boardAddress == CanId::MasterAddress &&
+#endif
+ !port.IsValid();
+}
+
+GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const StringRef &reply)
+{
+ if (gb.Seen('C'))
+ {
+ String<StringLength50> pinName;
+ gb.GetReducedString(pinName.GetRef());
+
+ // Remove any existing assignment
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ const GCodeResult rslt = CanInterface::DeleteHandle(boardAddress, handle, reply);
+ if (rslt != GCodeResult::ok)
+ {
+ reply.cat('\n');
+ const MessageType mtype = (rslt == GCodeResult::warning) ? AddWarning(gb.GetResponseMessageType()) : AddError(gb.GetResponseMessageType());
+ reprap.GetPlatform().Message(mtype, reply.c_str());
+ reply.Clear();
+ }
+ boardAddress = CanId::MasterAddress;
+ }
+#endif
+ port.Release();
+ currentState = false;
+
+ GCodeResult rslt;
+
+#if SUPPORT_CAN_EXPANSION
+ const CanAddress newBoard = IoPort::RemoveBoardAddress(pinName.GetRef());
+ if (newBoard != CanId::MasterAddress)
+ {
+ handle.Set(RemoteInputHandle::typeGpIn, gpinNumber, 0);
+ rslt = CanInterface::CreateHandle(newBoard, handle, pinName.c_str(), 0, MinimumGpinReportInterval, currentState, reply);
+ if (rslt == GCodeResult::ok)
+ {
+ boardAddress = newBoard;
+ }
+ else
+ {
+ currentState = false;
+ }
+ }
+ else
+#endif
+ {
+ if (port.AssignPort(pinName.c_str(), reply, PinUsedBy::gpin, PinAccess::read))
+ {
+ currentState = port.Read();
+ rslt = GCodeResult::ok;
+ }
+ else
+ {
+ rslt = GCodeResult::error;
+ }
+ }
+
+ reprap.InputsUpdated();
+ return rslt;
+ }
+ else
+ {
+ // Report the pin details
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ const GCodeResult rslt = CanInterface::GetHandlePinName(boardAddress, handle, currentState, reply);
+ if (rslt != GCodeResult::ok)
+ {
+ return rslt;
+ }
+ reply.Prepend("Pin ");
+ }
+ else
+#endif
+ {
+ reply.copy("Pin ");
+ port.AppendPinName(reply);
+ }
+ reply.catf(", active: %s", (GetState()) ? "true" : "false");
+ }
+ return GCodeResult::ok;
+}
+
+// End
diff --git a/src/GPIO/GpioPorts.h b/src/GPIO/GpInPort.h
index 30d5a074..7159ff36 100644
--- a/src/GPIO/GpioPorts.h
+++ b/src/GPIO/GpInPort.h
@@ -1,12 +1,12 @@
/*
- * GpioPorts.h
+ * GpInPort.h
*
* Created on: 11 Feb 2020
* Author: David
*/
-#ifndef SRC_GPIO_GPIOPORTS_H_
-#define SRC_GPIO_GPIOPORTS_H_
+#ifndef SRC_GPIO_GPINPORT_H_
+#define SRC_GPIO_GPINPORT_H_
#include <RepRapFirmware.h>
#include <Hardware/IoPorts.h>
@@ -48,29 +48,4 @@ private:
bool currentState;
};
-class GpOutputPort
-{
-public:
- GpOutputPort() noexcept
-#if SUPPORT_CAN_EXPANSION
- : boardAddress(CanId::MasterAddress)
-#endif
- { }
-
- GpOutputPort(const GpOutputPort&) = delete;
-
- GCodeResult WriteAnalog(uint32_t gpioPortNumber, bool isServo, float pwm, const GCodeBuffer& gb, const StringRef& reply) const noexcept;
- GCodeResult Configure(uint32_t gpioNumber, bool isServo, GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException);
-
-#ifdef PCCB
- void Assign(const char *pinName) noexcept;
-#endif
-
-private:
- PwmPort port; // will be initialised by PwmPort default constructor
-#if SUPPORT_CAN_EXPANSION
- CanAddress boardAddress;
-#endif
-};
-
-#endif /* SRC_GPIO_GPIOPORTS_H_ */
+#endif /* SRC_GPIO_GPINPORT_H_ */
diff --git a/src/GPIO/GpioPorts.cpp b/src/GPIO/GpOutPort.cpp
index 20ffa971..51f32c78 100644
--- a/src/GPIO/GpioPorts.cpp
+++ b/src/GPIO/GpOutPort.cpp
@@ -1,11 +1,11 @@
/*
- * GpioPorts.cpp
+ * GpOutPort.cpp
*
* Created on: 11 Feb 2020
* Author: David
*/
-#include "GpioPorts.h"
+#include "GpOutPort.h"
#include <GCodes/GCodeBuffer/GCodeBuffer.h>
#include <RepRap.h>
#include <Platform.h>
@@ -22,37 +22,23 @@
// Otherwise the table will be allocated in RAM instead of flash, which wastes too much RAM.
// Macro to build a standard lambda function that includes the necessary type conversions
-#define OBJECT_MODEL_FUNC(...) OBJECT_MODEL_FUNC_BODY(GpInputPort, __VA_ARGS__)
-#define OBJECT_MODEL_FUNC_IF(_condition,...) OBJECT_MODEL_FUNC_IF_BODY(GpInputPort, _condition,__VA_ARGS__)
+#define OBJECT_MODEL_FUNC(...) OBJECT_MODEL_FUNC_BODY(GpOutputPort, __VA_ARGS__)
+#define OBJECT_MODEL_FUNC_IF(_condition,...) OBJECT_MODEL_FUNC_IF_BODY(GpOutputPort, _condition,__VA_ARGS__)
-constexpr ObjectModelTableEntry GpInputPort::objectModelTable[] =
+constexpr ObjectModelTableEntry GpOutputPort::objectModelTable[] =
{
// Within each group, these entries must be in alphabetical order
- // 0. sensors members
- { "configured", OBJECT_MODEL_FUNC(!self->IsUnused()), ObjectModelEntryFlags::none },
- { "value", OBJECT_MODEL_FUNC_IF(!self->IsUnused(), self->GetState()), ObjectModelEntryFlags::live },
+ { "pwm", OBJECT_MODEL_FUNC(self->lastPwm, 2), ObjectModelEntryFlags::live },
};
-constexpr uint8_t GpInputPort::objectModelTableDescriptor[] = { 1, 2 };
+constexpr uint8_t GpOutputPort::objectModelTableDescriptor[] = { 1, 1 };
-DEFINE_GET_OBJECT_MODEL_TABLE(GpInputPort)
+DEFINE_GET_OBJECT_MODEL_TABLE(GpOutputPort)
#endif
-bool GpInputPort::GetState() const noexcept
-{
- // Temporary implementation until we use interrupts to track input pin state changes
-#if SUPPORT_CAN_EXPANSION
- if (boardAddress != CanId::MasterAddress)
- {
- return currentState;
- }
-#endif
- return port.Read();
-}
-
// Return true if the port is not configured
-bool GpInputPort::IsUnused() const noexcept
+bool GpOutputPort::IsUnused() const noexcept
{
return
#if SUPPORT_CAN_EXPANSION
@@ -61,89 +47,6 @@ bool GpInputPort::IsUnused() const noexcept
!port.IsValid();
}
-GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const StringRef &reply)
-{
- if (gb.Seen('C'))
- {
- String<StringLength50> pinName;
- gb.GetReducedString(pinName.GetRef());
-
- // Remove any existing assignment
-#if SUPPORT_CAN_EXPANSION
- if (boardAddress != CanId::MasterAddress)
- {
- const GCodeResult rslt = CanInterface::DeleteHandle(boardAddress, handle, reply);
- if (rslt != GCodeResult::ok)
- {
- reply.cat('\n');
- const MessageType mtype = (rslt == GCodeResult::warning) ? AddWarning(gb.GetResponseMessageType()) : AddError(gb.GetResponseMessageType());
- reprap.GetPlatform().Message(mtype, reply.c_str());
- reply.Clear();
- }
- boardAddress = CanId::MasterAddress;
- }
-#endif
- port.Release();
- currentState = false;
-
- GCodeResult rslt;
-
-#if SUPPORT_CAN_EXPANSION
- const CanAddress newBoard = IoPort::RemoveBoardAddress(pinName.GetRef());
- if (newBoard != CanId::MasterAddress)
- {
- handle.Set(RemoteInputHandle::typeGpIn, gpinNumber, 0);
- rslt = CanInterface::CreateHandle(newBoard, handle, pinName.c_str(), 0, MinimumGpinReportInterval, currentState, reply);
- if (rslt == GCodeResult::ok)
- {
- boardAddress = newBoard;
- }
- else
- {
- currentState = false;
- }
- }
- else
-#endif
- {
- if (port.AssignPort(pinName.c_str(), reply, PinUsedBy::gpin, PinAccess::read))
- {
- currentState = port.Read();
- rslt = GCodeResult::ok;
- }
- else
- {
- rslt = GCodeResult::error;
- }
- }
-
- reprap.InputsUpdated();
- return rslt;
- }
- else
- {
- // Report the pin details
-#if SUPPORT_CAN_EXPANSION
- if (boardAddress != CanId::MasterAddress)
- {
- const GCodeResult rslt = CanInterface::GetHandlePinName(boardAddress, handle, currentState, reply);
- if (rslt != GCodeResult::ok)
- {
- return rslt;
- }
- reply.Prepend("Pin ");
- }
- else
-#endif
- {
- reply.copy("Pin ");
- port.AppendPinName(reply);
- }
- reply.catf(", active: %s", (GetState()) ? "true" : "false");
- }
- return GCodeResult::ok;
-}
-
GCodeResult GpOutputPort::Configure(uint32_t gpioNumber, bool isServo, GCodeBuffer &gb, const StringRef &reply)
{
PwmFrequency freq = 0;
@@ -207,8 +110,7 @@ GCodeResult GpOutputPort::Configure(uint32_t gpioNumber, bool isServo, GCodeBuff
}
}
- // GPOut pins are not yet in the object model
- // reprap.OutputsUpdated();
+ reprap.StateUpdated();
return rslt;
}
else if (seenFreq)
@@ -219,12 +121,12 @@ GCodeResult GpOutputPort::Configure(uint32_t gpioNumber, bool isServo, GCodeBuff
CanMessageGenericConstructor cons(M950GpioParams);
cons.AddUParam('P', gpioNumber);
cons.AddUParam('Q', freq);
- // reprap.OutputsUpdated();
+ reprap.StateUpdated();
return cons.SendAndGetResponse(CanMessageType::m950Gpio, boardAddress, reply);
}
#endif
port.SetFrequency(freq);
- // reprap.OutputsUpdated();
+ reprap.StateUpdated();
}
else
{
@@ -242,8 +144,9 @@ GCodeResult GpOutputPort::Configure(uint32_t gpioNumber, bool isServo, GCodeBuff
return GCodeResult::ok;
}
-GCodeResult GpOutputPort::WriteAnalog(uint32_t gpioPortNumber, bool isServo, float pwm, const GCodeBuffer& gb, const StringRef& reply) const noexcept
+GCodeResult GpOutputPort::WriteAnalog(uint32_t gpioPortNumber, bool isServo, float pwm, const GCodeBuffer& gb, const StringRef& reply) noexcept
{
+ lastPwm = pwm;
#if SUPPORT_CAN_EXPANSION
if (boardAddress != CanId::MasterAddress)
{
diff --git a/src/GPIO/GpOutPort.h b/src/GPIO/GpOutPort.h
new file mode 100644
index 00000000..fbae879a
--- /dev/null
+++ b/src/GPIO/GpOutPort.h
@@ -0,0 +1,47 @@
+/*
+ * GpOutPort.h
+ *
+ * Created on: 11 Feb 2020
+ * Author: David
+ */
+
+#ifndef SRC_GPIO_GPOUTPORT_H_
+#define SRC_GPIO_GPOUTPORT_H_
+
+#include <RepRapFirmware.h>
+#include <Hardware/IoPorts.h>
+#include <GCodes/GCodeResult.h>
+#include <ObjectModel/ObjectModel.h>
+
+class GpOutputPort INHERIT_OBJECT_MODEL
+{
+public:
+ GpOutputPort() noexcept
+ : lastPwm(0.0)
+#if SUPPORT_CAN_EXPANSION
+ , boardAddress(CanId::MasterAddress)
+#endif
+ { }
+
+ GpOutputPort(const GpOutputPort&) = delete;
+
+ bool IsUnused() const noexcept;
+ GCodeResult WriteAnalog(uint32_t gpioPortNumber, bool isServo, float pwm, const GCodeBuffer& gb, const StringRef& reply) noexcept;
+ GCodeResult Configure(uint32_t gpioNumber, bool isServo, GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException);
+
+#ifdef PCCB
+ void Assign(const char *pinName) noexcept;
+#endif
+
+protected:
+ DECLARE_OBJECT_MODEL
+
+private:
+ PwmPort port; // will be initialised by PwmPort default constructor
+ float lastPwm;
+#if SUPPORT_CAN_EXPANSION
+ CanAddress boardAddress;
+#endif
+};
+
+#endif /* SRC_GPIO_GPOUTPORT_H_ */
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 57e17992..68046549 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -323,7 +323,7 @@ constexpr uint8_t Platform::objectModelTableDescriptor[] =
DEFINE_GET_OBJECT_MODEL_TABLE(Platform)
-size_t Platform::GetNumInputsToReport() const noexcept
+size_t Platform::GetNumGpInputsToReport() const noexcept
{
size_t ret = MaxGpInPorts;
while (ret != 0 && gpinPorts[ret - 1].IsUnused())
@@ -333,6 +333,16 @@ size_t Platform::GetNumInputsToReport() const noexcept
return ret;
}
+size_t Platform::GetNumGpOutputsToReport() const noexcept
+{
+ size_t ret = MaxGpOutPorts;
+ while (ret != 0 && gpoutPorts[ret - 1].IsUnused())
+ {
+ --ret;
+ }
+ return ret;
+}
+
#endif
Platform::Platform() noexcept :
@@ -2012,11 +2022,12 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, Ou
#endif
buf->lcat((testFailed) ? "***** ONE OR MORE CHECKS FAILED *****" : "All checks passed");
- #if SAM4E || SAM4S || SAME70
+#if SAM4E || SAM4S || SAME70
if (!testFailed)
{
AppendUniqueId(reply);
buf->lcat(reply.c_str());
+ reply.Clear();
}
#endif
}
@@ -2984,7 +2995,7 @@ void Platform::AppendAuxReply(OutputBuffer *reply, bool rawMessage) noexcept
}
else
{
- // Other responses are stored for M105/M408
+ // Other responses are stored for M408
auxSeq++;
auxGCodeReply.Push(reply);
}
diff --git a/src/Platform.h b/src/Platform.h
index cc284b22..51b95ce6 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -36,7 +36,8 @@ Licence: GPL
#include "MessageType.h"
#include "Tools/Spindle.h"
#include "Endstops/EndstopsManager.h"
-#include <GPIO/GpioPorts.h>
+#include <GPIO/GpInPort.h>
+#include <GPIO/GpOutPort.h>
#include <General/IPAddress.h>
#if defined(DUET_NG)
@@ -296,7 +297,8 @@ public:
const char* GetBoardString() const noexcept;
#if SUPPORT_OBJECT_MODEL
- size_t GetNumInputsToReport() const noexcept;
+ size_t GetNumGpInputsToReport() const noexcept;
+ size_t GetNumGpOutputsToReport() const noexcept;
#endif
#ifdef DUET_NG
@@ -544,8 +546,8 @@ public:
// Misc
GCodeResult ConfigurePort(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException);
- const GpOutputPort& GetGpioPort(size_t gpoutPortNumber) const noexcept
- pre(gpioPortNumber < MaxGpOutPorts) { return gpoutPorts[gpoutPortNumber]; }
+ GpOutputPort& GetGpOutPort(size_t gpoutPortNumber) noexcept
+ pre(gpioPortNumber < MaxGpOutPorts) { return gpoutPorts[gpoutPortNumber]; }
const GpInputPort& GetGpInPort(size_t gpinPortNumber) const noexcept
pre(gpinPortNumber < MaxGpInPorts) { return gpinPorts[gpinPortNumber]; }
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index 668cfdfa..2b1965b5 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -160,6 +160,17 @@ constexpr ObjectModelArrayDescriptor RepRap::inputsArrayDescriptor =
[] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue(((const RepRap*)self)->gCodes->GetInput(context.GetLastIndex())); }
};
+constexpr ObjectModelArrayDescriptor RepRap::gpoutArrayDescriptor =
+{
+ nullptr,
+ [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return reprap.GetPlatform().GetNumGpOutputsToReport(); },
+ [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue
+ {
+ const GpOutputPort& port = reprap.GetPlatform().GetGpOutPort(context.GetLastIndex());
+ return (port.IsUnused()) ? ExpressionValue(nullptr) : ExpressionValue(&port);
+ }
+};
+
constexpr ObjectModelArrayDescriptor RepRap::spindlesArrayDescriptor =
{
nullptr, // no lock needed
@@ -276,6 +287,7 @@ constexpr ObjectModelTableEntry RepRap::objectModelTable[] =
{ "beep", OBJECT_MODEL_FUNC_IF(self->beepDuration != 0, self, 4), ObjectModelEntryFlags::none },
{ "currentTool", OBJECT_MODEL_FUNC((int32_t)self->GetCurrentToolNumber()), ObjectModelEntryFlags::live },
{ "displayMessage", OBJECT_MODEL_FUNC(self->message.c_str()), ObjectModelEntryFlags::none },
+ { "gpOut", OBJECT_MODEL_FUNC_NOSELF(&gpoutArrayDescriptor), ObjectModelEntryFlags::live },
{ "laserPwm", OBJECT_MODEL_FUNC_IF(self->gCodes->GetMachineType() == MachineType::laser, self->platform->GetLaserPwm(), 2), ObjectModelEntryFlags::live },
#if HAS_MASS_STORAGE
{ "logFile", OBJECT_MODEL_FUNC(self->platform->GetLogFileName()), ObjectModelEntryFlags::none },
@@ -342,7 +354,7 @@ constexpr uint8_t RepRap::objectModelTableDescriptor[] =
0, // directories
#endif
25, // limits
- 13 + HAS_VOLTAGE_MONITOR, // state
+ 14 + HAS_VOLTAGE_MONITOR, // state
2, // state/beep
6, // state.messageBox
10 + 2 * HAS_NETWORKING + SUPPORT_SCANNER + 2 * HAS_MASS_STORAGE // seqs
@@ -2059,14 +2071,18 @@ OutputBuffer *RepRap::GetLegacyStatusResponse(uint8_t type, int seq) const noexc
}
// Send the response to the last command. Do this last because it can be long and may need to be truncated.
- const int auxSeq = (int)platform->GetAuxSeq();
- if (type < 2 || (seq != -1 && auxSeq != seq))
+ // auxSeq is the last sequence number that PanelDue has received from us.
+ // It's possible that we have queued several messages since PanelDue last polled us.
+ if (type < 2 || seq != -1)
{
-
- response->catf(",\"seq\":%d,\"resp\":", auxSeq); // send the response sequence number
-
- // Send the JSON response
- response->EncodeReply(platform->GetAuxGCodeReply()); // also releases the OutputBuffer chain
+ // PanelDue has asked us for any new responses
+ OutputBuffer * const buf = platform->GetAuxGCodeReply();
+ const int auxSeq = (int)platform->GetAuxSeq();
+ if (buf != nullptr || auxSeq != seq)
+ {
+ response->catf(",\"seq\":%d,\"resp\":", auxSeq); // send the response sequence number
+ response->EncodeReply(buf); // also releases the OutputBuffer chain
+ }
}
response->cat('}');
diff --git a/src/RepRap.h b/src/RepRap.h
index d875e018..1ef3cac4 100644
--- a/src/RepRap.h
+++ b/src/RepRap.h
@@ -200,6 +200,7 @@ protected:
DECLARE_OBJECT_MODEL
OBJECT_MODEL_ARRAY(boards)
OBJECT_MODEL_ARRAY(fans)
+ OBJECT_MODEL_ARRAY(gpout)
OBJECT_MODEL_ARRAY(inputs)
OBJECT_MODEL_ARRAY(spindles)
OBJECT_MODEL_ARRAY(tools)
diff --git a/src/Version.h b/src/Version.h
index e392992f..7aaccc0f 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -19,7 +19,7 @@
#endif
#ifndef DATE
-# define DATE "2020-04-18b1"
+# define DATE "2020-04-20b1"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d"