diff --git a/Motate b/Motate
index 76fc94edc..ee04b276a 160000
--- a/Motate
+++ b/Motate
@@ -1 +1 @@
-Subproject commit 76fc94edcab42d03f713e08786dea935ee9a560e
+Subproject commit ee04b276a9301e4e4542471b2c461dc2532e0543
diff --git a/g2core/board/Archim/hardware.cpp b/g2core/board/Archim/0_hardware.cpp
similarity index 100%
rename from g2core/board/Archim/hardware.cpp
rename to g2core/board/Archim/0_hardware.cpp
diff --git a/g2core/board/Archim/board_gpio.cpp b/g2core/board/Archim/board_gpio.cpp
new file mode 100644
index 000000000..4daf011d8
--- /dev/null
+++ b/g2core/board/Archim/board_gpio.cpp
@@ -0,0 +1,108 @@
+/*
+ * gpio.cpp - digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Switch Modes
+ *
+ * The switches are considered to be homing switches when cycle_state is
+ * CYCLE_HOMING. At all other times they are treated as limit switches:
+ * - Hitting a homing switch puts the current move into feedhold
+ * - Hitting a limit switch causes the machine to shut down and go into lockdown until reset
+ *
+ * The normally open switch modes (NO) trigger an interrupt on the falling edge
+ * and lockout subsequent interrupts for the defined lockout period. This approach
+ * beats doing debouncing as an integration as switches fire immediately.
+ *
+ * The normally closed switch modes (NC) trigger an interrupt on the rising edge
+ * and lockout subsequent interrupts for the defined lockout period. Ditto on the method.
+ */
+
+#include "../../g2core.h" // #1
+#include "config.h" // #2
+#include "gpio.h"
+#include "hardware.h"
+#include "canonical_machine.h"
+
+#include "text_parser.h"
+#include "controller.h"
+#include "util.h"
+#include "report.h"
+#include "xio.h"
+
+#include "MotateTimers.h"
+
+/**** Setup Actual Objects ****/
+
+gpioDigitalInputPin> din1 {DI1_MODE, 1};
+gpioDigitalInputPin> din2 {DI2_MODE, 2};
+gpioDigitalInputPin> din3 {DI3_MODE, 3};
+gpioDigitalInputPin> din4 {DI4_MODE, 4};
+gpioDigitalInputPin> din5 {DI5_MODE, 5};
+gpioDigitalInputPin> din6 {DI6_MODE, 6};
+gpioDigitalInputPin> din7 {DI7_MODE, 7};
+gpioDigitalInputPin> din8 {DI8_MODE, 8};
+gpioDigitalInputPin> din9 {DI9_MODE, 9};
+// gpioDigitalInputPin> din10 {DI10_MODE, 10};
+// gpioDigitalInputPin> din11 {DI11_MODE, 11};
+// gpioDigitalInputPin> din12 {DI12_MODE, 12};
+
+gpioDigitalOutputPin> dout1 { DO1_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout2 { DO2_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout3 { DO3_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout4 { DO4_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout5 { DO5_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout6 { DO6_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout7 { DO7_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout8 { DO8_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout9 { DO9_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout10 { DO10_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout11 { DO11_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout12 { DO12_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout13 { DO13_MODE, (uint32_t)200000 };
+
+/**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/
+
+gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4, &din5, &din6, &din7, &din8, &din9};
+gpioDigitalOutput* const d_out[] = {&dout1, &dout2, &dout3, &dout4, &dout5, &dout6, &dout7, &dout8, &dout9, &dout10, &dout11, &dout12, &dout13};
+// not yet used
+// gpioAnalogInput* a_in[A_IN_CHANNELS];
+// gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+/************************************************************************************
+ **** CODE **************************************************************************
+ ************************************************************************************/
+/*
+ * gpio_reset() - reset inputs and outputs (no initialization)
+ */
+
+
+void outputs_reset(void) {
+ // nothing to do
+}
+
+void inputs_reset(void) {
+ // nothing to do
+}
diff --git a/g2core/board/Archim/board_gpio.h b/g2core/board/Archim/board_gpio.h
new file mode 100644
index 000000000..25a1cddcd
--- /dev/null
+++ b/g2core/board/Archim/board_gpio.h
@@ -0,0 +1,90 @@
+/*
+ * gpio.h - Digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2017 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef BOARD_GPIO_H_ONCE
+#define BOARD_GPIO_H_ONCE
+
+// this file is included from the bottom of gpio.h, but we do this for completeness
+#include "../../gpio.h"
+
+/*
+ * GPIO defines
+ */
+//--- change as required for board and switch hardware ---//
+
+#define D_IN_CHANNELS 9 // v9 // number of digital inputs supported
+#define D_OUT_CHANNELS 13 // number of digital outputs supported
+#define A_IN_CHANNELS 0 // number of analog inputs supported
+#define A_OUT_CHANNELS 0 // number of analog outputs supported
+
+#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing
+
+/*
+ * The GPIO objects themselves - this must match up with board_gpio.cpp!
+ */
+
+extern gpioDigitalInput* const d_in[D_IN_CHANNELS];
+extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS];
+// extern gpioAnalogInput* a_in[A_IN_CHANNELS];
+// extern gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+// prepare the objects as externs (for config_app to not bloat)
+using Motate::IRQPin;
+using Motate::PWMOutputPin;
+using Motate::PWMLikeOutputPin;
+template
+using OutputType = typename std::conditional, PWMLikeOutputPin>::type;
+
+extern gpioDigitalInputPin> din1;
+extern gpioDigitalInputPin> din2;
+extern gpioDigitalInputPin> din3;
+extern gpioDigitalInputPin> din4;
+extern gpioDigitalInputPin> din5;
+extern gpioDigitalInputPin> din6;
+extern gpioDigitalInputPin> din7;
+extern gpioDigitalInputPin> din8;
+extern gpioDigitalInputPin> din9;
+// extern gpioDigitalInputPin> din10;
+// extern gpioDigitalInputPin> din11;
+// extern gpioDigitalInputPin> din12;
+
+extern gpioDigitalOutputPin> dout1;
+extern gpioDigitalOutputPin> dout2;
+extern gpioDigitalOutputPin> dout3;
+extern gpioDigitalOutputPin> dout4;
+extern gpioDigitalOutputPin> dout5;
+extern gpioDigitalOutputPin> dout6;
+extern gpioDigitalOutputPin> dout7;
+extern gpioDigitalOutputPin> dout8;
+extern gpioDigitalOutputPin> dout9;
+extern gpioDigitalOutputPin> dout10;
+extern gpioDigitalOutputPin> dout11;
+extern gpioDigitalOutputPin> dout12;
+extern gpioDigitalOutputPin> dout13;
+
+
+#endif // End of include guard: BOARD_GPIO_H_ONCE
diff --git a/g2core/board/Archim/board_xio.h b/g2core/board/Archim/board_xio.h
index 09f20fef8..ea0a3fa7b 100755
--- a/g2core/board/Archim/board_xio.h
+++ b/g2core/board/Archim/board_xio.h
@@ -37,10 +37,10 @@
#include "MotateUSBCDC.h"
#if USB_SERIAL_PORTS_EXPOSED == 1
-typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC > XIOUSBDevice_t;
#endif
#if USB_SERIAL_PORTS_EXPOSED == 2
-typedef Motate::USBDevice XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC, Motate::USBCDC > XIOUSBDevice_t;
#endif
extern XIOUSBDevice_t usb;
diff --git a/g2core/board/ArduinoDue/hardware.cpp b/g2core/board/ArduinoDue/0_hardware.cpp
similarity index 100%
rename from g2core/board/ArduinoDue/hardware.cpp
rename to g2core/board/ArduinoDue/0_hardware.cpp
diff --git a/g2core/board/ArduinoDue/board_gpio.cpp b/g2core/board/ArduinoDue/board_gpio.cpp
new file mode 100644
index 000000000..4daf011d8
--- /dev/null
+++ b/g2core/board/ArduinoDue/board_gpio.cpp
@@ -0,0 +1,108 @@
+/*
+ * gpio.cpp - digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Switch Modes
+ *
+ * The switches are considered to be homing switches when cycle_state is
+ * CYCLE_HOMING. At all other times they are treated as limit switches:
+ * - Hitting a homing switch puts the current move into feedhold
+ * - Hitting a limit switch causes the machine to shut down and go into lockdown until reset
+ *
+ * The normally open switch modes (NO) trigger an interrupt on the falling edge
+ * and lockout subsequent interrupts for the defined lockout period. This approach
+ * beats doing debouncing as an integration as switches fire immediately.
+ *
+ * The normally closed switch modes (NC) trigger an interrupt on the rising edge
+ * and lockout subsequent interrupts for the defined lockout period. Ditto on the method.
+ */
+
+#include "../../g2core.h" // #1
+#include "config.h" // #2
+#include "gpio.h"
+#include "hardware.h"
+#include "canonical_machine.h"
+
+#include "text_parser.h"
+#include "controller.h"
+#include "util.h"
+#include "report.h"
+#include "xio.h"
+
+#include "MotateTimers.h"
+
+/**** Setup Actual Objects ****/
+
+gpioDigitalInputPin> din1 {DI1_MODE, 1};
+gpioDigitalInputPin> din2 {DI2_MODE, 2};
+gpioDigitalInputPin> din3 {DI3_MODE, 3};
+gpioDigitalInputPin> din4 {DI4_MODE, 4};
+gpioDigitalInputPin> din5 {DI5_MODE, 5};
+gpioDigitalInputPin> din6 {DI6_MODE, 6};
+gpioDigitalInputPin> din7 {DI7_MODE, 7};
+gpioDigitalInputPin> din8 {DI8_MODE, 8};
+gpioDigitalInputPin> din9 {DI9_MODE, 9};
+// gpioDigitalInputPin> din10 {DI10_MODE, 10};
+// gpioDigitalInputPin> din11 {DI11_MODE, 11};
+// gpioDigitalInputPin> din12 {DI12_MODE, 12};
+
+gpioDigitalOutputPin> dout1 { DO1_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout2 { DO2_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout3 { DO3_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout4 { DO4_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout5 { DO5_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout6 { DO6_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout7 { DO7_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout8 { DO8_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout9 { DO9_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout10 { DO10_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout11 { DO11_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout12 { DO12_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout13 { DO13_MODE, (uint32_t)200000 };
+
+/**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/
+
+gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4, &din5, &din6, &din7, &din8, &din9};
+gpioDigitalOutput* const d_out[] = {&dout1, &dout2, &dout3, &dout4, &dout5, &dout6, &dout7, &dout8, &dout9, &dout10, &dout11, &dout12, &dout13};
+// not yet used
+// gpioAnalogInput* a_in[A_IN_CHANNELS];
+// gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+/************************************************************************************
+ **** CODE **************************************************************************
+ ************************************************************************************/
+/*
+ * gpio_reset() - reset inputs and outputs (no initialization)
+ */
+
+
+void outputs_reset(void) {
+ // nothing to do
+}
+
+void inputs_reset(void) {
+ // nothing to do
+}
diff --git a/g2core/board/ArduinoDue/board_gpio.h b/g2core/board/ArduinoDue/board_gpio.h
new file mode 100644
index 000000000..25a1cddcd
--- /dev/null
+++ b/g2core/board/ArduinoDue/board_gpio.h
@@ -0,0 +1,90 @@
+/*
+ * gpio.h - Digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2017 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef BOARD_GPIO_H_ONCE
+#define BOARD_GPIO_H_ONCE
+
+// this file is included from the bottom of gpio.h, but we do this for completeness
+#include "../../gpio.h"
+
+/*
+ * GPIO defines
+ */
+//--- change as required for board and switch hardware ---//
+
+#define D_IN_CHANNELS 9 // v9 // number of digital inputs supported
+#define D_OUT_CHANNELS 13 // number of digital outputs supported
+#define A_IN_CHANNELS 0 // number of analog inputs supported
+#define A_OUT_CHANNELS 0 // number of analog outputs supported
+
+#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing
+
+/*
+ * The GPIO objects themselves - this must match up with board_gpio.cpp!
+ */
+
+extern gpioDigitalInput* const d_in[D_IN_CHANNELS];
+extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS];
+// extern gpioAnalogInput* a_in[A_IN_CHANNELS];
+// extern gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+// prepare the objects as externs (for config_app to not bloat)
+using Motate::IRQPin;
+using Motate::PWMOutputPin;
+using Motate::PWMLikeOutputPin;
+template
+using OutputType = typename std::conditional, PWMLikeOutputPin>::type;
+
+extern gpioDigitalInputPin> din1;
+extern gpioDigitalInputPin> din2;
+extern gpioDigitalInputPin> din3;
+extern gpioDigitalInputPin> din4;
+extern gpioDigitalInputPin> din5;
+extern gpioDigitalInputPin> din6;
+extern gpioDigitalInputPin> din7;
+extern gpioDigitalInputPin> din8;
+extern gpioDigitalInputPin> din9;
+// extern gpioDigitalInputPin> din10;
+// extern gpioDigitalInputPin> din11;
+// extern gpioDigitalInputPin> din12;
+
+extern gpioDigitalOutputPin> dout1;
+extern gpioDigitalOutputPin> dout2;
+extern gpioDigitalOutputPin> dout3;
+extern gpioDigitalOutputPin> dout4;
+extern gpioDigitalOutputPin> dout5;
+extern gpioDigitalOutputPin> dout6;
+extern gpioDigitalOutputPin> dout7;
+extern gpioDigitalOutputPin> dout8;
+extern gpioDigitalOutputPin> dout9;
+extern gpioDigitalOutputPin> dout10;
+extern gpioDigitalOutputPin> dout11;
+extern gpioDigitalOutputPin> dout12;
+extern gpioDigitalOutputPin> dout13;
+
+
+#endif // End of include guard: BOARD_GPIO_H_ONCE
diff --git a/g2core/board/ArduinoDue/board_xio.h b/g2core/board/ArduinoDue/board_xio.h
index 09f20fef8..ea0a3fa7b 100755
--- a/g2core/board/ArduinoDue/board_xio.h
+++ b/g2core/board/ArduinoDue/board_xio.h
@@ -37,10 +37,10 @@
#include "MotateUSBCDC.h"
#if USB_SERIAL_PORTS_EXPOSED == 1
-typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC > XIOUSBDevice_t;
#endif
#if USB_SERIAL_PORTS_EXPOSED == 2
-typedef Motate::USBDevice XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC, Motate::USBCDC > XIOUSBDevice_t;
#endif
extern XIOUSBDevice_t usb;
diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/0_hardware.cpp
similarity index 100%
rename from g2core/board/G2v9/hardware.cpp
rename to g2core/board/G2v9/0_hardware.cpp
diff --git a/g2core/board/G2v9/board_gpio.cpp b/g2core/board/G2v9/board_gpio.cpp
new file mode 100644
index 000000000..4daf011d8
--- /dev/null
+++ b/g2core/board/G2v9/board_gpio.cpp
@@ -0,0 +1,108 @@
+/*
+ * gpio.cpp - digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Switch Modes
+ *
+ * The switches are considered to be homing switches when cycle_state is
+ * CYCLE_HOMING. At all other times they are treated as limit switches:
+ * - Hitting a homing switch puts the current move into feedhold
+ * - Hitting a limit switch causes the machine to shut down and go into lockdown until reset
+ *
+ * The normally open switch modes (NO) trigger an interrupt on the falling edge
+ * and lockout subsequent interrupts for the defined lockout period. This approach
+ * beats doing debouncing as an integration as switches fire immediately.
+ *
+ * The normally closed switch modes (NC) trigger an interrupt on the rising edge
+ * and lockout subsequent interrupts for the defined lockout period. Ditto on the method.
+ */
+
+#include "../../g2core.h" // #1
+#include "config.h" // #2
+#include "gpio.h"
+#include "hardware.h"
+#include "canonical_machine.h"
+
+#include "text_parser.h"
+#include "controller.h"
+#include "util.h"
+#include "report.h"
+#include "xio.h"
+
+#include "MotateTimers.h"
+
+/**** Setup Actual Objects ****/
+
+gpioDigitalInputPin> din1 {DI1_MODE, 1};
+gpioDigitalInputPin> din2 {DI2_MODE, 2};
+gpioDigitalInputPin> din3 {DI3_MODE, 3};
+gpioDigitalInputPin> din4 {DI4_MODE, 4};
+gpioDigitalInputPin> din5 {DI5_MODE, 5};
+gpioDigitalInputPin> din6 {DI6_MODE, 6};
+gpioDigitalInputPin> din7 {DI7_MODE, 7};
+gpioDigitalInputPin> din8 {DI8_MODE, 8};
+gpioDigitalInputPin> din9 {DI9_MODE, 9};
+// gpioDigitalInputPin> din10 {DI10_MODE, 10};
+// gpioDigitalInputPin> din11 {DI11_MODE, 11};
+// gpioDigitalInputPin> din12 {DI12_MODE, 12};
+
+gpioDigitalOutputPin> dout1 { DO1_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout2 { DO2_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout3 { DO3_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout4 { DO4_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout5 { DO5_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout6 { DO6_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout7 { DO7_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout8 { DO8_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout9 { DO9_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout10 { DO10_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout11 { DO11_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout12 { DO12_MODE, (uint32_t)200000 };
+gpioDigitalOutputPin> dout13 { DO13_MODE, (uint32_t)200000 };
+
+/**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/
+
+gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4, &din5, &din6, &din7, &din8, &din9};
+gpioDigitalOutput* const d_out[] = {&dout1, &dout2, &dout3, &dout4, &dout5, &dout6, &dout7, &dout8, &dout9, &dout10, &dout11, &dout12, &dout13};
+// not yet used
+// gpioAnalogInput* a_in[A_IN_CHANNELS];
+// gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+/************************************************************************************
+ **** CODE **************************************************************************
+ ************************************************************************************/
+/*
+ * gpio_reset() - reset inputs and outputs (no initialization)
+ */
+
+
+void outputs_reset(void) {
+ // nothing to do
+}
+
+void inputs_reset(void) {
+ // nothing to do
+}
diff --git a/g2core/board/G2v9/board_gpio.h b/g2core/board/G2v9/board_gpio.h
new file mode 100644
index 000000000..25a1cddcd
--- /dev/null
+++ b/g2core/board/G2v9/board_gpio.h
@@ -0,0 +1,90 @@
+/*
+ * gpio.h - Digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2017 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef BOARD_GPIO_H_ONCE
+#define BOARD_GPIO_H_ONCE
+
+// this file is included from the bottom of gpio.h, but we do this for completeness
+#include "../../gpio.h"
+
+/*
+ * GPIO defines
+ */
+//--- change as required for board and switch hardware ---//
+
+#define D_IN_CHANNELS 9 // v9 // number of digital inputs supported
+#define D_OUT_CHANNELS 13 // number of digital outputs supported
+#define A_IN_CHANNELS 0 // number of analog inputs supported
+#define A_OUT_CHANNELS 0 // number of analog outputs supported
+
+#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing
+
+/*
+ * The GPIO objects themselves - this must match up with board_gpio.cpp!
+ */
+
+extern gpioDigitalInput* const d_in[D_IN_CHANNELS];
+extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS];
+// extern gpioAnalogInput* a_in[A_IN_CHANNELS];
+// extern gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+// prepare the objects as externs (for config_app to not bloat)
+using Motate::IRQPin;
+using Motate::PWMOutputPin;
+using Motate::PWMLikeOutputPin;
+template
+using OutputType = typename std::conditional, PWMLikeOutputPin>::type;
+
+extern gpioDigitalInputPin> din1;
+extern gpioDigitalInputPin> din2;
+extern gpioDigitalInputPin> din3;
+extern gpioDigitalInputPin> din4;
+extern gpioDigitalInputPin> din5;
+extern gpioDigitalInputPin> din6;
+extern gpioDigitalInputPin> din7;
+extern gpioDigitalInputPin> din8;
+extern gpioDigitalInputPin> din9;
+// extern gpioDigitalInputPin> din10;
+// extern gpioDigitalInputPin> din11;
+// extern gpioDigitalInputPin> din12;
+
+extern gpioDigitalOutputPin> dout1;
+extern gpioDigitalOutputPin> dout2;
+extern gpioDigitalOutputPin> dout3;
+extern gpioDigitalOutputPin> dout4;
+extern gpioDigitalOutputPin> dout5;
+extern gpioDigitalOutputPin> dout6;
+extern gpioDigitalOutputPin> dout7;
+extern gpioDigitalOutputPin> dout8;
+extern gpioDigitalOutputPin> dout9;
+extern gpioDigitalOutputPin> dout10;
+extern gpioDigitalOutputPin> dout11;
+extern gpioDigitalOutputPin> dout12;
+extern gpioDigitalOutputPin> dout13;
+
+
+#endif // End of include guard: BOARD_GPIO_H_ONCE
diff --git a/g2core/board/G2v9/board_xio.h b/g2core/board/G2v9/board_xio.h
index 09f20fef8..ea0a3fa7b 100755
--- a/g2core/board/G2v9/board_xio.h
+++ b/g2core/board/G2v9/board_xio.h
@@ -37,10 +37,10 @@
#include "MotateUSBCDC.h"
#if USB_SERIAL_PORTS_EXPOSED == 1
-typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC > XIOUSBDevice_t;
#endif
#if USB_SERIAL_PORTS_EXPOSED == 2
-typedef Motate::USBDevice XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware, Motate::USBCDC, Motate::USBCDC > XIOUSBDevice_t;
#endif
extern XIOUSBDevice_t usb;
diff --git a/g2core/board/gquadratic.mk b/g2core/board/gquadratic.mk
index 9527cdc11..35837519a 100755
--- a/g2core/board/gquadratic.mk
+++ b/g2core/board/gquadratic.mk
@@ -18,6 +18,12 @@ ifeq ("$(BOARD)","gquadratic-b")
DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE}
endif
+ifeq ("$(BOARD)","gquadratic-c")
+ BASE_BOARD=gquadratic
+ DEVICE_DEFINES += MOTATE_BOARD="gquadratic-c"
+ DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE}
+endif
+
##########
# The general gquadratic BASE_BOARD.
@@ -25,16 +31,16 @@ endif
ifeq ("$(BASE_BOARD)","gquadratic")
_BOARD_FOUND = 1
- DEVICE_DEFINES += MOTATE_CONFIG_HAS_USBSERIAL=0
+ DEVICE_DEFINES += MOTATE_CONFIG_HAS_USBSERIAL=1 ENABLE_TCM=1
- FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sams70/*.cpp))
+ FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sams70/*.cpp) $(wildcard ${BOARD_PATH}/*.cpp))
CHIP = SAMS70N19
export CHIP
CHIP_LOWERCASE = sams70n19
BOARD_PATH = ./board/gquadratic
- SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver device/step_dir_hobbyservo device/neopixel
+ SOURCE_DIRS += ${BOARD_PATH} device/trinamic device/step_dir_hobbyservo device/max31865 device/neopixel
PLATFORM_BASE = ${MOTATE_PATH}/platform/atmel_sam
include $(PLATFORM_BASE).mk
diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/0_hardware.cpp
similarity index 98%
rename from g2core/board/gquadratic/hardware.cpp
rename to g2core/board/gquadratic/0_hardware.cpp
index d3674a2ee..465c7175d 100755
--- a/g2core/board/gquadratic/hardware.cpp
+++ b/g2core/board/gquadratic/0_hardware.cpp
@@ -73,6 +73,10 @@ namespace LEDs {
}
#endif // EXPERIMENTAL_NEOPIXEL_SUPPORT
+#if QUADRATIC_REVISION == 'C'
+HOT_DATA SPIBus_used_t spiBus;
+#endif
+
/*
* hardware_init() - lowest level hardware init
*/
@@ -82,6 +86,10 @@ void hardware_init()
board_hardware_init();
// external_clk_pin = 0; // Force external clock to 0 for now.
+#if QUADRATIC_REVISION == 'C'
+ spiBus.init();
+#endif
+
#if EXPERIMENTAL_NEOPIXEL_SUPPORT == 1
for (uint8_t pixel = 0; pixel < LEDs::rgbw_leds.count; pixel++) {
LEDs::display_color[pixel].startTransition(100, 0, 0, 0);
diff --git a/g2core/board/gquadratic/board_gpio.cpp b/g2core/board/gquadratic/board_gpio.cpp
new file mode 100644
index 000000000..614f4e0e6
--- /dev/null
+++ b/g2core/board/gquadratic/board_gpio.cpp
@@ -0,0 +1,89 @@
+/*
+ * gpio.cpp - digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Switch Modes
+ *
+ * The switches are considered to be homing switches when cycle_state is
+ * CYCLE_HOMING. At all other times they are treated as limit switches:
+ * - Hitting a homing switch puts the current move into feedhold
+ * - Hitting a limit switch causes the machine to shut down and go into lockdown until reset
+ *
+ * The normally open switch modes (NO) trigger an interrupt on the falling edge
+ * and lockout subsequent interrupts for the defined lockout period. This approach
+ * beats doing debouncing as an integration as switches fire immediately.
+ *
+ * The normally closed switch modes (NC) trigger an interrupt on the rising edge
+ * and lockout subsequent interrupts for the defined lockout period. Ditto on the method.
+ */
+
+#include "../../g2core.h" // #1
+#include "config.h" // #2
+#include "gpio.h"
+#include "hardware.h"
+#include "canonical_machine.h"
+
+#include "text_parser.h"
+#include "controller.h"
+#include "util.h"
+#include "report.h"
+#include "xio.h"
+
+#include "MotateTimers.h"
+
+/**** Setup Actual Objects ****/
+
+gpioDigitalInputPin> din1 {DI1_ENABLED, DI1_POLARITY, 1, DI1_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din2 {DI2_ENABLED, DI2_POLARITY, 2, DI2_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din3 {DI3_ENABLED, DI3_POLARITY, 3, DI3_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din4 {DI4_ENABLED, DI4_POLARITY, 4, DI4_EXTERNAL_NUMBER};
+
+gpioDigitalOutputPin> dout1 { DO1_ENABLED, DO1_POLARITY, DO1_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout2 { DO2_ENABLED, DO2_POLARITY, DO2_EXTERNAL_NUMBER, (uint32_t)200000 };
+
+/**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/
+
+gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4};
+gpioDigitalOutput* const d_out[] = {&dout1, &dout2};
+// not yet used
+// gpioAnalogInput* a_in[A_IN_CHANNELS];
+// gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+/************************************************************************************
+ **** CODE **************************************************************************
+ ************************************************************************************/
+/*
+ * gpio_reset() - reset inputs and outputs (no initialization)
+ */
+
+
+void outputs_reset(void) {
+ // nothing to do
+}
+
+void inputs_reset(void) {
+ // nothing to do
+}
diff --git a/g2core/board/gquadratic/board_gpio.h b/g2core/board/gquadratic/board_gpio.h
new file mode 100644
index 000000000..c596fc545
--- /dev/null
+++ b/g2core/board/gquadratic/board_gpio.h
@@ -0,0 +1,71 @@
+/*
+ * gpio.h - Digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2017 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef BOARD_GPIO_H_ONCE
+#define BOARD_GPIO_H_ONCE
+
+// this file is included from the bottom of gpio.h, but we do this for completeness
+#include "../../gpio.h"
+
+/*
+ * GPIO defines
+ */
+//--- change as required for board and switch hardware ---//
+
+#define D_IN_CHANNELS 4 // number of digital inputs supported
+#define D_OUT_CHANNELS 2 // number of digital outputs supported
+#define A_IN_CHANNELS 0 // number of analog inputs supported
+#define A_OUT_CHANNELS 0 // number of analog outputs supported
+
+#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing
+
+/*
+ * The GPIO objects themselves - this must match up with board_gpio.cpp!
+ */
+
+extern gpioDigitalInput* const d_in[D_IN_CHANNELS];
+extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS];
+// extern gpioAnalogInput* a_in[A_IN_CHANNELS];
+// extern gpioAnalogOutput* a_out[A_OUT_CHANNELS];
+
+// prepare the objects as externs (for config_app to not bloat)
+using Motate::IRQPin;
+using Motate::PWMOutputPin;
+using Motate::PWMLikeOutputPin;
+template
+using OutputType = typename std::conditional, PWMLikeOutputPin>::type;
+
+extern gpioDigitalInputPin> din1;
+extern gpioDigitalInputPin> din2;
+extern gpioDigitalInputPin> din3;
+extern gpioDigitalInputPin> din4;
+
+extern gpioDigitalOutputPin> dout1;
+extern gpioDigitalOutputPin> dout2;
+
+
+#endif // End of include guard: BOARD_GPIO_H_ONCE
diff --git a/g2core/board/gquadratic/board_stepper.cpp b/g2core/board/gquadratic/board_stepper.cpp
index bc927558a..cfe461447 100755
--- a/g2core/board/gquadratic/board_stepper.cpp
+++ b/g2core/board/gquadratic/board_stepper.cpp
@@ -2,8 +2,8 @@
* board_stepper.cpp - board-specific code for stepper.cpp
* This file is part of the g2core project
*
- * Copyright (c) 2016 Alden S. Hart, Jr.
- * Copyright (c) 2016 Robert Giseburt
+ * Copyright (c) 2016-2018 Alden S. Hart, Jr.
+ * Copyright (c) 2016-2018 Robert Giseburt
*
* This file ("the software") is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2 as published by the
@@ -29,54 +29,48 @@
#include "board_stepper.h"
// These are identical to board_stepper.h, except for the word "extern"
-StepDirStepper
- motor_1{};
+ motor_1 {};
-StepDirStepper
- motor_2{};
+ motor_2 {};
+#endif // QUADRATIC_REVISION == 'B'
-StepDirHobbyServo motor_3;
+#if QUADRATIC_REVISION == 'C'
+#warning setting up trinamics
+// Motate::SPIChipSelectPin motor_1_cs;
+HOT_DATA Trinamic2130
+ motor_1 {spiBus, Motate::SPIChipSelectPin{}};
-// StepDirStepper<
-// Motate::kSocket4_StepPinNumber,
-// Motate::kSocket4_DirPinNumber,
-// Motate::kSocket4_EnablePinNumber,
-// Motate::kSocket4_Microstep_0PinNumber,
-// Motate::kSocket4_Microstep_1PinNumber,
-// Motate::kSocket4_Microstep_2PinNumber,
-// Motate::kSocket4_VrefPinNumber> motor_4 {};
-//
-// StepDirStepper<
-// Motate::kSocket5_StepPinNumber,
-// Motate::kSocket5_DirPinNumber,
-// Motate::kSocket5_EnablePinNumber,
-// Motate::kSocket5_Microstep_0PinNumber,
-// Motate::kSocket5_Microstep_1PinNumber,
-// Motate::kSocket5_Microstep_2PinNumber,
-// Motate::kSocket5_VrefPinNumber> motor_5 {};
+// Motate::SPIChipSelectPin motor_2_cs;
+HOT_DATA Trinamic2130
+ motor_2 {spiBus, Motate::SPIChipSelectPin{}};
+#endif // QUADRATIC_REVISION == 'C'
-// StepDirStepper<
-// Motate::kSocket6_StepPinNumber,
-// Motate::kSocket6_DirPinNumber,
-// Motate::kSocket6_EnablePinNumber,
-// Motate::kSocket6_Microstep_0PinNumber,
-// Motate::kSocket6_Microstep_1PinNumber,
-// Motate::kSocket6_Microstep_2PinNumber,
-// Motate::kSocket6_VrefPinNumber> motor_6 {};
-Stepper* Motors[MOTORS] = {&motor_1, &motor_2, &motor_3};
+HOT_DATA StepDirHobbyServo motor_3;
+
+
+Stepper* const Motors[MOTORS] = {&motor_1, &motor_2, &motor_3};
void board_stepper_init() {
for (uint8_t motor = 0; motor < MOTORS; motor++) { Motors[motor]->init(); }
diff --git a/g2core/board/gquadratic/board_stepper.h b/g2core/board/gquadratic/board_stepper.h
index 6e044efa3..8072ff338 100755
--- a/g2core/board/gquadratic/board_stepper.h
+++ b/g2core/board/gquadratic/board_stepper.h
@@ -29,9 +29,9 @@
#define BOARD_STEPPER_H_ONCE
#include "hardware.h" // for MOTORS
-#include "step_dir_driver.h"
-#include "step_dir_hobbyservo.h"
+#if QUADRATIC_REVISION == 'B'
+#include "step_dir_driver.h"
extern StepDirStepper
motor_2;
+#endif // QUADRATIC_REVISION == 'B'
- extern StepDirHobbyServo motor_3;
+#if QUADRATIC_REVISION == 'C'
+#include "tmc2130.h"
+extern Trinamic2130
+ motor_1;
+extern Trinamic2130
+ motor_2;
+#endif // QUADRATIC_REVISION == 'C'
-// extern StepDirStepper<
-// Motate::kSocket5_StepPinNumber,
-// Motate::kSocket5_DirPinNumber,
-// Motate::kSocket5_EnablePinNumber,
-// Motate::kSocket5_Microstep_0PinNumber,
-// Motate::kSocket5_Microstep_1PinNumber,
-// Motate::kSocket5_Microstep_2PinNumber,
-// Motate::kSocket5_VrefPinNumber> motor_5;
-//
-// extern StepDirStepper<
-// Motate::kSocket6_StepPinNumber,
-// Motate::kSocket6_DirPinNumber,
-// Motate::kSocket6_EnablePinNumber,
-// Motate::kSocket6_Microstep_0PinNumber,
-// Motate::kSocket6_Microstep_1PinNumber,
-// Motate::kSocket6_Microstep_2PinNumber,
-// Motate::kSocket6_VrefPinNumber> motor_6 {};
+#include "step_dir_hobbyservo.h"
+extern StepDirHobbyServo motor_3;
-extern Stepper* Motors[MOTORS];
+extern Stepper* const Motors[MOTORS];
void board_stepper_init();
diff --git a/g2core/board/gquadratic/board_xio.cpp b/g2core/board/gquadratic/board_xio.cpp
index c48356be1..d05ce1ff8 100755
--- a/g2core/board/gquadratic/board_xio.cpp
+++ b/g2core/board/gquadratic/board_xio.cpp
@@ -71,6 +71,7 @@ void board_hardware_init(void) // called 1st
#if XIO_HAS_USB
// Init USB
usb.attach();
+ usb.handleVbusChange(/*force:*/ true);
#endif // XIO_HAS_USB
}
diff --git a/g2core/board/gquadratic/board_xio.h b/g2core/board/gquadratic/board_xio.h
index 09f20fef8..659f68a4a 100755
--- a/g2core/board/gquadratic/board_xio.h
+++ b/g2core/board/gquadratic/board_xio.h
@@ -36,11 +36,13 @@
#include "MotateUSB.h"
#include "MotateUSBCDC.h"
+typedef Motate::USBDeviceHardwareVBus> USBDeviceHardware_t;
+
#if USB_SERIAL_PORTS_EXPOSED == 1
-typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware_t, Motate::USBCDC > XIOUSBDevice_t;
#endif
#if USB_SERIAL_PORTS_EXPOSED == 2
-typedef Motate::USBDevice XIOUSBDevice_t;
+typedef Motate::USBDevice< USBDeviceHardware_t, Motate::USBCDC, Motate::USBCDC > XIOUSBDevice_t;
#endif
extern XIOUSBDevice_t usb;
diff --git a/g2core/board/gquadratic/gquadratic-b-pinout.h b/g2core/board/gquadratic/gquadratic-b-pinout.h
index 6eab01841..7eb8946bb 100755
--- a/g2core/board/gquadratic/gquadratic-b-pinout.h
+++ b/g2core/board/gquadratic/gquadratic-b-pinout.h
@@ -2,8 +2,8 @@
* gquadratic-b-pinout.h - board pinout specification
* This file is part of the g2core project
*
- * Copyright (c) 2016 Robert Giseburt
- * Copyright (c) 2016 Alden S. Hart Jr.
+ * Copyright (c) 2016-2018 Robert Giseburt
+ * Copyright (c) 2016-2018 Alden S. Hart Jr.
*
* This file is part of the Motate Library.
*
@@ -108,6 +108,8 @@
#define OUTPUT12_PWM 0 // Unused
#define OUTPUT13_PWM 0 // Unused
+#define QUADRATIC_REVISION 'B'
+
namespace Motate {
// Arduino pin name & function
diff --git a/g2core/board/gquadratic/gquadratic-c-pinout.h b/g2core/board/gquadratic/gquadratic-c-pinout.h
new file mode 100644
index 000000000..8c77c9d35
--- /dev/null
+++ b/g2core/board/gquadratic/gquadratic-c-pinout.h
@@ -0,0 +1,205 @@
+/*
+ * gquadratic-c-pinout.h - board pinout specification
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2018 Robert Giseburt
+ * Copyright (c) 2018 Alden S. Hart Jr.
+ *
+ * This file is part of the Motate Library.
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef GQUADRATIC_C_PINOUT_H
+#define GQUADRATIC_C_PINOUT_H
+
+/*
+ * USAGE NOTES
+ *
+ * Read this first:
+ * https://github.com/synthetos/g2/wiki/Adding-a-new-G2-board-(or-revision)-to-G2#making-a-new-pin-assignment
+ *
+ * USAGE:
+ *
+ * This file is lays out all the pin capabilities of the SAM3X8C organized by pin number.
+ * Each pin has its associated functions listed at the bottom of the file, and is essentially
+ * immutable for each processor.
+ *
+ * To use, assign Motate pin numbers to the first value in the _MAKE_MOTATE_PIN() macro.
+ * ALL PINS MUST BE ASSIGNED A NUMBER, even if they are not used. There will NOT be a
+ * code-size or speed penalty for unused pins, but the WILL be a compiler-failure for
+ * unassigned pins. This new restriction allows for simplification of linkages deep in
+ * Motate.
+ */
+/* See motate_pin_assignments.h for pin names to be used int he rest of the G2 code.
+ * EXAMPLES:
+ *
+ * *** Vanilla pin example ***
+ *
+ * _MAKE_MOTATE_PIN(4, A, 'A', 27); // SPI0_SCKPinNumber
+ *
+ * This assigns Motate pin 4 to Port A, pin 27 (A27)
+ * Look in motate_pin_assignments.h to see that this is kSPI_SCKPinNumber
+ *
+ * ** Other pin functions ***
+ *
+ * Please look in /platform/atmel_sam/motate_chip_pin_functions.h
+ */
+
+
+#include
+
+// We don't have all of the inputs, so we have to indicate as much:
+#define INPUT1_AVAILABLE 1
+#define INPUT2_AVAILABLE 1
+#define INPUT3_AVAILABLE 1
+#define INPUT4_AVAILABLE 1
+#define INPUT5_AVAILABLE 0
+#define INPUT6_AVAILABLE 0
+#define INPUT7_AVAILABLE 0
+#define INPUT8_AVAILABLE 0
+#define INPUT9_AVAILABLE 0
+#define INPUT10_AVAILABLE 0
+#define INPUT11_AVAILABLE 0
+#define INPUT12_AVAILABLE 0
+#define INPUT13_AVAILABLE 0
+
+#define XIO_HAS_USB 1
+#define XIO_HAS_UART 1
+#define XIO_HAS_SPI 0
+#define XIO_HAS_I2C 0
+
+#define TEMPERATURE_OUTPUT_ON 0 // NO ADC yet
+
+// Some pins, if the PWM capability is turned on, it will cause timer conflicts.
+// So we have to explicitly enable them as PWM pins.
+// Generated with:
+// perl -e 'for($i=1;$i<14;$i++) { print "#define OUTPUT${i}_PWM 0\n";}'
+#define OUTPUT1_PWM 1 // TC0.0
+#define OUTPUT2_PWM 1 // PWM0.0
+#define OUTPUT3_PWM 1 // TC0.1
+#define OUTPUT4_PWM 1 // PWM1.3
+#define OUTPUT5_PWM 0 // unused
+#define OUTPUT6_PWM 0 // unused
+#define OUTPUT7_PWM 0 // unused
+#define OUTPUT8_PWM 0 // unused
+#define OUTPUT9_PWM 0 // unused
+#define OUTPUT10_PWM 0 // unused
+#define OUTPUT11_PWM 0 // unused
+#define OUTPUT12_PWM 0 // Unused
+#define OUTPUT13_PWM 0 // Unused
+
+#define QUADRATIC_REVISION 'C'
+
+namespace Motate {
+
+// Arduino pin name & function
+_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 0); // TC0.0 or PWM0
+_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 1); // TC0.1 or PWM1
+_MAKE_MOTATE_PIN(kUnassigned1, 'A', 2); // PWM1
+_MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); //
+_MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); //
+_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'A', 5); //
+_MAKE_MOTATE_PIN(kUnassigned2, 'A', 6); // Missing in 100-pin package
+_MAKE_MOTATE_PIN(kUnassigned3, 'A', 7); //
+_MAKE_MOTATE_PIN(kUnassigned4, 'A', 8); //
+_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 9); //
+_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 10); //
+_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'A', 11); //
+_MAKE_MOTATE_PIN(kUnassigned5, 'A', 12); //
+_MAKE_MOTATE_PIN(kUnassigned6, 'A', 13); //
+_MAKE_MOTATE_PIN(kUnassigned7, 'A', 14); //
+_MAKE_MOTATE_PIN(kUnassigned8, 'A', 15); //
+_MAKE_MOTATE_PIN(kUnassigned9, 'A', 16); //
+_MAKE_MOTATE_PIN(kUnassigned10, 'A', 17); //
+_MAKE_MOTATE_PIN(kUnassigned11, 'A', 18); //
+_MAKE_MOTATE_PIN(kUnassigned12, 'A', 19); //
+_MAKE_MOTATE_PIN(kUnassigned13, 'A', 20); //
+_MAKE_MOTATE_PIN(kUnassigned14, 'A', 21); //
+_MAKE_MOTATE_PIN(kUnassigned15, 'A', 22); //
+_MAKE_MOTATE_PIN(kUnassigned16, 'A', 23); //
+_MAKE_MOTATE_PIN(kInput5_PinNumber, 'A', 24); // DIAG0
+_MAKE_MOTATE_PIN(kUnassigned17, 'A', 25); //
+_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'A', 26); //
+_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'A', 27); // TC2.1
+_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 28); //
+_MAKE_MOTATE_PIN(kUnassigned18, 'A', 29); // Missing in 100-pin package
+_MAKE_MOTATE_PIN(kServo1_PinNumber, 'A', 30); // PWM2 - kOutput4_PinNumber
+_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); //
+
+_MAKE_MOTATE_PIN(kUnassigned19, 'B', 0); //
+_MAKE_MOTATE_PIN(kUnassigned20, 'B', 1); //
+_MAKE_MOTATE_PIN(kSocket3_SPISlaveSelectPinNumber, 'B', 2); //
+_MAKE_MOTATE_PIN(kUnassigned21, 'B', 3); //
+//_MAKE_MOTATE_PIN( , 'B', 4); // TDI
+//_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO
+//_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO
+//_MAKE_MOTATE_PIN( , 'B', 7); // SWDCLK
+//_MAKE_MOTATE_PIN( , 'B', 8); // XOUT
+//_MAKE_MOTATE_PIN( , 'B', 9); // XIN
+//_MAKE_MOTATE_PIN( , 'B', 10); // USB_D-
+//_MAKE_MOTATE_PIN( , 'B', 11); // USB_D+
+//_MAKE_MOTATE_PIN( , 'B', 12); // ERASE
+_MAKE_MOTATE_PIN(kUnassigned22, 'B', 13); //
+
+_MAKE_MOTATE_PIN(kUSBVBUS_PinNumber, 'D', 0); // USB_VBUS
+_MAKE_MOTATE_PIN(kInput1_PinNumber, 'D', 1); //
+_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 2); //
+_MAKE_MOTATE_PIN(kUnassigned23, 'D', 3); //
+_MAKE_MOTATE_PIN(kUnassigned24, 'D', 4); //
+_MAKE_MOTATE_PIN(kUnassigned25, 'D', 5); //
+_MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 6); //
+_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'D', 7); //
+_MAKE_MOTATE_PIN(kOutput5_PinNumber, 'D', 8); // INTERRUPT_OUT
+_MAKE_MOTATE_PIN(kUnassigned26, 'D', 9); //
+_MAKE_MOTATE_PIN(kUnassigned27, 'D', 10); //
+_MAKE_MOTATE_PIN(kLED_RGBWPixelPinNumber, 'D', 11); // PWM0 - kOutput3_PinNumber
+_MAKE_MOTATE_PIN(kSocket4_SPISlaveSelectPinNumber, 'D', 12); //
+_MAKE_MOTATE_PIN(kUnassigned28, 'D', 13); //
+_MAKE_MOTATE_PIN(kUnassigned29, 'D', 14); //
+_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'D', 15); //
+_MAKE_MOTATE_PIN(kUnassigned30, 'D', 16); //
+_MAKE_MOTATE_PIN(kUnassigned31, 'D', 17); //
+_MAKE_MOTATE_PIN(kUnassigned32, 'D', 18); //
+_MAKE_MOTATE_PIN(kUnassigned33, 'D', 19); //
+_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'D', 20); //
+_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'D', 21); //
+_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'D', 22); //
+_MAKE_MOTATE_PIN(kUnassigned34, 'D', 23); // Missing in 100-pin package
+_MAKE_MOTATE_PIN(kInput6_PinNumber, 'D', 24); // DIAG1
+_MAKE_MOTATE_PIN(kSocket1_SPISlaveSelectPinNumber, 'D', 25); //
+_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'D', 26); //
+_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'D', 27); //
+_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'D', 28); //
+_MAKE_MOTATE_PIN(kUnassigned35, 'D', 29); // Missing in 100-pin package
+_MAKE_MOTATE_PIN(kLEDPWM_PinNumber, 'D', 30); //
+_MAKE_MOTATE_PIN(kUnassigned36, 'D', 31); //
+
+} // namespace Motate
+
+// We then allow each chip-type to have it's onw function definitions
+// that will refer to these pin assignments.
+#include "motate_chip_pin_functions.h"
+
+#endif
+
+// GQUADRATIC_C_PINOUT_H
diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h
index 9c3b27504..827346fb4 100644
--- a/g2core/board/gquadratic/hardware.h
+++ b/g2core/board/gquadratic/hardware.h
@@ -29,6 +29,7 @@
*/
#include "config.h"
+#include "settings.h"
#include "error.h"
#ifndef HARDWARE_H_ONCE
@@ -70,6 +71,11 @@ enum hwPlatform {
// ARM specific code start here
#include "MotatePins.h"
+#if QUADRATIC_REVISION == 'C'
+#define MOTOR_1_IS_TRINAMIC
+#define MOTOR_2_IS_TRINAMIC
+#include "MotateSPI.h"
+#endif
#include "MotateTimers.h" // for TimerChanel<> and related...
#include "MotateServiceCall.h" // for ServiceCall<>
@@ -89,43 +95,16 @@ using Motate::OutputPin;
#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16)
#define SYS_ID_LEN 24 // total length including dashes and NUL
-/************************************************************************************
- **** ARM SAM3X8E SPECIFIC HARDWARE *************************************************
- ************************************************************************************/
-
-/**** Resource Assignment via Motate ****
- *
- * This section defines resource usage for pins, timers, PWM channels, communications
- * and other resources. Please refer to /motate/utility/SamPins.h, SamTimers.h and
- * other files for pinouts and other configuration details.
- *
- * Commenting out or #ifdef'ing out definitions below will cause the compiler to
- * drop references to these resources from the compiled code. This will reduce
- * compiled code size and runtime CPU cycles. E.g. if you are compiling for a 3 motor,
- * XYZ axis config commenting out the higher motors and axes here will remove them
- * from later code (using the motate .isNull() test).
- */
-
-/* Interrupt usage and priority
- *
- * The following interrupts are defined w/indicated priorities
- *
- * 0 DDA_TIMER (9) for step pulse generation
- * 1 DWELL_TIMER (10) for dwell timing
- * 2 LOADER software generated interrupt (STIR / SGI)
- * 3 Serial read character interrupt
- * 4 EXEC software generated interrupt (STIR / SGI)
- * 5 Serial write character interrupt
- */
-
/**** Stepper DDA and dwell timer settings ****/
//#define FREQUENCY_DDA 200000UL // Hz step frequency. Interrupts actually fire at 2x (400 KHz)
-#define FREQUENCY_DDA 200000UL // Hz step frequency. Interrupts actually fire at 2x (300 KHz)
+#define FREQUENCY_DDA 400000UL // Hz step frequency. Interrupts actually fire at 2x (300 KHz)
#define FREQUENCY_DWELL 1000UL
#define MIN_SEGMENT_MS ((float)0.125) // S70 can handle much much smaller segements
+#define PLANNER_BUFFER_POOL_SIZE (60)
+
/**** Motate Definitions ****/
// Timer definitions. See stepper.h and other headers for setup
@@ -137,14 +116,17 @@ typedef TimerChannel<11, 0> fwd_plan_timer_type; // request exec timer in step
pin_number indicator_led_pin_num = Motate::kLEDPWM_PinNumber;
static OutputPin IndicatorLed;
+/**** SPI Setup ****/
+#if QUADRATIC_REVISION == 'C'
+Motate::service_call_number kSPI_ServiceCallNumber = 3;
+
+typedef Motate::SPIBus SPIBus_used_t;
+extern SPIBus_used_t spiBus;
+
+#endif
+
/**** Motate Global Pin Allocations ****/
-// static OutputPin spi_ss1_pin;
-// static OutputPin spi_ss2_pin;
-// static OutputPin spi_ss3_pin;
-// static OutputPin spi_ss4_pin;
-// static OutputPin spi_ss5_pin;
-// static OutputPin spi_ss6_pin;
static OutputPin kinen_sync_pin;
static OutputPin grbl_reset_pin;
@@ -152,14 +134,12 @@ static OutputPin grbl_feedhold_pin;
static OutputPin grbl_cycle_start_pin;
static OutputPin motor_common_enable_pin;
-static OutputPin spindle_enable_pin;
-static OutputPin spindle_dir_pin;
-
-// NOTE: In the v9 and the Due the flood and mist coolants are mapped to a the same pin
-// static OutputPin coolant_enable_pin;
-static OutputPin flood_enable_pin;
-static OutputPin mist_enable_pin;
+#define SPINDLE_OUTPUT_NUMBER 1 // drive our primary output as a spindle
+#define SPINDLE_ENABLE_OUTPUT_NUMBER 2 // use output 2 as the enable line for the spindle
+#define SPINDLE_DIRECTION_OUTPUT_NUMBER 0 // no direction control
+#define MIST_ENABLE_OUTPUT_NUMBER 0 // no mist
+#define FLOOD_ENABLE_OUTPUT_NUMBER 0 // no flood
// Input pins are defined in gpio.cpp
/********************************
diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h
index 0057a9e4c..57c099bb0 100755
--- a/g2core/board/gquadratic/motate_pin_assignments.h
+++ b/g2core/board/gquadratic/motate_pin_assignments.h
@@ -157,13 +157,14 @@ pin_number kDebug3_PinNumber = -1; // 116; //e Not the out-of-order numbering &
pin_number kDebug4_PinNumber = -1; // 114;
// END DEBUG PINS
-pin_number kLED_USBRXPinNumber = 117;
-pin_number kLED_USBTXPinNumber = 118;
-pin_number kSD_CardDetectPinNumber = 119;
-pin_number kSD_ChipSelectPinNumber = 120;
-pin_number kInterlock_InPinNumber = 121;
-pin_number kOutputSAFE_PinNumber = 122; // SAFE signal
-pin_number kLEDPWM_PinNumber = 123;
+pin_number kLED_USBRXPinNumber = 117;
+pin_number kLED_USBTXPinNumber = 118;
+pin_number kSD_CardDetectPinNumber = -1;
+pin_number kSD_ChipSelectPinNumber = -1;
+pin_number kUSBVBUS_PinNumber = 119;
+pin_number kInterlock_InPinNumber = 121;
+pin_number kOutputSAFE_PinNumber = 122; // SAFE signal
+pin_number kLEDPWM_PinNumber = 123;
pin_number kOutputInterrupt_PinNumber = 124; // to-host interrupt signal
pin_number kLED_RGBWPixelPinNumber = 125; // 117;
@@ -225,6 +226,8 @@ pin_number kServo3_PinNumber = 173; //
// blank spots for unassigned pins - all unassigned pins need a unique number (do not re-use numbers)
+pin_number kUnassigned40 = 215;
+pin_number kUnassigned39 = 216;
pin_number kUnassigned38 = 217;
pin_number kUnassigned37 = 218;
pin_number kUnassigned36 = 219;
diff --git a/g2core/board/gquintic/board_gpio.cpp b/g2core/board/gquintic/board_gpio.cpp
new file mode 100644
index 000000000..76f1ed70f
--- /dev/null
+++ b/g2core/board/gquintic/board_gpio.cpp
@@ -0,0 +1,143 @@
+/*
+ * gpio.cpp - digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2107 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Switch Modes
+ *
+ * The switches are considered to be homing switches when cycle_state is
+ * CYCLE_HOMING. At all other times they are treated as limit switches:
+ * - Hitting a homing switch puts the current move into feedhold
+ * - Hitting a limit switch causes the machine to shut down and go into lockdown until reset
+ *
+ * The normally open switch modes (NO) trigger an interrupt on the falling edge
+ * and lockout subsequent interrupts for the defined lockout period. This approach
+ * beats doing debouncing as an integration as switches fire immediately.
+ *
+ * The normally closed switch modes (NC) trigger an interrupt on the rising edge
+ * and lockout subsequent interrupts for the defined lockout period. Ditto on the method.
+ */
+
+#include "../../g2core.h" // #1
+#include "config.h" // #2
+#include "gpio.h"
+#include "hardware.h"
+#include "canonical_machine.h"
+
+#include "text_parser.h"
+#include "controller.h"
+#include "util.h"
+#include "report.h"
+#include "xio.h"
+
+#include "MotateTimers.h"
+
+/**** Setup Actual Objects ****/
+
+gpioDigitalInputPin> din1 {DI1_ENABLED, DI1_POLARITY, 1, DI1_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din2 {DI2_ENABLED, DI2_POLARITY, 2, DI2_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din3 {DI3_ENABLED, DI3_POLARITY, 3, DI3_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din4 {DI4_ENABLED, DI4_POLARITY, 4, DI4_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din5 {DI5_ENABLED, DI5_POLARITY, 5, DI5_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din6 {DI6_ENABLED, DI6_POLARITY, 6, DI6_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din7 {DI7_ENABLED, DI7_POLARITY, 7, DI7_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din8 {DI8_ENABLED, DI8_POLARITY, 8, DI8_EXTERNAL_NUMBER};
+gpioDigitalInputPin> din9 {DI9_ENABLED, DI9_POLARITY, 9, DI9_EXTERNAL_NUMBER};
+// gpioDigitalInputPin> din10 {DI10ENABLEDE, DI10_POLARITY, 10, DI10_EXTERNAL_NUMBER};
+// gpioDigitalInputPin> din11 {DI11ENABLEDE, DI11_POLARITY, 11, DI11_EXTERNAL_NUMBER};
+// gpioDigitalInputPin> din12 {DI12ENABLEDE, DI12_POLARITY, 12, DI12_EXTERNAL_NUMBER};
+
+gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4, &din5, &din6, &din7, &din8, &din9};
+
+
+gpioDigitalOutputPin> dout1 { DO1_ENABLED, DO1_POLARITY, DO1_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout2 { DO2_ENABLED, DO2_POLARITY, DO2_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout3 { DO3_ENABLED, DO3_POLARITY, DO3_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout4 { DO4_ENABLED, DO4_POLARITY, DO4_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout5 { DO5_ENABLED, DO5_POLARITY, DO5_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout6 { DO6_ENABLED, DO6_POLARITY, DO6_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout7 { DO7_ENABLED, DO7_POLARITY, DO7_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout8 { DO8_ENABLED, DO8_POLARITY, DO8_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout9 { DO9_ENABLED, DO9_POLARITY, DO9_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout10 { DO10_ENABLED, DO10_POLARITY, DO10_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout11 { DO11_ENABLED, DO11_POLARITY, DO11_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout12 { DO12_ENABLED, DO12_POLARITY, DO12_EXTERNAL_NUMBER, (uint32_t)200000 };
+gpioDigitalOutputPin> dout13 { DO13_ENABLED, DO13_POLARITY, DO13_EXTERNAL_NUMBER, (uint32_t)200000 };
+
+gpioDigitalOutput* const d_out[] = {&dout1, &dout2, &dout3, &dout4, &dout5, &dout6, &dout7, &dout8, &dout9, &dout10, &dout11, &dout12, &dout13};
+
+
+#if QUINTIC_REVISION == 'C'
+
+gpioAnalogInputPin> ai1 {AI1_ENABLED, gpioAnalogInput::AIN_TYPE_EXTERNAL, 1, AI1_EXTERNAL_NUMBER, spiBus, spiCSPinMux.getCS(5)};
+gpioAnalogInputPin> ai2 {AI2_ENABLED, gpioAnalogInput::AIN_TYPE_EXTERNAL, 2, AI2_EXTERNAL_NUMBER, spiBus, spiCSPinMux.getCS(6)};
+gpioAnalogInputPin> ai3 {AI3_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 3, AI3_EXTERNAL_NUMBER};
+gpioAnalogInputPin> ai4 {AI4_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 4, AI4_EXTERNAL_NUMBER};
+
+gpioAnalogInput* const a_in[] = {&ain1, &ain2, &ain3, &ain4};
+
+#endif // 'C'
+
+#if QUINTIC_REVISION == 'D'
+
+gpioAnalogInputPin> ai1 {AI1_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 1, AI1_EXTERNAL_NUMBER};
+gpioAnalogInputPin> ai2 {AI2_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 2, AI2_EXTERNAL_NUMBER};
+gpioAnalogInputPin> ai3 {AI3_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 3, AI3_EXTERNAL_NUMBER};
+gpioAnalogInputPin> ai4 {AI4_ENABLED, gpioAnalogInput::AIN_TYPE_INTERNAL, 4, AI4_EXTERNAL_NUMBER};
+
+gpioAnalogInput* const a_in[] = {&ai1, &ai2, &ai3, &ai4};
+
+#endif // 'D'
+
+
+/************************************************************************************
+ **** CODE **************************************************************************
+ ************************************************************************************/
+
+
+ // Register a SysTick event to call start_sampling every temperature_sample_freq ms
+ const int16_t ain_sample_freq = 10;
+ int16_t ain_sample_counter = ain_sample_freq;
+ Motate::SysTickEvent ain_tick_event {[&] {
+ if (!--ain_sample_counter) {
+ ai1.startSampling();
+ ai2.startSampling();
+ ai3.startSampling();
+ ai4.startSampling();
+ ain_sample_counter = ain_sample_freq;
+ }
+ }, nullptr};
+
+/*
+ * gpio_reset() - reset inputs and outputs (no initialization)
+ */
+
+void outputs_reset(void) {
+ // nothing to do
+}
+
+void inputs_reset(void) {
+ SysTickTimer.registerEvent(&ain_tick_event);
+}
diff --git a/g2core/board/gquintic/board_gpio.h b/g2core/board/gquintic/board_gpio.h
new file mode 100644
index 000000000..1dedb7ad8
--- /dev/null
+++ b/g2core/board/gquintic/board_gpio.h
@@ -0,0 +1,197 @@
+/*
+ * gpio.h - Digital IO handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2017 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2017 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software. If not, see .
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef BOARD_GPIO_H_ONCE
+#define BOARD_GPIO_H_ONCE
+
+// this file is included from the bottom of gpio.h, but we do this for completeness
+#include "../../gpio.h"
+#include "hardware.h"
+
+/*
+ * GPIO defines
+ */
+//--- change as required for board and switch hardware ---//
+
+#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing
+
+/*
+ * The GPIO objects themselves - this must match up with board_gpio.cpp!
+ */
+
+// prepare the objects as externs (for config_app to not bloat)
+using Motate::IRQPin;
+using Motate::PWMOutputPin;
+using Motate::PWMLikeOutputPin;
+using Motate::ADCPin;
+using Motate::ADCDifferentialPair;
+template
+using OutputType = typename std::conditional, PWMLikeOutputPin>::type;
+
+#define D_IN_CHANNELS 9 // number of digital inputs supported
+
+extern gpioDigitalInputPin> din1;
+extern gpioDigitalInputPin> din2;
+extern gpioDigitalInputPin> din3;
+extern gpioDigitalInputPin> din4;
+extern gpioDigitalInputPin