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 /src/GPIO | |
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
Diffstat (limited to 'src/GPIO')
-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 |
4 files changed, 211 insertions, 140 deletions
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_ */ |