diff --git a/.gitignore b/.gitignore
index ac2c9b5591..bc603ba38b 100755
--- a/.gitignore
+++ b/.gitignore
@@ -143,7 +143,11 @@ vc-fileutils.settings
.vscode/launch.json
.vscode/*.db
-# cmake
+#Simulation
+imgui.ini
+eeprom.dat
+
+#cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
diff --git a/Marlin/src/HAL/NATIVE_SIM/HAL.h b/Marlin/src/HAL/NATIVE_SIM/HAL.h
new file mode 100644
index 0000000000..d5c5782c36
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/HAL.h
@@ -0,0 +1,217 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
+ * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#define CPU_32_BIT
+#define HAL_IDLETASK
+void HAL_idletask();
+
+#define F_CPU 100000000
+#define SystemCoreClock F_CPU
+#include
+#include
+
+#undef min
+#undef max
+
+#include
+#include "pinmapping.h"
+
+void _printf (const char *format, ...);
+void _putc(uint8_t c);
+uint8_t _getc();
+
+//extern "C" volatile uint32_t _millis;
+
+//arduino: Print.h
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#define BIN 2
+//arduino: binary.h (weird defines)
+#define B01 1
+#define B10 2
+
+#include "../shared/Marduino.h"
+#include "../shared/math_32bit.h"
+#include "../shared/HAL_SPI.h"
+#include "fastio.h"
+#include "watchdog.h"
+#include "serial.h"
+
+#define SHARED_SERVOS HAS_SERVOS
+
+extern MSerialT serial_stream_0;
+extern MSerialT serial_stream_1;
+extern MSerialT serial_stream_2;
+extern MSerialT serial_stream_3;
+
+#define _MSERIAL(X) serial_stream_##X
+#define MSERIAL(X) _MSERIAL(X)
+
+#if WITHIN(SERIAL_PORT, 0, 3)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
+#else
+ #error "SERIAL_PORT must be from 0 to 3. Please update your configuration."
+#endif
+
+#ifdef SERIAL_PORT_2
+ #if WITHIN(SERIAL_PORT_2, 0, 3)
+ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
+ #else
+ #error "SERIAL_PORT_2 must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+#ifdef MMU2_SERIAL_PORT
+ #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+#ifdef LCD_SERIAL_PORT
+ #if WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
+ #else
+ #error "LCD_SERIAL_PORT must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+
+#define ST7920_DELAY_1 DELAY_NS(600)
+#define ST7920_DELAY_2 DELAY_NS(750)
+#define ST7920_DELAY_3 DELAY_NS(750)
+
+//
+// Interrupts
+//
+#define CRITICAL_SECTION_START()
+#define CRITICAL_SECTION_END()
+#define ISRS_ENABLED()
+#define ENABLE_ISRS()
+#define DISABLE_ISRS()
+
+inline void HAL_init() {}
+
+// Utility functions
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+int freeMemory();
+#pragma GCC diagnostic pop
+
+// ADC
+#define HAL_ADC_VREF 5.0
+#define HAL_ADC_RESOLUTION 10
+#define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch)
+#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
+#define HAL_READ_ADC() HAL_adc_get_result()
+#define HAL_ADC_READY() true
+
+void HAL_adc_init();
+void HAL_adc_enable_channel(const uint8_t ch);
+void HAL_adc_start_conversion(const uint8_t ch);
+uint16_t HAL_adc_get_result();
+
+// Reset source
+inline void HAL_clear_reset_source(void) {}
+inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
+
+/* ---------------- Delay in cycles */
+
+#define DELAY_CYCLES(x) Kernel::delayCycles(x)
+#define SYSTEM_YIELD() Kernel::yield()
+
+// Maple Compatibility
+typedef void (*systickCallback_t)(void);
+void systick_attach_callback(systickCallback_t cb);
+extern volatile uint32_t systick_uptime_millis;
+
+// Marlin uses strstr in constexpr context, this is not supported, workaround by defining constexpr versions of the required functions.
+#define strstr(a, b) strstr_constexpr((a), (b))
+
+constexpr inline std::size_t strlen_constexpr(const char* str) {
+ // https://github.com/gcc-mirror/gcc/blob/5c7634a0e5f202935aa6c11b6ea953b8bf80a00a/libstdc%2B%2B-v3/include/bits/char_traits.h#L329
+ if (str != nullptr) {
+ std::size_t i = 0;
+ while (str[i] != '\0') {
+ ++i;
+ }
+
+ return i;
+ }
+
+ return 0;
+}
+
+constexpr inline int strncmp_constexpr(const char* lhs, const char* rhs, std::size_t count) {
+ // https://github.com/gcc-mirror/gcc/blob/13b9cbfc32fe3ac4c81c4dd9c42d141c8fb95db4/libstdc%2B%2B-v3/include/bits/char_traits.h#L655
+ if (lhs == nullptr || rhs == nullptr) {
+ return rhs != nullptr ? -1 : 1;
+ }
+
+ for (std::size_t i = 0; i < count; ++i) {
+ if (lhs[i] != rhs[i]) {
+ return lhs[i] < rhs[i] ? -1 : 1;
+ } else if (lhs[i] == '\0') {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+constexpr inline const char* strstr_constexpr(const char* str, const char* target) {
+ // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c
+ if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) {
+ std::size_t len = strlen_constexpr(target);
+ do {
+ char sc = {};
+ do {
+ if ((sc = *str++) == '\0') {
+ return nullptr;
+ }
+ } while (sc != c);
+ } while (strncmp_constexpr(str, target, len) != 0);
+ --str;
+ }
+
+ return str;
+}
+
+constexpr inline char* strstr_constexpr(char* str, const char* target) {
+ // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c
+ if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) {
+ std::size_t len = strlen_constexpr(target);
+ do {
+ char sc = {};
+ do {
+ if ((sc = *str++) == '\0') {
+ return nullptr;
+ }
+ } while (sc != c);
+ } while (strncmp_constexpr(str, target, len) != 0);
+ --str;
+ }
+ return str;
+}
diff --git a/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h b/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h
new file mode 100644
index 0000000000..b5cc6f02a4
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
+ * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/NATIVE_SIM/fastio.h b/Marlin/src/HAL/NATIVE_SIM/fastio.h
new file mode 100644
index 0000000000..de8013b1e5
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/fastio.h
@@ -0,0 +1,111 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * Fast I/O Routines for X86_64
+ */
+
+#include "../shared/Marduino.h"
+#include
+
+#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1)
+#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0)
+
+#define SET_MODE(IO, mode) Gpio::setMode(IO, mode)
+
+#define WRITE_PIN_SET(IO) Gpio::set(IO)
+#define WRITE_PIN_CLR(IO) Gpio::clear(IO)
+
+#define READ_PIN(IO) Gpio::get(IO)
+#define WRITE_PIN(IO,V) Gpio::set(IO, V)
+
+/**
+ * Magic I/O routines
+ *
+ * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
+ *
+ * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
+ */
+
+/// Read a pin
+#define _READ(IO) READ_PIN(IO)
+
+/// Write to a pin
+#define _WRITE(IO,V) WRITE_PIN(IO,V)
+
+/// toggle a pin
+#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
+
+/// set pin as input
+#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
+
+/// set pin as output
+#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
+
+/// set pin as input with pullup mode
+#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
+
+/// set pin as input with pulldown mode
+#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
+
+// hg42: all pins can be input or output (I hope)
+// hg42: undefined pins create compile error (IO, is no pin)
+// hg42: currently not used, but was used by pinsDebug
+
+/// check if pin is an input
+#define _IS_INPUT(IO) (IO >= 0)
+
+/// check if pin is an output
+#define _IS_OUTPUT(IO) (IO >= 0)
+
+/// Read a pin wrapper
+#define READ(IO) _READ(IO)
+
+/// Write to a pin wrapper
+#define WRITE(IO,V) _WRITE(IO,V)
+
+/// toggle a pin wrapper
+#define TOGGLE(IO) _TOGGLE(IO)
+
+/// set pin as input wrapper
+#define SET_INPUT(IO) _SET_INPUT(IO)
+/// set pin as input with pullup wrapper
+#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
+/// set pin as input with pulldown wrapper
+#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
+/// set pin as output wrapper - reads the pin and sets the output to that value
+#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
+// set pin as PWM
+#define SET_PWM(IO) SET_OUTPUT(IO)
+
+/// check if pin is an input wrapper
+#define IS_INPUT(IO) _IS_INPUT(IO)
+/// check if pin is an output wrapper
+#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
+
+// Shorthand
+#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
+
+// digitalRead/Write wrappers
+#define extDigitalRead(IO) digitalRead(IO)
+#define extDigitalWrite(IO,V) digitalWrite(IO,V)
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
new file mode 100644
index 0000000000..1ac02f1182
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
@@ -0,0 +1,22 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
new file mode 100644
index 0000000000..69b6b4848f
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
@@ -0,0 +1,31 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+// Add strcmp_P if missing
+#ifndef strcmp_P
+ #define strcmp_P(a, b) strcmp((a), (b))
+#endif
+
+#ifndef strcat_P
+ #define strcat_P(dest, src) strcat((dest), (src))
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
new file mode 100644
index 0000000000..1ac02f1182
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
@@ -0,0 +1,22 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
new file mode 100644
index 0000000000..104af9af5b
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
@@ -0,0 +1,43 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * Test X86_64-specific configuration values for errors at compile-time.
+ */
+
+// Emulating RAMPS
+#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+ #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
+#endif
+
+#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
+ #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on LINUX."
+#endif
+
+#if HAS_TMC_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on LINUX."
+#endif
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not yet supported on LINUX."
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
new file mode 100644
index 0000000000..2aeeb52e92
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
@@ -0,0 +1,59 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 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 .
+ *
+ */
+
+/**
+ * Support routines for X86_64
+ */
+
+/**
+ * Translation of routines & variables used by pinsDebug.h
+ */
+
+#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
+#define pwm_details(pin) pin = pin // do nothing // print PWM details
+#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
+#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
+#define digitalRead_mod(p) digitalRead(p)
+#define PRINT_PORT(p)
+#define GET_ARRAY_PIN(p) pin_array[p].pin
+#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
+
+// active ADC function/mode/code values for PINSEL registers
+constexpr int8_t ADC_pin_mode(pin_t pin) {
+ return (-1);
+}
+
+int8_t get_pin_mode(pin_t pin) {
+ if (!VALID_PIN(pin)) return -1;
+ return 0;
+}
+
+bool GET_PINMODE(pin_t pin) {
+ int8_t pin_mode = get_pin_mode(pin);
+ if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin
+ return false;
+
+ return (Gpio::getMode(pin) != 0); //input/output state
+}
+
+bool GET_ARRAY_IS_DIGITAL(pin_t pin) {
+ return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
+}
diff --git a/Marlin/src/HAL/NATIVE_SIM/servo_private.h b/Marlin/src/HAL/NATIVE_SIM/servo_private.h
new file mode 100644
index 0000000000..06be1893f6
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/servo_private.h
@@ -0,0 +1,80 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
+ * Copyright (c) 2009 Michael Margolis. All right reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers -
+ * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
+ *
+ * The only modification was to update/delete macros to match the LPC176x.
+ *
+ */
+
+#include
+
+// Macros
+//values in microseconds
+#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
+#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
+#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
+#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds
+
+#define MAX_SERVOS 4
+
+#define INVALID_SERVO 255 // flag indicating an invalid servo index
+
+
+// Types
+
+typedef struct {
+ uint8_t nbr : 8 ; // a pin number from 0 to 254 (255 signals invalid pin)
+ uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false
+} ServoPin_t;
+
+typedef struct {
+ ServoPin_t Pin;
+ unsigned int pulse_width; // pulse width in microseconds
+} ServoInfo_t;
+
+// Global variables
+
+extern uint8_t ServoCount;
+extern ServoInfo_t servo_info[MAX_SERVOS];
diff --git a/Marlin/src/HAL/NATIVE_SIM/spi_pins.h b/Marlin/src/HAL/NATIVE_SIM/spi_pins.h
new file mode 100644
index 0000000000..a5138e0ccb
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/spi_pins.h
@@ -0,0 +1,55 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../../core/macros.h"
+#include "../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
+ #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
+ // needed due to the speed and mode required for communicating with each device being different.
+ // This requirement can be removed if the SPI access to these devices is updated to use
+ // spiBeginTransaction.
+#endif
+
+// Onboard SD
+//#define SD_SCK_PIN P0_07
+//#define SD_MISO_PIN P0_08
+//#define SD_MOSI_PIN P0_09
+//#define SD_SS_PIN P0_06
+
+// External SD
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 50
+#endif
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 51
+#endif
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 52
+#endif
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN 53
+#endif
+#ifndef SDSS
+ #define SDSS SD_SS_PIN
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h b/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h
new file mode 100644
index 0000000000..b3e622f19a
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h
@@ -0,0 +1,64 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfig.h"
+
+#ifndef LCD_READ_ID
+ #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
+#endif
+#ifndef LCD_READ_ID4
+ #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
+#endif
+
+#define DATASIZE_8BIT 8
+#define DATASIZE_16BIT 16
+#define TFT_IO_DRIVER TFT_SPI
+
+#define DMA_MINC_ENABLE 1
+#define DMA_MINC_DISABLE 0
+
+class TFT_SPI {
+private:
+ static uint32_t ReadID(uint16_t Reg);
+ static void Transmit(uint16_t Data);
+ static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
+
+public:
+ // static SPIClass SPIx;
+
+ static void Init();
+ static uint32_t GetID();
+ static bool isBusy();
+ static void Abort();
+
+ static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
+ static void DataTransferEnd();
+ static void DataTransferAbort();
+
+ static void WriteData(uint16_t Data);
+ static void WriteReg(uint16_t Reg);
+
+ static void WriteSequence(uint16_t *Data, uint16_t Count);
+ // static void WriteMultiple(uint16_t Color, uint16_t Count);
+ static void WriteMultiple(uint16_t Color, uint32_t Count);
+};
diff --git a/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h
new file mode 100644
index 0000000000..9ef1816c7b
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h
@@ -0,0 +1,80 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 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 .
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ #include
+#endif
+
+#ifndef TOUCH_MISO_PIN
+ #define TOUCH_MISO_PIN SD_MISO_PIN
+#endif
+#ifndef TOUCH_MOSI_PIN
+ #define TOUCH_MOSI_PIN SD_MOSI_PIN
+#endif
+#ifndef TOUCH_SCK_PIN
+ #define TOUCH_SCK_PIN SD_SCK_PIN
+#endif
+#ifndef TOUCH_CS_PIN
+ #define TOUCH_CS_PIN SD_SS_PIN
+#endif
+#ifndef TOUCH_INT_PIN
+ #define TOUCH_INT_PIN -1
+#endif
+
+#define XPT2046_DFR_MODE 0x00
+#define XPT2046_SER_MODE 0x04
+#define XPT2046_CONTROL 0x80
+
+enum XPTCoordinate : uint8_t {
+ XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+};
+
+#if !defined(XPT2046_Z1_THRESHOLD)
+ #define XPT2046_Z1_THRESHOLD 10
+#endif
+
+class XPT2046 {
+private:
+ static bool isBusy() { return false; }
+
+ static uint16_t getRawData(const XPTCoordinate coordinate);
+ static bool isTouched();
+
+ static inline void DataTransferBegin();
+ static inline void DataTransferEnd();
+ #if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ static uint16_t HardwareIO(uint16_t data);
+ #endif
+ static uint16_t SoftwareIO(uint16_t data);
+ static uint16_t IO(uint16_t data = 0);
+
+public:
+ #if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ static SPIClass SPIx;
+ #endif
+
+ static void Init();
+ static bool getRawPoint(int16_t *x, int16_t *y);
+};
diff --git a/Marlin/src/HAL/NATIVE_SIM/timers.h b/Marlin/src/HAL/NATIVE_SIM/timers.h
new file mode 100644
index 0000000000..c61eb29e76
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/timers.h
@@ -0,0 +1,91 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * HAL timers for Linux X86_64
+ */
+
+#include
+
+// ------------------------
+// Defines
+// ------------------------
+
+#define FORCE_INLINE __attribute__((always_inline)) inline
+
+typedef uint64_t hal_timer_t;
+#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFF
+
+#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
+
+#ifndef STEP_TIMER_NUM
+ #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#endif
+#ifndef PULSE_TIMER_NUM
+ #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#endif
+#ifndef TEMP_TIMER_NUM
+ #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
+#endif
+#ifndef SYSTICK_TIMER_NUM
+ #define SYSTICK_TIMER_NUM 2 // Timer Index for Systick
+#endif
+#define SYSTICK_TIMER_FREQUENCY 1000
+
+#define TEMP_TIMER_RATE 1000000
+#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
+
+#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
+#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
+#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
+
+#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
+#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
+#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
+
+#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
+
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+
+#ifndef HAL_STEP_TIMER_ISR
+ #define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
+#endif
+#ifndef HAL_TEMP_TIMER_ISR
+ #define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler()
+#endif
+
+void HAL_timer_init();
+void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
+
+void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare);
+hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
+hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
+
+void HAL_timer_enable_interrupt(const uint8_t timer_num);
+void HAL_timer_disable_interrupt(const uint8_t timer_num);
+bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
+
+#define HAL_timer_isr_prologue(TIMER_NUM)
+#define HAL_timer_isr_epilogue(TIMER_NUM)
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp
new file mode 100644
index 0000000000..745454394a
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp
@@ -0,0 +1,52 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+// adapted from I2C/master/master.c example
+// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html
+
+#ifdef __PLAT_NATIVE_SIM__
+
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+uint8_t u8g_i2c_start(const uint8_t sla) {
+ return 1;
+}
+
+void u8g_i2c_init(const uint8_t clock_option) {
+}
+
+uint8_t u8g_i2c_send_byte(uint8_t data) {
+ return 1;
+}
+
+void u8g_i2c_stop() {
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h
new file mode 100644
index 0000000000..6d5f91d3ba
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h
@@ -0,0 +1,37 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void u8g_i2c_init(const uint8_t clock_options);
+//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos);
+uint8_t u8g_i2c_start(uint8_t sla);
+uint8_t u8g_i2c_send_byte(uint8_t data);
+void u8g_i2c_stop();
+
+#ifdef __cplusplus
+ }
+#endif
+
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h
new file mode 100644
index 0000000000..44ffbfeb90
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h
@@ -0,0 +1,44 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+void usleep(uint64_t microsec);
+// The following are optional depending on the platform.
+
+// definitions of HAL specific com and device drivers.
+uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+
+// connect U8g com generic com names to the desired driver
+#define U8G_COM_SW_SPI u8g_com_sw_spi_fn
+#define U8G_COM_ST7920_SW_SPI u8g_com_ST7920_sw_spi_fn
+
+// let these default for now
+#define U8G_COM_HW_SPI u8g_com_null_fn
+#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn
+#define U8G_COM_SSD_I2C u8g_com_null_fn
+#define U8G_COM_PARALLEL u8g_com_null_fn
+#define U8G_COM_T6963 u8g_com_null_fn
+#define U8G_COM_FAST_PARALLEL u8g_com_null_fn
+#define U8G_COM_UC_I2C u8g_com_null_fn
+
+
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h
new file mode 100644
index 0000000000..297361cd44
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h
@@ -0,0 +1,43 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * LCD delay routines - used by all the drivers.
+ *
+ * These are based on the LPC1768 routines.
+ *
+ * Couldn't just call exact copies because the overhead
+ * results in a one microsecond delay taking about 4µS.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void U8g_delay(int msec);
+void u8g_MicroDelay();
+void u8g_10MicroDelay();
+
+#ifdef __cplusplus
+ }
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp
new file mode 100644
index 0000000000..3b5acc1656
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp
@@ -0,0 +1,52 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * Low level pin manipulation routines - used by all the drivers.
+ *
+ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
+ *
+ * Couldn't just call exact copies because the overhead killed the LCD update speed
+ * With an intermediate level the softspi was running in the 10-20kHz range which
+ * resulted in using about about 25% of the CPU's time.
+ */
+
+#ifdef __PLAT_NATIVE_SIM__
+
+#include "../fastio.h"
+#include "LCD_pin_routines.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+void u8g_SetPinOutput(uint8_t internal_pin_number){SET_DIR_OUTPUT(internal_pin_number);}
+void u8g_SetPinInput(uint8_t internal_pin_number){SET_DIR_INPUT(internal_pin_number);}
+void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status){WRITE_PIN(pin, pin_status);}
+uint8_t u8g_GetPinLevel(uint8_t pin){return READ_PIN(pin);}
+void usleep(uint64_t microsec){
+assert(false); // why we here?
+}
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h
new file mode 100644
index 0000000000..c27c84e8c3
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h
@@ -0,0 +1,46 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * Low level pin manipulation routines - used by all the drivers.
+ *
+ * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
+ *
+ * Couldn't just call exact copies because the overhead killed the LCD update speed
+ * With an intermediate level the softspi was running in the 10-20kHz range which
+ * resulted in using about about 25% of the CPU's time.
+ */
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void u8g_SetPinOutput(uint8_t internal_pin_number);
+void u8g_SetPinInput(uint8_t internal_pin_number);
+void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status);
+uint8_t u8g_GetPinLevel(uint8_t pin);
+
+#ifdef __cplusplus
+ }
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
new file mode 100644
index 0000000000..e95c6ebfbd
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
@@ -0,0 +1,171 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * Based on u8g_com_st7920_hw_spi.c
+ *
+ * Universal 8bit Graphics Library
+ *
+ * Copyright (c) 2011, olikraus@gmail.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * 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.
+ */
+
+#ifdef __PLAT_NATIVE_SIM__
+
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(U8GLIB_ST7920)
+
+#include
+#include "../../shared/Delay.h"
+
+#undef SPI_SPEED
+#define SPI_SPEED 6
+#define SPI_DELAY_CYCLES (1 + SPI_SPEED * 10)
+
+static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
+static uint8_t SPI_speed = 0;
+
+static uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
+ for (uint8_t i = 0; i < 8; i++) {
+ WRITE_PIN(mosi_pin, !!(b & 0x80));
+ DELAY_CYCLES(SPI_SPEED);
+ WRITE_PIN(sck_pin, HIGH);
+ DELAY_CYCLES(SPI_SPEED);
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ WRITE_PIN(sck_pin, LOW);
+ DELAY_CYCLES(SPI_SPEED);
+ }
+ return b;
+}
+
+static uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
+ WRITE_PIN(mosi_pin, HIGH);
+ WRITE_PIN(sck_pin, LOW);
+ return spiRate;
+}
+
+static void u8g_com_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) {
+ static uint8_t rs_last_state = 255;
+ if (rs != rs_last_state) {
+ // Transfer Data (FA) or Command (F8)
+ swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
+ rs_last_state = rs;
+ DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe
+ }
+ swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
+ swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
+}
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
+ switch (msg) {
+ case U8G_COM_MSG_INIT:
+ SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK];
+ MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI];
+
+ u8g_SetPIOutput(u8g, U8G_PI_CS);
+ u8g_SetPIOutput(u8g, U8G_PI_SCK);
+ u8g_SetPIOutput(u8g, U8G_PI_MOSI);
+ u8g_Delay(5);
+
+ SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
+
+ u8g_SetPILevel(u8g, U8G_PI_CS, 0);
+ u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
+ u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
+
+ u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */
+ break;
+
+ case U8G_COM_MSG_STOP:
+ break;
+
+ case U8G_COM_MSG_RESET:
+ if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
+ break;
+
+ case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
+ u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
+ break;
+
+ case U8G_COM_MSG_CHIP_SELECT:
+ if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select
+ break;
+
+ case U8G_COM_MSG_WRITE_BYTE:
+ u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val);
+ break;
+
+ case U8G_COM_MSG_WRITE_SEQ: {
+ uint8_t *ptr = (uint8_t*) arg_ptr;
+ while (arg_val > 0) {
+ u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
+ arg_val--;
+ }
+ }
+ break;
+
+ case U8G_COM_MSG_WRITE_SEQ_P: {
+ uint8_t *ptr = (uint8_t*) arg_ptr;
+ while (arg_val > 0) {
+ u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
+ arg_val--;
+ }
+ }
+ break;
+ }
+ return 1;
+}
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // U8GLIB_ST7920
+#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
new file mode 100644
index 0000000000..8e0ac9c7df
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
@@ -0,0 +1,215 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * Based on u8g_com_std_sw_spi.c
+ *
+ * Universal 8bit Graphics Library
+ *
+ * Copyright (c) 2015, olikraus@gmail.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * 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.
+ */
+
+#ifdef __PLAT_NATIVE_SIM__
+
+#include "../../../inc/MarlinConfig.h"
+
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+
+#undef SPI_SPEED
+#define SPI_SPEED 2 // About 2 MHz
+
+#include
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
+ LOOP_L_N(i, 8) {
+ if (spi_speed == 0) {
+ WRITE_PIN(mosi_pin, !!(b & 0x80));
+ WRITE_PIN(sck_pin, HIGH);
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ WRITE_PIN(sck_pin, LOW);
+ }
+ else {
+ const uint8_t state = (b & 0x80) ? HIGH : LOW;
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(mosi_pin, state);
+
+ LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
+ WRITE_PIN(sck_pin, HIGH);
+
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(sck_pin, LOW);
+ }
+ }
+
+ return b;
+}
+
+uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
+
+ LOOP_L_N(i, 8) {
+ const uint8_t state = (b & 0x80) ? HIGH : LOW;
+ if (spi_speed == 0) {
+ WRITE_PIN(sck_pin, LOW);
+ WRITE_PIN(mosi_pin, state);
+ WRITE_PIN(mosi_pin, state); // need some setup time
+ WRITE_PIN(sck_pin, HIGH);
+ }
+ else {
+ LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
+ WRITE_PIN(sck_pin, LOW);
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(mosi_pin, state);
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(sck_pin, HIGH);
+ }
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ }
+
+ return b;
+}
+
+static uint8_t SPI_speed = 0;
+
+static uint8_t swSpiInit(const uint8_t spi_speed, const uint8_t clk_pin, const uint8_t mosi_pin) {
+ return spi_speed;
+}
+
+static void u8g_sw_spi_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
+ #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864)
+ swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
+ #else
+ swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
+ #endif
+}
+
+uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
+ switch (msg) {
+ case U8G_COM_MSG_INIT:
+ u8g_SetPIOutput(u8g, U8G_PI_SCK);
+ u8g_SetPIOutput(u8g, U8G_PI_MOSI);
+ u8g_SetPIOutput(u8g, U8G_PI_CS);
+ u8g_SetPIOutput(u8g, U8G_PI_A0);
+ if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
+ SPI_speed = swSpiInit(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
+ u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
+ u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
+ break;
+
+ case U8G_COM_MSG_STOP:
+ break;
+
+ case U8G_COM_MSG_RESET:
+ if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
+ break;
+
+ case U8G_COM_MSG_CHIP_SELECT:
+ #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
+ if (arg_val) { // SCK idle state needs to be set to the proper idle state before
+ // the next chip select goes active
+ u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
+ u8g_SetPILevel(u8g, U8G_PI_CS, LOW);
+ }
+ else {
+ u8g_SetPILevel(u8g, U8G_PI_CS, HIGH);
+ u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
+ }
+ #else
+ u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val);
+ #endif
+ break;
+
+ case U8G_COM_MSG_WRITE_BYTE:
+ u8g_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val);
+ break;
+
+ case U8G_COM_MSG_WRITE_SEQ: {
+ uint8_t *ptr = (uint8_t *)arg_ptr;
+ while (arg_val > 0) {
+ u8g_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++);
+ arg_val--;
+ }
+ }
+ break;
+
+ case U8G_COM_MSG_WRITE_SEQ_P: {
+ uint8_t *ptr = (uint8_t *)arg_ptr;
+ while (arg_val > 0) {
+ u8g_sw_spi_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr));
+ ptr++;
+ arg_val--;
+ }
+ }
+ break;
+
+ case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
+ u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
+ break;
+ }
+ return 1;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#elif !ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB
+ #include
+ uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {return 0;}
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/watchdog.h b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
new file mode 100644
index 0000000000..4e404c3887
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
@@ -0,0 +1,27 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#define WDT_TIMEOUT 4000000 // 4 second timeout
+
+void watchdog_init();
+void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/platforms.h b/Marlin/src/HAL/platforms.h
index e0617bdf7f..0b1b305f6d 100644
--- a/Marlin/src/HAL/platforms.h
+++ b/Marlin/src/HAL/platforms.h
@@ -43,6 +43,8 @@
#define HAL_PATH(PATH, NAME) XSTR(PATH/ESP32/NAME)
#elif defined(__PLAT_LINUX__)
#define HAL_PATH(PATH, NAME) XSTR(PATH/LINUX/NAME)
+#elif defined(__PLAT_NATIVE_SIM__)
+ #define HAL_PATH(PATH, NAME) XSTR(PATH/NATIVE_SIM/NAME)
#elif defined(__SAMD51__)
#define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD51/NAME)
#else
diff --git a/Marlin/src/HAL/shared/Delay.h b/Marlin/src/HAL/shared/Delay.h
index 3174968c1b..04df35d88d 100644
--- a/Marlin/src/HAL/shared/Delay.h
+++ b/Marlin/src/HAL/shared/Delay.h
@@ -160,7 +160,7 @@ void calibrate_delay_loop();
// Delay in microseconds
#define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL))
-#elif defined(__PLAT_LINUX__) || defined(ESP32)
+#elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__)
// DELAY_CYCLES specified inside platform
diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h
index ba771596c7..7f96a30d6f 100644
--- a/Marlin/src/core/serial.h
+++ b/Marlin/src/core/serial.h
@@ -305,6 +305,9 @@ void serial_echopair_PGM(PGM_P const s_P, unsigned int v);
void serial_echopair_PGM(PGM_P const s_P, unsigned long v);
inline void serial_echopair_PGM(PGM_P const s_P, bool v) { serial_echopair_PGM(s_P, (int)v); }
inline void serial_echopair_PGM(PGM_P const s_P, void *v) { serial_echopair_PGM(s_P, (uintptr_t)v); }
+#if __INTPTR_WIDTH__ != __SIZE_WIDTH__
+ inline void serial_echopair_PGM(PGM_P const s_P, size_t v) { serial_echopair_PGM(s_P, (long int)v); }
+#endif
void serial_echo_start();
void serial_error_start();
diff --git a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
index 98a8f0a98a..a30dd4ca17 100644
--- a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
+++ b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
@@ -97,6 +97,11 @@
#define U8G_COM_ST7920_HAL_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn
#define U8G_COM_SSD_I2C_HAL u8g_com_HAL_LPC1768_ssd_hw_i2c_fn
+#elif defined(__PLAT_NATIVE_SIM__)
+ uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+ uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+ #define U8G_COM_HAL_SW_SPI_FN u8g_com_sw_spi_fn
+ #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_ST7920_sw_spi_fn
#endif
#ifndef U8G_COM_HAL_SW_SPI_FN
diff --git a/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp b/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp
index 6b973241fe..5e1dfae5d1 100644
--- a/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/draw_print_file.cpp
@@ -360,7 +360,7 @@ void disp_gcode_icon(uint8_t file_num) {
uint32_t lv_open_gcode_file(char *path) {
#if ENABLED(SDSUPPORT)
uint32_t *ps4;
- uint32_t pre_sread_cnt = UINT32_MAX;
+ uintptr_t pre_sread_cnt = UINTPTR_MAX;
char *cur_name;
cur_name = strrchr(path, '/');
@@ -370,7 +370,7 @@ uint32_t lv_open_gcode_file(char *path) {
ps4 = (uint32_t *)strstr((char *)public_buf, ";simage:");
// Ignore the beginning message of gcode file
if (ps4) {
- pre_sread_cnt = (uint32_t)ps4 - (uint32_t)((uint32_t *)(&public_buf[0]));
+ pre_sread_cnt = (uintptr_t)ps4 - (uintptr_t)((uint32_t *)(&public_buf[0]));
card.setIndex(pre_sread_cnt);
}
return pre_sread_cnt;
diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
index 1c1e5cc1f5..aae6e62a66 100644
--- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
@@ -560,11 +560,11 @@ char *creat_title_text() {
#if HAS_GCODE_PREVIEW
- uint32_t gPicturePreviewStart = 0;
+ uintptr_t gPicturePreviewStart = 0;
void preview_gcode_prehandle(char *path) {
#if ENABLED(SDSUPPORT)
- uint32_t pre_read_cnt = 0;
+ uintptr_t pre_read_cnt = 0;
uint32_t *p1;
char *cur_name;
@@ -575,7 +575,7 @@ char *creat_title_text() {
p1 = (uint32_t *)strstr((char *)public_buf, ";simage:");
if (p1) {
- pre_read_cnt = (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0]));
+ pre_read_cnt = (uintptr_t)p1 - (uintptr_t)((uint32_t *)(&public_buf[0]));
To_pre_view = pre_read_cnt;
gcode_preview_over = true;
@@ -606,7 +606,7 @@ char *creat_title_text() {
uint32_t br = card.read(public_buf, 400);
uint32_t *p1 = (uint32_t *)strstr((char *)public_buf, ";gimage:");
if (p1) {
- gPicturePreviewStart += (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0]));
+ gPicturePreviewStart += (uintptr_t)p1 - (uintptr_t)((uint32_t *)(&public_buf[0]));
break;
}
else {
diff --git a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp
index 2127b23a15..cfd6db15fd 100644
--- a/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp
@@ -398,7 +398,7 @@ lv_fs_res_t sd_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_
// find small image size
card.read(public_buf, 512);
public_buf[511] = '\0';
- char* eol = strpbrk((const char*)public_buf, "\n\r");
+ const char* eol = strpbrk((const char*)public_buf, "\n\r");
small_image_size = (uintptr_t)eol - (uintptr_t)((uint32_t *)(&public_buf[0])) + 1;
return LV_FS_RES_OK;
}
@@ -530,4 +530,10 @@ void lv_encoder_pin_init() {
#endif // HAS_ENCODER_ACTION
+#if __PLAT_NATIVE_SIM__
+ #include
+ typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *);
+ extern "C" void lv_log_register_print_cb(lv_log_print_g_cb_t print_cb) {}
+#endif
+
#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h
index 3930279c94..a0f8c1648c 100644
--- a/Marlin/src/pins/linux/pins_RAMPS_LINUX.h
+++ b/Marlin/src/pins/linux/pins_RAMPS_LINUX.h
@@ -49,6 +49,10 @@
#define BOARD_INFO_NAME "RAMPS 1.4"
#endif
+#ifndef DEFAULT_MACHINE_NAME
+ #define DEFAULT_MACHINE_NAME "SimRap 1.4"
+#endif
+
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
@@ -208,6 +212,7 @@
//
#define SDSS 53
#define LED_PIN 13
+#define NEOPIXEL_PIN 71
#ifndef FILWIDTH_PIN
#define FILWIDTH_PIN 5 // Analog Input on AUX2
@@ -215,7 +220,7 @@
// define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector
#ifndef FIL_RUNOUT_PIN
- #define FIL_RUNOUT_PIN 4
+ #define FIL_RUNOUT_PIN 21
#endif
#ifndef PS_ON_PIN
@@ -389,7 +394,54 @@
// LCDs and Controllers //
//////////////////////////
-#if HAS_WIRED_LCD
+#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI)
+
+ #define TFT_A0_PIN 43
+ #define TFT_CS_PIN 49
+ #define TFT_DC_PIN 43
+ #define TFT_SCK_PIN SD_SCK_PIN
+ #define TFT_MOSI_PIN SD_MOSI_PIN
+ #define TFT_MISO_PIN SD_MISO_PIN
+ #define LCD_USE_DMA_SPI
+
+ #define BTN_EN1 40
+ #define BTN_EN2 63
+ #define BTN_ENC 59
+ #define BEEPER_PIN 42
+
+ #define TOUCH_CS_PIN 33
+ #define SD_DETECT_PIN 41
+
+ #define HAS_SPI_FLASH 1
+ #if HAS_SPI_FLASH
+ #define SPI_DEVICE 1
+ #define SPI_FLASH_SIZE 0x1000000 // 16MB
+ #define W25QXX_CS_PIN 31
+ #define W25QXX_MOSI_PIN SD_MOSI_PIN
+ #define W25QXX_MISO_PIN SD_MISO_PIN
+ #define W25QXX_SCK_PIN SD_SCK_PIN
+ #endif
+
+ #define TFT_BUFFER_SIZE 0xFFFF
+ #ifndef TFT_DRIVER
+ #define TFT_DRIVER ST7796
+ #endif
+ #ifndef XPT2046_X_CALIBRATION
+ #define XPT2046_X_CALIBRATION 63934
+ #endif
+ #ifndef XPT2046_Y_CALIBRATION
+ #define XPT2046_Y_CALIBRATION 63598
+ #endif
+ #ifndef XPT2046_X_OFFSET
+ #define XPT2046_X_OFFSET -1
+ #endif
+ #ifndef XPT2046_Y_OFFSET
+ #define XPT2046_Y_OFFSET -20
+ #endif
+
+ #define BTN_BACK 70
+
+#elif HAS_WIRED_LCD
//
// LCD Display output pins
@@ -622,14 +674,18 @@
#define BTN_EN1 37
#define BTN_EN2 35
#define BTN_ENC 31
+ #define SD_DETECT_PIN 41
#endif
#if ENABLED(G3D_PANEL)
#define SD_DETECT_PIN 49
#define KILL_PIN 41
#endif
-
#endif
+
+ // CUSTOM SIMULATOR INPUTS
+ #define BTN_BACK 70
+
#endif // IS_NEWPANEL
#endif // HAS_WIRED_LCD
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index e6d6cbdaf5..b3e1605613 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -683,7 +683,7 @@
//
#elif MB(LINUX_RAMPS)
- #include "linux/pins_RAMPS_LINUX.h" // Linux env:linux_native
+ #include "linux/pins_RAMPS_LINUX.h" // Native or Simulation lin:linux_native mac:simulator_macos_debug mac:simulator_macos_release win:simulator_windows lin:simulator_linux_debug lin:simulator_linux_release
#else
diff --git a/Marlin/src/sd/SdFatUtil.cpp b/Marlin/src/sd/SdFatUtil.cpp
index 7d9f33dc50..e6f7a9a013 100644
--- a/Marlin/src/sd/SdFatUtil.cpp
+++ b/Marlin/src/sd/SdFatUtil.cpp
@@ -48,7 +48,7 @@
return &top - reinterpret_cast(sbrk(0));
}
-#else
+#elif defined(__AVR__)
extern char* __brkval;
extern char __bss_end;
diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp
index 913ae5152b..61b2b72bb6 100644
--- a/Marlin/src/sd/cardreader.cpp
+++ b/Marlin/src/sd/cardreader.cpp
@@ -939,7 +939,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &inDirPtr, con
while (atom_ptr) {
// Find next subdirectory delimiter
- char * const name_end = strchr(atom_ptr, '/');
+ const char * const name_end = strchr(atom_ptr, '/');
// Last atom in the path? Item found.
if (name_end <= atom_ptr) break;
diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies.py b/buildroot/share/PlatformIO/scripts/common-dependencies.py
index 01ee89e25e..83dfeca879 100644
--- a/buildroot/share/PlatformIO/scripts/common-dependencies.py
+++ b/buildroot/share/PlatformIO/scripts/common-dependencies.py
@@ -215,7 +215,13 @@ def search_compiler():
# Find the current platform compiler by searching the $PATH
# which will be in a platformio toolchain bin folder
path_regex = re.escape(env['PROJECT_PACKAGES_DIR'])
- gcc = "g++"
+
+ # See if the environment provides a default compiler
+ try:
+ gcc = env.GetProjectOption('custom_deps_gcc')
+ except:
+ gcc = "g++"
+
if env['PLATFORM'] == 'win32':
path_separator = ';'
path_regex += r'.*\\bin'
@@ -241,6 +247,8 @@ def search_compiler():
return filepath
filepath = env.get('CXX')
+ if filepath == 'CC':
+ filepath = gcc
blab("Couldn't find a compiler! Fallback to %s" % filepath)
return filepath
diff --git a/buildroot/share/PlatformIO/scripts/simulator.py b/buildroot/share/PlatformIO/scripts/simulator.py
new file mode 100644
index 0000000000..fb9d93cceb
--- /dev/null
+++ b/buildroot/share/PlatformIO/scripts/simulator.py
@@ -0,0 +1,52 @@
+#
+# PlatformIO pre: script for simulator builds
+#
+
+# Get the environment thus far for the build
+Import("env")
+
+#print(env.Dump())
+
+#
+# Give the binary a distinctive name
+#
+
+env['PROGNAME'] = "MarlinSimulator"
+
+#
+# If Xcode is installed add the path to its Frameworks folder,
+# or if Mesa is installed try to use its GL/gl.h.
+#
+
+import sys
+if sys.platform == 'darwin':
+
+ #
+ # Silence half of the ranlib warnings. (No equivalent for 'ARFLAGS')
+ #
+ env['RANLIBFLAGS'] += [ "-no_warning_for_no_symbols" ]
+
+ # Default paths for Xcode and a lucky GL/gl.h dropped by Mesa
+ xcode_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
+ mesa_path = "/opt/local/include/GL/gl.h"
+
+ import os.path
+
+ if os.path.exists(xcode_path):
+
+ env['BUILD_FLAGS'] += [ "-F" + xcode_path ]
+ print("Using OpenGL framework headers from Xcode.app")
+
+ elif os.path.exists(mesa_path):
+
+ env['BUILD_FLAGS'] += [ '-D__MESA__' ]
+ print("Using OpenGL header from", mesa_path)
+
+ else:
+
+ print("\n\nNo OpenGL headers found. Install Xcode for matching headers, or use 'sudo port install mesa' to get a GL/gl.h.\n\n")
+
+ # Break out of the PIO build immediately
+ sys.exit(1)
+
+env.AddCustomTarget("upload", "$BUILD_DIR/${PROGNAME}", "$BUILD_DIR/${PROGNAME}")
diff --git a/ini/native.ini b/ini/native.ini
index dbdfd26f8b..b40ea836da 100644
--- a/ini/native.ini
+++ b/ini/native.ini
@@ -21,3 +21,110 @@ build_unflags = -Wall
lib_ldf_mode = off
lib_deps =
src_filter = ${common.default_src_filter} +
+
+#
+# Native Simulation
+# Builds with a small subset of available features
+# Required system libraries: SDL2, SDL2-net, OpenGL, GLM
+#
+# Tested with Linux (Mint 20) : gcc [9.3.0, 10.2.0]: libsdl2-dev[2.0.10], libsdl2-net-dev[2.0.1], libglm-dev[0.9.9.7, 0.9.9.8]
+#
+# Debugging with gdb in vscode is as easy as adding the launch task as usual, but platformio
+# will randomly remove your task when it recreates its tasks from a template. Add your gdb
+# launch task to '~/.platformio/penv/lib/python{PYTHON_VERSION}/site-packages/platformio/ide/tpls/vscode/.vscode'
+# to avoid this until platformio updates.
+#
+[simulator_common]
+platform = native
+framework =
+build_flags = ${common.build_flags} -std=gnu++17 -D__PLAT_NATIVE_SIM__ -DU8G_HAL_LINKS -I/usr/include/SDL2 -IMarlin -IMarlin/src/HAL/NATIVE_SIM/include -IMarlin/src/HAL/NATIVE_SIM/u8g
+src_build_flags = -Wall -Wno-expansion-to-defined -Wcast-align
+release_flags = -g0 -O3 -flto
+debug_build_flags = -fstack-protector-strong -g -g3 -ggdb
+lib_compat_mode = off
+src_filter = ${common.default_src_filter} +
+
+lib_deps = ${common.lib_deps}
+ MarlinSimUI=https://github.com/p3p/MarlinSimUI.git
+ Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/marlin_sim_native.zip
+ LiquidCrystal=https://github.com/p3p/LiquidCrystal/archive/master.zip
+extra_scripts = ${common.extra_scripts}
+ pre:buildroot/share/PlatformIO/scripts/simulator.py
+
+
+[simulator_linux]
+extends = simulator_common
+build_flags = ${simulator_common.build_flags} -ldl -lpthread -lSDL2 -lSDL2_net -lGL
+
+[env:simulator_linux_debug]
+platform = ${simulator_linux.platform}
+extends = simulator_linux
+build_type = debug
+
+[env:simulator_linux_release]
+platform = ${simulator_linux.platform}
+extends = simulator_linux
+build_type = release
+build_flags = ${simulator_linux.build_flags} ${simulator_linux.release_flags}
+
+#
+# Simulator for macOS (MacPorts)
+#
+# sudo port install gcc10 gdb glm libsdl2 freetype
+# sudo port install ld64 @3_3 +ld64_xcode
+# sudo port uninstall ld64 ld64-latest
+# cd /opt/local/bin
+# sudo rm -f gcc g++ cc
+# sudo ln gcc-mp-10 gcc ; sudo ln g++-mp-10 g++ ; sudo ln g++ cc
+# cd -
+#
+# Use 'sudo port install mesa' to get a if no Xcode is installed.
+# If Xcode is installed be sure to run `xcode-select --install` first.
+#
+# For VSCode debugging paste the block below near the top of launch.json.
+# NOTE: The PlatformIO VSCode extension will remove it when regenerating launch.json.
+#
+# { "name": "Debug Sim",
+# "type": "cppdbg",
+# "request": "launch",
+# "program": "${workspaceFolder}/.pio/build/simulator_macos/MarlinSimulator",
+# "miDebuggerPath": "/opt/local/bin/ggdb",
+# "MIMode": "gdb",
+# "cwd": "${workspaceFolder}/.pio/build/simulator_macos" },
+#
+[simulator_macos]
+build_unflags = -lGL
+custom_verbose = 0
+build_flags =
+ -I/opt/local/include
+ -I/opt/local/include/freetype2
+ -I/opt/local/include/SDL2/
+ -L/opt/local/lib
+ -Wl,-framework,OpenGl
+ -Wl,-framework,CoreFoundation
+ -lSDL2
+
+[env:simulator_macos_debug]
+platform = ${env:simulator_linux_release.platform}
+extends = env:simulator_linux_debug
+build_flags = ${env:simulator_linux_debug.build_flags} ${simulator_macos.build_flags} -ggdb -Og -D_THREAD_SAFE
+build_unflags = ${simulator_macos.build_unflags}
+
+[env:simulator_macos_release]
+platform = ${env:simulator_linux_release.platform}
+extends = env:simulator_linux_release
+build_flags = ${env:simulator_linux_release.build_flags} ${simulator_macos.build_flags}
+build_unflags = ${simulator_macos.build_unflags}
+
+#
+# Simulator for Windows 10
+#
+# MSYS2 mingw-w64-x86_64 with these packages:
+# pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw64/mingw-w64-x86_64-glm mingw64/mingw-w64-x86_64-SDL2 mingw64/mingw-w64-x86_64-SDL2_net
+#
+[env:simulator_windows]
+platform = ${simulator_common.platform}
+extends = simulator_common
+src_build_flags = ${simulator_common.src_build_flags} -fpermissive
+build_flags = ${simulator_common.build_flags} ${simulator_common.debug_build_flags} -fno-stack-protector -Wl,-subsystem,windows -ldl -lmingw32 -lSDL2main -lSDL2 -lSDL2_net -lopengl32 -lssp
+build_type = debug