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 43e7ca5e4..ad11d95e5 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 0a03107aa..37d21ec13 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 da779286f..6b6ad03d4 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 000000000..1c2a9d53f
--- /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 .
+ *
+ */
+
+#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 000000000..3dd131346
--- /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 .
+ *
+ */
+#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 000000000..b03aea0e4
--- /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 .
+ *
+ */
+
+/**
+ * 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
+
+// --------------------------------------------------------------------------
+// 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 000000000..70733e241
--- /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 .
+ *
+ */
+
+#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 000000000..60d2b3296
--- /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 .
+ *
+ */
+#pragma once
+
+#include
+
+// --------------------------------------------------------------------------
+// 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 000000000..5e582806d
--- /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 .
+ *
+ */
+
+#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 000000000..9f318709d
--- /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 .
+ *
+ */
+#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 000000000..63d53a960
--- /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 .
+ *
+ */
+#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 000000000..93317e004
--- /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 .
+ *
+ */
+
+/**
+ * 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 000000000..58b969825
--- /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 .
+ *
+ */
+
+/**
+ * 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 000000000..67f35a97a
--- /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 .
+ *
+ */
+#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 000000000..70847ebf0
--- /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 .
+ *
+ */
+#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 000000000..40658adfe
--- /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 .
+ *
+ */
+
+#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 000000000..99e49536c
--- /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 .
+ *
+ */
+#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 000000000..87fedc948
--- /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 .
+ *
+ */
+#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 000000000..efcfb6c9a
--- /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 .
+ *
+ */
+
+#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 000000000..b4332dace
--- /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 .
+ *
+ */
+#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 20f1a7bc0..8cf31cadf 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 d7da8c659..905c050a4 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 6e89ae853..617090a6f 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 b6e22b308..a6f4f8f5d 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 21c3c4e23..d0285a3fe 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 b1813d711..549539b75 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 3d3c9bb82..a150e4460 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 000000000..ee5f16a1e
--- /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 .
+ */
+
+/**
+ * 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 0530a5ed7..19cc7adb8 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 000000000..453cefc6c
--- /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 acf3f7fa7..dfc985d7a 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 3ef33ac9a..4f614740e 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 3909633f0..b7d54daa1 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 222ca5e89..52dc2f422 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 bfc513652..129b9e315 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 06ae9cdb7..80b89ccb0 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 06ae9cdb7..80b89ccb0 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 ae124115c..11bbf5aa3 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 b76e99440..1f6115678 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 0df718fe8..bb783af9c 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 1914c1b3d..714592c2c 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 ccb7838e0..dcd17deb2 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 da7e38ec5..ef9f652aa 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 8ca487e10..3c7ec8eb9 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 17ac8d3b7..d3b1c28a8 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 25a59be6b..1d05cd7d8 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 90e657c77..020f66efb 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 25a59be6b..1d05cd7d8 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 88b439e7d..0e7fea96b 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 67901ed20..ca5ebfc01 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 10a5dedf3..5eb7ee226 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 700704aaf..bec9f6884 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 7f9c2d73f..ee1a7d63e 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 1c2d8a780..28435aca0 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 5773dbc91..bc6f39380 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 2b32402ea..4a134f375 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 92d2fcc7b..74740329d 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 1c2d8a780..28435aca0 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 751c85c98..1a9103258 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 32c5c20d4..0f0661629 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 5830f5899..957ce4771 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 fc35c2b4e..c46b5e93f 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 602c0e09d..62bb56a8a 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 dcc879ab0..53fc99edb 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 2fedb22ba..c650cc36f 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 2fedb22ba..c650cc36f 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 9dec7c12c..09c4af1bc 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 9e45549db..ea477f156 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 c2c1cb6dc..62c5342f2 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 2db158e21..bc25553fd 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 e5c2e18b5..f74e62bfc 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 4bbc3838c..6a4766e56 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 1e5852745..c90d708c5 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 5b53500f4..7b01a0a12 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 afe3813b3..e7c9828c6 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 5c6409025..f32c0b78e 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 d13aa552b..09925372b 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 5b53500f4..7b01a0a12 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 5b53500f4..7b01a0a12 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 84672d36b..d97b3fd60 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 0be1cc161..cfc2ffe5d 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 94a83c82d..bc19275f8 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 b9f3802c2..1ca65cbe6 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 2df7dba58..0ecde4263 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 6822af626..8d9e34f88 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 a176e9ef0..55e7036d6 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 5be6be4f9..923ef31c7 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 ec8aee780..0874ded2c 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 807255035..667ee6267 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 5d87137e3..4790710ba 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 d4d0c30f2..d722809e7 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 663173352..f592f8b8c 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 1bf1a93da..28f99959c 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 a5c345242..7c0e8679c 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 c6d0e2822..8a68f0b7a 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 e4d7ab805..afeefc840 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 6f0eb113a..704ee7e07 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 6f0eb113a..704ee7e07 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 3cd097da6..3df044d9a 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 c02460f3f..21c7833b7 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 191f8d274..eec7bc0a1 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 3d55d7c5b..b9282d2b9 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 45d441789..d1dbb7ae9 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 d48af69cc..7a6ab612a 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 47a8a06ac..f598b4b2d 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 a99d732da..4e01b9c1a 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 6e3a2aeeb..9b2e4615c 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 b19ca6cab..1fccfb63b 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 bd94e4a1e..6a50b6f8c 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 23ebf8c55..53c4fb2e5 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 398106aa0..5b3a96e78 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 037751bba..14ffeeb25 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 037751bba..14ffeeb25 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 f66044588..df8d9912f 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 33793a06f..fedbc21b1 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 a90f65e68..28b3fa33d 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 f68568eef..5f98ae8ee 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 f66044588..df8d9912f 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 f66044588..df8d9912f 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 476b8d6bd..05e92fa23 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 74be1aefd..6f49e03ea 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 66e0fe096..5e105272e 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 970609733..ca9de6a6f 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 af6c38c7b..6a598832e 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 27a5604b6..2c8942e70 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} +
+
+#
+# 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} +