diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index dee8431e8d9f88cd6bc0f91d15b3f44ffd4f07e9..e47cfa83950faf0350b38fdfdd2e42bb2e3b8164 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -76,6 +76,7 @@ jobs:
         - rumba32
         - mks_robin_pro
         - STM32F103RET6_creality
+        - LERDGEX
 
         # Put lengthy tests last
 
diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index b3d5f91bde15c74968e870a42438970de50bf360..e2c3c888f73f10e329a380a992463fd1f72d7d59 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -337,11 +337,12 @@
 #define BOARD_BTT_BTT002_V1_0         4211  // BigTreeTech BTT002 v1.0 (STM32F407VG)
 #define BOARD_BTT_GTR_V1_0            4212  // BigTreeTech GTR v1.0 (STM32F407IGT)
 #define BOARD_LERDGE_K                4213  // Lerdge K (STM32F407ZG)
-#define BOARD_LERDGE_X                4214  // Lerdge X (STM32F407VE)
-#define BOARD_VAKE403D                4215  // VAkE 403D (STM32F446VET6)
-#define BOARD_FYSETC_S6               4216  // FYSETC S6 board
-#define BOARD_FLYF407ZG               4217  // FLYF407ZG board (STM32F407ZG)
-#define BOARD_MKS_ROBIN2              4218  // MKS_ROBIN2 (STM32F407ZE)
+#define BOARD_LERDGE_S                4214  // Lerdge S (STM32F407VE)
+#define BOARD_LERDGE_X                4215  // Lerdge X (STM32F407VE)
+#define BOARD_VAKE403D                4216  // VAkE 403D (STM32F446VET6)
+#define BOARD_FYSETC_S6               4217  // FYSETC S6 board
+#define BOARD_FLYF407ZG               4218  // FLYF407ZG board (STM32F407ZG)
+#define BOARD_MKS_ROBIN2              4219  // MKS_ROBIN2 (STM32F407ZE)
 
 //
 // ARM Cortex M7
diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp
index 6746595ffea783e189cff99507d4d23a47734e77..1afe5c4e4ecfce90f34da91b30be79ec89a11233 100644
--- a/Marlin/src/module/temperature.cpp
+++ b/Marlin/src/module/temperature.cpp
@@ -1598,12 +1598,20 @@ void Temperature::init() {
   #if MB(RUMBA)
     // Disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
     #define _AD(N) ANY(HEATER_##N##_USES_AD595, HEATER_##N##_USES_AD8495)
-    #if  _AD(0) || _AD(1) || _AD(2) || _AD(BED) || _AD(CHAMBER)
+    #if _AD(0) || _AD(1) || _AD(2) || _AD(BED) || _AD(CHAMBER)
       MCUCR = _BV(JTD);
       MCUCR = _BV(JTD);
     #endif
   #endif
 
+  // Thermistor activation by MCU pin
+  #if PIN_EXISTS(TEMP_0_TR_ENABLE_PIN)
+    OUT_WRITE(TEMP_0_TR_ENABLE_PIN, ENABLED(HEATER_0_USES_MAX6675));
+  #endif
+  #if PIN_EXISTS(TEMP_1_TR_ENABLE_PIN)
+    OUT_WRITE(TEMP_1_TR_ENABLE_PIN, ENABLED(HEATER_1_USES_MAX6675));
+  #endif
+
   #if BOTH(PIDTEMP, PID_EXTRUSION_SCALING)
     last_e_position = 0;
   #endif
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index 6b06bda8871908dd5f2de369841bc98b8cd93f88..f81f8f42f23a92a036a2c1eaee9decb1f6a3bf49 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -586,8 +586,10 @@
   #include "stm32f4/pins_BTT_BTT002_V1_0.h"     // STM32F4                                env:BIGTREE_BTT002
 #elif MB(LERDGE_K)
   #include "stm32f4/pins_LERDGE_K.h"            // STM32F4                                env:STM32F4
+#elif MB(LERDGE_S)
+  #include "stm32f4/pins_LERDGE_S.h"            // STM32F4                                env:LERDGE_S
 #elif MB(LERDGE_X)
-  #include "stm32f4/pins_LERDGE_X.h"            // STM32F4                                env:STM32F4
+  #include "stm32f4/pins_LERDGE_X.h"            // STM32F4                                env:LERDGE_X
 #elif MB(VAKE403D)
   #include "stm32f4/pins_VAKE403D.h"            // STM32F4                                env:STM32F4
 #elif MB(FYSETC_S6)
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
index 35ad324b58a2a7ea4ba16ea06a78a9979c7130b1..2146c4a5287ee145681c9a32cfc7f45c6c2b10a8 100644
--- a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
@@ -29,13 +29,10 @@
 
 #define I2C_EEPROM
 
-// Ignore temp readings during develpment.
-//#define BOGUS_TEMPERATURE_GRACE_PERIOD 2000
-
 //
 // Servos
 //
-//#define SERVO0_PIN                        PD12
+//#define SERVO0_PIN                        PB11
 
 //
 // Limit Switches
@@ -48,14 +45,14 @@
 // Z Probe (when not Z_MIN_PIN)
 //
 //#ifndef Z_MIN_PROBE_PIN
-//  #define Z_MIN_PROBE_PIN  PB15
+//  #define Z_MIN_PROBE_PIN                 PG6
 //#endif
 
 //
 // Filament runout
 //
-#define FIL_RUNOUT_PIN                      PE6
-#define FIL_RUNOUT2_PIN                     PE7
+#define FIL_RUNOUT_PIN                      PE5
+#define FIL_RUNOUT2_PIN                     PE6
 
 //
 // Steppers
@@ -64,35 +61,35 @@
 #define X_DIR_PIN                           PB10
 #define X_ENABLE_PIN                        PG0
 //#ifndef X_CS_PIN
-//  #define X_CS_PIN       PE0
+//  #define X_CS_PIN                        PE0
 //#endif
 
 #define Y_STEP_PIN                          PF14
 #define Y_DIR_PIN                           PF15
 #define Y_ENABLE_PIN                        PF13
 //#ifndef Y_CS_PIN
-//  #define Y_CS_PIN       PE1
+//  #define Y_CS_PIN                        PE1
 //#endif
 
 #define Z_STEP_PIN                          PF11
 #define Z_DIR_PIN                           PF12
 #define Z_ENABLE_PIN                        PC5
 //#ifndef Z_CS_PIN
-//  #define Z_CS_PIN       PE2
+//  #define Z_CS_PIN                        PE2
 //#endif
 
 #define E0_STEP_PIN                         PC14
 #define E0_DIR_PIN                          PC13
 #define E0_ENABLE_PIN                       PC15
 //#ifndef E0_CS_PIN
-//  #define E0_CS_PIN      PE3
+//  #define E0_CS_PIN                       PE3
 //#endif
 
 #define E1_STEP_PIN                         PF1
 #define E1_DIR_PIN                          PF0
 #define E1_ENABLE_PIN                       PF2
 //#ifndef E1_CS_PIN
-//  #define E1_CS_PIN      PE4
+//  #define E1_CS_PIN                       PE4
 //#endif
 
 //
@@ -102,6 +99,12 @@
 #define TEMP_1_PIN                          PC2   // Analog Input
 #define TEMP_BED_PIN                        PC0   // Analog Input
 
+// Lergde-K can choose thermocouple/thermistor mode in software.
+// For use with thermistors, these pins must be OUT/LOW. 
+// This is done automatically.
+#define TEMP_0_TR_ENABLE_PIN                PF10
+#define TEMP_1_TR_ENABLE_PIN                PF9
+
 //
 // Heaters / Fans
 //
@@ -110,10 +113,10 @@
 #define HEATER_BED_PIN                      PA2
 
 #ifndef FAN_PIN
-  #define FAN_PIN                           PC15
+  #define FAN_PIN                           PF7
 #endif
 #define FAN1_PIN                            PF6
-#define FAN2_PIN                            PF7
+#define FAN2_PIN                            PF8
 
 #ifndef E0_AUTO_FAN_PIN
   #define E0_AUTO_FAN_PIN                   PF6
@@ -125,12 +128,15 @@
 //#define CASE_LIGHT_PIN_CI                 -1
 //#define CASE_LIGHT_PIN_DO                 -1
 //#define NEOPIXEL_PIN                      -1
-
-//
-// Prusa i3 MK2 Multi-Material Multiplexer Support
-//
-//#define E_MUX0_PIN                        -1
-//#define E_MUX1_PIN                        -1
+#ifndef RGB_LED_R_PIN
+  #define RGB_LED_R_PIN                     PB7
+#endif
+#ifndef RGB_LED_G_PIN
+  #define RGB_LED_G_PIN                     PB8
+#endif
+#ifndef RGB_LED_B_PIN
+  #define RGB_LED_B_PIN                     PB9
+#endif
 
 //
 // SD support
@@ -141,45 +147,34 @@
 // Misc. Functions
 //
 #define SDSS                                PC11
-#define LED_PIN                             PC7   // Alive
+#define LED_PIN                             PA15   // Alive
 #define PS_ON_PIN                           -1
 #define KILL_PIN                            -1
-#define POWER_LOSS_PIN                      -1    // Power-loss / nAC_FAULT
+#define POWER_LOSS_PIN                      PA4    // Power-loss / nAC_FAULT
 
 #define SCK_PIN                             PC12
 #define MISO_PIN                            PC8
 #define MOSI_PIN                            PD2
 #define SS_PIN                              PC11
 
+#define SD_DETECT_PIN                       PA8
+#define BEEPER_PIN                          PC7
+
 //
 // LCD / Controller
 //
 
-// TODO: Replace these with the correct FSMC pins, once known
-#define SD_DETECT_PIN                       -1
-#define BEEPER_PIN                          PD12
-#define LCD_PINS_RS                         -1
-#define LCD_PINS_ENABLE                     -1
-#define LCD_PINS_D4                         -1
-#define LCD_PINS_D5                         -1
-#define LCD_PINS_D6                         -1
-#define LCD_PINS_D7                         -1
-
-#define BTN_EN1                             PE3
-#define BTN_EN2                             PE4
-#define BTN_ENC                             PE2
-
-//
-// ST7920 Delays
-//
-#if HAS_GRAPHICAL_LCD
-  #ifndef BOARD_ST7920_DELAY_1
-    #define BOARD_ST7920_DELAY_1  DELAY_NS(96)
-  #endif
-  #ifndef BOARD_ST7920_DELAY_2
-    #define BOARD_ST7920_DELAY_2  DELAY_NS(48)
-  #endif
-  #ifndef BOARD_ST7920_DELAY_3
-    #define BOARD_ST7920_DELAY_3 DELAY_NS(715)
-  #endif
-#endif
+#define TFT_RESET_PIN                       PD6
+#define TFT_BACKLIGHT_PIN                   PD3
+
+#define TFT_CS_PIN                          PD7
+#define TFT_RS_PIN                          PD11
+
+#define TOUCH_CS_PIN                        PG15
+#define TOUCH_SCK_PIN                       PB3
+#define TOUCH_MOSI_PIN                      PB5
+#define TOUCH_MISO_PIN                      PB4
+
+#define BTN_EN1                             PG10
+#define BTN_EN2                             PG11
+#define BTN_ENC                             PG9
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h
new file mode 100644
index 0000000000000000000000000000000000000000..258cd697fe7c42bfb0743211db3f56cb65cf2521
--- /dev/null
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h
@@ -0,0 +1,208 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if !defined(STM32F4) && !defined(STM32F4xx)
+  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
+#elif HOTENDS > 2 || E_STEPPERS > 2
+  #error "LERDGE S supports up to 2 hotends / E-steppers."
+#endif
+
+#define BOARD_INFO_NAME      "Lerdge S"
+#define DEFAULT_MACHINE_NAME "LERDGE"
+
+#define STEP_TIMER 4
+#define TEMP_TIMER 2
+
+//#define I2C_EEPROM
+
+//
+// Servos
+//
+#define SERVO0_PIN                          PD12  //confirmed
+//#define SERVO1_PIN                        -1
+
+//
+// Limit Switches
+//
+#define X_MIN_PIN                           PG9   //confirmed
+#define Y_MIN_PIN                           PG10  //confirmed
+#define Z_MIN_PIN                           PG11  //confirmed
+
+#define X_MAX_PIN                           PG12  //confirmed
+#define Y_MAX_PIN                           PG13  //confirmed
+#define Z_MAX_PIN                           PG14  //confirmed
+
+//
+// Filament runout
+//
+#define FIL_RUNOUT_PIN                      PC5   //confirmed
+
+//
+// Z Probe (when not Z_MIN_PIN)
+//
+#ifndef Z_MIN_PROBE_PIN
+  #define Z_MIN_PROBE_PIN                   PG8   //confirmed
+#endif
+
+//
+// Steppers
+//
+#define X_STEP_PIN                          PF7   //confirmed
+#define X_DIR_PIN                           PF8   //confirmed
+#define X_ENABLE_PIN                        PF6   //confirmed
+
+#define Y_STEP_PIN                          PF10  //confirmed
+#define Y_DIR_PIN                           PF11  //confirmed
+#define Y_ENABLE_PIN                        PF9   //confirmed
+
+#define Z_STEP_PIN                          PF13  //confirmed
+#define Z_DIR_PIN                           PF14  //confirmed
+#define Z_ENABLE_PIN                        PF12  //confirmed
+
+#define E0_STEP_PIN                         PG0   //confirmed
+#define E0_DIR_PIN                          PG1   //confirmed
+#define E0_ENABLE_PIN                       PF15  //confirmed
+
+#define E1_STEP_PIN                         PG3   //confirmed
+#define E1_DIR_PIN                          PG4   //confirmed
+#define E1_ENABLE_PIN                       PG2   //confirmed
+
+//
+// Temperature Sensors
+//
+#define TEMP_0_PIN                          PC0   // See below for activation of thermistor readings
+#define TEMP_1_PIN                          PC1   // See below for activation of thermistor readings
+#define TEMP_BED_PIN                        PC3   //confirmed
+
+// Lergde-S can choose thermocouple/thermistor mode in software.
+// For use with thermistors, these pins must be OUT/LOW.
+// This is done automatically.
+#define TEMP_0_TR_ENABLE_PIN                PF3
+#define TEMP_1_TR_ENABLE_PIN                PF4
+
+// MAX6675 Cold-Junction-Compensated K-Thermocouple to Digital Converter (0°C to +1024°C)
+// https://datasheets.maximintegrated.com/en/ds/MAX6675.pdf
+
+#define MAX6675_SCK_PIN                     PB3   // max6675 datasheet: SCK pin, found with multimeter, not tested
+#define MAX6675_DO_PIN                      PB4   // max6675 datasheet: SO pin, found with multimeter, not tested
+#define MAX6675_SS_PIN                      PC4   // max6675 datasheet: /CS pin, found with multimeter, not tested and likely wrong
+
+// Expansion board with second max6675
+// Warning: Some boards leave the slot unpopulated.
+
+//#define MAX6675_SCK2_PIN                  PB3   // max6675 datasheet: SCK pin, found with multimeter, not tested
+//#define MAX6675_DO2_PIN                   PB4   // max6675 datasheet: SO pin, found with multimeter, not tested
+//#define MAX6675_SS2_PIN                   PF1   // max6675 datasheet: /CS pin, found with multimeter, not tested
+
+//
+// Heaters / Fans
+//
+#define HEATER_0_PIN                        PA0   //confirmed
+#define HEATER_1_PIN                        PA1   //confirmed
+#define HEATER_BED_PIN                      PA3   //confirmed
+
+#define FAN_PIN                             PA15  // heater 0 fan 1 //confirmed
+#define FAN1_PIN                            PB10  // heater 1 fan 2 //confirmed
+#define FAN2_PIN                            PF5   // heater 0 fan 2 and heater 1 fan 1 (two sockets, switched together) //confirmed
+
+#ifndef E0_AUTO_FAN_PIN
+  #define E0_AUTO_FAN_PIN                   PF5
+#endif
+
+//
+// Prusa i3 MK2 Multi Material Multiplexer Support
+//
+//#define E_MUX0_PIN                        -1
+//#define E_MUX1_PIN                        -1
+
+//
+// LED / Lighting
+//
+//Lerdge-S board has two LED connectors (this is the one on the mainboard)
+#define CASE_LIGHT_PIN                      PC7   //confirmed
+
+//on the dual extrusion addon board is a RGB connector
+#define RGB_LED_R_PIN                       PC7   // Shared with the mainboard LED light connector (CASE_LIGHT_PIN), confirmed
+#define RGB_LED_G_PIN                       PB0   //confirmed
+#define RGB_LED_B_PIN                       PB1   //confirmed
+
+//
+// Misc. Functions
+//
+#define SDSS                                PC11  // SD is working using SDIO, not sure if this definition is needed?
+#define LED_PIN                             PC6   // Mainboard soldered green LED, confirmed
+#define PS_ON_PIN                           PB2   // Board has a power module connector, confirmed
+#define KILL_PIN                            -1    // There is no reset button on the LCD
+#define POWER_LOSS_PIN                      -1    // PB2 could be used for this as well
+
+//
+// SD support
+//
+#define SDIO_SUPPORT
+
+#define SCK_PIN                             PC12  //confirmed working
+#define MISO_PIN                            PC8   //confirmed working
+#define MOSI_PIN                            PD2   //confirmed working
+#define SS_PIN                              PC11  //confirmed working
+
+#define SD_DETECT_PIN                       PG15  //confirmed
+
+//
+// Persistent Storage
+// If no option is selected below the SD Card will be used
+// (this section modelled after pins_LONGER3D_LK.h)
+// Warning: Not tested yet! Pins traced with multimeter, mistakes are possible
+//#define SPI_EEPROM
+
+#if ENABLED(SPI_EEPROM)
+  // Lerdge has an SPI EEPROM Winbond W25Q128 (128Mbits) https://www.pjrc.com/teensy/W25Q128FV.pdf
+  #define SPI_CHAN_EEPROM1 1
+  #define SPI_EEPROM1_CS                    PB12  // datasheet: /CS pin, found with multimeter, not tested
+  #define EEPROM_SCK                        PB13  // datasheet: CLK pin, found with multimeter, not tested
+  #define EEPROM_MISO                       PB14  // datasheet: DO pin, found with multimeter, not tested
+  #define EEPROM_MOSI                       PB15  // datasheet: DI pin, found with multimeter, not tested
+  #define EEPROM_PAGE_SIZE 0x1000U                // 4KB (from datasheet)
+  #define MARLIN_EEPROM_SIZE 16UL * (EEPROM_PAGE_SIZE)   // Limit to 64KB for now...
+#else
+  #define MARLIN_EEPROM_SIZE 0x800U               // On SD, Limit to 2KB, require this amount of RAM
+#endif
+
+//
+// LCD / Controller
+//
+
+// The LCD is initialized in FSMC mode
+#define BEEPER_PIN                          PD13  //confirmed
+
+#define BTN_EN1                             PC14  //confirmed
+#define BTN_EN2                             PC15  //confirmed
+#define BTN_ENC                             PC13  //confirmed
+
+#define TFT_RESET_PIN                       PD6   //confirmed
+#define TFT_BACKLIGHT_PIN                   PD3   //confirmed
+
+#define TFT_CS_PIN                          PD7   // TFT works
+#define TFT_RS_PIN                          PD11  // TFT works
+
+// There is touch, but calibration is off
+#define TOUCH_CS_PIN                        PB6
+#define TOUCH_SCK_PIN                       PB3
+#define TOUCH_MOSI_PIN                      PB5
+#define TOUCH_MISO_PIN                      PB4
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
index 04588bee253e7b578f92c22bbe4213e9b8f085e2..a9efe102102b2efe33df8da182a0e57810dcfbc8 100644
--- a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
@@ -20,20 +20,22 @@
 
 #if !defined(STM32F4) && !defined(STM32F4xx)
   #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
-  #error "LERDGE X supports up to 2 hotends / E-steppers."
+#elif HOTENDS > 1 || E_STEPPERS > 1
+  #error "LERDGE X supports only one hotend / E-steppers"
 #endif
 
 #define BOARD_INFO_NAME      "Lerdge X"
 #define DEFAULT_MACHINE_NAME "LERDGE"
 
-//#define I2C_EEPROM
+#define STEP_TIMER 4
+#define TEMP_TIMER 2
+
+#define I2C_EEPROM
 
 //
 // Servos
 //
-//#define SERVO0_PIN                        PD12
-//#define SERVO1_PIN                        -1
+//#define SERVO0_PIN                        PD13
 
 //
 // Limit Switches
@@ -51,7 +53,7 @@
 // Z Probe (when not Z_MIN_PIN)
 //
 //#ifndef Z_MIN_PROBE_PIN
-//  #define Z_MIN_PROBE_PIN  PB15
+//  #define Z_MIN_PROBE_PIN                 PB15
 //#endif
 
 //
@@ -60,37 +62,18 @@
 #define X_STEP_PIN                          PB10
 #define X_DIR_PIN                           PB2
 #define X_ENABLE_PIN                        PB11
-//#ifndef X_CS_PIN
-//  #define X_CS_PIN       PD1
-//#endif
 
 #define Y_STEP_PIN                          PB0
 #define Y_DIR_PIN                           PC5
 #define Y_ENABLE_PIN                        PB1
-//#ifndef Y_CS_PIN
-//  #define Y_CS_PIN       PE12
-//#endif
 
 #define Z_STEP_PIN                          PA7
 #define Z_DIR_PIN                           PA6
 #define Z_ENABLE_PIN                        PC4
-//#ifndef Z_CS_PIN
-//  #define Z_CS_PIN       PD5
-//#endif
 
 #define E0_STEP_PIN                         PA4
 #define E0_DIR_PIN                          PA3
 #define E0_ENABLE_PIN                       PA5
-//#ifndef E0_CS_PIN
-//  #define E0_CS_PIN      PB4
-//#endif
-
-#define E1_STEP_PIN                         -1
-#define E1_DIR_PIN                          -1
-#define E1_ENABLE_PIN                       -1
-//#ifndef E1_CS_PIN
-//  #define E1_CS_PIN      PE5
-//#endif
 
 //
 // Temperature Sensors
@@ -106,9 +89,9 @@
 #define HEATER_1_PIN                        -1
 #define HEATER_BED_PIN                      PA2
 
-#ifndef FAN_PIN
-  //#define FAN_PIN                         PC15
-#endif
+//#ifndef FAN_PIN
+//  #define FAN_PIN                         PC15
+//#endif
 #define FAN1_PIN                            PC15
 #define FAN2_PIN                            PA0
 
@@ -116,12 +99,6 @@
   #define E0_AUTO_FAN_PIN                   PC15  // FAN1_PIN
 #endif
 
-//
-// Prusa i3 MK2 Multi Material Multiplexer Support
-//
-//#define E_MUX0_PIN                        -1
-//#define E_MUX1_PIN                        -1
-
 //
 // LED / Lighting
 //
@@ -136,7 +113,9 @@
 #define LED_PIN                             PC7   // Alive
 #define PS_ON_PIN                           -1
 #define KILL_PIN                            -1
-#define POWER_LOSS_PIN                      -1    // Power-loss / nAC_FAULT
+
+// Lerdge supports auto-power off and power loss sense through a single pin.
+#define POWER_LOSS_PIN                      PC14    // Power-loss / nAC_FAULT
 
 #define SCK_PIN                             PC12
 #define MISO_PIN                            PC8
@@ -147,36 +126,26 @@
 // SD support
 //
 #define SDIO_SUPPORT
+#define SD_DETECT_PIN                       PA8
 
 //
 // LCD / Controller
 //
 
 // The LCD is initialized in FSMC mode
-#define SD_DETECT_PIN                       -1
 #define BEEPER_PIN                          PD12
 
 #define BTN_EN1                             PE3
 #define BTN_EN2                             PE4
 #define BTN_ENC                             PE2
 
-#define LCD_RESET_PIN                       PD6
-#define LCD_BACKLIGHT_PIN                   PD3
-#define FSMC_CS_PIN                         PD4
-#define FSMC_RS_PIN                         PD11
-#define TOUCH_CS                            PB6
-
-//
-// ST7920 Delays
-//
-#if HAS_GRAPHICAL_LCD
-  #ifndef BOARD_ST7920_DELAY_1
-    #define BOARD_ST7920_DELAY_1  DELAY_NS(96)
-  #endif
-  #ifndef BOARD_ST7920_DELAY_2
-    #define BOARD_ST7920_DELAY_2  DELAY_NS(48)
-  #endif
-  #ifndef BOARD_ST7920_DELAY_3
-    #define BOARD_ST7920_DELAY_3 DELAY_NS(715)
-  #endif
-#endif
+#define TFT_RESET_PIN                       PD6
+#define TFT_BACKLIGHT_PIN                   PD3
+
+#define TFT_CS_PIN                          PD7
+#define TFT_RS_PIN                          PD11
+
+#define TOUCH_CS_PIN                        PB6
+#define TOUCH_SCK_PIN                       PB3
+#define TOUCH_MOSI_PIN                      PB5
+#define TOUCH_MISO_PIN                      PB4
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp
index 5601446f8108534ea411c4b866ed038d83022cb6..9092633b844f2d15b0eeafb21e138afbd974ffb0 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp
@@ -428,7 +428,7 @@ void USB::Task() { //USB state machine
   uint8_t rcode;
   uint8_t tmpdata;
   static uint32_t delay = 0;
-  //USB_FD_DEVICE_DESCRIPTOR buf;
+  //USB_DEVICE_DESCRIPTOR buf;
   bool lowspeed = false;
 
   MAX3421E::Task();
@@ -647,8 +647,8 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
   //printf("Configuring: parent = %i, port = %i\r\n", parent, port);
   uint8_t devConfigIndex;
   uint8_t rcode = 0;
-  uint8_t buf[sizeof (USB_FD_DEVICE_DESCRIPTOR)];
-  USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
+  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
+  USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
   UsbDevice *p = nullptr;
   EpInfo *oldep_ptr = nullptr;
   EpInfo epInfo;
@@ -678,13 +678,13 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
 
   p->lowspeed = lowspeed;
   // Get device descriptor
-  rcode = getDevDescr(0, 0, sizeof (USB_FD_DEVICE_DESCRIPTOR), (uint8_t*)buf);
+  rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
 
   // Restore p->epinfo
   p->epinfo = oldep_ptr;
 
   if (rcode) {
-    //printf("Configuring error: Can't get USB_FD_DEVICE_DESCRIPTOR\r\n");
+    //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
     return rcode;
   }
 
@@ -762,7 +762,7 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t con
 uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
   const uint8_t bufSize = 64;
   uint8_t buf[bufSize];
-  USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
+  USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
 
   uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
   if (ret) return ret;
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h
index 10478eb6441dc572b9d4b57b6a13d176975bd056..5d4ddaf175c9b088837e2d2dc9b176e23077b04f 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h
@@ -30,10 +30,10 @@
 
 class UsbConfigXtracter {
 public:
-  //virtual void ConfigXtract(const USB_FD_CONFIGURATION_DESCRIPTOR *conf) = 0;
-  //virtual void InterfaceXtract(uint8_t conf, const USB_FD_INTERFACE_DESCRIPTOR *iface) = 0;
+  //virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
+  //virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
 
-  virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
+  virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
   }
 };
 
@@ -50,7 +50,7 @@ class ConfigDescParser : public USBReadParser {
   MultiValueBuffer theBuffer;
   MultiByteValueParser valParser;
   ByteSkipper theSkipper;
-  uint8_t varBuffer[16 /*sizeof(USB_FD_CONFIGURATION_DESCRIPTOR)*/];
+  uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
 
   uint8_t stateParseDescr; // ParseDescriptor state
 
@@ -97,8 +97,8 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
   compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
 template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
 bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
-  USB_FD_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR*>(varBuffer);
-  USB_FD_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_FD_INTERFACE_DESCRIPTOR*>(varBuffer);
+  USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
+  USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
   switch (stateParseDescr) {
     case 0:
       theBuffer.valueSize = 2;
@@ -155,7 +155,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
         case USB_DESCRIPTOR_ENDPOINT:
           if (!valParser.Parse(pp, pcntdn)) return false;
           if (isGoodInterface && theXtractor)
-            theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_FD_ENDPOINT_DESCRIPTOR*)varBuffer);
+            theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
           break;
           //case HID_DESCRIPTOR_HID:
           //  if (!valParser.Parse(pp, pcntdn)) return false;
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp
index 2512e3846c63a2320dc4d5b617573fd3b81227a3..a57245f78a70f7c8affd56a93c2bcede955e4a59 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp
@@ -250,10 +250,10 @@ bLastUsbError(0) {
  */
 uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
 
-  const uint8_t constBufSize = sizeof (USB_FD_DEVICE_DESCRIPTOR);
+  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
 
   uint8_t buf[constBufSize];
-  USB_FD_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR*>(buf);
+  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
   uint8_t rcode;
   UsbDevice *p = nullptr;
   EpInfo *oldep_ptr = nullptr;
@@ -529,7 +529,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
  * @param proto
  * @param pep
  */
-void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR * pep) {
+void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR * pep) {
   ErrorMessage<uint8_t> (PSTR("Conf.Val"), conf);
   ErrorMessage<uint8_t> (PSTR("Iface Num"), iface);
   ErrorMessage<uint8_t> (PSTR("Alt.Set"), alt);
@@ -1166,7 +1166,7 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
  *
  * @param ep_ptr
  */
-void BulkOnly::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) {
+void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
   Notify(PSTR("Endpoint descriptor:"), 0x80);
   Notify(PSTR("\r\nLength:\t\t"), 0x80);
   D_PrintHex<uint8_t> (ep_ptr->bLength, 0x80);
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h
index 960651ff2fc2e149726f2e73b424d2327c8498f6..09b82fdb92d4abe13600f709c860412e0ad29ca8 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h
@@ -491,7 +491,7 @@ protected:
   uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
   bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
   bool WriteOk[MASS_MAX_SUPPORTED_LUN];
-  void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr);
+  void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
 
   // Additional Initialization Method for Subclasses
 
@@ -526,7 +526,7 @@ public:
   virtual uint8_t GetAddress() { return bAddress; }
 
   // UsbConfigXtracter implementation
-  void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_FD_ENDPOINT_DESCRIPTOR *ep);
+  void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
 
   virtual bool DEVCLASSOK(uint8_t klass) { return klass == USB_CLASS_MASS_STORAGE; }
 
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp
index 0ab58b91f3ed60ee31f444f5dcf679160b32e398..78a9ba1fd71d92f5be77691c0840b89603b59043 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp
@@ -37,7 +37,7 @@ int UsbDEBUGlvl = 0x80;
 void E_Notifyc(char c, int lvl) {
   if (UsbDEBUGlvl < lvl) return;
   USB_HOST_SERIAL.print(c
-    #if !defined(ARDUINO) && !defined(ARDUINO_ARCH_LPC176X)
+    #if !defined(ARDUINO) || ARDUINO < 100
       , BYTE
     #endif
   );
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h
index a08d58b23169d06ea1ccba7756d7fc71ff7781f8..039215b1bbcfbf82d28e0f581a75651444f3439e 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h
@@ -116,7 +116,7 @@ typedef struct {
         uint8_t iProduct; // Index of String Descriptor describing the product.
         uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
         uint8_t bNumConfigurations; // Number of possible configurations.
-} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR;
+} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
 
 /* Configuration descriptor structure */
 typedef struct {
@@ -128,7 +128,7 @@ typedef struct {
         uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
         uint8_t bmAttributes; // Configuration characteristics.
         uint8_t bMaxPower; // Maximum power consumed by this configuration.
-} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR;
+} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
 
 /* Interface descriptor structure */
 typedef struct {
@@ -141,7 +141,7 @@ typedef struct {
         uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
         uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF).  0xFF-Vendor specific.
         uint8_t iInterface; // Index of String Descriptor describing the interface.
-} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR;
+} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
 
 /* Endpoint descriptor structure */
 typedef struct {
@@ -151,7 +151,7 @@ typedef struct {
         uint8_t bmAttributes; // Endpoint transfer type.
         uint16_t wMaxPacketSize; // Maximum packet size.
         uint8_t bInterval; // Polling interval in frames.
-} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR;
+} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
 
 /* HID descriptor */
 typedef struct {
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h
index 26ed852a279ec1efcb84db5e88149f1ffd21d079..6ad9cb5c8dc3574b50be2e2934bf0d47f5b1e38f 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h
@@ -174,7 +174,7 @@ protected:
         volatile uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
         volatile bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
         volatile bool WriteOk[MASS_MAX_SUPPORTED_LUN];
-        void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr);
+        void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
 
 public:
         UHS_Bulk_Storage(UHS_USB_HOST_BASE *p);
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h
index 6ad9cff7f086b356aa0ea8945155788c580e3da5..a171b13818cafecc28520a226b776237770db876 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h
@@ -1188,7 +1188,7 @@ uint8_t UHS_NI UHS_Bulk_Storage::HandleSCSIError(uint8_t status) {
  *
  * @param ep_ptr
  */
-void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) {
+void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
         Notify(PSTR("Endpoint descriptor:"), 0x80);
         Notify(PSTR("\r\nLength:\t\t"), 0x80);
         D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h
index eb96c7eb5d5d501d241d64ec1ffb8efe5bd51025..908391a157f159615dfabbd27817a8f9a47bf999 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h
@@ -239,12 +239,12 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe
         // wrap in {} to throw away the 64 byte buffer when we are done with it
         {
                 uint8_t buf[biggest];
-                USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
+                USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
 #else
         const uint8_t biggest = 18;
         uint8_t buf[biggest];
-        USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
-        USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
+        USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
+        USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
 #endif
 
                 //for(devConfigIndex = 0; devConfigIndex < UHS_HOST_MAX_INTERFACE_DRIVERS; devConfigIndex++) {
@@ -309,7 +309,7 @@ again:
                                 sof_delay(200);
                                 goto again;
                         }
-                        HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_FD_DEVICE_DESCRIPTOR\r\n", rcode);
+                        HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_DEVICE_DESCRIPTOR\r\n", rcode);
                         return rcode;
                 }
 
