diff --git a/Grbl_Esp32/src/Config.h b/Grbl_Esp32/src/Config.h
index fa7a452a..013611b2 100644
--- a/Grbl_Esp32/src/Config.h
+++ b/Grbl_Esp32/src/Config.h
@@ -207,12 +207,6 @@ static const uint8_t NHomingLocateCycle = 1; // Integer (1-128)
// in the machine definition file.
//#define ENABLE_M7 // Don't uncomment...see above!
-// This option causes the feed hold input to act as a safety door switch. A safety door, when triggered,
-// immediately forces a feed hold and then safely de-energizes the machine. Resuming is blocked until
-// the safety door is re-engaged. When it is, Grbl will re-energize the machine and then resume on the
-// previous tool path, as if nothing happened.
-#define ENABLE_SAFETY_DOOR_INPUT_PIN // ESP32 Leave this enabled for now .. code for undefined not ready
-
// When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM
// by default. This is to make it as simple as possible for new users to start using Grbl. When homing
// is enabled and a user has installed limit switches, Grbl will boot up in an ALARM state to indicate
diff --git a/Grbl_Esp32/src/Control.cpp b/Grbl_Esp32/src/Control.cpp
new file mode 100644
index 00000000..2e9c6748
--- /dev/null
+++ b/Grbl_Esp32/src/Control.cpp
@@ -0,0 +1,74 @@
+/*
+ Control.cpp - input pins
+ Part of Grbl
+
+ Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+ 2018 - Bart Dring This file was modifed for use on the ESP32
+ CPU. Do not use this with Grbl for atMega328P
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+*/
+
+#include "Grbl.h"
+#include "Control.h"
+
+// TODO: the plumbing to communicate with System.cpp is not yet done.
+// These variables are placeholders.
+bool rtSafetyDoor;
+bool rtReset;
+bool rtFeedHold;
+bool rtCycleStart;
+bool rtButtonMacro0;
+bool rtButtonMacro1;
+bool rtButtonMacro2;
+bool rtButtonMacro3;
+
+Control::Control() :
+ _safetyDoor(0, &rtSafetyDoor, "Door", 'D'), _reset(1, &rtReset, "Reset", 'R'), _feedHold(2, &rtFeedHold, "FeedHold", 'H'),
+ _cycleStart(3, &rtCycleStart, "CycleStart", 'S'), _macro0(4, &rtButtonMacro0, "Macro 0", '0'),
+ _macro1(5, &rtButtonMacro1, "Macro 1", '1'), _macro2(6, &rtButtonMacro2, "Macro 2", '2'), _macro3(7, &rtButtonMacro3, "Macro 3", '3') {}
+
+void Control::init() {
+ _safetyDoor.init();
+ _reset.init();
+ _feedHold.init();
+ _cycleStart.init();
+ _macro0.init();
+ _macro1.init();
+ _macro2.init();
+ _macro3.init();
+}
+
+void Control::validate() const {}
+
+void Control::handle(Configuration::HandlerBase& handler) {
+ handler.handle("safetyDoor", _safetyDoor._pin);
+ handler.handle("reset", _reset._pin);
+ handler.handle("feed_hold", _feedHold._pin);
+ handler.handle("cycle_start", _cycleStart._pin);
+ handler.handle("macro0", _macro0._pin);
+ handler.handle("macro1", _macro1._pin);
+ handler.handle("macro2", _macro2._pin);
+ handler.handle("macro3", _macro3._pin);
+}
+#if 0
+// Returns if safety door is ajar(T) or closed(F), based on pin state.
+bool system_check_safety_door_ajar() {
+ // If a safety door pin is not defined, this will return false
+ // because that is the default for the value field, which will
+ // never be changed for an undefined pin.
+ return _safetyDoor.get();
+}
+#endif
diff --git a/Grbl_Esp32/src/Control.h b/Grbl_Esp32/src/Control.h
new file mode 100644
index 00000000..5bf20803
--- /dev/null
+++ b/Grbl_Esp32/src/Control.h
@@ -0,0 +1,53 @@
+#pragma once
+
+/*
+ Control.h - collection of input pins
+ Part of Grbl
+
+ Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
+
+ 2018 - Bart Dring This file was modifed for use on the ESP32
+ CPU. Do not use this with Grbl for atMega328P
+
+ Grbl is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Grbl is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grbl. If not, see .
+*/
+
+#include "Configuration/HandlerBase.h"
+#include "Configuration/Configurable.h"
+#include "GCode.h"
+#include "ControlPin.h"
+
+class Control : public Configuration::Configurable {
+private:
+ ControlPin _safetyDoor;
+ ControlPin _reset;
+ ControlPin _feedHold;
+ ControlPin _cycleStart;
+ ControlPin _macro0;
+ ControlPin _macro1;
+ ControlPin _macro2;
+ ControlPin _macro3;
+
+public:
+ Control();
+
+ // Initializes control pins.
+ void init();
+
+ // Configuration handlers.
+ void validate() const override;
+ void handle(Configuration::HandlerBase& handler) override;
+
+ ~Control() = default;
+};
diff --git a/Grbl_Esp32/src/ControlPin.cpp b/Grbl_Esp32/src/ControlPin.cpp
new file mode 100644
index 00000000..7b1fca2f
--- /dev/null
+++ b/Grbl_Esp32/src/ControlPin.cpp
@@ -0,0 +1,30 @@
+#include "Grbl.h"
+
+#include "ControlPin.h"
+
+// XXX we need to dispatch the user defined macros somehow
+// user_defined_macro(N)
+
+void IRAM_ATTR ControlPin::handleISR() {
+ bool pinState = _pin.read();
+ _value = pinState;
+ if (_rtVariable) {
+ *_rtVariable = pinState;
+ }
+}
+
+void /* IRAM_ATTR */ ControlPin::handle_control_pin(void* arg) {
+ ((ControlPin*)arg)->handleISR();
+}
+
+void ControlPin::init() {
+ if (_pin.defined()) {
+ grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "%s switch on pin %s", _legend, _pin.name());
+ auto attr = Pin::Attr::Input | Pin::Attr::ISR;
+ if (_pin.capabilities().has(Pins::PinCapabilities::PullUp)) {
+ attr = attr | Pin::Attr::PullUp;
+ }
+ _pin.setAttr(attr);
+ _pin.attachInterrupt(ControlPin::handle_control_pin, CHANGE, (void*)this);
+ }
+}
diff --git a/Grbl_Esp32/src/ControlPin.h b/Grbl_Esp32/src/ControlPin.h
new file mode 100644
index 00000000..bd18443b
--- /dev/null
+++ b/Grbl_Esp32/src/ControlPin.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "Pin.h"
+
+class ControlPin {
+private:
+ // invertBitNum refers to a bit in INVERT_CONTROL_PIN_MASK. It is a
+ // short-term hack to reduce the extent of the patch.
+ bool _invertBitNum;
+ bool _value;
+ const char _letter;
+ volatile bool* _rtVariable;
+ const char* _legend;
+ void IRAM_ATTR handleISR();
+ static void /* IRAM_ATTR */ handle_control_pin(void* arg);
+
+public:
+ ControlPin(uint8_t bitNum, volatile bool* rtVariable, const char* legend, char letter) :
+ _invertBitNum(bitNum), _value(false), _letter(letter), _rtVariable(rtVariable), _legend(legend) {}
+
+ Pin _pin;
+ bool get() { return _value; }
+ const char* legend() { return _legend; }
+ // char invertBitNum() { return _invertBitNum; }
+ char letter() { return _letter; }
+ void init();
+};
diff --git a/Grbl_Esp32/src/MachineConfig.cpp b/Grbl_Esp32/src/MachineConfig.cpp
index b7579690..186f8973 100644
--- a/Grbl_Esp32/src/MachineConfig.cpp
+++ b/Grbl_Esp32/src/MachineConfig.cpp
@@ -350,6 +350,7 @@ void MachineConfig::handle(Configuration::HandlerBase& handler) {
handler.handle("axes", _axes);
handler.handle("i2so", _i2so);
handler.handle("spi", _spi);
+ handler.handle("control", _control);
handler.handle("coolant", _coolant);
handler.handle("probe", _probe);
handler.handle("pulse_microseconds", _pulseMicroSeconds);
diff --git a/Grbl_Esp32/src/MachineConfig.h b/Grbl_Esp32/src/MachineConfig.h
index b223c131..7c79af3a 100644
--- a/Grbl_Esp32/src/MachineConfig.h
+++ b/Grbl_Esp32/src/MachineConfig.h
@@ -23,6 +23,7 @@
#include "Configuration/HandlerBase.h"
#include "Configuration/Configurable.h"
#include "CoolantControl.h"
+#include "Control.h"
#include "Probe.h"
// TODO FIXME: Split this file up into several files, perhaps put it in some folder and namespace Machine?
@@ -366,6 +367,7 @@ public:
CoolantControl* _coolant = nullptr;
Probe* _probe = nullptr;
Communications* _comms = nullptr;
+ Control* _control = nullptr;
int _pulseMicroSeconds = 3;
int _directionDelayMilliSeconds = 0;
diff --git a/Grbl_Esp32/src/Pins/GPIOPinDetail.cpp b/Grbl_Esp32/src/Pins/GPIOPinDetail.cpp
index 5cbef37b..70df61a4 100644
--- a/Grbl_Esp32/src/Pins/GPIOPinDetail.cpp
+++ b/Grbl_Esp32/src/Pins/GPIOPinDetail.cpp
@@ -136,7 +136,7 @@ namespace Pins {
int value = _readWriteMask ^ high;
__digitalWrite(_index, value);
}
- int GPIOPinDetail::read() {
+ int IRAM_ATTR GPIOPinDetail::read() {
auto raw = __digitalRead(_index);
return raw ^ _readWriteMask;
}
diff --git a/Grbl_Esp32/src/Pins/GPIOPinDetail.h b/Grbl_Esp32/src/Pins/GPIOPinDetail.h
index fb50e835..f8a51362 100644
--- a/Grbl_Esp32/src/Pins/GPIOPinDetail.h
+++ b/Grbl_Esp32/src/Pins/GPIOPinDetail.h
@@ -35,7 +35,7 @@ namespace Pins {
// I/O:
void write(int high) override;
- int read() override;
+ int IRAM_ATTR read() override;
void setAttr(PinAttributes value) override;
PinAttributes getAttr() const override;
diff --git a/Grbl_Esp32/src/Pins/PinLookup.cpp b/Grbl_Esp32/src/Pins/PinLookup.cpp
index 845021ee..997f977c 100644
--- a/Grbl_Esp32/src/Pins/PinLookup.cpp
+++ b/Grbl_Esp32/src/Pins/PinLookup.cpp
@@ -16,6 +16,8 @@
along with Grbl_ESP32. If not, see .
*/
+#include
+
#include "PinLookup.h"
#include "PinAttributes.h"
@@ -24,8 +26,6 @@
#include "GPIOPinDetail.h"
#include "PinOptionsParser.h"
-#include
-
namespace Pins {
PinLookup PinLookup::_instance;
diff --git a/Grbl_Esp32/src/System.cpp b/Grbl_Esp32/src/System.cpp
index 32384d57..d50ef7e8 100644
--- a/Grbl_Esp32/src/System.cpp
+++ b/Grbl_Esp32/src/System.cpp
@@ -292,6 +292,7 @@ ControlPins system_control_get_state() {
return pin_states;
}
+// TODO: make this work with Control.cpp
// execute the function of the control pin
void system_exec_control_pin(ControlPins pins) {
if (pins.bit.reset) {