diff --git a/Marlin/src/HAL/HAL_STM32/HAL.cpp b/Marlin/src/HAL/HAL_STM32/HAL.cpp
index 09c598e238fcb7ee3b823f96d2775a96f7649247..d3559420aa9c6ccf50b1165c81e9f34f37989601 100644
--- a/Marlin/src/HAL/HAL_STM32/HAL.cpp
+++ b/Marlin/src/HAL/HAL_STM32/HAL.cpp
@@ -80,10 +80,16 @@ uint16_t HAL_adc_result;
 // HAL initialization task
 void HAL_init(void) {
 
+  FastIO_init();
+
   #if ENABLED(SDSUPPORT)
     OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
   #endif
 
+  #if PIN_EXISTS(LED)
+    OUT_WRITE(LED_PIN, LOW);
+  #endif
+
   #if ENABLED(EEPROM_EMULATED_WITH_SRAM)
   // Enable access to backup SRAM
   __HAL_RCC_PWR_CLK_ENABLE();
diff --git a/Marlin/src/HAL/HAL_STM32/fastio_STM32.cpp b/Marlin/src/HAL/HAL_STM32/fastio_STM32.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1824ed181bb283ec27c9b3e838fc3e209324d76
--- /dev/null
+++ b/Marlin/src/HAL/HAL_STM32/fastio_STM32.cpp
@@ -0,0 +1,34 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ * Copyright (C) 2017 Victor Perez
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifdef ARDUINO_ARCH_STM32
+
+#include "../../inc/MarlinConfig.h"
+
+GPIO_TypeDef* FastIOPortMap[LastPort + 1];
+
+void FastIO_init() {
+  for (uint8_t i = 0; i < NUM_DIGITAL_PINS; i++)
+    FastIOPortMap[STM_PORT(digitalPin[i])] = get_GPIO_Port(STM_PORT(digitalPin[i]));
+}
+
+#endif
diff --git a/Marlin/src/HAL/HAL_STM32/fastio_STM32.h b/Marlin/src/HAL/HAL_STM32/fastio_STM32.h
index d348e739a8f33f624c922614d3509f4263de1dc1..156756b1ba7b4414e49e18b53491e034cb650ad8 100644
--- a/Marlin/src/HAL/HAL_STM32/fastio_STM32.h
+++ b/Marlin/src/HAL/HAL_STM32/fastio_STM32.h
@@ -24,19 +24,49 @@
 
 /**
  * Fast I/O interfaces for STM32
- * These use GPIO functions instead of Direct Port Manipulation, as on AVR.
+ * These use GPIO register access for fast port manipulation.
  */
 
+// --------------------------------------------------------------------------
+// Public Variables
+// --------------------------------------------------------------------------
+
+extern GPIO_TypeDef * FastIOPortMap[];
+
+// --------------------------------------------------------------------------
+// Public functions
+// --------------------------------------------------------------------------
+
+void FastIO_init(); // Must be called before using fast io macros
+
+// --------------------------------------------------------------------------
+// Defines
+// --------------------------------------------------------------------------
+
 #define _BV(b) (1 << (b))
+#define _BV32(b) (1UL << (b))
+
+#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx)
+  #define _WRITE(IO, V) do { \
+    if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \
+    else   FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR  = _BV32(STM_PIN(digitalPin[IO])) ; \
+  } while(0)
+#else
+  #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO] + (V ? 0 : 16))))
+#endif
 
-#define READ(IO)                digitalRead(IO)
-#define WRITE(IO,V)             digitalWrite(IO,V)
-#define WRITE_VAR(IO,V)         WRITE(IO,V)
+#define _READ(IO)               bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPin[IO])]->IDR, _BV32(STM_PIN(digitalPin[IO]))))
+#define _TOGGLE(IO)             (FastIOPortMap[STM_PORT(digitalPin[IO])]->ODR ^= _BV32(STM_PIN(digitalPin[IO])))
 
 #define _GET_MODE(IO)
 #define _SET_MODE(IO,M)         pinMode(IO, M)
 #define _SET_OUTPUT(IO)         pinMode(IO, OUTPUT)                               /*!< Output Push Pull Mode & GPIO_NOPULL   */
 
+#define WRITE_VAR(IO,V)         _WRITE(IO,V)
+#define WRITE(IO,V)             _WRITE(IO,V)
+#define READ(IO)                _READ(IO)
+#define TOGGLE(IO)              _TOGGLE(IO)
+
 #define OUT_WRITE(IO,V)         do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
 
 #define SET_INPUT(IO)           _SET_MODE(IO, INPUT)                              /*!< Input Floating Mode                   */
@@ -44,8 +74,6 @@
 #define SET_INPUT_PULLDOWN(IO)  _SET_MODE(IO, INPUT_PULLDOWN)                     /*!< Input with Pull-down activation       */
 #define SET_OUTPUT(IO)          OUT_WRITE(IO, LOW)
 
-#define TOGGLE(IO)              OUT_WRITE(IO, !READ(IO))
-
 #define GET_INPUT(IO)
 #define GET_OUTPUT(IO)
 #define GET_TIMER(IO)
diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
index 76c488fa5ad54223ada2f639834b8e2b7695b337..6f8fea6e741c3a676ec16d69958d43d345481f9c 100644
--- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
+++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp
@@ -73,9 +73,9 @@
   #define CPU_ST7920_DELAY_2 DELAY_NS(0)
   #define CPU_ST7920_DELAY_3 DELAY_NS(189)
 #elif defined(ARDUINO_ARCH_STM32)
-  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
-  #define CPU_ST7920_DELAY_2 DELAY_NS(0)
-  #define CPU_ST7920_DELAY_3 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_1 DELAY_NS(300)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(40)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(340)
 #elif F_CPU == 16000000
   #define CPU_ST7920_DELAY_1 DELAY_NS(0)
   #define CPU_ST7920_DELAY_2 DELAY_NS(0)