diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-04-20 17:39:53 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-04-20 17:39:53 +0300 |
commit | f33d299919ca83729da74d4ebcef48c66d9a007d (patch) | |
tree | 03e39a6a2a0195e6d44bc119a8e5eab34047ebd2 | |
parent | 669b2fb36307dbb57e3686f1eaa5b12f89f640f9 (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.cpp | 11 | ||||
-rw-r--r-- | src/Endstops/EndstopsManager.h | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 4 | ||||
-rw-r--r-- | src/GPIO/GpInPort.cpp | 146 | ||||
-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.h | 47 | ||||
-rw-r--r-- | src/Platform.cpp | 17 | ||||
-rw-r--r-- | src/Platform.h | 10 | ||||
-rw-r--r-- | src/RepRap.cpp | 32 | ||||
-rw-r--r-- | src/RepRap.h | 1 | ||||
-rw-r--r-- | src/Version.h | 2 |
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" |