From 1946f729fdb4f18cf6b249b988363c693589150e Mon Sep 17 00:00:00 2001
From: Karl Andersson <karl@iaccess.se>
Date: Wed, 31 Oct 2018 01:25:44 +0100
Subject: [PATCH] STM32 FastIO using register access (#12276)

---
 Marlin/src/HAL/HAL_STM32/HAL.cpp              |  6 +++
 Marlin/src/HAL/HAL_STM32/fastio_STM32.cpp     | 34 ++++++++++++++++
 Marlin/src/HAL/HAL_STM32/fastio_STM32.h       | 40 ++++++++++++++++---
 .../dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp   |  6 +--
 4 files changed, 77 insertions(+), 9 deletions(-)
 create mode 100644 Marlin/src/HAL/HAL_STM32/fastio_STM32.cpp

diff --git a/Marlin/src/HAL/HAL_STM32/HAL.cpp b/Marlin/src/HAL/HAL_STM32/HAL.cpp
index 09c598e238..d3559420aa 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 0000000000..e1824ed181
--- /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 d348e739a8..156756b1ba 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 76c488fa5a..6f8fea6e74 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)
-- 
GitLab