@@ -378,7 +378,7 @@ again:
         } // unwrapped, old large buf now invalid and discarded.
 
         uint8_t buf[18];
-        USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
+        USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
 #endif
 
         ei.address = addrPool.AllocAddress(parent, IsHub(ei.klass), port);
@@ -415,9 +415,9 @@ again:
                 HOST_DEBUG("configs: %i\r\n", configs);
                 for(uint8_t conf = 0; (!rcode) && (conf < configs); conf++) {
                         // read the config descriptor into a buffer.
-                        rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), conf, buf);
+                        rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), conf, buf);
                         if(rcode) {
-                                HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode);
+                                HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode);
                                 rcode = UHS_HOST_ERROR_FailGetConfDescr;
                                 continue;
                         }
@@ -438,7 +438,7 @@ again:
                         uint8_t offset;
                         rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset);
                         if(rcode) {
-                                HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
+                                HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
                                 break;
                         }
                         for(; (numinf) && (!rcode); inf++) {
@@ -451,7 +451,7 @@ again:
                                         break;
                                 }
                                 if(rcode) {
-                                        HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
+                                        HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
                                         continue;
                                 }
                                 rcode = TestInterface(&ei);
@@ -471,9 +471,9 @@ again:
                 if(!bestsuccess) rcode = UHS_HOST_ERROR_DEVICE_NOT_SUPPORTED;
         }
         if(!rcode) {
-                rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), bestconf, buf);
+                rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), bestconf, buf);
                 if(rcode) {
-                        HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode);
+                        HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode);
                         rcode = UHS_HOST_ERROR_FailGetConfDescr;
                 }
         }
