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:
Diffstat (limited to 'src/GPIO/GpOutPort.cpp')
-rw-r--r--src/GPIO/GpOutPort.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/GPIO/GpOutPort.cpp b/src/GPIO/GpOutPort.cpp
new file mode 100644
index 00000000..51f32c78
--- /dev/null
+++ b/src/GPIO/GpOutPort.cpp
@@ -0,0 +1,171 @@
+/*
+ * GpOutPort.cpp
+ *
+ * Created on: 11 Feb 2020
+ * Author: David
+ */
+
+#include "GpOutPort.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(GpOutputPort, __VA_ARGS__)
+#define OBJECT_MODEL_FUNC_IF(_condition,...) OBJECT_MODEL_FUNC_IF_BODY(GpOutputPort, _condition,__VA_ARGS__)
+
+constexpr ObjectModelTableEntry GpOutputPort::objectModelTable[] =
+{
+ // Within each group, these entries must be in alphabetical order
+ { "pwm", OBJECT_MODEL_FUNC(self->lastPwm, 2), ObjectModelEntryFlags::live },
+};
+
+constexpr uint8_t GpOutputPort::objectModelTableDescriptor[] = { 1, 1 };
+
+DEFINE_GET_OBJECT_MODEL_TABLE(GpOutputPort)
+
+#endif
+
+// Return true if the port is not configured
+bool GpOutputPort::IsUnused() const noexcept
+{
+ return
+#if SUPPORT_CAN_EXPANSION
+ boardAddress == CanId::MasterAddress &&
+#endif
+ !port.IsValid();
+}
+
+GCodeResult GpOutputPort::Configure(uint32_t gpioNumber, bool isServo, GCodeBuffer &gb, const StringRef &reply)
+{
+ PwmFrequency freq = 0;
+ const bool seenFreq = gb.Seen('Q');
+ if (seenFreq)
+ {
+ freq = gb.GetPwmFrequency();
+ }
+
+ if (gb.Seen('C'))
+ {
+ String<StringLength50> pinName;
+ gb.GetReducedString(pinName.GetRef());
+
+ // Remove any existing assignment
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ CanMessageGenericConstructor cons(M950GpioParams);
+ cons.AddUParam('P', gpioNumber);
+ cons.AddStringParam('C', NoPinName);
+ if (cons.SendAndGetResponse(CanMessageType::m950Gpio, boardAddress, reply) != GCodeResult::ok)
+ {
+ reprap.GetPlatform().Message(WarningMessage, reply.c_str());
+ reply.Clear();
+ }
+ boardAddress = CanId::MasterAddress;
+ }
+#endif
+ port.Release();
+
+ if (!seenFreq)
+ {
+ freq = (isServo) ? ServoRefreshFrequency : DefaultPinWritePwmFreq;
+ }
+
+ GCodeResult rslt;
+
+#if SUPPORT_CAN_EXPANSION
+ boardAddress = IoPort::RemoveBoardAddress(pinName.GetRef());
+ if (boardAddress != CanId::MasterAddress)
+ {
+ CanMessageGenericConstructor cons(M950GpioParams);
+ cons.AddUParam('P', gpioNumber);
+ cons.AddUParam('Q', freq);
+ cons.AddUParam('S', (isServo) ? 1 : 0);
+ cons.AddStringParam('C', pinName.c_str());
+ rslt = cons.SendAndGetResponse(CanMessageType::m950Gpio, boardAddress, reply);
+ }
+ else
+#endif
+ {
+ if (port.AssignPort(pinName.c_str(), reply, PinUsedBy::gpout, (isServo) ? PinAccess::servo : PinAccess::pwm))
+ {
+ rslt = GCodeResult::ok;
+ port.SetFrequency(freq);
+ }
+ else
+ {
+ rslt = GCodeResult::error;
+ }
+ }
+
+ reprap.StateUpdated();
+ return rslt;
+ }
+ else if (seenFreq)
+ {
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ CanMessageGenericConstructor cons(M950GpioParams);
+ cons.AddUParam('P', gpioNumber);
+ cons.AddUParam('Q', freq);
+ reprap.StateUpdated();
+ return cons.SendAndGetResponse(CanMessageType::m950Gpio, boardAddress, reply);
+ }
+#endif
+ port.SetFrequency(freq);
+ reprap.StateUpdated();
+ }
+ else
+ {
+#if SUPPORT_CAN_EXPANSION
+ if (boardAddress != CanId::MasterAddress)
+ {
+ CanMessageGenericConstructor cons(M950GpioParams);
+ cons.AddUParam('P', gpioNumber);
+ return cons.SendAndGetResponse(CanMessageType::m950Gpio, boardAddress, reply);
+ }
+#endif
+ reply.printf("GPIO/servo port %" PRIu32, gpioNumber);
+ port.AppendDetails(reply);
+ }
+ return GCodeResult::ok;
+}
+
+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)
+ {
+ return CanInterface::WriteGpio(boardAddress, gpioPortNumber, pwm, isServo, gb, reply);
+ }
+#endif
+ port.WriteAnalog(pwm);
+ return GCodeResult::ok;
+}
+
+#ifdef PCCB
+
+// Function used to assign default GPOUT devices
+void GpOutputPort::Assign(const char *pinName) noexcept
+{
+ String<1> dummy;
+ port.AssignPort(pinName, dummy.GetRef(), PinUsedBy::gpout, PinAccess::pwm);
+}
+
+#endif
+
+// End