From 290466578f8bb6ba0cd61e1dd3dc0839ae53d4f3 Mon Sep 17 00:00:00 2001
From: Giuliano Zaro <3684609+GMagician@users.noreply.github.com>
Date: Sun, 28 Jul 2019 21:48:29 +0200
Subject: [PATCH] Adafruit Grand Central M4 (#14749)

---
 .travis.yml                                   |   1 +
 Marlin/Configuration_adv.h                    |   2 +-
 Marlin/src/HAL/HAL.h                          |   2 +
 Marlin/src/HAL/HAL_SAMD51/HAL.cpp             | 475 ++++++++++++++++++
 Marlin/src/HAL/HAL_SAMD51/HAL.h               | 141 ++++++
 Marlin/src/HAL/HAL_SAMD51/HAL_spi_SAMD51.cpp  | 151 ++++++
 .../src/HAL/HAL_SAMD51/HAL_timers_SAMD51.cpp  | 135 +++++
 Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.h | 117 +++++
 .../src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp |  55 ++
 .../src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h   |  25 +
 Marlin/src/HAL/HAL_SAMD51/SAMD51.h            |  70 +++
 Marlin/src/HAL/HAL_SAMD51/SanityCheck.h       |  48 ++
 Marlin/src/HAL/HAL_SAMD51/Tone.cpp            |  59 +++
 .../src/HAL/HAL_SAMD51/endstop_interrupts.h   | 184 +++++++
 Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h     | 251 +++++++++
 .../HAL_SAMD51/persistent_store_eeprom.cpp    | 129 +++++
 Marlin/src/HAL/HAL_SAMD51/pinsDebug.h         | 153 ++++++
 Marlin/src/HAL/HAL_SAMD51/spi_pins.h          |  54 ++
 Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.cpp |  53 ++
 Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.h   |  31 ++
 .../src/HAL/shared/backtrace/unwmemaccess.cpp |  11 +
 Marlin/src/core/boards.h                      |   5 +
 Marlin/src/core/drivers.h                     |   2 +-
 Marlin/src/gcode/calibrate/M100.cpp           |  16 +-
 Marlin/src/inc/Conditionals_LCD.h             |   2 +
 Marlin/src/pins/pins.h                        |   7 +
 Marlin/src/pins/pinsDebug_list.h              |   2 +-
 .../src/pins/samd/pins_AGCM4_RURAMPS4D_13.h   | 254 ++++++++++
 README.md                                     |   3 +-
 .../tests/adafruit_grandcentral_m4-tests      |  14 +
 config/default/Configuration_adv.h            |   2 +-
 .../3DFabXYZ/Migbot/Configuration_adv.h       |   2 +-
 .../AlephObjects/TAZ4/Configuration_adv.h     |   2 +-
 .../examples/Alfawise/U20/Configuration_adv.h |   2 +-
 .../AliExpress/UM2pExt/Configuration_adv.h    |   2 +-
 config/examples/Anet/A2/Configuration_adv.h   |   2 +-
 .../examples/Anet/A2plus/Configuration_adv.h  |   2 +-
 config/examples/Anet/A6/Configuration_adv.h   |   2 +-
 config/examples/Anet/A8/Configuration_adv.h   |   2 +-
 .../examples/Anet/A8plus/Configuration_adv.h  |   2 +-
 config/examples/Anet/E16/Configuration_adv.h  |   2 +-
 .../examples/AnyCubic/i3/Configuration_adv.h  |   2 +-
 config/examples/ArmEd/Configuration_adv.h     |   2 +-
 .../BIBO/TouchX/cyclops/Configuration_adv.h   |   2 +-
 .../BIBO/TouchX/default/Configuration_adv.h   |   2 +-
 .../examples/BQ/Hephestos/Configuration_adv.h |   2 +-
 .../BQ/Hephestos_2/Configuration_adv.h        |   2 +-
 config/examples/BQ/WITBOX/Configuration_adv.h |   2 +-
 config/examples/Cartesio/Configuration_adv.h  |   2 +-
 .../Creality/CR-10/Configuration_adv.h        |   2 +-
 .../Creality/CR-10S/Configuration_adv.h       |   2 +-
 .../Creality/CR-10_5S/Configuration_adv.h     |   2 +-
 .../Creality/CR-10mini/Configuration_adv.h    |   2 +-
 .../Creality/CR-20 Pro/Configuration_adv.h    |   2 +-
 .../Creality/CR-20/Configuration_adv.h        |   2 +-
 .../Creality/CR-8/Configuration_adv.h         |   2 +-
 .../Creality/Ender-2/Configuration_adv.h      |   2 +-
 .../Creality/Ender-3/Configuration_adv.h      |   2 +-
 .../Creality/Ender-4/Configuration_adv.h      |   2 +-
 .../Creality/Ender-5/Configuration_adv.h      |   2 +-
 .../Dagoma/Disco Ultimate/Configuration_adv.h |   2 +-
 .../Sidewinder X1/Configuration_adv.h         |   2 +-
 .../examples/Einstart-S/Configuration_adv.h   |   2 +-
 .../FYSETC/AIO_II/Configuration_adv.h         |   2 +-
 .../Cheetah/BLTouch/Configuration_adv.h       |   2 +-
 .../FYSETC/Cheetah/base/Configuration_adv.h   |   2 +-
 .../examples/FYSETC/F6_13/Configuration_adv.h |   2 +-
 config/examples/Felix/Configuration_adv.h     |   2 +-
 .../FlashForge/CreatorPro/Configuration_adv.h |   2 +-
 .../FolgerTech/i3-2020/Configuration_adv.h    |   2 +-
 .../Formbot/Raptor/Configuration_adv.h        |   2 +-
 .../Formbot/T_Rex_2+/Configuration_adv.h      |   2 +-
 .../Formbot/T_Rex_3/Configuration_adv.h       |   2 +-
 .../examples/Geeetech/A10/Configuration_adv.h |   2 +-
 .../Geeetech/A10M/Configuration_adv.h         |   2 +-
 .../Geeetech/A20M/Configuration_adv.h         |   2 +-
 .../Geeetech/MeCreator2/Configuration_adv.h   |   2 +-
 .../Prusa i3 Pro C/Configuration_adv.h        |   2 +-
 .../Prusa i3 Pro W/Configuration_adv.h        |   2 +-
 .../Infitary/i3-M508/Configuration_adv.h      |   2 +-
 .../examples/JGAurora/A1/Configuration_adv.h  |   2 +-
 .../examples/JGAurora/A5/Configuration_adv.h  |   2 +-
 .../examples/JGAurora/A5S/Configuration_adv.h |   2 +-
 .../examples/MakerParts/Configuration_adv.h   |   2 +-
 .../examples/Malyan/M150/Configuration_adv.h  |   2 +-
 .../examples/Malyan/M200/Configuration_adv.h  |   2 +-
 .../Micromake/C1/enhanced/Configuration_adv.h |   2 +-
 config/examples/Mks/Robin/Configuration_adv.h |   2 +-
 config/examples/Mks/Sbase/Configuration_adv.h |   2 +-
 .../RapideLite/RL200/Configuration_adv.h      |   2 +-
 config/examples/RigidBot/Configuration_adv.h  |   2 +-
 config/examples/SCARA/Configuration_adv.h     |   2 +-
 .../Black_STM32F407VET6/Configuration_adv.h   |   2 +-
 .../examples/Sanguinololu/Configuration_adv.h |   2 +-
 .../Tevo/Michelangelo/Configuration_adv.h     |   2 +-
 .../Tevo/Tarantula Pro/Configuration_adv.h    |   2 +-
 .../Tornado/V1 (MKS Base)/Configuration_adv.h |   2 +-
 .../V2 (MKS GEN-L)/Configuration_adv.h        |   2 +-
 config/examples/TheBorg/Configuration_adv.h   |   2 +-
 config/examples/TinyBoy2/Configuration_adv.h  |   2 +-
 .../examples/Tronxy/X3A/Configuration_adv.h   |   2 +-
 .../Tronxy/X5S-2E/Configuration_adv.h         |   2 +-
 .../UltiMachine/Archim1/Configuration_adv.h   |   2 +-
 .../UltiMachine/Archim2/Configuration_adv.h   |   2 +-
 .../examples/VORONDesign/Configuration_adv.h  |   2 +-
 .../Velleman/K8200/Configuration_adv.h        |   2 +-
 .../Velleman/K8400/Configuration_adv.h        |   2 +-
 .../WASP/PowerWASP/Configuration_adv.h        |   2 +-
 .../Wanhao/Duplicator 6/Configuration_adv.h   |   2 +-
 .../Duplicator i3 Mini/Configuration_adv.h    |   2 +-
 .../delta/Anycubic/Kossel/Configuration_adv.h |   2 +-
 .../FLSUN/auto_calibrate/Configuration_adv.h  |   2 +-
 .../delta/FLSUN/kossel/Configuration_adv.h    |   2 +-
 .../FLSUN/kossel_mini/Configuration_adv.h     |   2 +-
 .../Geeetech/Rostock 301/Configuration_adv.h  |   2 +-
 .../delta/MKS/SBASE/Configuration_adv.h       |   2 +-
 .../Tevo Little Monster/Configuration_adv.h   |   2 +-
 .../delta/generic/Configuration_adv.h         |   2 +-
 .../delta/kossel_mini/Configuration_adv.h     |   2 +-
 .../delta/kossel_xl/Configuration_adv.h       |   2 +-
 .../gCreate/gMax1.5+/Configuration_adv.h      |   2 +-
 config/examples/makibox/Configuration_adv.h   |   2 +-
 .../tvrrug/Round2/Configuration_adv.h         |   2 +-
 config/examples/wt150/Configuration_adv.h     |   2 +-
 platformio.ini                                |  14 +
 125 files changed, 2555 insertions(+), 99 deletions(-)
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/HAL.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/HAL.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/HAL_spi_SAMD51.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/SAMD51.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/SanityCheck.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/Tone.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/pinsDebug.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/spi_pins.h
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.cpp
 create mode 100644 Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.h
 create mode 100644 Marlin/src/pins/samd/pins_AGCM4_RURAMPS4D_13.h
 create mode 100644 buildroot/share/tests/adafruit_grandcentral_m4-tests

diff --git a/.travis.yml b/.travis.yml
index 43e7ca5e40..ad11d95e58 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ env:
   - TEST_PLATFORM="esp32"
   - TEST_PLATFORM="alfawise_U20"
   - TEST_PLATFORM="black_stm32f407ve"
+  - TEST_PLATFORM="adafruit_grandcentral_m4"
 
 before_install:
   #
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 0a03107aa6..37d21ec138 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index da779286f5..6b6ad03d4f 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -41,6 +41,8 @@
   #define HAL_PLATFORM HAL_ESP32
 #elif defined(__PLAT_LINUX__)
   #define HAL_PLATFORM HAL_LINUX
+#elif defined(__SAMD51__)
+  #define HAL_PLATFORM HAL_SAMD51
 #else
   #error "Unsupported Platform!"
 #endif
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.cpp b/Marlin/src/HAL/HAL_SAMD51/HAL.cpp
new file mode 100644
index 0000000000..1c2a9d53fd
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL.cpp
@@ -0,0 +1,475 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __SAMD51__
+
+#include "../../inc/MarlinConfig.h"
+#include "Adafruit_ZeroDMA.h"
+#include "wiring_private.h"
+
+// ------------------------
+// Local defines
+// ------------------------
+
+#if HAS_TEMP_ADC_0
+  #define GET_TEMP_0_ADC()          PIN_TO_ADC(TEMP_0_PIN)
+#else
+  #define GET_TEMP_0_ADC()          -1
+#endif
+#if HAS_TEMP_ADC_1
+  #define GET_TEMP_1_ADC()          PIN_TO_ADC(TEMP_1_PIN)
+#else
+  #define GET_TEMP_1_ADC()          -1
+#endif
+#if HAS_TEMP_ADC_2
+  #define GET_TEMP_2_ADC()          PIN_TO_ADC(TEMP_2_PIN)
+#else
+  #define GET_TEMP_2_ADC()          -1
+#endif
+#if HAS_TEMP_ADC_3
+  #define GET_TEMP_3_ADC()          PIN_TO_ADC(TEMP_3_PIN)
+#else
+  #define GET_TEMP_3_ADC()          -1
+#endif
+#if HAS_TEMP_ADC_4
+  #define GET_TEMP_4_ADC()          PIN_TO_ADC(TEMP_4_PIN)
+#else
+  #define GET_TEMP_4_ADC()          -1
+#endif
+#if HAS_TEMP_ADC_5
+  #define GET_TEMP_5_ADC()          PIN_TO_ADC(TEMP_5_PIN)
+#else
+  #define GET_TEMP_5_ADC()          -1
+#endif
+#if HAS_HEATED_BED
+  #define GET_BED_ADC()             PIN_TO_ADC(TEMP_BED_PIN)
+#else
+  #define GET_BED_ADC()             -1
+#endif
+#if HAS_HEATED_CHAMBER
+  #define GET_CHAMBER_ADC()         PIN_TO_ADC(TEMP_CHAMBER_PIN)
+#else
+  #define GET_CHAMBER_ADC()         -1
+#endif
+#if ENABLED(FILAMENT_WIDTH_SENSOR)
+  #define GET_FILAMENT_WIDTH_ADC()  PIN_TO_ADC(FILWIDTH_PIN)
+#else
+  #define GET_FILAMENT_WIDTH_ADC()  -1
+#endif
+#if HAS_ADC_BUTTONS
+  #define GET_BUTTONS_ADC()         PIN_TO_ADC(ADC_KEYPAD_PIN)
+#else
+  #define GET_BUTTONS_ADC()         -1
+#endif
+
+#define IS_ADC_REQUIRED(n)      (GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n      \
+                                 || GET_TEMP_3_ADC() == n || GET_TEMP_4_ADC() == n || GET_TEMP_5_ADC() == n   \
+                                 || GET_BED_ADC() == n                                                        \
+                                 || GET_CHAMBER_ADC() == n                                                    \
+                                 || GET_FILAMENT_WIDTH_ADC() == n                                             \
+                                 || GET_BUTTONS_ADC() == n)
+
+#define ADC0_IS_REQUIRED    IS_ADC_REQUIRED(0)
+#define ADC1_IS_REQUIRED    IS_ADC_REQUIRED(1)
+#define ADC_IS_REQUIRED     (ADC0_IS_REQUIRED || ADC1_IS_REQUIRED)
+#if ADC0_IS_REQUIRED
+  #define FIRST_ADC     0
+#else
+  #define FIRST_ADC     1
+#endif
+#if ADC1_IS_REQUIRED
+  #define LAST_ADC      1
+#else
+  #define LAST_ADC      0
+#endif
+
+#define DMA_IS_REQUIRED     ADC_IS_REQUIRED
+
+// ------------------------
+// Types
+// ------------------------
+
+#if DMA_IS_REQUIRED
+
+  // Struct must be 32 bits aligned because of DMA accesses but fields needs to be 8 bits packed
+  typedef struct  __attribute__((aligned(4), packed)) {
+    ADC_INPUTCTRL_Type INPUTCTRL;
+  } HAL_DMA_DAC_Registers;    // DMA transfered registers
+
+#endif
+
+// ------------------------
+// Private Variables
+// ------------------------
+
+uint16_t HAL_adc_result;
+
+#if ADC_IS_REQUIRED
+
+  // Pins used by ADC inputs. Order must be ADC0 inputs first then ADC1
+  const uint8_t adc_pins[] = {
+    // ADC0 pins
+    #if GET_TEMP_0_ADC() == 0
+      TEMP_0_PIN,
+    #endif
+    #if GET_TEMP_1_ADC() == 0
+      TEMP_1_PIN,
+    #endif
+    #if GET_TEMP_2_ADC() == 0
+      TEMP_2_PIN,
+    #endif
+    #if GET_TEMP_3_ADC() == 0
+      TEMP_3_PIN,
+    #endif
+    #if GET_TEMP_4_ADC() == 0
+      TEMP_4_PIN,
+    #endif
+    #if GET_TEMP_5_ADC() == 0
+      TEMP_5_PIN,
+    #endif
+    #if GET_BED_ADC() == 0
+      TEMP_BED_PIN,
+    #endif
+    #if GET_CHAMBER_ADC() == 0
+      TEMP_CHAMBER_PIN,
+    #endif
+    #if GET_FILAMENT_WIDTH_ADC() == 0
+      FILWIDTH_PIN,
+    #endif
+    #if GET_BUTTONS_ADC() == 0
+      ADC_KEYPAD_PIN,
+    #endif
+    // ADC1 pins
+    #if GET_TEMP_0_ADC() == 1
+      TEMP_0_PIN,
+    #endif
+    #if GET_TEMP_1_ADC() == 1
+      TEMP_1_PIN,
+    #endif
+    #if GET_TEMP_2_ADC() == 1
+      TEMP_2_PIN,
+    #endif
+    #if GET_TEMP_3_ADC() == 1
+      TEMP_3_PIN,
+    #endif
+    #if GET_TEMP_4_ADC() == 1
+      TEMP_4_PIN,
+    #endif
+    #if GET_TEMP_5_ADC() == 1
+      TEMP_5_PIN,
+    #endif
+    #if GET_BED_ADC() == 1
+      TEMP_BED_PIN,
+    #endif
+    #if GET_CHAMBER_ADC() == 1
+      TEMP_CHAMBER_PIN,
+    #endif
+    #if GET_FILAMENT_WIDTH_ADC() == 1
+      FILWIDTH_PIN,
+    #endif
+    #if GET_BUTTONS_ADC() == 1
+      ADC_KEYPAD_PIN,
+    #endif
+  };
+
+  uint16_t HAL_adc_results[COUNT(adc_pins)];
+
+  #if ADC0_IS_REQUIRED
+    Adafruit_ZeroDMA adc0ProgramDMA,
+                     adc0ReadDMA;
+
+    const HAL_DMA_DAC_Registers adc0_dma_regs_list[] = {
+      #if GET_TEMP_0_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_0_PIN) },
+      #endif
+      #if GET_TEMP_1_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_1_PIN) },
+      #endif
+      #if GET_TEMP_2_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_2_PIN) },
+      #endif
+      #if GET_TEMP_3_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_3_PIN) },
+      #endif
+      #if GET_TEMP_4_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_4_PIN) },
+      #endif
+      #if GET_TEMP_5_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_5_PIN) },
+      #endif
+      #if GET_BED_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
+      #endif
+      #if GET_CHAMBER_ADC() == 0
+        { PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
+      #endif
+      #if GET_FILAMENT_WIDTH_ADC() == 0
+        { PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
+      #endif
+      #if GET_BUTTONS_ADC() == 0
+        { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
+      #endif
+    };
+
+    #define ADC0_AINCOUNT   COUNT(adc0_dma_regs_list)
+  #endif // ADC0_IS_REQUIRED
+
+  #if ADC1_IS_REQUIRED
+    Adafruit_ZeroDMA adc1ProgramDMA,
+                     adc1ReadDMA;
+
+    const HAL_DMA_DAC_Registers adc1_dma_regs_list[] = {
+      #if GET_TEMP_0_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_0_PIN) },
+      #endif
+      #if GET_TEMP_1_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_1_PIN) },
+      #endif
+      #if GET_TEMP_2_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_2_PIN) },
+      #endif
+      #if GET_TEMP_3_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_3_PIN) },
+      #endif
+      #if GET_TEMP_4_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_4_PIN) },
+      #endif
+      #if GET_TEMP_5_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_5_PIN) },
+      #endif
+      #if GET_BED_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
+      #endif
+      #if GET_CHAMBER_ADC() == 1
+        { PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
+      #endif
+      #if GET_FILAMENT_WIDTH_ADC() == 1
+        { PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
+      #endif
+      #if GET_BUTTONS_ADC() == 1
+        { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
+      #endif
+    };
+
+    #define ADC1_AINCOUNT   COUNT(adc1_dma_regs_list)
+  #endif // ADC1_IS_REQUIRED
+
+#endif // ADC_IS_REQUIRED
+
+// ------------------------
+// Private functions
+// ------------------------
+
+#if DMA_IS_REQUIRED
+
+  void dma_init() {
+    DmacDescriptor *descriptor;
+
+    #if ADC0_IS_REQUIRED
+      adc0ProgramDMA.setTrigger(ADC0_DMAC_ID_SEQ);
+      adc0ProgramDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
+      adc0ProgramDMA.loop(true);
+      if (adc0ProgramDMA.allocate() == DMA_STATUS_OK) {
+        descriptor = adc0ProgramDMA.addDescriptor(
+          (void *)adc0_dma_regs_list,         // SRC
+          (void *)&ADC0->DSEQDATA.reg,        // DEST
+          sizeof(adc0_dma_regs_list) / 4,     // CNT
+          DMA_BEAT_SIZE_WORD,
+          true,                               // SRCINC
+          false,                              // DSTINC
+          DMA_ADDRESS_INCREMENT_STEP_SIZE_1,  // STEPSIZE
+          DMA_STEPSEL_SRC                     // STEPSEL
+        );
+        if (descriptor != nullptr)
+          descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
+        adc0ProgramDMA.startJob();
+      }
+
+      adc0ReadDMA.setTrigger(ADC0_DMAC_ID_RESRDY);
+      adc0ReadDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
+      adc0ReadDMA.loop(true);
+      if (adc0ReadDMA.allocate() == DMA_STATUS_OK) {
+        adc0ReadDMA.addDescriptor(
+          (void *)&ADC0->RESULT.reg,          // SRC
+          &HAL_adc_results,                   // DEST
+          ADC0_AINCOUNT,                      // CNT
+          DMA_BEAT_SIZE_HWORD,
+          false,                              // SRCINC
+          true,                               // DSTINC
+          DMA_ADDRESS_INCREMENT_STEP_SIZE_1,  // STEPSIZE
+          DMA_STEPSEL_DST                     // STEPSEL
+        );
+        adc0ReadDMA.startJob();
+      }
+    #endif
+    #if ADC1_IS_REQUIRED
+      adc1ProgramDMA.setTrigger(ADC1_DMAC_ID_SEQ);
+      adc1ProgramDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
+      adc1ProgramDMA.loop(true);
+      if (adc1ProgramDMA.allocate() == DMA_STATUS_OK) {
+        descriptor = adc1ProgramDMA.addDescriptor(
+          (void *)adc1_dma_regs_list,         // SRC
+          (void *)&ADC1->DSEQDATA.reg,        // DEST
+          sizeof(adc1_dma_regs_list) / 4,     // CNT
+          DMA_BEAT_SIZE_WORD,
+          true,                               // SRCINC
+          false,                              // DSTINC
+          DMA_ADDRESS_INCREMENT_STEP_SIZE_1,  // STEPSIZE
+          DMA_STEPSEL_SRC                     // STEPSEL
+        );
+        if (descriptor != nullptr)
+          descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
+        adc1ProgramDMA.startJob();
+      }
+
+      adc1ReadDMA.setTrigger(ADC1_DMAC_ID_RESRDY);
+      adc1ReadDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
+      adc1ReadDMA.loop(true);
+      if (adc1ReadDMA.allocate() == DMA_STATUS_OK) {
+        adc1ReadDMA.addDescriptor(
+          (void *)&ADC1->RESULT.reg,          // SRC
+          &HAL_adc_results[ADC0_AINCOUNT],    // DEST
+          ADC1_AINCOUNT,                      // CNT
+          DMA_BEAT_SIZE_HWORD,
+          false,                              // SRCINC
+          true,                               // DSTINC
+          DMA_ADDRESS_INCREMENT_STEP_SIZE_1,  // STEPSIZE
+          DMA_STEPSEL_DST                     // STEPSEL
+        );
+        adc1ReadDMA.startJob();
+      }
+    #endif
+
+    DMAC->PRICTRL0.bit.RRLVLEN0 = true;                         // Activate round robin for DMA channels used by ADCs
+  }
+
+#endif // DMA_IS_REQUIRED
+
+// ------------------------
+// Public functions
+// ------------------------
+
+// HAL initialization task
+void HAL_init(void) {
+  #if DMA_IS_REQUIRED
+    dma_init();
+  #endif
+  #if ENABLED(SDSUPPORT)
+    #if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)    // SD_DETECT_PIN may be remove when NO_SD_HOST_DRIVE is not defined in configuration_adv
+      SET_INPUT_PULLUP(SD_DETECT_PIN);
+    #endif
+    OUT_WRITE(SDSS, HIGH);  // Try to set SDSS inactive before any other SPI users start up
+  #endif
+}
+
+// HAL idle task
+/*
+void HAL_idletask(void) {
+}
+*/
+
+void HAL_clear_reset_source(void) { }
+
+#pragma push_macro("WDT")
+#undef WDT    // Required to be able to use '.bit.WDT'. Compiler wrongly replace struct field with WDT define 
+uint8_t HAL_get_reset_source(void) {
+  RSTC_RCAUSE_Type resetCause;
+
+  resetCause.reg = REG_RSTC_RCAUSE;
+  if (resetCause.bit.POR)                                   return RST_POWER_ON;
+  else if (resetCause.bit.EXT)                              return RST_EXTERNAL;
+  else if (resetCause.bit.BODCORE || resetCause.bit.BODVDD) return RST_BROWN_OUT;
+  else if (resetCause.bit.WDT)                              return RST_WATCHDOG;
+  else if (resetCause.bit.SYST || resetCause.bit.NVM)       return RST_SOFTWARE;
+  else if (resetCause.bit.BACKUP)                           return RST_BACKUP;
+  return 0;
+}
+#pragma pop_macro("WDT")
+
+extern "C" {
+  void * _sbrk(int incr);
+
+  extern unsigned int __bss_end__; // end of bss section
+}
+
+// Return free memory between end of heap (or end bss) and whatever is current
+int freeMemory() {
+  int free_memory, heap_end = (int)_sbrk(0);
+  return (int)&free_memory - (heap_end ? heap_end : (int)&__bss_end__);
+}
+
+// ------------------------
+// ADC
+// ------------------------
+
+void HAL_adc_init(void) {
+  #if ADC_IS_REQUIRED
+    memset(HAL_adc_results, 0xFF, sizeof(HAL_adc_results));                 // Fill result with invalid values
+
+    for (uint8_t pi = 0; pi < COUNT(adc_pins); ++pi)
+        pinPeripheral(adc_pins[pi], PIO_ANALOG);
+
+    for (uint8_t ai = FIRST_ADC; ai <= LAST_ADC; ++ai) {
+      Adc* adc = ((Adc*[])ADC_INSTS)[ai];
+
+      // ADC clock setup
+      GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN = false;
+      SYNC(GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN);
+      GCLK->PCHCTRL[ADC0_GCLK_ID + ai].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN;   // 48MHz startup code programmed
+      SYNC(!GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN);
+      adc->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val;             // 1.5MHZ adc clock
+
+      // ADC setup
+      // Preloaded data (fixed for all ADC instances hence not loaded by DMA)
+      adc->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;               // VRefA pin
+      SYNC(adc->SYNCBUSY.bit.REFCTRL);
+      adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
+      SYNC(adc->SYNCBUSY.bit.CTRLB);
+      adc->SAMPCTRL.bit.SAMPLEN = (6 - 1);                                  // Sampling clocks
+      // Registers loaded by DMA
+      adc->DSEQCTRL.bit.INPUTCTRL = true;
+
+      adc->DSEQCTRL.bit.AUTOSTART = true;                                   // Start conversion after DMA sequence
+
+      adc->CTRLA.bit.ENABLE = true;                                         // Enable ADC
+      SYNC(adc->SYNCBUSY.bit.ENABLE);
+    }
+  #endif // ADC_IS_REQUIRED
+}
+
+void HAL_adc_start_conversion(const uint8_t adc_pin) {
+  #if ADC_IS_REQUIRED
+    for (uint8_t pi = 0; pi < COUNT(adc_pins); ++pi) {
+      if (adc_pin == adc_pins[pi]) {
+        HAL_adc_result = HAL_adc_results[pi];
+        return;
+      }
+    }
+  #endif
+
+  HAL_adc_result = 0xFFFF;
+}
+
+uint16_t HAL_adc_get_result(void) {
+  return HAL_adc_result;
+}
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL.h b/Marlin/src/HAL/HAL_SAMD51/HAL.h
new file mode 100644
index 0000000000..3dd1313462
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL.h
@@ -0,0 +1,141 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#define CPU_32_BIT
+
+#include "../shared/Marduino.h"
+#include "../shared/math_32bit.h"
+#include "../shared/HAL_SPI.h"
+#include "fastio_SAMD51.h"
+#include "watchdog_SAMD51.h"
+#include "HAL_timers_SAMD51.h"
+
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+  #include "MarlinSerial_AGCM4.h"
+
+  // Serial ports
+  #if !WITHIN(SERIAL_PORT, -1, 3)
+    #error "SERIAL_PORT must be from -1 to 3"
+  #endif
+
+  // MYSERIAL0 required before MarlinSerial includes!
+  #if SERIAL_PORT == -1
+    #define MYSERIAL0 Serial
+  #elif SERIAL_PORT == 0
+    #define MYSERIAL0 Serial1
+  #elif SERIAL_PORT == 1
+    #define MYSERIAL0 Serial2
+  #elif SERIAL_PORT == 2
+    #define MYSERIAL0 Serial3
+  #else
+    #define MYSERIAL0 Serial4
+  #endif
+
+  #ifdef SERIAL_PORT_2
+    #if !WITHIN(SERIAL_PORT_2, -1, 3)
+      #error "SERIAL_PORT_2 must be from -1 to 3"
+    #elif SERIAL_PORT_2 == SERIAL_PORT
+      #error "SERIAL_PORT_2 must be different than SERIAL_PORT"
+    #endif
+    #define NUM_SERIAL 2
+    #if SERIAL_PORT_2 == -1
+      #define MYSERIAL1 Serial
+    #elif SERIAL_PORT_2 == 0
+      #define MYSERIAL1 Serial1
+    #elif SERIAL_PORT_2 == 1
+      #define MYSERIAL1 Serial2
+    #elif SERIAL_PORT_2 == 2
+      #define MYSERIAL1 Serial3
+    #else
+      #define MYSERIAL1 Serial4
+    #endif
+  #else
+    #define NUM_SERIAL 1
+  #endif
+
+#endif // ADAFRUIT_GRAND_CENTRAL_M4
+
+typedef int8_t pin_t;
+
+//#define HAL_SERVO_LIB Servo
+
+//
+// Interrupts
+//
+#define CRITICAL_SECTION_START  uint32_t primask = __get_PRIMASK(); __disable_irq()
+#define CRITICAL_SECTION_END    if (!primask) __enable_irq()
+#define ISRS_ENABLED() (!__get_PRIMASK())
+#define ENABLE_ISRS()  __enable_irq()
+#define DISABLE_ISRS() __disable_irq()
+
+#define cli() __disable_irq()       // Disable interrupts
+#define sei() __enable_irq()        // Enable interrupts
+
+void HAL_clear_reset_source(void);  // clear reset reason
+uint8_t HAL_get_reset_source(void); // get reset reason
+
+//
+// EEPROM
+//
+void eeprom_write_byte(uint8_t *pos, unsigned char value);
+uint8_t eeprom_read_byte(uint8_t *pos);
+
+//
+// ADC
+//
+extern uint16_t HAL_adc_result;     // result of last ADC conversion
+
+#define HAL_ANALOG_SELECT(pin)
+
+void HAL_adc_init(void);
+
+#define HAL_START_ADC(pin)  HAL_adc_start_conversion(pin)
+#define HAL_READ_ADC()      HAL_adc_result
+#define HAL_ADC_READY()     true
+
+void HAL_adc_start_conversion(const uint8_t adc_pin);
+uint16_t HAL_adc_get_result(void);
+
+//
+// Pin Map
+//
+#define GET_PIN_MAP_PIN(index) index
+#define GET_PIN_MAP_INDEX(pin) pin
+#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
+
+//
+// Tone
+//
+void toneInit();
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
+void noTone(const pin_t _pin);
+
+// Enable hooks into idle and setup for HAL
+void HAL_init(void);
+/*#define HAL_IDLETASK 1
+void HAL_idletask(void);*/
+
+//
+// Utility functions
+//
+FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+int freeMemory(void);
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL_spi_SAMD51.cpp b/Marlin/src/HAL/HAL_SAMD51/HAL_spi_SAMD51.cpp
new file mode 100644
index 0000000000..b03aea0e4a
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL_spi_SAMD51.cpp
@@ -0,0 +1,151 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Hardware and software SPI implementations are included in this file.
+ *
+ * Control of the slave select pin(s) is handled by the calling routines and
+ * SAMD51 let hardware SPI handling to remove SS from its logic.
+ */
+
+#ifdef __SAMD51__
+
+// --------------------------------------------------------------------------
+// Includes
+// --------------------------------------------------------------------------
+
+#include "../../inc/MarlinConfig.h"
+#include <SPI.h>
+
+// --------------------------------------------------------------------------
+// Public functions
+// --------------------------------------------------------------------------
+
+#if EITHER(SOFTWARE_SPI, FORCE_SOFT_SPI)
+
+  // ------------------------
+  // Software SPI
+  // ------------------------
+  #error "Software SPI not supported for SAMD51. Use Hardware SPI."
+
+  #if SD_CONNECTION_IS(ONBOARD)
+  #endif
+
+#else // !SOFTWARE_SPI
+
+  #ifdef ADAFRUIT_GRAND_CENTRAL_M4
+    #if SD_CONNECTION_IS(ONBOARD)
+      #define sdSPI SDCARD_SPI
+    #else
+      #define sdSPI SPI
+    #endif
+  #endif
+
+  static SPISettings spiConfig;
+
+  // ------------------------
+  // Hardware SPI
+  // ------------------------
+  void spiBegin(void) {
+    spiInit(SPI_HALF_SPEED);
+  }
+
+  void spiInit(uint8_t spiRate) {
+    // Use datarates Marlin uses
+    uint32_t clock;
+    switch (spiRate) {
+      case SPI_FULL_SPEED:      clock = 8000000; break;
+      case SPI_HALF_SPEED:      clock = 4000000; break;
+      case SPI_QUARTER_SPEED:   clock = 2000000; break;
+      case SPI_EIGHTH_SPEED:    clock = 1000000; break;
+      case SPI_SIXTEENTH_SPEED: clock =  500000; break;
+      case SPI_SPEED_5:         clock =  250000; break;
+      case SPI_SPEED_6:         clock =  125000; break;
+      default:                  clock = 4000000; break; // Default from the SPI library
+    }
+    spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
+    sdSPI.begin();
+  }
+
+  /**
+   * @brief  Receives a single byte from the SPI port.
+   *
+   * @return Byte received
+   *
+   * @details
+   */
+  uint8_t spiRec(void) {
+    sdSPI.beginTransaction(spiConfig);
+    uint8_t returnByte = sdSPI.transfer(0xFF);
+    sdSPI.endTransaction();
+    return returnByte;
+  }
+
+  /**
+   * @brief  Receives a number of bytes from the SPI port to a buffer
+   *
+   * @param  buf   Pointer to starting address of buffer to write to.
+   * @param  nbyte Number of bytes to receive.
+   * @return Nothing
+   */
+  void spiRead(uint8_t* buf, uint16_t nbyte) {
+    if (nbyte == 0) return;
+    memset(buf, 0xFF, nbyte);
+    sdSPI.beginTransaction(spiConfig);
+    sdSPI.transfer(buf, nbyte);
+    sdSPI.endTransaction();
+  }
+
+  /**
+   * @brief  Sends a single byte on SPI port
+   *
+   * @param  b Byte to send
+   *
+   * @details
+   */
+  void spiSend(uint8_t b) {
+    sdSPI.beginTransaction(spiConfig);
+    sdSPI.transfer(b);
+    sdSPI.endTransaction();
+  }
+
+  /**
+   * @brief  Write token and then write from 512 byte buffer to SPI (for SD card)
+   *
+   * @param  buf   Pointer with buffer start address
+   * @return Nothing
+   *
+   * @details Uses DMA
+   */
+  void spiSendBlock(uint8_t token, const uint8_t* buf) {
+    sdSPI.beginTransaction(spiConfig);
+    sdSPI.transfer(token);
+    sdSPI.transfer((uint8_t*)buf, nullptr, 512);
+    sdSPI.endTransaction();
+  }
+
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
+    spiConfig = SPISettings(spiClock, (BitOrder)bitOrder, dataMode);
+    sdSPI.beginTransaction(spiConfig);
+  }
+#endif // !SOFTWARE_SPI
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.cpp b/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.cpp
new file mode 100644
index 0000000000..70733e2415
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.cpp
@@ -0,0 +1,135 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __SAMD51__
+
+// --------------------------------------------------------------------------
+// Includes
+// --------------------------------------------------------------------------
+#include "../../inc/MarlinConfig.h"
+#include "HAL_timers_SAMD51.h"
+
+// --------------------------------------------------------------------------
+// Local defines
+// --------------------------------------------------------------------------
+
+#define NUM_HARDWARE_TIMERS 8
+
+// --------------------------------------------------------------------------
+// Private Variables
+// --------------------------------------------------------------------------
+
+const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS] = {
+  { TC0, TC0_IRQn, TC_PRIORITY(0) },
+  { TC1, TC1_IRQn, TC_PRIORITY(1) },
+  { TC2, TC2_IRQn, TC_PRIORITY(2) },
+  { TC3, TC3_IRQn, TC_PRIORITY(3) },
+  { TC4, TC4_IRQn, TC_PRIORITY(4) },
+  { TC5, TC5_IRQn, TC_PRIORITY(5) },
+  { TC6, TC6_IRQn, TC_PRIORITY(6) },
+  { TC7, TC7_IRQn, TC_PRIORITY(7) }
+};
+
+// --------------------------------------------------------------------------
+// Private functions
+// --------------------------------------------------------------------------
+
+FORCE_INLINE void Disable_Irq(IRQn_Type irq) {
+  NVIC_DisableIRQ(irq);
+
+  // We NEED memory barriers to ensure Interrupts are actually disabled!
+  // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
+  __DSB();
+  __ISB();
+}
+
+// --------------------------------------------------------------------------
+// Public functions
+// --------------------------------------------------------------------------
+
+void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
+  Tc * const tc = TimerConfig[timer_num].pTimer;
+  IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+
+  // Disable interrupt, just in case it was already enabled
+  Disable_Irq(irq);
+
+  // Disable timer interrupt
+  tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
+
+  // TCn clock setup
+  const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num];
+  GCLK->PCHCTRL[clockID].bit.CHEN = false;
+  SYNC(GCLK->PCHCTRL[clockID].bit.CHEN);
+  GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;   // 120MHz startup code programmed
+  SYNC(!GCLK->PCHCTRL[clockID].bit.CHEN);
+
+  // Stop timer, just in case, to be able to reconfigure it
+  tc->COUNT32.CTRLA.bit.ENABLE = false;
+  SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
+
+  // Reset timer
+  tc->COUNT32.CTRLA.bit.SWRST = true;
+  SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST);
+
+  NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
+
+  // Wave mode, reset counter on overflow on 0 (I use count down to prevent double buffer use)
+  tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
+  tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1;
+  tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_DIR;
+  SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
+
+  // Set compare value
+  tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = HAL_TIMER_RATE / frequency;
+
+  // And start timer
+  tc->COUNT32.CTRLA.bit.ENABLE = true;
+  SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
+
+  // Enable interrupt on RC compare
+  tc->COUNT32.INTENSET.reg = TC_INTENCLR_OVF; // enable overflow interrupt
+
+  // Finally, enable IRQ
+  NVIC_EnableIRQ(irq);
+}
+
+void HAL_timer_enable_interrupt(const uint8_t timer_num) {
+  IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+  NVIC_EnableIRQ(irq);
+}
+
+void HAL_timer_disable_interrupt(const uint8_t timer_num) {
+  IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+  Disable_Irq(irq);
+}
+
+// missing from CMSIS: Check if interrupt is enabled or not
+static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
+  return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
+}
+
+bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
+  IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+  return NVIC_GetEnabledIRQ(irq);
+}
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.h b/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.h
new file mode 100644
index 0000000000..60d2b32962
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/HAL_timers_SAMD51.h
@@ -0,0 +1,117 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include <stdint.h>
+
+// --------------------------------------------------------------------------
+// Defines
+// --------------------------------------------------------------------------
+
+typedef uint32_t hal_timer_t;
+#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
+
+#define HAL_TIMER_RATE      SystemCoreClock  // frequency of timers peripherals
+
+#define STEP_TIMER_NUM      0  // index of timer to use for stepper (also +1 for 32bits counter)
+#define PULSE_TIMER_NUM     STEP_TIMER_NUM
+#define TONE_TIMER_NUM      2  // index of timer to use for beeper tones (also +1 for 32bits counter)
+#define TEMP_TIMER_NUM      4  // index of timer to use for temperature (also +1 for 32bits counter)
+
+#define TEMP_TIMER_FREQUENCY   1000 // temperature interrupt frequency
+
+#define STEPPER_TIMER_RATE          HAL_TIMER_RATE   // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
+#define STEPPER_TIMER_TICKS_PER_US  ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
+#define STEPPER_TIMER_PRESCALE      (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
+
+#define PULSE_TIMER_RATE          STEPPER_TIMER_RATE
+#define PULSE_TIMER_PRESCALE      STEPPER_TIMER_PRESCALE
+#define PULSE_TIMER_TICKS_PER_US  STEPPER_TIMER_TICKS_PER_US
+
+#define ENABLE_STEPPER_DRIVER_INTERRUPT()   HAL_timer_enable_interrupt(STEP_TIMER_NUM)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT()  HAL_timer_disable_interrupt(STEP_TIMER_NUM)
+#define STEPPER_ISR_ENABLED()               HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
+
+#define ENABLE_TEMPERATURE_INTERRUPT()  HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+
+#define TC_PRIORITY(t)        (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2     \
+                               : (t == TEMP_TIMER_NUM) ? 6                          \
+                               : (t == TONE_TIMER_NUM) ? 5 : 7
+#define _TC_HANDLER(t)        void TC##t##_Handler()
+#define TC_HANDLER(t)         _TC_HANDLER(t)
+#define HAL_STEP_TIMER_ISR()  TC_HANDLER(STEP_TIMER_NUM)
+#if STEP_TIMER_NUM != PULSE_TIMER_NUM
+  #define HAL_PULSE_TIMER_ISR()  TC_HANDLER(PULSE_TIMER_NUM)
+#endif
+#define HAL_TEMP_TIMER_ISR()  TC_HANDLER(TEMP_TIMER_NUM)
+#define HAL_TONE_TIMER_ISR()  TC_HANDLER(TONE_TIMER_NUM)
+
+// --------------------------------------------------------------------------
+// Types
+// --------------------------------------------------------------------------
+
+typedef struct {
+  Tc          *pTimer;
+  IRQn_Type   IRQ_Id;
+  uint8_t     priority;
+} tTimerConfig;
+
+// --------------------------------------------------------------------------
+// Public Variables
+// --------------------------------------------------------------------------
+
+extern const tTimerConfig TimerConfig[];
+
+// --------------------------------------------------------------------------
+// Public functions
+// --------------------------------------------------------------------------
+
+void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
+
+FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
+  Tc * const tc = TimerConfig[timer_num].pTimer;
+  tc->COUNT32.CC[0].reg = HAL_TIMER_TYPE_MAX - compare;
+}
+
+FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
+  Tc * const tc = TimerConfig[timer_num].pTimer;
+  return (hal_timer_t)(HAL_TIMER_TYPE_MAX - tc->COUNT32.CC[0].reg);
+}
+
+FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
+  Tc * const tc = TimerConfig[timer_num].pTimer;
+  tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
+  SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
+  return HAL_TIMER_TYPE_MAX - tc->COUNT32.COUNT.reg;
+}
+
+void HAL_timer_enable_interrupt(const uint8_t timer_num);
+void HAL_timer_disable_interrupt(const uint8_t timer_num);
+bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
+
+FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
+  Tc * const tc = TimerConfig[timer_num].pTimer;
+  // Clear interrupt flag
+  tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
+}
+
+#define HAL_timer_isr_epilogue(timer_num)
diff --git a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp b/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp
new file mode 100644
index 0000000000..5e582806d3
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.cpp
@@ -0,0 +1,55 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+
+/**
+ * Framework doesn't define some serial to save sercom resources
+ * hence if these are used I need to define them
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
+  Uart Serial2(&sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
+  void SERCOM4_0_Handler() { Serial2.IrqHandler(); }
+  void SERCOM4_1_Handler() { Serial2.IrqHandler(); }
+  void SERCOM4_2_Handler() { Serial2.IrqHandler(); }
+  void SERCOM4_3_Handler() { Serial2.IrqHandler(); }
+#endif
+
+#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2
+  Uart Serial3(&sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
+  void SERCOM1_0_Handler() { Serial3.IrqHandler(); }
+  void SERCOM1_1_Handler() { Serial3.IrqHandler(); }
+  void SERCOM1_2_Handler() { Serial3.IrqHandler(); }
+  void SERCOM1_3_Handler() { Serial3.IrqHandler(); }
+#endif
+
+#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3
+  Uart Serial4(&sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
+  void SERCOM5_0_Handler() { Serial4.IrqHandler(); }
+  void SERCOM5_1_Handler() { Serial4.IrqHandler(); }
+  void SERCOM5_2_Handler() { Serial4.IrqHandler(); }
+  void SERCOM5_3_Handler() { Serial4.IrqHandler(); }
+#endif
+
+#endif // ADAFRUIT_GRAND_CENTRAL_M4
diff --git a/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h b/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h
new file mode 100644
index 0000000000..9f318709d7
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/MarlinSerial_AGCM4.h
@@ -0,0 +1,25 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+extern Uart Serial2;
+extern Uart Serial3;
+extern Uart Serial4;
diff --git a/Marlin/src/HAL/HAL_SAMD51/SAMD51.h b/Marlin/src/HAL/HAL_SAMD51/SAMD51.h
new file mode 100644
index 0000000000..63d53a9600
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/SAMD51.h
@@ -0,0 +1,70 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#define SYNC(sc)    while (sc) {   \
+                      asm("");     \
+                    }
+
+// Get SAMD port/pin from specified arduino pin
+#define GET_SAMD_PORT(P)    _GET_SAMD_PORT(PIN_TO_SAMD_PIN(P))
+#define GET_SAMD_PIN(P)     _GET_SAMD_PIN(PIN_TO_SAMD_PIN(P))
+
+// Get external interrupt line associated to specified arduino pin
+#define PIN_TO_EILINE(P)    _SAMDPORTPIN_TO_EILINE(GET_SAMD_PORT(P), GET_SAMD_PIN(P))
+
+// Get adc/ain associated to specified arduino pin
+#define PIN_TO_ADC(P)       (ANAPIN_TO_ADCAIN(P) >> 8)
+#define PIN_TO_AIN(P)       (ANAPIN_TO_ADCAIN(P) & 0xFF)
+
+// Private defines
+#define PIN_TO_SAMD_PIN(P)    DIO##P##_PIN
+
+#define _GET_SAMD_PORT(P)     ((P) >> 5)
+#define _GET_SAMD_PIN(P)      ((P) & 0x1F)
+
+// Get external interrupt line
+#define _SAMDPORTPIN_TO_EILINE(P,B)   ((P == 0 && WITHIN(B, 0, 31) && B != 8 && B != 26 && B != 28 && B != 29) ? (B) & 0xF    \
+                                       : (P == 1 && (WITHIN(B, 0, 25) || WITHIN(B, 30, 31))) ? (B) & 0xF                      \
+                                       : (P == 1 && WITHIN(B, 26, 29)) ? 12 + (B) - 26                                        \
+                                       : (P == 2 && (WITHIN(B, 0, 6) || WITHIN(B, 10, 31)) && B != 29) ? (B) & 0xF            \
+                                       : (P == 2 && B == 7) ? 9                                                               \
+                                       : (P == 3 && WITHIN(B, 0, 1)) ? (B)                                                    \
+                                       : (P == 3 && WITHIN(B, 8, 12)) ? 3 + (B) - 8                                           \
+                                       : (P == 3 && WITHIN(B, 20, 21)) ? 10 + (B) - 20                                        \
+                                       : -1)
+
+// Get adc/ain
+#define ANAPIN_TO_ADCAIN(P)     _PIN_TO_ADCAIN(ANAPIN_TO_SAMDPIN(P))
+#define _PIN_TO_ADCAIN(P)       _SAMDPORTPIN_TO_ADCAIN(_GET_SAMD_PORT(P), _GET_SAMD_PIN(P))
+
+#define _SAMDPORTPIN_TO_ADCAIN(P,B)       ((P == 0 && WITHIN(B, 2, 3)) ? 0x000 + (B) - 2            \
+                                           : (P == 0 && WITHIN(B, 4, 7)) ? 0x000 + (B)              \
+                                           : (P == 0 && WITHIN(B, 8, 9)) ? 0x100 + 2 + (B) - 8      \
+                                           : (P == 0 && WITHIN(B, 10, 11)) ? 0x000 + (B)            \
+                                           : (P == 1 && WITHIN(B, 0, 3)) ? 0x000 + 12 + (B)         \
+                                           : (P == 1 && WITHIN(B, 4, 7)) ? 0x100 + 6 + (B) - 4      \
+                                           : (P == 1 && WITHIN(B, 8, 9)) ? 0x100 + (B) - 8          \
+                                           : (P == 2 && WITHIN(B, 0, 1)) ? 0x100 + 10 + (B)         \
+                                           : (P == 2 && WITHIN(B, 2, 3)) ? 0x100 + 4 + (B) - 2      \
+                                           : (P == 2 && WITHIN(B, 30, 31)) ? 0x100 + 12 + (B) - 30  \
+                                           : (P == 3 && WITHIN(B, 0, 1)) ? 0x100 + 14 + (B)         \
+                                           : -1)
diff --git a/Marlin/src/HAL/HAL_SAMD51/SanityCheck.h b/Marlin/src/HAL/HAL_SAMD51/SanityCheck.h
new file mode 100644
index 0000000000..93317e0049
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/SanityCheck.h
@@ -0,0 +1,48 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Test SAMD51 specific configuration values for errors at compile-time.
+ */
+
+#if defined(ADAFRUIT_GRAND_CENTRAL_M4) && SD_CONNECTION_IS(CUSTOM_CABLE)
+  #error "No custom SD drive cable defined for this board."
+#endif
+
+#if defined(MAX6675_SCK_PIN) && defined(MAX6675_DO_PIN) && (MAX6675_SCK_PIN == SCK1 || MAX6675_DO_PIN == MISO1)
+  #error "OnBoard SPI BUS can't be shared with other devices."
+#endif
+
+#if ENABLED(EMERGENCY_PARSER)
+  #error "EMERGENCY_PARSER is not yet implemented for STM32F4. Disable EMERGENCY_PARSER to continue."
+#endif
+
+#if ENABLED(SDIO_SUPPORT)
+  #error "SDIO_SUPPORT is not supported."
+#endif
+
+#if ENABLED(FAST_PWM_FAN)
+  #error "FAST_PWM_FAN is not yet implemented for this platform."
+#endif
+
+#if ENABLED(EEPROM_SETTINGS) && NONE(SPI_EEPROM, I2C_EEPROM)
+  #warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Activator"
+#endif
diff --git a/Marlin/src/HAL/HAL_SAMD51/Tone.cpp b/Marlin/src/HAL/HAL_SAMD51/Tone.cpp
new file mode 100644
index 0000000000..58b9698251
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/Tone.cpp
@@ -0,0 +1,59 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Description: Tone function for Arduino Due and compatible (SAM3X8E)
+ * Derived from http://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
+ */
+
+#ifdef __SAMD51__
+
+#include "../../inc/MarlinConfig.h"
+#include "HAL_timers_SAMD51.h"
+
+static pin_t tone_pin;
+volatile static int32_t toggles;
+
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
+  tone_pin = _pin;
+  toggles = 2 * frequency * duration / 1000;
+  HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
+}
+
+void noTone(const pin_t _pin) {
+  HAL_timer_disable_interrupt(TONE_TIMER_NUM);
+  extDigitalWrite(_pin, LOW);
+}
+
+HAL_TONE_TIMER_ISR() {
+  static bool pin_state = false;
+  HAL_timer_isr_prologue(TONE_TIMER_NUM);
+
+  if (toggles) {
+    toggles--;
+    extDigitalWrite(tone_pin, (pin_state = !pin_state));
+  }
+  else noTone(tone_pin);                         // turn off interrupt
+
+  HAL_timer_isr_epilogue(TONE_TIMER_NUM);
+}
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h b/Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h
new file mode 100644
index 0000000000..67f35a97a1
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/endstop_interrupts.h
@@ -0,0 +1,184 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+/**
+ * Endstop interrupts for ATMEL SAMD51 based targets.
+ *
+ * On SAMD51, all pins support external interrupt capability.
+ * Any pin can be used for external interrupts, but there are some restrictions.
+ * At most 16 different external interrupts can be used at one time.
+ * Further, you can’t just pick any 16 pins to use. This is because every pin on the SAMD51
+ * connects to what is called an EXTINT line, and only one pin per EXTINT line can be used for external 
+ * interrupts at a time
+ */
+
+/**
+ * Endstop Interrupts
+ *
+ * Without endstop interrupts the endstop pins must be polled continually in
+ * the temperature-ISR via endstops.update(), most of the time finding no change.
+ * With this feature endstops.update() is called only when we know that at
+ * least one endstop has changed state, saving valuable CPU cycles.
+ *
+ * This feature only works when all used endstop pins can generate an 'external interrupt'.
+ *
+ * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
+ * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
+ */
+
+#include "../../module/endstops.h"
+
+#define MATCH_EILINE(P1,P2)     (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2))
+#if HAS_X_MAX
+  #define MATCH_X_MAX_EILINE(P) MATCH_EILINE(P, X_MAX_PIN)
+#else
+  #define MATCH_X_MAX_EILINE(P) false
+#endif
+#if HAS_X_MIN
+  #define MATCH_X_MIN_EILINE(P) MATCH_EILINE(P, X_MIN_PIN)
+#else
+  #define MATCH_X_MIN_EILINE(P) false
+#endif
+#if HAS_Y_MAX
+   #define MATCH_Y_MAX_EILINE(P) MATCH_EILINE(P, Y_MAX_PIN)
+#else
+   #define MATCH_Y_MAX_EILINE(P) false
+#endif
+#if HAS_Y_MIN
+  #define MATCH_Y_MIN_EILINE(P) MATCH_EILINE(P, Y_MIN_PIN)
+#else
+  #define MATCH_Y_MIN_EILINE(P) false
+#endif
+#if HAS_Z_MAX
+   #define MATCH_Z_MAX_EILINE(P) MATCH_EILINE(P, Z_MAX_PIN)
+#else
+  #define MATCH_Z_MAX_EILINE(P) false
+#endif
+#if HAS_Z_MIN
+  #define MATCH_Z_MIN_EILINE(P) MATCH_EILINE(P, Z_MIN_PIN)
+#else
+  #define MATCH_Z_MIN_EILINE(P) false
+#endif
+#if HAS_Z2_MAX
+  #define MATCH_Z2_MAX_EILINE(P) MATCH_EILINE(P, Z2_MAX_PIN)
+#else
+  #define MATCH_Z2_MAX_EILINE(P) false
+#endif
+#if HAS_Z2_MIN
+  #define MATCH_Z2_MIN_EILINE(P) MATCH_EILINE(P, Z2_MIN_PIN)
+#else
+  #define MATCH_Z2_MIN_EILINE(P) false
+#endif
+#if HAS_Z3_MAX
+  #define MATCH_Z3_MAX_EILINE(P) MATCH_EILINE(P, Z3_MAX_PIN)
+#else
+  #define MATCH_Z3_MAX_EILINE(P) false
+#endif
+#if HAS_Z3_MIN
+  #define MATCH_Z3_MIN_EILINE(P) MATCH_EILINE(P, Z3_MIN_PIN)
+#else
+  #define MATCH_Z3_MIN_EILINE(P) false
+#endif
+#if HAS_Z_MIN_PROBE_PIN
+  #define MATCH_Z_MIN_PROBE_EILINE(P)   MATCH_EILINE(P, Z_MIN_PROBE_PIN)
+#else
+  #define MATCH_Z_MIN_PROBE_EILINE(P) false
+#endif
+#define AVAILABLE_EILINE(P)     (PIN_TO_EILINE(P) != -1                                 \
+                                 && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P)    \
+                                 && !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P)    \
+                                 && !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P)    \
+                                 && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P)  \
+                                 && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P)  \
+                                 && !MATCH_Z_MIN_PROBE_EILINE(P))
+
+// One ISR for all EXT-Interrupts
+void endstop_ISR(void) { endstops.update(); }
+
+void setup_endstop_interrupts(void) {
+  #if HAS_X_MAX
+    #if !AVAILABLE_EILINE(X_MAX_PIN)
+      static_assert(false, "X_MAX_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(X_MAX_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_X_MIN
+    #if !AVAILABLE_EILINE(X_MIN_PIN)
+      static_assert(false, "X_MIN_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(X_MIN_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Y_MAX
+    #if !AVAILABLE_EILINE(Y_MAX_PIN)
+      static_assert(false, "Y_MAX_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Y_MAX_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Y_MIN
+    #if !AVAILABLE_EILINE(Y_MIN_PIN)
+      static_assert(false, "Y_MIN_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Y_MIN_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z_MAX
+    #if !AVAILABLE_EILINE(Z_MAX_PIN)
+      static_assert(false, "Z_MAX_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z_MAX_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z_MIN
+    #if !AVAILABLE_EILINE(Z_MIN_PIN)
+      static_assert(false, "Z_MIN_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z_MIN_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z2_MAX
+    #if !AVAILABLE_EILINE(Z2_MAX_PIN)
+      static_assert(false, "Z2_MAX_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z2_MAX_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z2_MIN
+    #if !AVAILABLE_EILINE(Z2_MIN_PIN)
+      static_assert(false, "Z2_MIN_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z2_MIN_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z3_MAX
+    #if !AVAILABLE_EILINE(Z3_MAX_PIN)
+      static_assert(false, "Z3_MAX_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z3_MAX_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z3_MIN
+    #if !AVAILABLE_EILINE(Z3_MIN_PIN)
+      static_assert(false, "Z3_MIN_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z3_MIN_PIN, endstop_ISR, CHANGE);
+  #endif
+  #if HAS_Z_MIN_PROBE_PIN
+    #if !AVAILABLE_EILINE(Z_MIN_PROBE_PIN)
+      static_assert(false, "Z_MIN_PROBE_PIN has no EXTINT line available.");
+    #endif
+    attachInterrupt(Z_MIN_PROBE_PIN, endstop_ISR, CHANGE);
+  #endif
+}
diff --git a/Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h b/Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h
new file mode 100644
index 0000000000..70847ebf08
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/fastio_SAMD51.h
@@ -0,0 +1,251 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+/**
+ * Fast IO functions for SAMD51
+ */
+
+#include "SAMD51.h"
+
+/**
+ * Utility functions
+ */
+
+#ifndef MASK
+  #define MASK(PIN) (1 << PIN)
+#endif
+
+/**
+ * Magic I/O routines
+ *
+ * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
+ */
+
+// Read a pin
+#define READ(IO)        ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].IN.reg & MASK(GET_SAMD_PIN(IO))) != 0)
+
+// Write to a pin
+#define WRITE(IO,V)     do{                                                     \
+                          const EPortType port = (EPortType)GET_SAMD_PORT(IO);  \
+                          const uint32_t mask = MASK(GET_SAMD_PIN(IO));         \
+                                                                                \
+                          if (V) PORT->Group[port].OUTSET.reg = mask;           \
+                          else PORT->Group[port].OUTCLR.reg = mask;             \
+                        }while(0)
+
+// Toggle a pin
+#define TOGGLE(IO)      PORT->Group[(EPortType)GET_SAMD_PORT(IO)].OUTTGL.reg = MASK(GET_SAMD_PIN(IO));
+
+// Set pin as input
+#define SET_INPUT(IO)           do{                                                                 \
+                                  const EPortType port = (EPortType)GET_SAMD_PORT(IO);              \
+                                  const uint32_t pin = GET_SAMD_PIN(IO);                            \
+                                                                                                    \
+                                  PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN);  \
+                                  PORT->Group[port].DIRCLR.reg = MASK(pin);                         \
+                                }while(0)
+// Set pin as input with pullup
+#define SET_INPUT_PULLUP(IO)    do{                                                                                       \
+                                  const EPortType port = (EPortType)GET_SAMD_PORT(IO);                                    \
+                                  const uint32_t pin = GET_SAMD_PIN(IO);                                                  \
+                                  const uint32_t mask = MASK(pin);                                                        \
+                                                                                                                          \
+                                  PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);   \
+                                  PORT->Group[port].DIRCLR.reg = mask;                                                    \
+                                  PORT->Group[port].OUTSET.reg = mask;                                                    \
+                                }while(0)
+// Set pin as input with pulldown
+#define SET_INPUT_PULLDOWN(IO)  do{                                                                                       \
+                                  const EPortType port = (EPortType)GET_SAMD_PORT(IO);                                    \
+                                  const uint32_t pin = GET_SAMD_PIN(IO);                                                  \
+                                  const uint32_t mask = MASK(pin);                                                        \
+                                                                                                                          \
+                                  PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);   \
+                                  PORT->Group[port].DIRCLR.reg = mask;                                                    \
+                                  PORT->Group[port].OUTCLR.reg = mask;                                                    \
+                                }while(0)
+// Set pin as output (push pull)
+#define SET_OUTPUT(IO)          do{                                                                 \
+                                  const EPortType port = (EPortType)GET_SAMD_PORT(IO);              \
+                                  const uint32_t pin = GET_SAMD_PIN(IO);                            \
+                                                                                                    \
+                                  PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN);  \
+                                  PORT->Group[port].DIRSET.reg = MASK(pin);                         \
+                                }while(0)
+// Set pin as output (open drain)
+#define SET_OUTPUT_OD(IO)       do{                                                                   \
+                                  const EPortType port = (EPortType)GET_SAMD_PORT(IO);                \
+                                  const uint32_t pin = GET_SAMD_PIN(IO);                              \
+                                                                                                      \
+                                  PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_PULLEN);  \
+                                  PORT->Group[port].DIRCLR.reg = MASK(pin);                           \
+                                }while(0)
+// Set pin as PWM (push pull)
+#define SET_PWM(IO)             SET_OUTPUT(IO)
+// Set pin as PWM (open drain)
+#define SET_PWM_OD(IO)          SET_OUTPUT_OD(IO)
+
+// check if pin is an output
+#define IS_OUTPUT(IO)            ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].DIR.reg & MASK(GET_SAMD_PIN(IO))) \
+                                 || (PORT->Group[(EPortType)GET_SAMD_PORT(IO)].PINCFG[GET_SAMD_PIN(IO)].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN)
+// check if pin is an input
+#define IS_INPUT(IO)            !IS_OUTPUT(IO)
+
+// Shorthand
+#define OUT_WRITE(IO,V)         do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
+#define OUT_WRITE_OD(IO,V)      do{ SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
+
+// digitalRead/Write wrappers
+#define extDigitalRead(IO)      digitalRead(IO)
+#define extDigitalWrite(IO,V)   digitalWrite(IO,V)
+
+/**
+ * Ports and functions
+ * Added as necessary or if I feel like it- not a comprehensive list!
+ */
+
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+
+  /*
+   * Adafruit Grand Central M4 has a lot of PWMs the availables are listed here.
+   * Some of these share the same source and so can't be used in the same time
+   */
+  #define PWM_PIN(P)        (WITHIN(P, 2, 13) || WITHIN(P, 22, 23) || WITHIN(P, 44, 45) || P == 48)
+
+  // Return fullfilled ADCx->INPUTCTRL.reg
+  #define PIN_TO_INPUTCTRL(P)     (  (PIN_TO_AIN(P) == 0) ? ADC_INPUTCTRL_MUXPOS_AIN0   \
+                                   : (PIN_TO_AIN(P) == 1) ? ADC_INPUTCTRL_MUXPOS_AIN1   \
+                                   : (PIN_TO_AIN(P) == 2) ? ADC_INPUTCTRL_MUXPOS_AIN2   \
+                                   : (PIN_TO_AIN(P) == 3) ? ADC_INPUTCTRL_MUXPOS_AIN3   \
+                                   : (PIN_TO_AIN(P) == 4) ? ADC_INPUTCTRL_MUXPOS_AIN4   \
+                                   : (PIN_TO_AIN(P) == 5) ? ADC_INPUTCTRL_MUXPOS_AIN5   \
+                                   : (PIN_TO_AIN(P) == 6) ? ADC_INPUTCTRL_MUXPOS_AIN6   \
+                                   : (PIN_TO_AIN(P) == 7) ? ADC_INPUTCTRL_MUXPOS_AIN7   \
+                                   : (PIN_TO_AIN(P) == 8) ? ADC_INPUTCTRL_MUXPOS_AIN8   \
+                                   : (PIN_TO_AIN(P) == 9) ? ADC_INPUTCTRL_MUXPOS_AIN9   \
+                                   : (PIN_TO_AIN(P) == 10) ? ADC_INPUTCTRL_MUXPOS_AIN10 \
+                                   : (PIN_TO_AIN(P) == 11) ? ADC_INPUTCTRL_MUXPOS_AIN11 \
+                                   : (PIN_TO_AIN(P) == 12) ? ADC_INPUTCTRL_MUXPOS_AIN12 \
+                                   : (PIN_TO_AIN(P) == 13) ? ADC_INPUTCTRL_MUXPOS_AIN13 \
+                                   : (PIN_TO_AIN(P) == 14) ? ADC_INPUTCTRL_MUXPOS_AIN14 \
+                                   : ADC_INPUTCTRL_MUXPOS_AIN15)
+
+  #define ANAPIN_TO_SAMDPIN(P)    (  (P == 0) ? PIN_TO_SAMD_PIN(67)   \
+                                   : (P == 1) ? PIN_TO_SAMD_PIN(68)   \
+                                   : (P == 2) ? PIN_TO_SAMD_PIN(69)   \
+                                   : (P == 3) ? PIN_TO_SAMD_PIN(70)   \
+                                   : (P == 4) ? PIN_TO_SAMD_PIN(71)   \
+                                   : (P == 5) ? PIN_TO_SAMD_PIN(72)   \
+                                   : (P == 6) ? PIN_TO_SAMD_PIN(73)   \
+                                   : (P == 7) ? PIN_TO_SAMD_PIN(74)   \
+                                   : (P == 8) ? PIN_TO_SAMD_PIN(54)   \
+                                   : (P == 9) ? PIN_TO_SAMD_PIN(55)   \
+                                   : (P == 10) ? PIN_TO_SAMD_PIN(56)  \
+                                   : (P == 11) ? PIN_TO_SAMD_PIN(57)  \
+                                   : (P == 12) ? PIN_TO_SAMD_PIN(58)  \
+                                   : (P == 13) ? PIN_TO_SAMD_PIN(59)  \
+                                   : (P == 14) ? PIN_TO_SAMD_PIN(60)  \
+                                   : (P == 15) ? PIN_TO_SAMD_PIN(61)  \
+                                   : (P == 16) ? PIN_TO_SAMD_PIN(12)  \
+                                   : (P == 17) ? PIN_TO_SAMD_PIN(13)  \
+                                   : PIN_TO_SAMD_PIN(9))
+
+  #define digitalPinToAnalogInput(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1)
+
+  /*
+   * pins
+   */
+
+   // PORTA
+  #define DIO67_PIN   PIN_PA02    // A0
+  #define DIO59_PIN   PIN_PA04    // A13
+  #define DIO68_PIN   PIN_PA05    // A1
+  #define DIO60_PIN   PIN_PA06    // A14
+  #define DIO61_PIN   PIN_PA07    // A15
+  #define DIO26_PIN   PIN_PA12
+  #define DIO27_PIN   PIN_PA13
+  #define DIO28_PIN   PIN_PA14
+  #define DIO23_PIN   PIN_PA15
+  #define DIO37_PIN   PIN_PA16
+  #define DIO36_PIN   PIN_PA17
+  #define DIO35_PIN   PIN_PA18
+  #define DIO34_PIN   PIN_PA19
+  #define DIO33_PIN   PIN_PA20
+  #define DIO32_PIN   PIN_PA21
+  #define DIO31_PIN   PIN_PA22
+  #define DIO30_PIN   PIN_PA23
+  // PORTB
+  #define DIO12_PIN   PIN_PB00    // A16
+  #define DIO13_PIN   PIN_PB01    // A17
+  #define DIO9_PIN    PIN_PB02    // A18
+  #define DIO69_PIN   PIN_PB03    // A2
+  #define DIO74_PIN   PIN_PB04    // A7
+  #define DIO54_PIN   PIN_PB05    // A8
+  #define DIO55_PIN   PIN_PB06    // A9
+  #define DIO56_PIN   PIN_PB07    // A10
+  #define DIO57_PIN   PIN_PB08    // A11
+  #define DIO58_PIN   PIN_PB09    // A12
+  #define DIO18_PIN   PIN_PB12
+  #define DIO19_PIN   PIN_PB13
+  #define DIO39_PIN   PIN_PB14
+  #define DIO38_PIN   PIN_PB15
+  #define DIO14_PIN   PIN_PB16
+  #define DIO15_PIN   PIN_PB17
+  #define DIO8_PIN    PIN_PB18
+  #define DIO29_PIN   PIN_PB19
+  #define DIO20_PIN   PIN_PB20
+  #define DIO21_PIN   PIN_PB21
+  #define DIO10_PIN   PIN_PB22
+  #define DIO11_PIN   PIN_PB23
+  #define DIO1_PIN    PIN_PB24
+  #define DIO0_PIN    PIN_PB25
+  #define DIO83_PIN   PIN_PB28    // SD_CS
+  #define DIO95_PIN   PIN_PB31    // SD_CD
+  // PORTC
+  #define DIO70_PIN   PIN_PC00    // A3
+  #define DIO71_PIN   PIN_PC01    // A4
+  #define DIO72_PIN   PIN_PC02    // A5
+  #define DIO73_PIN   PIN_PC03    // A6
+  #define DIO48_PIN   PIN_PC04
+  #define DIO49_PIN   PIN_PC05
+  #define DIO46_PIN   PIN_PC06
+  #define DIO47_PIN   PIN_PC07
+  #define DIO45_PIN   PIN_PC10
+  #define DIO44_PIN   PIN_PC11
+  #define DIO41_PIN   PIN_PC12
+  #define DIO40_PIN   PIN_PC13
+  #define DIO43_PIN   PIN_PC14
+  #define DIO42_PIN   PIN_PC15
+  #define DIO25_PIN   PIN_PC16
+  #define DIO24_PIN   PIN_PC17
+  #define DIO2_PIN    PIN_PC18
+  #define DIO3_PIN    PIN_PC19
+  #define DIO4_PIN    PIN_PC20
+  #define DIO5_PIN    PIN_PC21
+  #define DIO16_PIN   PIN_PC22
+  #define DIO17_PIN   PIN_PC23
+  // PORTD
+  #define DIO22_PIN   PIN_PD12
+  #define DIO6_PIN    PIN_PD20
+  #define DIO7_PIN    PIN_PD21
+
+#endif // ADAFRUIT_GRAND_CENTRAL_M4
diff --git a/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp b/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp
new file mode 100644
index 0000000000..40658adfe1
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/persistent_store_eeprom.cpp
@@ -0,0 +1,129 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __SAMD51__
+
+#include "../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS)
+
+#include "../shared/persistent_store_api.h"
+
+#if NONE(SPI_EEPROM, I2C_EEPROM)
+  #define NVMCTRL_CMD(c)    do{                                                 \
+                              SYNC(!NVMCTRL->STATUS.bit.READY);                 \
+                              NVMCTRL->INTFLAG.bit.DONE = true;                 \
+                              NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \
+                              SYNC(NVMCTRL->INTFLAG.bit.DONE);                  \
+                            }while(0)
+  #define NVMCTRL_FLUSH()   do{                                           \
+                              if (NVMCTRL->SEESTAT.bit.LOAD)              \
+                                NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH);  \
+                            }while(0)
+#endif
+
+bool PersistentStore::access_start() {
+  #if NONE(SPI_EEPROM, I2C_EEPROM)
+    NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED;  // Buffered mode and segment reallocation active
+  #endif
+
+  return true; 
+}
+
+bool PersistentStore::access_finish() {
+  #if NONE(SPI_EEPROM, I2C_EEPROM)
+    NVMCTRL_FLUSH();
+    if (!NVMCTRL->SEESTAT.bit.LOCK)
+      NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE);    // Lock E2P data write access
+  #endif
+
+  return true;
+}
+
+bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+  #if NONE(SPI_EEPROM, I2C_EEPROM)
+    if (NVMCTRL->SEESTAT.bit.RLOCK)
+      NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE);    // Unlock E2P data write access
+  #endif
+
+  while (size--) {
+    const uint8_t v = *value;
+    #if ANY(SPI_EEPROM, I2C_EEPROM)
+      uint8_t * const p = (uint8_t * const)pos;
+      if (v != eeprom_read_byte(p)) {
+        eeprom_write_byte(p, v);
+        delay(2);
+        if (eeprom_read_byte(p) != v) {
+          SERIAL_ECHO_MSG(MSG_ERR_EEPROM_WRITE);
+          return true;
+        }
+      }
+    #else
+      SYNC(NVMCTRL->SEESTAT.bit.BUSY);
+      if (NVMCTRL->INTFLAG.bit.SEESFULL)
+        NVMCTRL_FLUSH();      // Next write will trigger a sector reallocation. I need to flush 'pagebuffer'
+      ((volatile uint8_t *)SEEPROM_ADDR)[pos] = v;
+      SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC);
+    #endif
+    crc16(crc, &v, 1);
+    pos++;
+    value++;
+  }
+  return false;
+}
+
+bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+  while (size--) {
+    uint8_t c;
+    #if ANY(SPI_EEPROM, I2C_EEPROM)
+      c = eeprom_read_byte((uint8_t*)pos);
+    #else
+      SYNC(NVMCTRL->SEESTAT.bit.BUSY);
+      c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
+    #endif
+    if (writing) *value = c;
+    crc16(crc, &c, 1);
+    pos++;
+    value++;
+  }
+  return false;
+}
+
+size_t PersistentStore::capacity() {
+  #if ANY(SPI_EEPROM, I2C_EEPROM)
+    return E2END + 1;
+  #else
+    const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
+                  sblk = NVMCTRL->SEESTAT.bit.SBLK;
+
+         if (!psz && !sblk)         return     0;
+    else if (psz <= 2)              return (0x200 << psz);
+    else if (sblk == 1 || psz == 3) return  4096;
+    else if (sblk == 2 || psz == 4) return  8192;
+    else if (sblk <= 4 || psz == 5) return 16384;
+    else if (sblk >= 9 && psz == 7) return 65536;
+    else                            return 32768;
+  #endif
+}
+
+#endif // EEPROM_SETTINGS
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/pinsDebug.h b/Marlin/src/HAL/HAL_SAMD51/pinsDebug.h
new file mode 100644
index 0000000000..99e49536c1
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/pinsDebug.h
@@ -0,0 +1,153 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#define NUMBER_PINS_TOTAL PINS_COUNT
+
+#define digitalRead_mod(p) extDigitalRead(p)
+#define PRINT_PORT(p) do{ SERIAL_ECHOPGM("  Port: "); sprintf_P(buffer, PSTR("%c%02ld"), 'A' + g_APinDescription[p].ulPort, g_APinDescription[p].ulPin); SERIAL_ECHO(buffer); }while (0)
+#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define GET_ARRAY_PIN(p) pin_array[p].pin
+#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
+#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL)
+#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p)
+#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1)
+#define pwm_status(pin) digitalPinHasPWM(pin)
+#define MULTI_NAME_PAD 27 // space needed to be pretty if not first name assigned to a pin
+
+// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
+// uses pin index
+#define M43_NEVER_TOUCH(Q) ((Q) >= 75)
+
+bool GET_PINMODE(int8_t pin) {  // 1: output, 0: input
+  const EPortType samdport = g_APinDescription[pin].ulPort;
+  const uint32_t samdpin = g_APinDescription[pin].ulPin;
+  return PORT->Group[samdport].DIR.reg & MASK(samdpin) || (PORT->Group[samdport].PINCFG[samdpin].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN;
+}
+
+void pwm_details(int32_t pin) {
+  if (pwm_status(pin)) {
+    //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative;
+    //SERIAL_ECHOPAIR("PWM = ", duty);
+  }
+}
+
+/**
+ * AGCM4 Board pin |  PORT  | Label
+ * ----------------+--------+-------
+ *   0             |  PB25  | "RX0"
+ *   1             |  PB24  | "TX0"
+ *   2             |  PC18  |
+ *   3             |  PC19  |
+ *   4             |  PC20  |
+ *   5             |  PC21  |
+ *   6             |  PD20  |
+ *   7             |  PD21  |
+ *   8             |  PB18  |
+ *   9             |  PB2   |
+ *  10             |  PB22  |
+ *  11             |  PB23  |
+ *  12             |  PB0   | "A16"
+ *  13             |  PB1   | LED AMBER "L" / "A17"
+ *  14             |  PB16  | "TX3"
+ *  15             |  PB17  | "RX3"
+ *  16             |  PC22  | "TX2"
+ *  17             |  PC23  | "RX2"
+ *  18             |  PB12  | "TX1" / "A18"
+ *  19             |  PB13  | "RX1"
+ *  20             |  PB20  | "SDA"
+ *  21             |  PB21  | "SCL"
+ *  22             |  PD12  |
+ *  23             |  PA15  |
+ *  24             |  PC17  |
+ *  25             |  PC16  |
+ *  26             |  PA12  |
+ *  27             |  PA13  |
+ *  28             |  PA14  |
+ *  29             |  PB19  |
+ *  30             |  PA23  |
+ *  31             |  PA22  |
+ *  32             |  PA21  |
+ *  33             |  PA20  |
+ *  34             |  PA19  |
+ *  35             |  PA18  |
+ *  36             |  PA17  |
+ *  37             |  PA16  |
+ *  38             |  PB15  |
+ *  39             |  PB14  |
+ *  40             |  PC13  |
+ *  41             |  PC12  |
+ *  42             |  PC15  |
+ *  43             |  PC14  |
+ *  44             |  PC11  |
+ *  45             |  PC10  |
+ *  46             |  PC6   |
+ *  47             |  PC7   |
+ *  48             |  PC4   |
+ *  49             |  PC5   |
+ *  50             |  PD11  |
+ *  51             |  PD8   |
+ *  52             |  PD9   |
+ *  53             |  PD10  |
+ *  54             |  PB5   | "A8"
+ *  55             |  PB6   | "A9"
+ *  56             |  PB7   | "A10"
+ *  57             |  PB8   | "A11"
+ *  58             |  PB9   | "A12"
+ *  69             |  PA4   | "A13"
+ *  60             |  PA6   | "A14"
+ *  61             |  PA7   | "A15"
+ *  62             |  PB17  |
+ *  63             |  PB20  |
+ *  64             |  PD11  |
+ *  65             |  PD8   |
+ *  66             |  PD9   |
+ *  67             |  PA2   | "A0" / "DAC0"
+ *  68             |  PA5   | "A1" / "DAC1"
+ *  69             |  PB3   | "A2"
+ *  70             |  PC0   | "A3"
+ *  71             |  PC1   | "A4"
+ *  72             |  PC2   | "A5"
+ *  73             |  PC3   | "A6"
+ *  74             |  PB4   | "A7"
+ *  75             |  PC31  | LED GREEN "RX"
+ *  76             |  PC30  | LED GREEN "TX"
+ *  77             |  PA27  | USB: Host enable
+ *  78             |  PA24  | USB: D-
+ *  79             |  PA25  | USB: D+
+ *  80             |  PB29  | SD: MISO
+ *  81             |  PB27  | SD: SCK
+ *  82             |  PB26  | SD: MOSI
+ *  83             |  PB28  | SD: CS
+ *  84             |  PA3   | AREF
+ *  85             |  PA2   | DAC0 (Duplicate)
+ *  86             |  PA5   | DAC1 (Duplicate)
+ *  87             |  PB1   | LED AMBER "L" (Duplicate)
+ *  88             |  PC24  | NeoPixel
+ *  89             |  PB10  | QSPI: SCK
+ *  90             |  PB11  | QSPI: CS
+ *  91             |  PA8   | QSPI: IO0
+ *  92             |  PA9   | QSPI: IO1
+ *  93             |  PA10  | QSPI: IO2
+ *  94             |  PA11  | QSPI: IO3
+ *
+ */
diff --git a/Marlin/src/HAL/HAL_SAMD51/spi_pins.h b/Marlin/src/HAL/HAL_SAMD51/spi_pins.h
new file mode 100644
index 0000000000..87fedc9485
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/spi_pins.h
@@ -0,0 +1,54 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+
+ /*
+  * AGCM4 Default SPI Pins
+  *
+  *         SS    SCK   MISO   MOSI
+  *       +-------------------------+
+  *  SPI  | 53    52     50     51  |
+  *  SPI1 | 83    81     80     82  |
+  *       +-------------------------+
+  * Any pin can be used for Chip Select (SS_PIN)
+  */
+  #ifndef SCK_PIN
+    #define SCK_PIN       52
+  #endif
+  #ifndef MISO_PIN
+    #define MISO_PIN      50
+  #endif
+  #ifndef MOSI_PIN
+    #define MOSI_PIN      51
+  #endif
+  #ifndef SDSS
+    #define SDSS          53
+  #endif
+
+#else
+
+  #error "Unsupported board!"
+
+#endif
+
+#define SS_PIN        SDSS
diff --git a/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.cpp b/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.cpp
new file mode 100644
index 0000000000..efcfb6c9af
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.cpp
@@ -0,0 +1,53 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __SAMD51__
+
+#include "../../inc/MarlinConfig.h"
+
+#if ENABLED(USE_WATCHDOG)
+
+  #include "watchdog_SAMD51.h"
+
+  void watchdog_init(void) {
+    // The low-power oscillator used by the WDT runs at 32,768 Hz with
+    // a 1:32 prescale, thus 1024 Hz, though probably not super precise.
+
+    // Setup WDT clocks
+    MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
+    MCLK->APBAMASK.bit.WDT_ = true;
+    OSC32KCTRL->OSCULP32K.bit.EN1K = true;      // Enable out 1K (this is what WDT uses)
+
+    WDT->CTRLA.bit.ENABLE = false;              // Disable watchdog for config
+    SYNC(WDT->SYNCBUSY.bit.ENABLE);
+
+    WDT->INTENCLR.reg = WDT_INTENCLR_EW;        // Disable early warning interrupt
+    WDT->CONFIG.reg = WDT_CONFIG_PER_CYC4096;   // Set at least 4s period for chip reset
+
+    watchdog_reset();
+
+    WDT->CTRLA.reg = WDT_CTRLA_ENABLE;          // Start watchdog now in normal mode
+    SYNC(WDT->SYNCBUSY.bit.ENABLE);
+  }
+
+#endif // USE_WATCHDOG
+
+#endif // __SAMD51__
diff --git a/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.h b/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.h
new file mode 100644
index 0000000000..b4332dace1
--- /dev/null
+++ b/Marlin/src/HAL/HAL_SAMD51/watchdog_SAMD51.h
@@ -0,0 +1,31 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+// Initialize watchdog with a 4 second interrupt time
+void watchdog_init();
+
+// Reset watchdog. MUST be called at least every 4 seconds after the
+// first watchdog_init or SAMD will go into emergency procedures.
+inline void watchdog_reset() {
+  SYNC(WDT->SYNCBUSY.bit.CLEAR);        // Test first if previous is 'ongoing' to save time waiting for command execution
+  WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
+}
diff --git a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
index 20f1a7bc0f..8cf31cadf5 100644
--- a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
+++ b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
@@ -129,6 +129,17 @@
 #define END_FLASH_ADDR    0x00140000
 #endif
 
+#ifdef __SAMD51P20A__
+// For SAMD51x20, valid address ranges are
+//  SRAM  (0x20000000 - 0x20040000) (256kb)
+//  FLASH (0x00000000 - 0x00100000) (1024kb)
+//
+#define START_SRAM_ADDR   0x20000000
+#define END_SRAM_ADDR     0x20040000
+#define START_FLASH_ADDR  0x00000000
+#define END_FLASH_ADDR    0x00100000
+#endif
+
 static bool validate_addr(uint32_t addr) {
 
   // Address must be in SRAM range
diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index d7da8c659e..905c050a47 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -302,6 +302,11 @@
 //
 #define BOARD_ESP32                   6000
 
+//
+// SAMD51 ARM Cortex M4
+//
+#define BOARD_AGCM4_RURAMPS4D_13      6100
+
 //
 // Simulations
 //
diff --git a/Marlin/src/core/drivers.h b/Marlin/src/core/drivers.h
index 6e89ae8532..617090a6f2 100644
--- a/Marlin/src/core/drivers.h
+++ b/Marlin/src/core/drivers.h
@@ -120,7 +120,7 @@
                                    || AXIS_DRIVER_TYPE(A,TMC5160) )
 
 //
-// Stretching 'drivers.h' to include LPC SD options
+// Stretching 'drivers.h' to include LPC/SAMD51 SD options
 //
 #define _SDCARD_LCD          1
 #define _SDCARD_ONBOARD      2
diff --git a/Marlin/src/gcode/calibrate/M100.cpp b/Marlin/src/gcode/calibrate/M100.cpp
index b6e22b3083..a6f4f8f5d2 100644
--- a/Marlin/src/gcode/calibrate/M100.cpp
+++ b/Marlin/src/gcode/calibrate/M100.cpp
@@ -75,7 +75,7 @@
 
   char *end_bss = &__bss_end__,
        *stacklimit = &__StackLimit,
-       *heaplimit = &__HeapLimit ;
+       *heaplimit = &__HeapLimit;
 
   #define MEMORY_END_CORRECTION 0x200
 
@@ -94,6 +94,20 @@
 
   #define MEMORY_END_CORRECTION 0x10000  // need to stay well below 0x20080000 or M100 F crashes
 
+#elif defined(__SAMD51__)
+
+  extern unsigned int __bss_end__, __StackLimit, __HeapLimit;
+  extern "C" void * _sbrk(int incr);
+
+  void *end_bss = &__bss_end__,
+       *stacklimit = &__StackLimit,
+       *heaplimit = &__HeapLimit;
+
+  #define MEMORY_END_CORRECTION 0x400
+
+  char *free_memory_start = (char *)_sbrk(0) + 0x200,     //  Leave some heap space
+       *free_memory_end = (char *)stacklimit - MEMORY_END_CORRECTION;
+
 #else
   #error "M100 - unsupported CPU"
 #endif
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 21c3c4e23c..d0285a3fe9 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -605,3 +605,5 @@
 #endif
 
 #define IS_RE_ARM_BOARD (MB(RAMPS_14_RE_ARM_EFB) || MB(RAMPS_14_RE_ARM_EEB) || MB(RAMPS_14_RE_ARM_EFF) || MB(RAMPS_14_RE_ARM_EEF) || MB(RAMPS_14_RE_ARM_SF))
+
+#define HAS_SDCARD_CONNECTION EITHER(TARGET_LPC1768, ADAFRUIT_GRAND_CENTRAL_M4)
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index b1813d711e..549539b75f 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -515,6 +515,13 @@
 #elif MB(ESP32)
   #include "esp32/pins_ESP32.h"                 // ESP32                                  env:esp32
 
+//
+// Adafruit Grand Central M4 (SAMD51 ARM Cortex-M4)
+//
+
+#elif MB(AGCM4_RURAMPS4D_13)
+  #include "samd/pins_AGCM4_RURAMPS4D_13.h"     // SAMD51                                 env:adafruit_grandcentral_m4
+
 //
 // Linux Native Debug board
 //
diff --git a/Marlin/src/pins/pinsDebug_list.h b/Marlin/src/pins/pinsDebug_list.h
index 3d3c9bb82f..a150e4460a 100644
--- a/Marlin/src/pins/pinsDebug_list.h
+++ b/Marlin/src/pins/pinsDebug_list.h
@@ -51,7 +51,7 @@
 #if PIN_EXISTS(MAIN_VOLTAGE_MEASURE) && MAIN_VOLTAGE_MEASURE_PIN < NUM_ANALOG_INPUTS
   REPORT_NAME_ANALOG(__LINE__, MAIN_VOLTAGE_MEASURE_PIN)
 #endif
-#if !defined(ARDUINO_ARCH_SAM)  //TC1 & TC2 are macros in the SAM tool chain
+#if !defined(ARDUINO_ARCH_SAM) && !defined(ARDUINO_ARCH_SAMD)  //TC1 & TC2 are macros in the SAM/SAMD tool chain
   #if defined(TC1) && TC1 >= 0 && TC1 < NUM_ANALOG_INPUTS
     REPORT_NAME_ANALOG(__LINE__, TC1)
   #endif
diff --git a/Marlin/src/pins/samd/pins_AGCM4_RURAMPS4D_13.h b/Marlin/src/pins/samd/pins_AGCM4_RURAMPS4D_13.h
new file mode 100644
index 0000000000..ee5f16a1e6
--- /dev/null
+++ b/Marlin/src/pins/samd/pins_AGCM4_RURAMPS4D_13.h
@@ -0,0 +1,254 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program 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.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Adafruit Grand Central M4 pin assignments ported by Giuliano Zaro
+ */
+#ifndef ARDUINO_GRAND_CENTRAL_M4
+  #error "Oops! Select 'Adafruit Grand Central M4' in 'Tools > Board.'"
+#endif
+
+#define BOARD_NAME "RuRAMPS4AGCM4 v1.3"
+
+//
+// Servos
+//
+#define SERVO0_PIN          5
+#define SERVO1_PIN          3
+
+//
+// Limit Switches
+//
+#define X_MIN_PIN          45
+#define X_MAX_PIN          39
+#define Y_MIN_PIN          46
+#define Y_MAX_PIN          41
+#define Z_MIN_PIN          47
+#define Z_MAX_PIN          43
+
+//
+// Z Probe (when not Z_MIN_PIN)
+//
+#ifndef Z_MIN_PROBE_PIN
+  #define Z_MIN_PROBE_PIN  49
+#endif
+
+//
+// Steppers
+//
+#define X_STEP_PIN         37   // Support Extension Board
+#define X_DIR_PIN          36
+#define X_ENABLE_PIN       31
+#ifndef X_CS_PIN
+  #define X_CS_PIN         38
+#endif
+
+#define Y_STEP_PIN         32   // Support Extension Board
+#define Y_DIR_PIN          35
+#define Y_ENABLE_PIN       31
+#ifndef Y_CS_PIN
+  #define Y_CS_PIN         34
+#endif
+
+#define Z_STEP_PIN         30   // Support Extension Board
+#define Z_DIR_PIN           2
+#define Z_ENABLE_PIN       31
+#ifndef Z_CS_PIN
+  #define Z_CS_PIN         10
+#endif
+
+#define E0_STEP_PIN        29
+#define E0_DIR_PIN         28
+#define E0_ENABLE_PIN      33
+#ifndef E0_CS_PIN
+  #define E0_CS_PIN        14
+#endif
+
+#define E1_STEP_PIN        22
+#define E1_DIR_PIN         24
+#define E1_ENABLE_PIN      26
+#ifndef E1_CS_PIN
+  #define E1_CS_PIN        15
+#endif
+
+#define E2_STEP_PIN        25
+#define E2_DIR_PIN         23
+#define E2_ENABLE_PIN      27
+#ifndef E2_CS_PIN
+  #define E2_CS_PIN        74
+#endif
+
+#if USES_Z_MIN_PROBE_ENDSTOP
+  #define Z_MIN_PROBE_PIN  49
+#endif
+
+#if HAS_FILAMENT_SENSOR
+  #ifndef FIL_RUNOUT_PIN
+    #define FIL_RUNOUT_PIN   Y_MIN_PIN
+  #endif
+#endif
+
+//
+// Heaters / Fans
+//
+#define HEATER_0_PIN       13
+#define HEATER_1_PIN       12
+#define HEATER_2_PIN       11
+#define HEATER_BED_PIN      7   // BED H1
+
+#define FAN_PIN             9
+#define FAN1_PIN            8
+#define CONTROLLER_FAN_PIN -1
+
+//
+// Temperature Sensors
+//
+#define TEMP_0_PIN          0   // ANALOG A0
+#define TEMP_1_PIN          1   // ANALOG A1
+#define TEMP_2_PIN          2   // ANALOG A2
+#define TEMP_3_PIN          3   // ANALOG A3
+#define TEMP_BED_PIN        4   // ANALOG A4
+
+// The thermocouple uses Analog pins
+#if ENABLED(VER_WITH_THERMOCOUPLE) // Must be defined in Configuration.h
+  #define TEMP_4_PIN        5   // A5
+  #define TEMP_5_PIN        6   // A6 (Marlin 2.0 not support)
+#endif
+
+// SPI for Max6675 or Max31855 Thermocouple
+/*
+#if DISABLED(SDSUPPORT)
+  #define MAX6675_SS_PIN   53
+#else
+  #define MAX6675_SS_PIN   49
+#endif
+*/
+
+//
+// Misc. Functions
+//
+#define SDSS                4
+#define LED_PIN            -1   // 13 - HEATER_0_PIN
+#define PS_ON_PIN          -1   // 57
+
+// MKS TFT / Nextion Use internal USART-1
+#define TFT_LCD_MODULE_COM        1
+#define TFT_LCD_MODULE_BAUDRATE   115200
+
+// ESP WiFi Use internal USART-2
+#define ESP_WIFI_MODULE_COM       2
+#define ESP_WIFI_MODULE_BAUDRATE  115200
+#define ESP_WIFI_MODULE_RESET_PIN -1
+#define PIGGY_GPIO_PIN            -1
+
+//
+// EEPROM
+//
+#define E2END             0x7FFF  // 32Kb (24lc256)
+#define I2C_EEPROM                // EEPROM on I2C
+
+//
+// LCD / Controller
+//
+#if HAS_SPI_LCD
+
+  #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER)
+
+    #define BEEPER_PIN     75
+    #define LCD_PINS_D4    48
+    #define LCD_PINS_D7    53
+    #define SD_DETECT_PIN  -1    // 51 can't be used, it's MOSI
+    #define LCD_PINS_RS    76
+    #define LCD_PINS_ENABLE 77
+
+  #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
+
+    #define BEEPER_PIN     75
+    #define LCD_PINS_D4    48
+    #define SD_DETECT_PIN  -1    // 51 can't be used, it's MOSI
+    #define LCD_PINS_RS    76
+    #define LCD_PINS_ENABLE 77
+
+  #elif HAS_SSD1306_OLED_I2C
+
+    #define BEEPER_PIN     75
+    #define LCD_SDSS       10
+    #define SD_DETECT_PIN  -1    // 51 can't be used, it's MOSI
+
+  #elif ENABLED(FYSETC_MINI_12864)
+
+    #define BEEPER_PIN     75
+    #define DOGLCD_CS      77
+    #define DOGLCD_A0      76
+
+    //#define FORCE_SOFT_SPI    // Use this if default of hardware SPI causes display problems
+                                //   results in LCD soft SPI mode 3, SD soft SPI mode 0
+
+    #define LCD_RESET_PIN  48   // Must be high or open for LCD to operate normally.
+
+    #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0)
+      #error "Pin compatibility check needed! Grand central M4 pins 50, 51 and 52 are not GPIO pins, they are wired to MISO, MOSI, and SCK."
+      #ifndef RGB_LED_R_PIN
+        #define RGB_LED_R_PIN 50   // D5
+      #endif
+      #ifndef RGB_LED_G_PIN
+        #define RGB_LED_G_PIN 52   // D6
+      #endif
+      #ifndef RGB_LED_B_PIN
+        #define RGB_LED_B_PIN 53   // D7
+      #endif
+    #elif ENABLED(FYSETC_MINI_12864_2_1)
+      #error "Pin compatibility check needed! Grand central M4 pins 50, 51 and 52 are not GPIO pins, they are wired to MISO, MOSI, and SCK."
+      #define NEOPIXEL_PIN    50   // D5
+    #endif
+
+  #elif ENABLED(MKS_MINI_12864)
+    #error "Pin compatibility check needed! Grand central M4 pins 50, 51 and 52 are not GPIO pins, they are wired to MISO, MOSI, and SCK."
+    #define ORIG_BEEPER_PIN 75
+
+    #define DOGLCD_A0      52
+    #define DOGLCD_CS      50
+
+    #define SD_DETECT_PIN  -1    // 51 can't be used, it's MOSI
+
+  #endif
+
+  #if ENABLED(NEWPANEL)
+    #define BTN_EN1        44
+    #define BTN_EN2        42
+    #define BTN_ENC        40
+  #endif
+
+#endif // HAS_SPI_LCD
+
+//
+// SD Support
+//
+#ifndef SDCARD_CONNECTION
+  #define SDCARD_CONNECTION ONBOARD
+#endif
+
+#if SD_CONNECTION_IS(ONBOARD)
+  #undef SDSS
+  #define SDSS             83
+  #undef SD_DETECT_PIN
+  #define SD_DETECT_PIN    95
+#endif
diff --git a/README.md b/README.md
index 0530a5ed72..19cc7adb8e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Marlin 3D Printer Firmware
+# Marlin 3D Printer Firmware
 
 [![Build Status](https://travis-ci.org/MarlinFirmware/Marlin.svg?branch=bugfix-2.0.x)](https://travis-ci.org/MarlinFirmware/Marlin)
 ![GitHub](https://img.shields.io/github/license/marlinfirmware/marlin.svg)
@@ -49,6 +49,7 @@ Marlin 2.0 introduces a layer of abstraction so that all the existing high-level
   ----|---------|-----|-----|----|-----|---
   [STEVAL-3DP001V1](http://www.st.com/en/evaluation-tools/steval-3dp001v1.html)|[STM32F401VE Arm-Cortex M4](http://www.st.com/en/microcontrollers/stm32f401ve.html)|84MHz|512k|64+32k|3.3-5V|yes
   [Smoothieboard](http://reprap.org/wiki/Smoothieboard)|LPC1769 ARM-Cortex M3|120MHz|512k|64k|3.3-5V|no
+  [Adafruit Grand Central M4](https://www.adafruit.com/product/4064)|ARM-Cortex M4|120MHz|1M|256k|3.3V|yes
 
 ## Submitting Patches
 
diff --git a/buildroot/share/tests/adafruit_grandcentral_m4-tests b/buildroot/share/tests/adafruit_grandcentral_m4-tests
new file mode 100644
index 0000000000..453cefc6ce
--- /dev/null
+++ b/buildroot/share/tests/adafruit_grandcentral_m4-tests
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#
+# Build tests for Adafruit Grand Central M4 (ATMEL ARM Cortex-M4)
+#
+
+# exit on first failure
+set -e
+
+restore_configs
+opt_set MOTHERBOARD BOARD_AGCM4_RURAMPS4D_13
+exec_test $1 $2 "Build Grand Central M4 Default Configuration"
+
+# clean up
+restore_configs
diff --git a/config/default/Configuration_adv.h b/config/default/Configuration_adv.h
index acf3f7fa7d..dfc985d7a2 100644
--- a/config/default/Configuration_adv.h
+++ b/config/default/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/3DFabXYZ/Migbot/Configuration_adv.h b/config/examples/3DFabXYZ/Migbot/Configuration_adv.h
index 3ef33ac9a3..4f614740e2 100644
--- a/config/examples/3DFabXYZ/Migbot/Configuration_adv.h
+++ b/config/examples/3DFabXYZ/Migbot/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/AlephObjects/TAZ4/Configuration_adv.h b/config/examples/AlephObjects/TAZ4/Configuration_adv.h
index 3909633f09..b7d54daa1d 100644
--- a/config/examples/AlephObjects/TAZ4/Configuration_adv.h
+++ b/config/examples/AlephObjects/TAZ4/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Alfawise/U20/Configuration_adv.h b/config/examples/Alfawise/U20/Configuration_adv.h
index 222ca5e89d..52dc2f422d 100644
--- a/config/examples/Alfawise/U20/Configuration_adv.h
+++ b/config/examples/Alfawise/U20/Configuration_adv.h
@@ -1040,7 +1040,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/AliExpress/UM2pExt/Configuration_adv.h b/config/examples/AliExpress/UM2pExt/Configuration_adv.h
index bfc5136524..129b9e315a 100644
--- a/config/examples/AliExpress/UM2pExt/Configuration_adv.h
+++ b/config/examples/AliExpress/UM2pExt/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/A2/Configuration_adv.h b/config/examples/Anet/A2/Configuration_adv.h
index 06ae9cdb7c..80b89ccb01 100644
--- a/config/examples/Anet/A2/Configuration_adv.h
+++ b/config/examples/Anet/A2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/A2plus/Configuration_adv.h b/config/examples/Anet/A2plus/Configuration_adv.h
index 06ae9cdb7c..80b89ccb01 100644
--- a/config/examples/Anet/A2plus/Configuration_adv.h
+++ b/config/examples/Anet/A2plus/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/A6/Configuration_adv.h b/config/examples/Anet/A6/Configuration_adv.h
index ae124115c9..11bbf5aa31 100644
--- a/config/examples/Anet/A6/Configuration_adv.h
+++ b/config/examples/Anet/A6/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/A8/Configuration_adv.h b/config/examples/Anet/A8/Configuration_adv.h
index b76e99440c..1f61156788 100644
--- a/config/examples/Anet/A8/Configuration_adv.h
+++ b/config/examples/Anet/A8/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/A8plus/Configuration_adv.h b/config/examples/Anet/A8plus/Configuration_adv.h
index 0df718fe8c..bb783af9ce 100644
--- a/config/examples/Anet/A8plus/Configuration_adv.h
+++ b/config/examples/Anet/A8plus/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Anet/E16/Configuration_adv.h b/config/examples/Anet/E16/Configuration_adv.h
index 1914c1b3d3..714592c2cc 100644
--- a/config/examples/Anet/E16/Configuration_adv.h
+++ b/config/examples/Anet/E16/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/AnyCubic/i3/Configuration_adv.h b/config/examples/AnyCubic/i3/Configuration_adv.h
index ccb7838e05..dcd17deb2b 100644
--- a/config/examples/AnyCubic/i3/Configuration_adv.h
+++ b/config/examples/AnyCubic/i3/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/ArmEd/Configuration_adv.h b/config/examples/ArmEd/Configuration_adv.h
index da7e38ec5f..ef9f652aa7 100644
--- a/config/examples/ArmEd/Configuration_adv.h
+++ b/config/examples/ArmEd/Configuration_adv.h
@@ -1041,7 +1041,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h b/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
index 8ca487e106..3c7ec8eb97 100644
--- a/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
+++ b/config/examples/BIBO/TouchX/cyclops/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/BIBO/TouchX/default/Configuration_adv.h b/config/examples/BIBO/TouchX/default/Configuration_adv.h
index 17ac8d3b77..d3b1c28a84 100644
--- a/config/examples/BIBO/TouchX/default/Configuration_adv.h
+++ b/config/examples/BIBO/TouchX/default/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/BQ/Hephestos/Configuration_adv.h b/config/examples/BQ/Hephestos/Configuration_adv.h
index 25a59be6bf..1d05cd7d80 100644
--- a/config/examples/BQ/Hephestos/Configuration_adv.h
+++ b/config/examples/BQ/Hephestos/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/BQ/Hephestos_2/Configuration_adv.h b/config/examples/BQ/Hephestos_2/Configuration_adv.h
index 90e657c77b..020f66efb9 100644
--- a/config/examples/BQ/Hephestos_2/Configuration_adv.h
+++ b/config/examples/BQ/Hephestos_2/Configuration_adv.h
@@ -1045,7 +1045,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/BQ/WITBOX/Configuration_adv.h b/config/examples/BQ/WITBOX/Configuration_adv.h
index 25a59be6bf..1d05cd7d80 100644
--- a/config/examples/BQ/WITBOX/Configuration_adv.h
+++ b/config/examples/BQ/WITBOX/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Cartesio/Configuration_adv.h b/config/examples/Cartesio/Configuration_adv.h
index 88b439e7d5..0e7fea96b3 100644
--- a/config/examples/Cartesio/Configuration_adv.h
+++ b/config/examples/Cartesio/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-10/Configuration_adv.h b/config/examples/Creality/CR-10/Configuration_adv.h
index 67901ed205..ca5ebfc016 100644
--- a/config/examples/Creality/CR-10/Configuration_adv.h
+++ b/config/examples/Creality/CR-10/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-10S/Configuration_adv.h b/config/examples/Creality/CR-10S/Configuration_adv.h
index 10a5dedf3f..5eb7ee226a 100644
--- a/config/examples/Creality/CR-10S/Configuration_adv.h
+++ b/config/examples/Creality/CR-10S/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-10_5S/Configuration_adv.h b/config/examples/Creality/CR-10_5S/Configuration_adv.h
index 700704aafc..bec9f6884b 100644
--- a/config/examples/Creality/CR-10_5S/Configuration_adv.h
+++ b/config/examples/Creality/CR-10_5S/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-10mini/Configuration_adv.h b/config/examples/Creality/CR-10mini/Configuration_adv.h
index 7f9c2d73f9..ee1a7d63e3 100644
--- a/config/examples/Creality/CR-10mini/Configuration_adv.h
+++ b/config/examples/Creality/CR-10mini/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-20 Pro/Configuration_adv.h b/config/examples/Creality/CR-20 Pro/Configuration_adv.h
index 1c2d8a780e..28435aca04 100644
--- a/config/examples/Creality/CR-20 Pro/Configuration_adv.h	
+++ b/config/examples/Creality/CR-20 Pro/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-20/Configuration_adv.h b/config/examples/Creality/CR-20/Configuration_adv.h
index 5773dbc91f..bc6f393800 100644
--- a/config/examples/Creality/CR-20/Configuration_adv.h
+++ b/config/examples/Creality/CR-20/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/CR-8/Configuration_adv.h b/config/examples/Creality/CR-8/Configuration_adv.h
index 2b32402ea0..4a134f375e 100644
--- a/config/examples/Creality/CR-8/Configuration_adv.h
+++ b/config/examples/Creality/CR-8/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/Ender-2/Configuration_adv.h b/config/examples/Creality/Ender-2/Configuration_adv.h
index 92d2fcc7be..74740329da 100644
--- a/config/examples/Creality/Ender-2/Configuration_adv.h
+++ b/config/examples/Creality/Ender-2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/Ender-3/Configuration_adv.h b/config/examples/Creality/Ender-3/Configuration_adv.h
index 1c2d8a780e..28435aca04 100644
--- a/config/examples/Creality/Ender-3/Configuration_adv.h
+++ b/config/examples/Creality/Ender-3/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/Ender-4/Configuration_adv.h b/config/examples/Creality/Ender-4/Configuration_adv.h
index 751c85c986..1a91032589 100644
--- a/config/examples/Creality/Ender-4/Configuration_adv.h
+++ b/config/examples/Creality/Ender-4/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Creality/Ender-5/Configuration_adv.h b/config/examples/Creality/Ender-5/Configuration_adv.h
index 32c5c20d4e..0f06616294 100644
--- a/config/examples/Creality/Ender-5/Configuration_adv.h
+++ b/config/examples/Creality/Ender-5/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Dagoma/Disco Ultimate/Configuration_adv.h b/config/examples/Dagoma/Disco Ultimate/Configuration_adv.h
index 5830f58995..957ce47716 100644
--- a/config/examples/Dagoma/Disco Ultimate/Configuration_adv.h	
+++ b/config/examples/Dagoma/Disco Ultimate/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/EVNOVO (Artillery)/Sidewinder X1/Configuration_adv.h b/config/examples/EVNOVO (Artillery)/Sidewinder X1/Configuration_adv.h
index fc35c2b4ee..c46b5e93fc 100755
--- a/config/examples/EVNOVO (Artillery)/Sidewinder X1/Configuration_adv.h	
+++ b/config/examples/EVNOVO (Artillery)/Sidewinder X1/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Einstart-S/Configuration_adv.h b/config/examples/Einstart-S/Configuration_adv.h
index 602c0e09d5..62bb56a8a5 100644
--- a/config/examples/Einstart-S/Configuration_adv.h
+++ b/config/examples/Einstart-S/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FYSETC/AIO_II/Configuration_adv.h b/config/examples/FYSETC/AIO_II/Configuration_adv.h
index dcc879ab06..53fc99edb2 100644
--- a/config/examples/FYSETC/AIO_II/Configuration_adv.h
+++ b/config/examples/FYSETC/AIO_II/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FYSETC/Cheetah/BLTouch/Configuration_adv.h b/config/examples/FYSETC/Cheetah/BLTouch/Configuration_adv.h
index 2fedb22ba9..c650cc36f4 100644
--- a/config/examples/FYSETC/Cheetah/BLTouch/Configuration_adv.h
+++ b/config/examples/FYSETC/Cheetah/BLTouch/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FYSETC/Cheetah/base/Configuration_adv.h b/config/examples/FYSETC/Cheetah/base/Configuration_adv.h
index 2fedb22ba9..c650cc36f4 100644
--- a/config/examples/FYSETC/Cheetah/base/Configuration_adv.h
+++ b/config/examples/FYSETC/Cheetah/base/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FYSETC/F6_13/Configuration_adv.h b/config/examples/FYSETC/F6_13/Configuration_adv.h
index 9dec7c12c0..09c4af1bcc 100644
--- a/config/examples/FYSETC/F6_13/Configuration_adv.h
+++ b/config/examples/FYSETC/F6_13/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Felix/Configuration_adv.h b/config/examples/Felix/Configuration_adv.h
index 9e45549dba..ea477f1565 100644
--- a/config/examples/Felix/Configuration_adv.h
+++ b/config/examples/Felix/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FlashForge/CreatorPro/Configuration_adv.h b/config/examples/FlashForge/CreatorPro/Configuration_adv.h
index c2c1cb6dc2..62c5342f22 100644
--- a/config/examples/FlashForge/CreatorPro/Configuration_adv.h
+++ b/config/examples/FlashForge/CreatorPro/Configuration_adv.h
@@ -1036,7 +1036,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/FolgerTech/i3-2020/Configuration_adv.h b/config/examples/FolgerTech/i3-2020/Configuration_adv.h
index 2db158e21f..bc25553fdc 100644
--- a/config/examples/FolgerTech/i3-2020/Configuration_adv.h
+++ b/config/examples/FolgerTech/i3-2020/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Formbot/Raptor/Configuration_adv.h b/config/examples/Formbot/Raptor/Configuration_adv.h
index e5c2e18b5d..f74e62bfc4 100644
--- a/config/examples/Formbot/Raptor/Configuration_adv.h
+++ b/config/examples/Formbot/Raptor/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Formbot/T_Rex_2+/Configuration_adv.h b/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
index 4bbc3838c3..6a4766e56a 100644
--- a/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
+++ b/config/examples/Formbot/T_Rex_2+/Configuration_adv.h
@@ -1041,7 +1041,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Formbot/T_Rex_3/Configuration_adv.h b/config/examples/Formbot/T_Rex_3/Configuration_adv.h
index 1e58527453..c90d708c58 100644
--- a/config/examples/Formbot/T_Rex_3/Configuration_adv.h
+++ b/config/examples/Formbot/T_Rex_3/Configuration_adv.h
@@ -1041,7 +1041,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/A10/Configuration_adv.h b/config/examples/Geeetech/A10/Configuration_adv.h
index 5b53500f49..7b01a0a126 100644
--- a/config/examples/Geeetech/A10/Configuration_adv.h
+++ b/config/examples/Geeetech/A10/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/A10M/Configuration_adv.h b/config/examples/Geeetech/A10M/Configuration_adv.h
index afe3813b33..e7c9828c6b 100644
--- a/config/examples/Geeetech/A10M/Configuration_adv.h
+++ b/config/examples/Geeetech/A10M/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/A20M/Configuration_adv.h b/config/examples/Geeetech/A20M/Configuration_adv.h
index 5c6409025c..f32c0b78ed 100644
--- a/config/examples/Geeetech/A20M/Configuration_adv.h
+++ b/config/examples/Geeetech/A20M/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/MeCreator2/Configuration_adv.h b/config/examples/Geeetech/MeCreator2/Configuration_adv.h
index d13aa552ba..09925372be 100644
--- a/config/examples/Geeetech/MeCreator2/Configuration_adv.h
+++ b/config/examples/Geeetech/MeCreator2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h b/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h
index 5b53500f49..7b01a0a126 100644
--- a/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h	
+++ b/config/examples/Geeetech/Prusa i3 Pro C/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h b/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h
index 5b53500f49..7b01a0a126 100644
--- a/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h	
+++ b/config/examples/Geeetech/Prusa i3 Pro W/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Infitary/i3-M508/Configuration_adv.h b/config/examples/Infitary/i3-M508/Configuration_adv.h
index 84672d36bf..d97b3fd605 100644
--- a/config/examples/Infitary/i3-M508/Configuration_adv.h
+++ b/config/examples/Infitary/i3-M508/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/JGAurora/A1/Configuration_adv.h b/config/examples/JGAurora/A1/Configuration_adv.h
index 0be1cc1619..cfc2ffe5d1 100644
--- a/config/examples/JGAurora/A1/Configuration_adv.h
+++ b/config/examples/JGAurora/A1/Configuration_adv.h
@@ -1042,7 +1042,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/JGAurora/A5/Configuration_adv.h b/config/examples/JGAurora/A5/Configuration_adv.h
index 94a83c82d3..bc19275f81 100644
--- a/config/examples/JGAurora/A5/Configuration_adv.h
+++ b/config/examples/JGAurora/A5/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/JGAurora/A5S/Configuration_adv.h b/config/examples/JGAurora/A5S/Configuration_adv.h
index b9f3802c22..1ca65cbe69 100644
--- a/config/examples/JGAurora/A5S/Configuration_adv.h
+++ b/config/examples/JGAurora/A5S/Configuration_adv.h
@@ -1042,7 +1042,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/MakerParts/Configuration_adv.h b/config/examples/MakerParts/Configuration_adv.h
index 2df7dba58f..0ecde42637 100644
--- a/config/examples/MakerParts/Configuration_adv.h
+++ b/config/examples/MakerParts/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Malyan/M150/Configuration_adv.h b/config/examples/Malyan/M150/Configuration_adv.h
index 6822af6268..8d9e34f888 100644
--- a/config/examples/Malyan/M150/Configuration_adv.h
+++ b/config/examples/Malyan/M150/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Malyan/M200/Configuration_adv.h b/config/examples/Malyan/M200/Configuration_adv.h
index a176e9ef03..55e7036d6d 100644
--- a/config/examples/Malyan/M200/Configuration_adv.h
+++ b/config/examples/Malyan/M200/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Micromake/C1/enhanced/Configuration_adv.h b/config/examples/Micromake/C1/enhanced/Configuration_adv.h
index 5be6be4f95..923ef31c71 100644
--- a/config/examples/Micromake/C1/enhanced/Configuration_adv.h
+++ b/config/examples/Micromake/C1/enhanced/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Mks/Robin/Configuration_adv.h b/config/examples/Mks/Robin/Configuration_adv.h
index ec8aee7806..0874ded2c7 100644
--- a/config/examples/Mks/Robin/Configuration_adv.h
+++ b/config/examples/Mks/Robin/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Mks/Sbase/Configuration_adv.h b/config/examples/Mks/Sbase/Configuration_adv.h
index 8072550350..667ee62672 100644
--- a/config/examples/Mks/Sbase/Configuration_adv.h
+++ b/config/examples/Mks/Sbase/Configuration_adv.h
@@ -1038,7 +1038,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/RapideLite/RL200/Configuration_adv.h b/config/examples/RapideLite/RL200/Configuration_adv.h
index 5d87137e31..4790710ba4 100644
--- a/config/examples/RapideLite/RL200/Configuration_adv.h
+++ b/config/examples/RapideLite/RL200/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/RigidBot/Configuration_adv.h b/config/examples/RigidBot/Configuration_adv.h
index d4d0c30f28..d722809e70 100644
--- a/config/examples/RigidBot/Configuration_adv.h
+++ b/config/examples/RigidBot/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/SCARA/Configuration_adv.h b/config/examples/SCARA/Configuration_adv.h
index 6631733529..f592f8b8c4 100644
--- a/config/examples/SCARA/Configuration_adv.h
+++ b/config/examples/SCARA/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/STM32/Black_STM32F407VET6/Configuration_adv.h b/config/examples/STM32/Black_STM32F407VET6/Configuration_adv.h
index 1bf1a93da9..28f99959ce 100644
--- a/config/examples/STM32/Black_STM32F407VET6/Configuration_adv.h
+++ b/config/examples/STM32/Black_STM32F407VET6/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Sanguinololu/Configuration_adv.h b/config/examples/Sanguinololu/Configuration_adv.h
index a5c3452429..7c0e8679c0 100644
--- a/config/examples/Sanguinololu/Configuration_adv.h
+++ b/config/examples/Sanguinololu/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tevo/Michelangelo/Configuration_adv.h b/config/examples/Tevo/Michelangelo/Configuration_adv.h
index c6d0e28224..8a68f0b7a4 100644
--- a/config/examples/Tevo/Michelangelo/Configuration_adv.h
+++ b/config/examples/Tevo/Michelangelo/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tevo/Tarantula Pro/Configuration_adv.h b/config/examples/Tevo/Tarantula Pro/Configuration_adv.h
index e4d7ab805d..afeefc8403 100755
--- a/config/examples/Tevo/Tarantula Pro/Configuration_adv.h	
+++ b/config/examples/Tevo/Tarantula Pro/Configuration_adv.h	
@@ -1033,7 +1033,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tevo/Tornado/V1 (MKS Base)/Configuration_adv.h b/config/examples/Tevo/Tornado/V1 (MKS Base)/Configuration_adv.h
index 6f0eb113a3..704ee7e072 100755
--- a/config/examples/Tevo/Tornado/V1 (MKS Base)/Configuration_adv.h	
+++ b/config/examples/Tevo/Tornado/V1 (MKS Base)/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tevo/Tornado/V2 (MKS GEN-L)/Configuration_adv.h b/config/examples/Tevo/Tornado/V2 (MKS GEN-L)/Configuration_adv.h
index 6f0eb113a3..704ee7e072 100755
--- a/config/examples/Tevo/Tornado/V2 (MKS GEN-L)/Configuration_adv.h	
+++ b/config/examples/Tevo/Tornado/V2 (MKS GEN-L)/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/TheBorg/Configuration_adv.h b/config/examples/TheBorg/Configuration_adv.h
index 3cd097da62..3df044d9af 100644
--- a/config/examples/TheBorg/Configuration_adv.h
+++ b/config/examples/TheBorg/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/TinyBoy2/Configuration_adv.h b/config/examples/TinyBoy2/Configuration_adv.h
index c02460f3fc..21c7833b74 100644
--- a/config/examples/TinyBoy2/Configuration_adv.h
+++ b/config/examples/TinyBoy2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tronxy/X3A/Configuration_adv.h b/config/examples/Tronxy/X3A/Configuration_adv.h
index 191f8d274a..eec7bc0a11 100644
--- a/config/examples/Tronxy/X3A/Configuration_adv.h
+++ b/config/examples/Tronxy/X3A/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Tronxy/X5S-2E/Configuration_adv.h b/config/examples/Tronxy/X5S-2E/Configuration_adv.h
index 3d55d7c5bc..b9282d2b96 100644
--- a/config/examples/Tronxy/X5S-2E/Configuration_adv.h
+++ b/config/examples/Tronxy/X5S-2E/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/UltiMachine/Archim1/Configuration_adv.h b/config/examples/UltiMachine/Archim1/Configuration_adv.h
index 45d441789d..d1dbb7ae95 100644
--- a/config/examples/UltiMachine/Archim1/Configuration_adv.h
+++ b/config/examples/UltiMachine/Archim1/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/UltiMachine/Archim2/Configuration_adv.h b/config/examples/UltiMachine/Archim2/Configuration_adv.h
index d48af69ccc..7a6ab612a1 100644
--- a/config/examples/UltiMachine/Archim2/Configuration_adv.h
+++ b/config/examples/UltiMachine/Archim2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/VORONDesign/Configuration_adv.h b/config/examples/VORONDesign/Configuration_adv.h
index 47a8a06ace..f598b4b2d1 100644
--- a/config/examples/VORONDesign/Configuration_adv.h
+++ b/config/examples/VORONDesign/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Velleman/K8200/Configuration_adv.h b/config/examples/Velleman/K8200/Configuration_adv.h
index a99d732da6..4e01b9c1ab 100644
--- a/config/examples/Velleman/K8200/Configuration_adv.h
+++ b/config/examples/Velleman/K8200/Configuration_adv.h
@@ -1050,7 +1050,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Velleman/K8400/Configuration_adv.h b/config/examples/Velleman/K8400/Configuration_adv.h
index 6e3a2aeeb7..9b2e4615c7 100644
--- a/config/examples/Velleman/K8400/Configuration_adv.h
+++ b/config/examples/Velleman/K8400/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/WASP/PowerWASP/Configuration_adv.h b/config/examples/WASP/PowerWASP/Configuration_adv.h
index b19ca6cab4..1fccfb63b1 100644
--- a/config/examples/WASP/PowerWASP/Configuration_adv.h
+++ b/config/examples/WASP/PowerWASP/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Wanhao/Duplicator 6/Configuration_adv.h b/config/examples/Wanhao/Duplicator 6/Configuration_adv.h
index bd94e4a1ec..6a50b6f8c5 100644
--- a/config/examples/Wanhao/Duplicator 6/Configuration_adv.h	
+++ b/config/examples/Wanhao/Duplicator 6/Configuration_adv.h	
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/Wanhao/Duplicator i3 Mini/Configuration_adv.h b/config/examples/Wanhao/Duplicator i3 Mini/Configuration_adv.h
index 23ebf8c55b..53c4fb2e53 100644
--- a/config/examples/Wanhao/Duplicator i3 Mini/Configuration_adv.h	
+++ b/config/examples/Wanhao/Duplicator i3 Mini/Configuration_adv.h	
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/Anycubic/Kossel/Configuration_adv.h b/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
index 398106aa0b..5b3a96e789 100644
--- a/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
+++ b/config/examples/delta/Anycubic/Kossel/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h b/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
index 037751bba9..14ffeeb253 100644
--- a/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
+++ b/config/examples/delta/FLSUN/auto_calibrate/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/FLSUN/kossel/Configuration_adv.h b/config/examples/delta/FLSUN/kossel/Configuration_adv.h
index 037751bba9..14ffeeb253 100644
--- a/config/examples/delta/FLSUN/kossel/Configuration_adv.h
+++ b/config/examples/delta/FLSUN/kossel/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h b/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
index f660445880..df8d9912f4 100644
--- a/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
+++ b/config/examples/delta/FLSUN/kossel_mini/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/Geeetech/Rostock 301/Configuration_adv.h b/config/examples/delta/Geeetech/Rostock 301/Configuration_adv.h
index 33793a06f7..fedbc21b1b 100644
--- a/config/examples/delta/Geeetech/Rostock 301/Configuration_adv.h	
+++ b/config/examples/delta/Geeetech/Rostock 301/Configuration_adv.h	
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/MKS/SBASE/Configuration_adv.h b/config/examples/delta/MKS/SBASE/Configuration_adv.h
index a90f65e683..28b3fa33d0 100644
--- a/config/examples/delta/MKS/SBASE/Configuration_adv.h
+++ b/config/examples/delta/MKS/SBASE/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/Tevo Little Monster/Configuration_adv.h b/config/examples/delta/Tevo Little Monster/Configuration_adv.h
index f68568eef5..5f98ae8eec 100644
--- a/config/examples/delta/Tevo Little Monster/Configuration_adv.h	
+++ b/config/examples/delta/Tevo Little Monster/Configuration_adv.h	
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/generic/Configuration_adv.h b/config/examples/delta/generic/Configuration_adv.h
index f660445880..df8d9912f4 100644
--- a/config/examples/delta/generic/Configuration_adv.h
+++ b/config/examples/delta/generic/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/kossel_mini/Configuration_adv.h b/config/examples/delta/kossel_mini/Configuration_adv.h
index f660445880..df8d9912f4 100644
--- a/config/examples/delta/kossel_mini/Configuration_adv.h
+++ b/config/examples/delta/kossel_mini/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/delta/kossel_xl/Configuration_adv.h b/config/examples/delta/kossel_xl/Configuration_adv.h
index 476b8d6bd4..05e92fa236 100644
--- a/config/examples/delta/kossel_xl/Configuration_adv.h
+++ b/config/examples/delta/kossel_xl/Configuration_adv.h
@@ -1039,7 +1039,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/gCreate/gMax1.5+/Configuration_adv.h b/config/examples/gCreate/gMax1.5+/Configuration_adv.h
index 74be1aefdc..6f49e03ea8 100644
--- a/config/examples/gCreate/gMax1.5+/Configuration_adv.h
+++ b/config/examples/gCreate/gMax1.5+/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/makibox/Configuration_adv.h b/config/examples/makibox/Configuration_adv.h
index 66e0fe096a..5e105272e0 100644
--- a/config/examples/makibox/Configuration_adv.h
+++ b/config/examples/makibox/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/tvrrug/Round2/Configuration_adv.h b/config/examples/tvrrug/Round2/Configuration_adv.h
index 9706097338..ca9de6a6f4 100644
--- a/config/examples/tvrrug/Round2/Configuration_adv.h
+++ b/config/examples/tvrrug/Round2/Configuration_adv.h
@@ -1037,7 +1037,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/config/examples/wt150/Configuration_adv.h b/config/examples/wt150/Configuration_adv.h
index af6c38c7b3..6a598832e6 100644
--- a/config/examples/wt150/Configuration_adv.h
+++ b/config/examples/wt150/Configuration_adv.h
@@ -1038,7 +1038,7 @@
   // Add an optimized binary file transfer mode, initiated with 'M28 B1'
   //#define BINARY_FILE_TRANSFER
 
-  #ifdef TARGET_LPC1768
+  #if HAS_SDCARD_CONNECTION
     /**
      * Set this option to one of the following (or the board's defaults apply):
      *
diff --git a/platformio.ini b/platformio.ini
index 27a5604b65..2c8942e70e 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -617,3 +617,17 @@ lib_ldf_mode    = off
 lib_deps        =
 extra_scripts   =
 src_filter      = ${common.default_src_filter} +<src/HAL/HAL_LINUX>
+
+#
+# Adafruit Grand Central M4 (Atmel SAMD51P20A ARM Cortex-M4)
+#
+[env:adafruit_grandcentral_m4]
+platform      = atmelsam
+board         = adafruit_grandcentral_m4
+framework     = arduino
+build_flags   = ${common.build_flags}
+  -Wl,-Map,$BUILD_DIR/firmware.map -Wl,--cref
+lib_deps      = ${common.lib_deps}
+lib_ignore    = U8glib-HAL
+ c1921b4
+src_filter    = ${common.default_src_filter} +<src/HAL/HAL_SAMD51>
-- 
GitLab