@@ -497,7 +497,7 @@ again:
                                 uint8_t offset;
                                 rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset);
                                 if(rcode) {
-                                        HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
+                                        HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
                                 } else {
                                         for(; (numinf) && (!rcode); inf++) {
                                                 // iterate for each interface on this config
@@ -508,7 +508,7 @@ again:
                                                         break;
                                                 }
                                                 if(rcode) {
-                                                        HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
+                                                        HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
                                                         continue;
                                                 }
 
@@ -721,7 +721,7 @@ uint8_t UHS_USB_HOST_BASE::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytes
  * @param offset
  * @return zero for success or error code
  */
-uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) {
+uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) {
         if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT;
         if(!pep) return UHS_HOST_ERROR_NULL_EPINFO;
         *left = ucd->wTotalLength;
@@ -837,7 +837,7 @@ uint8_t UHS_USB_HOST_BASE::getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pe
         return rcode;
 }
 
-uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd) {
+uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd) {
         if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT;
         uint8_t data[ei->bMaxPacketSize0];
         UHS_EpInfo *pep;
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h
index 9d945d69c52b222c1cd548dc12921066e249f107..34b8ad72e7ef4e3780f28440e750142d67cee431 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h
@@ -164,7 +164,7 @@ typedef struct {
         uint8_t iProduct; // Index of String Descriptor describing the product.
         uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
         uint8_t bNumConfigurations; // Number of possible configurations.
-} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR;
+} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
 
 /* Configuration descriptor structure */
 typedef struct {
@@ -176,7 +176,7 @@ typedef struct {
         uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
         uint8_t bmAttributes; // Configuration characteristics.
         uint8_t bMaxPower; // Maximum power consumed by this configuration.
-} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR;
+} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
 
 /* Interface descriptor structure */
 typedef struct {
@@ -189,7 +189,7 @@ typedef struct {
         uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
         uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF).  0xFF-Vendor specific.
         uint8_t iInterface; // Index of String Descriptor describing the interface.
-} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR;
+} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
 
 /* Endpoint descriptor structure */
 typedef struct {
@@ -199,7 +199,7 @@ typedef struct {
         uint8_t bmAttributes; // Endpoint transfer type.
         uint16_t wMaxPacketSize; // Maximum packet size.
         uint8_t bInterval; // Polling interval in frames.
-} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR;
+} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
 
 /* HID descriptor */
 /*
diff --git a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h
index c19574b4af1c7bd9ab97f2b25466d3cff05b641d..9a6b110a156b9198b82584b84b9879c42753d817 100644
--- a/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h
+++ b/Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h
@@ -207,7 +207,7 @@ public:
                 interrupts();
         }
 
-        uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd);
+        uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd);
 
         uint8_t UHS_NI setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t epcount, volatile UHS_EpInfo* eprecord_ptr);
 
@@ -261,7 +261,7 @@ public:
         uint8_t TestInterface(ENUMERATION_INFO *ei);
         uint8_t enumerateInterface(ENUMERATION_INFO *ei);
         uint8_t getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pep, uint8_t data[], uint16_t *left, uint16_t *read, uint8_t *offset);
-        uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset);
+        uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset);
         uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
         uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data);
         uint8_t doSoftReset(uint8_t parent, uint8_t port, uint8_t address);
diff --git a/buildroot/share/PlatformIO/boards/LERDGE.json b/buildroot/share/PlatformIO/boards/LERDGE.json
new file mode 100644
index 0000000000000000000000000000000000000000..b3e4ca44fa9059c95e07bc8155e171810bdd6bba
--- /dev/null
+++ b/buildroot/share/PlatformIO/boards/LERDGE.json
@@ -0,0 +1,64 @@
+{
+  "build": {
+    "core": "stm32",
+    "cpu": "cortex-m4",
+    "extra_flags": "-DSTM32F407xx",
+    "f_cpu": "168000000L",
+    "hwids": [
+      [
+        "0x1EAF",
+        "0x0003"
+      ],
+      [
+        "0x0483",
+        "0x3748"
+      ]
+    ],
+    "mcu": "stm32f407zgt6",
+    "variant": "LERDGE"
+  },
+  "debug": {
+    "jlink_device": "STM32F407ZG",
+    "openocd_target": "stm32f4x",
+    "svd_path": "STM32F40x.svd",
+    "tools": {
+      "stlink": {
+        "server": {
+          "arguments": [
+            "-f",
+            "scripts/interface/stlink.cfg",
+            "-c",
+            "transport select hla_swd",
+            "-f",
+            "scripts/target/stm32f4x.cfg",
+            "-c",
+            "reset_config none"
+          ],
+          "executable": "bin/openocd",
+          "package": "tool-openocd"
+        }
+      }
+    }
+  },
+  "frameworks": [
+    "arduino",
+    "stm32cube"
+  ],
+  "name": "STM32F407ZGT6(192k RAM. 1024k Flash)",
+  "upload": {
+    "disable_flushing": false,
+    "maximum_ram_size": 196608,
+    "maximum_size": 1048576,
+    "protocol": "stlink",
+    "protocols": [
+      "stlink",
+      "dfu",
+      "jlink"
+    ],
+    "require_upload_port": true,
+    "use_1200bps_touch": false,
+    "wait_for_upload_port": false
+  },
+  "url": "http://www.st.com/en/microcontrollers/stm32f407ZG.html",
+  "vendor": "Generic"
+}
diff --git a/buildroot/share/PlatformIO/ldscripts/lerdge.ld b/buildroot/share/PlatformIO/ldscripts/lerdge.ld
new file mode 100644
index 0000000000000000000000000000000000000000..aa0b1dd9cb365980b5e806281b6f0ee222ba9601
--- /dev/null
+++ b/buildroot/share/PlatformIO/ldscripts/lerdge.ld
@@ -0,0 +1,186 @@
+/*
+*****************************************************************************
+**
+**  File        : LinkerScript.ld
+**
+**  Abstract    : Linker script for STM32F407VGTx Device with
+**                1024KByte FLASH, 128KByte RAM
+**
+**                Set heap size, stack size and stack location according
+**                to application requirements.
+**
+**                Set memory bank area and size if external memory is used.
+**
+**  Target      : STMicroelectronics STM32
+**
+**
+**  Distribution: The file is distributed as is, without any warranty
+**                of any kind.
+**
+**  (c)Copyright Ac6.
+**  You may use this file as-is or modify it according to the needs of your
+**  project. Distribution of this file (unmodified or modified) is not
+**  permitted. Ac6 permit registered System Workbench for MCU users the
+**  rights to distribute the assembled, compiled & linked contents of this
+**  file as part of an application binary file, provided that it is built
+**  using the System Workbench for MCU toolchain.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20010000;    /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200;;      /* required amount of heap  */
+_Min_Stack_Size = 0x400;; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+FLASH (rx)      : ORIGIN = 0x8000000 + LD_FLASH_OFFSET, LENGTH = LD_MAX_SIZE - LD_FLASH_OFFSET
+RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = LD_MAX_DATA_SIZE
+CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
+}
+
+/* Define output sections */
+SECTIONS
+{
+  /* The startup code goes first into FLASH */
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector)) /* Startup code */
+    . = ALIGN(4);
+  } >FLASH
+
+  /* The program code and other data goes into FLASH */
+  .text ALIGN(4):
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+  } >FLASH
+
+  /* Constant data goes into FLASH */
+  .rodata ALIGN(4):
+  {
+    . = ALIGN(4);
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    . = ALIGN(4);
+  } >FLASH
+
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+  .ARM : {
+    __exidx_start = .;
+    *(.ARM.exidx*)
+    __exidx_end = .;
+  } >FLASH
+
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  } >FLASH
+  .init_array :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  } >FLASH
+  .fini_array :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT(.fini_array.*)))
+    KEEP (*(.fini_array*))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >FLASH
+
+  /* used by the startup to initialize data */
+  _sidata = LOADADDR(.data);
+
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .data :
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM AT> FLASH
+
+  _siccmram = LOADADDR(.ccmram);
+
+  /* CCM-RAM section
+  *
+  * IMPORTANT NOTE!
+  * If initialized variables will be placed in this section,
+  * the startup code needs to be modified to copy the init-values.
+  */
+  .ccmram :
+  {
+    . = ALIGN(4);
+    _sccmram = .;       /* create a global symbol at ccmram start */
+    *(.ccmram)
+    *(.ccmram*)
+
+    . = ALIGN(4);
+    _eccmram = .;       /* create a global symbol at ccmram end */
+  } >CCMRAM AT> FLASH
+
+
+  /* Uninitialized data section */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss secion */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM
+
+  /* User_heap_stack section, used to check that there is enough RAM left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(4);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(4);
+  } >RAM
+
+
+
+  /* Remove information from the standard libraries */
+  /DISCARD/ :
+  {
+    libc.a ( * )
+    libm.a ( * )
+    libgcc.a ( * )
+  }
+
+  .ARM.attributes 0 : { *(.ARM.attributes) }
+}
diff --git a/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py
new file mode 100644
index 0000000000000000000000000000000000000000..c27019990fc5054e0fd425f51c86b7adeafb6520
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py
@@ -0,0 +1,47 @@
+import os,shutil
+from SCons.Script import DefaultEnvironment
+from platformio import util
+
+def copytree(src, dst, symlinks=False, ignore=None):
+    for item in os.listdir(src):
+        s = os.path.join(src, item)
+        d = os.path.join(dst, item)
+        if os.path.isdir(s):
+            shutil.copytree(s, d, symlinks, ignore)
+        else:
+            shutil.copy2(s, d)
+
+env = DefaultEnvironment()
+platform = env.PioPlatform()
+board = env.BoardConfig()
+variant = board.get("build.variant")
+variant_dir = ' +<buildroot/share/PlatformIO/variants/' + variant + '>';
+src_filter = env.get("SRC_FILTER")
+print("Starting SRC Filter:", env.get("SRC_FILTER"))
+src_filter_value = src_filter[0];
+
+src_filter_value = src_filter_value + variant_dir
+src_filter[0] = src_filter_value;
+env["SRC_FILTER"] = src_filter
+
+print("Modified SRC Filter:", env.get("SRC_FILTER"))
+
+cxx_flags = env['CXXFLAGS']
+print("CXXFLAGS", cxx_flags)
+
+FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoststm32")
+assert os.path.isdir(FRAMEWORK_DIR)
+assert os.path.isdir("buildroot/share/PlatformIO/variants")
+
+variant_dir = os.path.join(FRAMEWORK_DIR, "variants", variant)
+
+source_dir = os.path.join("buildroot/share/PlatformIO/variants", variant)
+assert os.path.isdir(source_dir)
+
+if os.path.isdir(variant_dir):
+    shutil.rmtree(variant_dir)
+
+if not os.path.isdir(variant_dir):
+    os.mkdir(variant_dir)
+
+copytree(source_dir, variant_dir)
diff --git a/buildroot/share/PlatformIO/scripts/lerdge.py b/buildroot/share/PlatformIO/scripts/lerdge.py
new file mode 100644
index 0000000000000000000000000000000000000000..fd934a1278669f6f610cfef305183c4640883835
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/lerdge.py
@@ -0,0 +1,46 @@
+import os,sys
+Import("env")
+
+from SCons.Script import DefaultEnvironment
+board = DefaultEnvironment().BoardConfig()
+
+custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/lerdge.ld")
+for i, flag in enumerate(env["LINKFLAGS"]):
+    if "-Wl,-T" in flag:
+        env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script
+    elif flag == "-T":
+        env["LINKFLAGS"][i + 1] = custom_ld_script
+
+def encryptByte(byte):
+    byte = 0xFF & ((byte << 6) | (byte >> 2))
+    i = 0x58 + byte
+    j = 0x05 + byte + (i >> 8)
+    byte = (0xF8 & i) | (0x07 & j)
+    return byte
+
+def encrypt_file(input, output_file, file_length):
+    input_file = bytearray(input.read())
+    for i in range(len(input_file)):
+        result = encryptByte(input_file[i])
+        input_file[i] = result
+
+    output_file.write(input_file)
+    return
+
+# Encrypt ${PROGNAME}.bin and save it as build.firmware
+def encrypt(source, target, env):
+    print("Encrypting to:", board.get("build.firmware"))
+    firmware = open(target[0].path, "rb")
+    result = open(target[0].dir.path + "/" + board.get("build.firmware"), "wb")
+    length = os.path.getsize(target[0].path)
+
+    encrypt_file(firmware, result, length)
+
+    firmware.close()
+    result.close()
+
+if 'firmware' in board.get("build").keys():
+  env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", encrypt);
+else:
+  print("You need to define output file via board_build.firmware = 'filename' parameter")
+  exit(1);
diff --git a/buildroot/share/PlatformIO/scripts/stm32_bootloader.py b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py
new file mode 100644
index 0000000000000000000000000000000000000000..d517f1c8d1aabdc63560cf47aeab2d9396eef218
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/stm32_bootloader.py
@@ -0,0 +1,30 @@
+import os,sys,shutil
+Import("env")
+
+from SCons.Script import DefaultEnvironment
+board = DefaultEnvironment().BoardConfig()
+
+def noencrypt(source, target, env):
+  firmware = os.path.join(target[0].dir.path, board.get("build.firmware"))
+  # do not overwrite encrypted firmware if present
+  if not os.path.isfile(firmware):
+    shutil.copy(target[0].path, firmware)
+
+if 'offset' in board.get("build").keys():
+  LD_FLASH_OFFSET = board.get("build.offset")
+
+  for define in env['CPPDEFINES']:
+    if define[0] == "VECT_TAB_OFFSET":
+      env['CPPDEFINES'].remove(define)
+  env['CPPDEFINES'].append(("VECT_TAB_OFFSET", LD_FLASH_OFFSET))
+
+  maximum_ram_size = board.get("upload.maximum_ram_size")
+
+  for i, flag in enumerate(env["LINKFLAGS"]):
+    if "-Wl,--defsym=LD_FLASH_OFFSET" in flag:
+      env["LINKFLAGS"][i] = "-Wl,--defsym=LD_FLASH_OFFSET=" + LD_FLASH_OFFSET
+    if "-Wl,--defsym=LD_MAX_DATA_SIZE" in flag:
+      env["LINKFLAGS"][i] = "-Wl,--defsym=LD_MAX_DATA_SIZE=" + str(maximum_ram_size - 40)
+
+  if 'firmware' in board.get("build").keys():
+    env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", noencrypt);
diff --git a/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c b/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c
new file mode 100644
index 0000000000000000000000000000000000000000..8cb0776ffad1ec09f422395f09eebae5c71f001c
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/LERDGE/PeripheralPins.c
@@ -0,0 +1,418 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019, STMicroelectronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ * Automatically generated from STM32F407Z(E-G)Tx.xml
+ */
+#include <Arduino.h>
+#include <PeripheralPins.h>
+
+/* =====
+ * Note: Commented lines are alternative possibilities which are not used per default.
+ *       If you change them, you will have to know what you do
+ * =====
+ */
+
+//*** ADC ***
+
+#ifdef HAL_ADC_MODULE_ENABLED
+const PinMap PinMap_ADC[] = {
+  {PA_0,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC1_IN0
+  //{PA_0,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC2_IN0
+  //{PA_0,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 0, 0)}, // ADC3_IN0
+  {PA_1,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC1_IN1
+  //{PA_1,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC2_IN1
+  //{PA_1,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // ADC3_IN1
+  //{PA_2,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC1_IN2
+  {PA_2,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC2_IN2
+  //{PA_2,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // ADC3_IN2
+  //{PA_3,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC1_IN3
+  //{PA_3,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC2_IN3
+  {PA_3,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 3, 0)}, // ADC3_IN3
+  {PA_4,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC1_IN4
+  //{PA_4,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC2_IN4
+  //{PA_5,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC1_IN5
+  {PA_5,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC2_IN5
+  {PA_6,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC1_IN6
+  //{PA_6,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC2_IN6
+  {PA_7,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC1_IN7
+  //{PA_7,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC2_IN7
+  //{PB_0,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC1_IN8
+  {PB_0,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC2_IN8
+  {PB_1,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC1_IN9
+  //{PB_1,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC2_IN9
+  //{PC_0,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC1_IN10
+  //{PC_0,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC2_IN10
+  {PC_0,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 10, 0)}, // ADC3_IN10
+  {PC_1,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC1_IN11
+  //{PC_1,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC2_IN11
+  //{PC_1,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 11, 0)}, // ADC3_IN11
+  //{PC_2,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC1_IN12
+  {PC_2,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC2_IN12
+  //{PC_2,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)}, // ADC3_IN12
+  //{PC_3,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC1_IN13
+  //{PC_3,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC2_IN13
+  {PC_3,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)}, // ADC3_IN13
+  //{PC_4,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC1_IN14
+  {PC_4,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC2_IN14
+  //{PC_5,  ADC1,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC1_IN15
+  {PC_5,  ADC2,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC2_IN15
+  {PF_3,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 9, 0)}, // ADC3_IN9
+  {PF_4,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)}, // ADC3_IN14
+  {PF_5,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 15, 0)}, // ADC3_IN15
+  {PF_6,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 4, 0)}, // ADC3_IN4
+  {PF_7,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 5, 0)}, // ADC3_IN5
+  {PF_8,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 6, 0)}, // ADC3_IN6
+  //{PF_9,  ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 7, 0)}, // ADC3_IN7
+  {PF_10, ADC3,  STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 8, 0)}, // ADC3_IN8
+  {NC,    NP,    0}
+};
+#endif
+
+//*** DAC ***
+
+#ifdef HAL_DAC_MODULE_ENABLED
+const PinMap PinMap_DAC[] = {
+  {PA_4,  DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC_OUT1
+  {PA_5,  DAC1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC_OUT2
+  {NC,    NP,    0}
+};
+#endif
+
+//*** I2C ***
+
+#ifdef HAL_I2C_MODULE_ENABLED
+const PinMap PinMap_I2C_SDA[] = {
+  {PB_7,  I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
+  {PB_9,  I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
+  {PB_11, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
+  {PC_9,  I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
+  {PF_0,  I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_I2C_MODULE_ENABLED
+const PinMap PinMap_I2C_SCL[] = {
+  {PA_8,  I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
+  {PB_6,  I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
+  {PB_8,  I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
+  {PB_10, I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
+  {PF_1,  I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
+  {NC,    NP,    0}
+};
+#endif
+
+//*** PWM ***
+
+#ifdef HAL_TIM_MODULE_ENABLED
+const PinMap PinMap_PWM[] = {
+  {PA_0,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
+  //{PA_0,  TIM5,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 1, 0)}, // TIM5_CH1
+  {PA_1,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
+  //{PA_1,  TIM5,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 2, 0)}, // TIM5_CH2
+  {PA_2,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
+  //{PA_2,  TIM5,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 3, 0)}, // TIM5_CH3
+  //{PA_2,  TIM9,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1
+  {PA_3,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
+  //{PA_3,  TIM5,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5, 4, 0)}, // TIM5_CH4
+  //{PA_3,  TIM9,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2
+  {PA_5,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
+  //{PA_5,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N
+  {PA_6,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
+  //{PA_6,  TIM13,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1
+  //{PA_7,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N
+  {PA_7,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
+  //{PA_7,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 1)}, // TIM8_CH1N
+  //{PA_7,  TIM14,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1
+  {PA_8,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1
+  {PA_9,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2
+  {PA_10, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3
+  {PA_11, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4
+  //{PA_15, TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 1, 0)}, // TIM2_CH1
+  //{PB_0,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N
+  {PB_0,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
+  //{PB_0,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N
+  //{PB_1,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N
+  {PB_1,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
+  //{PB_1,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N
+  //{PB_3,  TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 2, 0)}, // TIM2_CH2
+  {PB_4,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
+  {PB_5,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
+  {PB_6,  TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1
+  {PB_7,  TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2
+  {PB_8,  TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3
+  {PB_8,  TIM10,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1
+  {PB_9,  TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4
+  {PB_9,  TIM11,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1
+  {PB_10, TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
+  {PB_11, TIM2,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
+  {PB_13, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N
+  {PB_14, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N
+  {PB_14, TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 1)}, // TIM8_CH2N
+  {PB_14, TIM12,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 1, 0)}, // TIM12_CH1
+  {PB_15, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N
+  {PB_15, TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 1)}, // TIM8_CH3N
+  {PB_15, TIM12,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM12, 2, 0)}, // TIM12_CH2
+  {PC_6,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 1, 0)}, // TIM3_CH1
+  {PC_6,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 1, 0)}, // TIM8_CH1
+  {PC_7,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 2, 0)}, // TIM3_CH2
+  {PC_7,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 2, 0)}, // TIM8_CH2
+  {PC_8,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 3, 0)}, // TIM3_CH3
+  {PC_8,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 3, 0)}, // TIM8_CH3
+  {PC_9,  TIM3,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3, 4, 0)}, // TIM3_CH4
+  {PC_9,  TIM8,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM8, 4, 0)}, // TIM8_CH4
+  {PD_12, TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 1, 0)}, // TIM4_CH1
+  {PD_13, TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 2, 0)}, // TIM4_CH2
+  {PD_14, TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 3, 0)}, // TIM4_CH3
+  {PD_15, TIM4,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4
+  {PE_5,  TIM9,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 1, 0)}, // TIM9_CH1
+  {PE_6,  TIM9,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9, 2, 0)}, // TIM9_CH2
+  {PE_8,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 1)}, // TIM1_CH1N
+  {PE_9,  TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 1, 0)}, // TIM1_CH1
+  {PE_10, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 1)}, // TIM1_CH2N
+  {PE_11, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 2, 0)}, // TIM1_CH2
+  {PE_12, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 1)}, // TIM1_CH3N
+  {PE_13, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 3, 0)}, // TIM1_CH3
+  {PE_14, TIM1,   STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1, 4, 0)}, // TIM1_CH4
+  {PF_6,  TIM10,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10, 1, 0)}, // TIM10_CH1
+  {PF_7,  TIM11,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11, 1, 0)}, // TIM11_CH1
+  {PF_8,  TIM13,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM13, 1, 0)}, // TIM13_CH1
+  {PF_9,  TIM14,  STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_TIM14, 1, 0)}, // TIM14_CH1
+  {NC,    NP,    0}
+};
+#endif
+
+//*** SERIAL ***
+
+#ifdef HAL_UART_MODULE_ENABLED
+const PinMap PinMap_UART_TX[] = {
+  {PA_0,  UART4,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
+  {PA_2,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PA_9,  USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_6,  USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_10, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PC_6,  USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  //{PC_10, UART4,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
+  {PC_10, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PC_12, UART5,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
+  {PD_5,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PD_8,  USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PG_14, USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_UART_MODULE_ENABLED
+const PinMap PinMap_UART_RX[] = {
+  {PA_1,  UART4,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
+  {PA_3,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PA_10, USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_7,  USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_11, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PC_7,  USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  //{PC_11, UART4,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART4)},
+  {PC_11, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PD_2,  UART5,   STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_UART5)},
+  {PD_6,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PD_9,  USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PG_9,  USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_UART_MODULE_ENABLED
+const PinMap PinMap_UART_RTS[] = {
+  {PA_1,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PA_12, USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_14, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PD_4,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PD_12, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PG_8,  USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {PG_12, USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_UART_MODULE_ENABLED
+const PinMap PinMap_UART_CTS[] = {
+  {PA_0,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PA_11, USART1,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
+  {PB_13, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PD_3,  USART2,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
+  {PD_11, USART3,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
+  {PG_13, USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {PG_15, USART6,  STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
+  {NC,    NP,    0}
+};
+#endif
+
+//*** SPI ***
+
+#ifdef HAL_SPI_MODULE_ENABLED
+const PinMap PinMap_SPI_MOSI[] = {
+  {PA_7,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_5,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_5,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {PB_15, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PC_3,  SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PC_12, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_SPI_MODULE_ENABLED
+const PinMap PinMap_SPI_MISO[] = {
+  {PA_6,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_4,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_4,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {PB_14, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PC_2,  SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PC_11, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_SPI_MODULE_ENABLED
+const PinMap PinMap_SPI_SCLK[] = {
+  {PA_5,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_3,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PB_3,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {PB_10, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PB_13, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PC_10, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_SPI_MODULE_ENABLED
+const PinMap PinMap_SPI_SSEL[] = {
+  {PA_4,  SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PA_4,  SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {PA_15, SPI1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
+  {PA_15, SPI3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
+  {PB_9,  SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {PB_12, SPI2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
+  {NC,    NP,    0}
+};
+#endif
+
+//*** CAN ***
+
+#ifdef HAL_CAN_MODULE_ENABLED
+const PinMap PinMap_CAN_RD[] = {
+  {PA_11, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {PB_5,  CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
+  {PB_8,  CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {PB_12, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
+  {PD_0,  CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_CAN_MODULE_ENABLED
+const PinMap PinMap_CAN_TD[] = {
+  {PA_12, CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {PB_6,  CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
+  {PB_9,  CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {PB_13, CAN2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN2)},
+  {PD_1,  CAN1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN1)},
+  {NC,    NP,    0}
+};
+#endif
+
+//*** ETHERNET ***
+
+#ifdef HAL_ETH_MODULE_ENABLED
+const PinMap PinMap_Ethernet[] = {
+  {PA_0,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_CRS
+  {PA_1,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_REF_CLK|ETH_RX_CLK
+  {PA_2,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_MDIO
+  {PA_3,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_COL
+  {PA_7,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_CRS_DV|ETH_RX_DV
+  {PB_0,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD2
+  {PB_1,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD3
+  {PB_5,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT
+  {PB_8,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD3
+  {PB_10, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RX_ER
+  {PB_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN
+  {PB_12, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0
+  {PB_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1
+  {PC_1,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_MDC
+  {PC_2,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD2
+  {PC_3,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_CLK
+  {PC_4,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD0
+  {PC_5,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_RXD1
+  {PE_2,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD3
+  {PG_8,  ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_PPS_OUT
+  {PG_11, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TX_EN
+  {PG_13, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD0
+  {PG_14, ETH, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF11_ETH)}, // ETH_TXD1
+  {NC,    NP,    0}
+};
+#endif
+
+//*** No QUADSPI ***
+
+//*** USB ***
+
+#ifdef HAL_PCD_MODULE_ENABLED
+const PinMap PinMap_USB_OTG_FS[] = {
+  //{PA_8,  USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_SOF
+  //{PA_9,  USB_OTG_FS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_FS_VBUS
+  //{PA_10, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_ID
+  {PA_11, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DM
+  {PA_12, USB_OTG_FS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_FS)}, // USB_OTG_FS_DP
+  {NC,    NP,    0}
+};
+#endif
+
+#ifdef HAL_PCD_MODULE_ENABLED
+const PinMap PinMap_USB_OTG_HS[] = {
+#ifdef USE_USB_HS_IN_FS
+  {PA_4,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_SOF
+  {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_ID
+  {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF_NONE)}, // USB_OTG_HS_VBUS
+  {PB_14, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DM
+  {PB_15, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_OTG_HS_FS)}, // USB_OTG_HS_DP
+#else
+  {PA_3,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D0
+  {PA_5,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_CK
+  {PB_0,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D1
+  {PB_1,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D2
+  {PB_5,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D7
+  {PB_10, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D3
+  {PB_11, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D4
+  {PB_12, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D5
+  {PB_13, USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_D6
+  {PC_0,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_STP
+  {PC_2,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_DIR
+  {PC_3,  USB_OTG_HS, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_OTG_HS)}, // USB_OTG_HS_ULPI_NXT
+#endif /* USE_USB_HS_IN_FS */
+  {NC,    NP,    0}
+};
+#endif
diff --git a/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h b/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h
new file mode 100644
index 0000000000000000000000000000000000000000..b4bb9d45f8ac59c4f03f13aac69fa97e9116a4b2
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/LERDGE/PinNamesVar.h
@@ -0,0 +1,50 @@
+/* SYS_WKUP */
+#ifdef PWR_WAKEUP_PIN1
+  SYS_WKUP1 = PA_0,
+#endif
+#ifdef PWR_WAKEUP_PIN2
+  SYS_WKUP2 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN3
+  SYS_WKUP3 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN4
+  SYS_WKUP4 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN5
+  SYS_WKUP5 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN6
+  SYS_WKUP6 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN7
+  SYS_WKUP7 = NC,
+#endif
+#ifdef PWR_WAKEUP_PIN8
+  SYS_WKUP8 = NC,
+#endif
+/* USB */
+#ifdef USBCON
+  USB_OTG_FS_SOF      = PA_8,
+  USB_OTG_FS_VBUS     = PA_9,
+  USB_OTG_FS_ID       = PA_10,
+  USB_OTG_FS_DM       = PA_11,
+  USB_OTG_FS_DP       = PA_12,
+  USB_OTG_HS_ULPI_D0  = PA_3,
+  USB_OTG_HS_SOF      = PA_4,
+  USB_OTG_HS_ULPI_CK  = PA_5,
+  USB_OTG_HS_ULPI_D1  = PB_0,
+  USB_OTG_HS_ULPI_D2  = PB_1,
+  USB_OTG_HS_ULPI_D7  = PB_5,
+  USB_OTG_HS_ULPI_D3  = PB_10,
+  USB_OTG_HS_ULPI_D4  = PB_11,
+  USB_OTG_HS_ID       = PB_12,
+  USB_OTG_HS_ULPI_D5  = PB_12,
+  USB_OTG_HS_ULPI_D6  = PB_13,
+  USB_OTG_HS_VBUS     = PB_13,
+  USB_OTG_HS_DM       = PB_14,
+  USB_OTG_HS_DP       = PB_15,
+  USB_OTG_HS_ULPI_STP = PC_0,
+  USB_OTG_HS_ULPI_DIR = PC_2,
+  USB_OTG_HS_ULPI_NXT = PC_3,
+#endif
diff --git a/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp b/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ebc1922eb856fe0f93b30252f470c16fdc35f707
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/LERDGE/variant.cpp
@@ -0,0 +1,297 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2017, STMicroelectronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ */
+
+#include "pins_arduino.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+const PinName digitalPin[] = {
+ PB_12,
+ PB_13,
+ PB_14,
+ PB_15,
+ PD_8,
+ PD_9,
+ PD_10,
+ PD_11,
+ PD_12,
+ PD_13,
+ PD_14,
+ PD_15,
+ PG_2,
+ PG_3,
+ PG_4,
+ PG_5,
+ PG_6,
+ PG_7,
+ PG_8,
+ PC_6,
+ PC_7,
+ PC_8,
+ PC_9,
+ PA_8,
+ PA_9,
+ PA_10,
+ PA_11,
+ PA_12,
+ PA_13,
+ PA_14,
+ PA_15,
+ PC_10,
+ PC_11,
+ PC_12,
+ PD_0,
+ PD_1,
+ PD_2,
+ PD_3,
+ PD_4,
+ PD_5,
+ PD_6,
+ PD_7,
+ PG_9,
+ PG_10,
+ PG_11,
+ PG_12,
+ PG_13,
+ PG_14,
+ PG_15,
+ PB_3,
+ PB_4,
+ PB_5,
+ PB_6,
+ PB_7,
+ PB_8,
+ PB_9,
+ PB_10,
+ PB_11,
+ PE_14,
+ PE_15,
+ PE_12,
+ PE_13,
+ PE_10,
+ PE_11,
+ PE_8,
+ PE_9,
+ PG_1,
+ PE_7,
+ PF_15,
+ PG_0,
+ PF_13,
+ PF_14,
+ PF_11,
+ PF_12,
+ PB_2,
+ PB_1,
+ PC_5,
+ PB_0,
+ PA_7,
+ PC_4,
+ PA_5,
+ PA_6,
+ PA_3,
+ PA_4,
+ PA_1,
+ PA_2,
+ PC_3,
+ PA_0,
+ PC_1,
+ PC_2,
+ PC_0,
+ PF_8,
+ PF_6,
+ PF_7,
+ PF_9,
+ PF_10,
+ PF_4,
+ PF_5,
+ PF_2,
+ PF_3,
+ PF_0,
+ PF_1,
+ PE_6,
+ PC_13,
+ PE_4,
+ PE_5,
+ PE_2,
+ PE_3,
+ PE_0,
+ PE_1,
+ PC_14,
+ PC_15,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __fatal_error(X)
+
+
+/**
+  * @brief  System Clock Configuration
+  *
+  *         The system Clock is configured for F4/F7 as follows:
+  *            System Clock source            = PLL (HSE)
+  *            SYSCLK(Hz)                     = 168000000
+  *            HCLK(Hz)                       = 168000000
+  *            AHB Prescaler                  = 1
+  *            APB1 Prescaler                 = 4
+  *            APB2 Prescaler                 = 2
+  *            HSE Frequency(Hz)              = HSE_VALUE
+  *            PLL_M                          = HSE_VALUE/1000000
+  *            PLL_N                          = 336
+  *            PLL_P                          = 2
+  *            PLL_Q                          = 7
+  *            VDD(V)                         = 3.3
+  *            Main regulator output voltage  = Scale1 mode
+  *            Flash Latency(WS)              = 5
+  *
+  *         The system Clock is configured for L4 as follows:
+  *            System Clock source            = PLL (MSI)
+  *            SYSCLK(Hz)                     = 80000000
+  *            HCLK(Hz)                       = 80000000
+  *            AHB Prescaler                  = 1
+  *            APB1 Prescaler                 = 1
+  *            APB2 Prescaler                 = 1
+  *            MSI Frequency(Hz)              = MSI_VALUE (4000000)
+  *            LSE Frequency(Hz)              = 32768
+  *            PLL_M                          = 1
+  *            PLL_N                          = 40
+  *            PLL_P                          = 7
+  *            PLL_Q                          = 2
+  *            PLL_R                          = 2 <= This is the source for SysClk, not as on F4/7 PLL_P
+  *            Flash Latency(WS)              = 4
+  * @param  None
+  * @retval None
+  *
+  * PLL is configured as follows:
+  *
+  *     VCO_IN
+  *         F4/F7 = HSE / M
+  *         L4    = MSI / M
+  *     VCO_OUT
+  *         F4/F7 = HSE / M * N
+  *         L4    = MSI / M * N
+  *     PLLCLK
+  *         F4/F7 = HSE / M * N / P
+  *         L4    = MSI / M * N / R
+  *     PLL48CK
+  *         F4/F7 = HSE / M * N / Q
+  *         L4    = MSI / M * N / Q  USB Clock is obtained over PLLSAI1
+  *
+  *     SYSCLK = PLLCLK
+  *     HCLK   = SYSCLK / AHB_PRESC
+  *     PCLKx  = HCLK / APBx_PRESC
+  *
+  * Constraints on parameters:
+  *
+  *     VCO_IN between 1MHz and 2MHz (2MHz recommended)
+  *     VCO_OUT between 192MHz and 432MHz
+  *     HSE = 8MHz
+  *     M = 2 .. 63 (inclusive)
+  *     N = 192 ... 432 (inclusive)
+  *     P = 2, 4, 6, 8
+  *     Q = 2 .. 15 (inclusive)
+  *
+  *     AHB_PRESC=1,2,4,8,16,64,128,256,512
+  *     APBx_PRESC=1,2,4,8,16
+  *
+  * Output clocks:
+  *
+  * CPU             SYSCLK      max 168MHz
+  * USB,RNG,SDIO    PLL48CK     must be 48MHz for USB
+  * AHB             HCLK        max 168MHz
+  * APB1            PCLK1       max 42MHz
+  * APB2            PCLK2       max 84MHz
+  *
+  * Timers run from APBx if APBx_PRESC=1, else 2x APBx
+  */
+void SystemClock_Config(void)
+{
+    RCC_ClkInitTypeDef RCC_ClkInitStruct;
+    RCC_OscInitTypeDef RCC_OscInitStruct;
+
+    __PWR_CLK_ENABLE();
+
+    /* The voltage scaling allows optimizing the power consumption when the device is
+       clocked below the maximum system frequency, to update the voltage scaling value
+       regarding system frequency refer to product datasheet.  */
+    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+    /* Enable HSE Oscillator and activate PLL with HSE as source */
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+    RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
+     clocks dividers */
+    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+
+    RCC_OscInitStruct.PLL.PLLM = 25;
+    RCC_OscInitStruct.PLL.PLLN = 336;
+    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+    RCC_OscInitStruct.PLL.PLLQ = 7;
+
+    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
+    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
+
+    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
+      __fatal_error("HAL_RCC_OscConfig");
+    }
+
+    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
+    {
+      __fatal_error("HAL_RCC_ClockConfig");
+    }
+
+    /**Configure the Systick interrupt time */
+    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
+
+    /**Configure the Systick */
+    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+
+    /* SysTick_IRQn interrupt configuration */
+    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/buildroot/share/PlatformIO/variants/LERDGE/variant.h b/buildroot/share/PlatformIO/variants/LERDGE/variant.h
new file mode 100644
index 0000000000000000000000000000000000000000..87033a68e5f6d35accfa1f2f106d863f53d5fdaf
--- /dev/null
+++ b/buildroot/share/PlatformIO/variants/LERDGE/variant.h
@@ -0,0 +1,238 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2017, STMicroelectronics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *******************************************************************************
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+/*----------------------------------------------------------------------------
+ *        Pins
+ *----------------------------------------------------------------------------*/
+
+// Left Side
+#define PB12 0
+#define PB13 1
+#define PB14 2
+#define PB15 3
+#define PD8  4
+#define PD9  5
+#define PD10 6
+#define PD11 7
+#define PD12 8
+#define PD13 9
+#define PD14 10
+#define PD15 11
+#define PG2  12
+#define PG3  13
+#define PG4  14
+#define PG5  15
+#define PG6  16
+#define PG7  17
+#define PG8  18
+#define PC6  19
+#define PC7  20
+#define PC8  21
+#define PC9  22
+#define PA8  23
+#define PA9  24
+#define PA10 25
+#define PA11 26 // USB_DM
+#define PA12 27 // USB_DP
+#define PA13 28
+#define PA14 29
+#define PA15 30
+#define PC10 31
+#define PC11 32
+#define PC12 33
+#define PD0  34
+#define PD1  35
+#define PD2  36
+#define PD3  37
+#define PD4  38
+#define PD5  39
+#define PD6  40
+#define PD7  41
+#define PG9  42
+#define PG10 43
+#define PG11 44
+#define PG12 45
+#define PG13 46
+#define PG14 47
+#define PG15 48
+#define PB3  49
+#define PB4  50
+#define PB5  51
+#define PB6  52
+#define PB7  53
+#define PB8  54
+#define PB9  55
+
+// Right Side
+#define PB10 56
+#define PB11 57
+#define PE14 58
+#define PE15 59
+#define PE12 60
+#define PE13 61
+#define PE10 62
+#define PE11 63
+#define PE8  64
+#define PE9  65
+#define PG1  66
+#define PE7  67
+#define PF15 68
+#define PG0  69
+#define PF13 70
+#define PF14 71
+#define PF11 72
+#define PF12 73
+#define PB2  74
+#define PB1  75 // A0
+#define PC5  76 // A1
+#define PB0  77 // A2
+#define PA7  78 // A3
+#define PC4  79 // A4
+#define PA5  80 // A5
+#define PA6  81 // A6
+#define PA3  82 // A7
+#define PA4  83 // A8
+#define PA1  84 // A9
+#define PA2  85 // A10
+#define PC3  86 // A11
+#define PA0  87 // A12/PA_0(WK_UP): BUT K_UP)
+#define PC1  88 // A13
+#define PC2  89 // A14
+#define PC0  90 // A15
+#define PF8  91 // A16
+#define PF6  92 // A17
+#define PF7  93 // A18
+#define PF9  94 // LED D1 (active low)
+#define PF10 95 // LED D2 (active low)
+#define PF4  96
+#define PF5  97
+#define PF2  98
+#define PF3  99
+#define PF0  100
+#define PF1  101
+#define PE6  102
+#define PC13 103
+#define PE4  104 // BUT K0
+#define PE5  105 // BUT K1
+#define PE2  106
+#define PE3  107
+#define PE0  108
+#define PE1  109
+#define PC14  110
+#define PC15  111
+// This must be a literal
+#define NUM_DIGITAL_PINS        112
+// This must be a literal with a value less than or equal to MAX_ANALOG_INPUTS
+#define NUM_ANALOG_INPUTS       23
+#define NUM_ANALOG_FIRST        75
+
+
+// Below SPI and I2C definitions already done in the core
+// Could be redefined here if differs from the default one
+// SPI Definitions
+#define PIN_SPI_SS              PF11
+#define PIN_SPI_MOSI            PB15
+#define PIN_SPI_MISO            PB14
+#define PIN_SPI_SCK             PB13
+
+
+
+//max6675
+//#define PIN_SPI_SS              PA4
+//#define PIN_SPI_SCK             PA5
+//#define PIN_SPI_MISO            PA6
+//#define PIN_SPI_MOSI            PA7
+
+
+
+
+// I2C Definitions
+#define PIN_WIRE_SDA            PB7
+#define PIN_WIRE_SCL            PB6
+
+// Timer Definitions
+//Do not use timer used by PWM pins when possible. See PinMap_PWM in PeripheralPins.c
+#define TIMER_TONE              TIM6
+
+// Do not use basic timer: OC is required
+#define TIMER_SERVO             TIM1  //TODO: advanced-control timers don't work
+
+// UART Definitions
+// Define here Serial instance number to map on Serial generic name
+#define SERIAL_UART_INSTANCE    1 //ex: 2 for Serial2 (USART2)
+// DEBUG_UART could be redefined to print on another instance than 'Serial'
+//#define DEBUG_UART              ((USART_TypeDef *) U(S)ARTX) // ex: USART3
+// DEBUG_UART baudrate, default: 9600 if not defined
+//#define DEBUG_UART_BAUDRATE     x
+// DEBUG_UART Tx pin name, default: the first one found in PinMap_UART_TX for DEBUG_UART
+//#define DEBUG_PINNAME_TX        PX_n // PinName used for TX
+
+// Default pin used for 'Serial' instance (ex: ST-Link)
+// Mandatory for Firmata
+#define PIN_SERIAL_RX           PA10
+#define PIN_SERIAL_TX           PA9
+
+/* Extra HAL modules */
+//#define HAL_DAC_MODULE_ENABLED
+#define HAL_SD_MODULE_ENABLED
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+/*----------------------------------------------------------------------------
+ *        Arduino objects - C++ only
+ *----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+// These serial port names are intended to allow libraries and architecture-neutral
+// sketches to automatically default to the correct port name for a particular type
+// of use.  For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
+// the first hardware serial port whose RX/TX pins are not dedicated to another use.
+//
+// SERIAL_PORT_MONITOR        Port which normally prints to the Arduino Serial Monitor
+//
+// SERIAL_PORT_USBVIRTUAL     Port which is USB virtual serial
+//
+// SERIAL_PORT_LINUXBRIDGE    Port which connects to a Linux system via Bridge library
+//
+// SERIAL_PORT_HARDWARE       Hardware serial port, physical RX & TX pins.
+//
+// SERIAL_PORT_HARDWARE_OPEN  Hardware serial ports which are open for use.  Their RX & TX
+//                            pins are NOT connected to anything by default.
+#define SERIAL_PORT_MONITOR     Serial
+#define SERIAL_PORT_HARDWARE    Serial1
+#endif
+
diff --git a/buildroot/tests/LERDGEX-tests b/buildroot/tests/LERDGEX-tests
new file mode 100644
index 0000000000000000000000000000000000000000..c2d72e0d77e6361baec6272a2ca2028093f468f1
--- /dev/null
+++ b/buildroot/tests/LERDGEX-tests
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+#
+# Build tests for LERDGEX environment
+#
+
+# exit on first failure
+set -e
+
+#
+# Build with the default configurations
+#
+restore_configs
+opt_set MOTHERBOARD BOARD_LERDGE_X
+opt_set SERIAL_PORT 1
+exec_test $1 $2 "LERDGE X with Default Configuration"
+
+# clean up
+restore_configs
diff --git a/platformio.ini b/platformio.ini
index 2c0df405a2fc664221fd64aebf37618f119902dc..a493db923735d36ea4646ad851e00240e8ca8f3b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -821,6 +821,46 @@ build_flags       = ${common_stm32.build_flags}
 extra_scripts     = pre:buildroot/share/PlatformIO/scripts/generic_create_variant.py
 lib_ignore        = Adafruit NeoPixel, SailfishLCD, SlowSoftI2CMaster, SoftwareSerial
 
+#
+# Lerdge base
+#
+[lerdge_common]
+platform           = ${common_stm32.platform}
+extends            = common_stm32
+board              = LERDGE
+board_build.offset = 0x10000
+extra_scripts      = pre:buildroot/share/PlatformIO/scripts/copy_marlin_variant_to_framework.py
+                     buildroot/share/PlatformIO/scripts/stm32_bootloader.py
+                     buildroot/share/PlatformIO/scripts/lerdge.py
+build_flags        = ${common_stm32.build_flags}
+  -DSTM32F4 -DSTM32F4xx -DTARGET_STM32F4
+  -DDISABLE_GENERIC_SERIALUSB -DARDUINO_ARCH_STM32 -DARDUINO_LERDGE
+  -DTRANSFER_CLOCK_DIV=8
+build_unflags      = ${common_stm32.build_unflags} -DUSBCON -DUSBD_USE_CDC -DUSBD_VID=0x0483
+
+#
+# Lerdge X
+#
+[env:LERDGEX]
+extends              = lerdge_common
+board_build.firmware = Lerdge_X_firmware_force.bin
+
+#
+# Lerdge S
+#
+[env:LERDGES]
+extends              = lerdge_common
+board_build.firmware = Lerdge_firmware_force.bin
+
+#
+# Lerdge K
+#
+[env:LERDGEK]
+extends              = lerdge_common
+board_build.firmware = Lerdge_K_firmware_force.bin
+build_flags          = ${lerdge_common.build_flags}
+  -DLERDGEK
+
 #
 # RUMBA32
 #