diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 1f34c0691..c6ec607d9 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -2156,6 +2156,12 @@
//
//#define FSMC_GRAPHICAL_TFT
+//
+// SPI display (MKS Robin Nano V2.0, MKS Gen L V2.0)
+// Upscaled 128x64 Marlin UI
+//
+//#define SPI_GRAPHICAL_TFT
+
//
// TFT LVGL UI
//
@@ -2189,10 +2195,10 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
- #define XPT2046_X_CALIBRATION 12316
- #define XPT2046_Y_CALIBRATION -8981
- #define XPT2046_X_OFFSET -43
- #define XPT2046_Y_OFFSET 257
+ //#define XPT2046_X_CALIBRATION 12316
+ //#define XPT2046_Y_CALIBRATION -8981
+ //#define XPT2046_X_OFFSET -43
+ //#define XPT2046_Y_OFFSET 257
#endif
//
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 7ebab9d16..37c997977 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1509,9 +1509,10 @@
#endif
//
-// FSMC Graphical TFT
+// FSMC / SPI Graphical TFT
//
-#if ENABLED(FSMC_GRAPHICAL_TFT)
+#if TFT_SCALED_DOGLCD
+ //#define GRAPHICAL_TFT_ROTATE_180
//#define TFT_MARLINUI_COLOR 0xFFFF // White
//#define TFT_MARLINBG_COLOR 0x0000 // Black
//#define TFT_DISABLED_COLOR 0x0003 // Almost black
diff --git a/Marlin/src/HAL/STM32F1/SPI.h b/Marlin/src/HAL/STM32F1/SPI.h
index dc2a21586..0d20a4657 100644
--- a/Marlin/src/HAL/STM32F1/SPI.h
+++ b/Marlin/src/HAL/STM32F1/SPI.h
@@ -208,6 +208,8 @@ public:
*/
void setDataSize(uint32_t ds);
+ uint32_t getDataSize() { return _currentSetting->dataSize; }
+
/* Victor Perez 2017. Added to set and clear callback functions for callback
* on DMA transfer completion.
* onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed
diff --git a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_hwspi.cpp b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_hwspi.cpp
new file mode 100644
index 000000000..286dcfb5d
--- /dev/null
+++ b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_hwspi.cpp
@@ -0,0 +1,236 @@
+/**
+ * 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 .
+ *
+ */
+#ifdef __STM32F1__
+
+#include "../../../inc/MarlinConfig.h"
+
+#if BOTH(HAS_GRAPHICAL_LCD, SPI_GRAPHICAL_TFT) && DISABLED(FORCE_SOFT_SPI)
+
+#include "../HAL.h"
+#include
+#include
+
+#define SPI_TFT_CS_H OUT_WRITE(SPI_TFT_CS_PIN, HIGH)
+#define SPI_TFT_CS_L OUT_WRITE(SPI_TFT_CS_PIN, LOW)
+
+#define SPI_TFT_DC_H OUT_WRITE(SPI_TFT_DC_PIN, HIGH)
+#define SPI_TFT_DC_L OUT_WRITE(SPI_TFT_DC_PIN, LOW)
+
+#define SPI_TFT_RST_H OUT_WRITE(SPI_TFT_RST_PIN, HIGH)
+#define SPI_TFT_RST_L OUT_WRITE(SPI_TFT_RST_PIN, LOW)
+
+#define SPI_TFT_BLK_H OUT_WRITE(LCD_BACKLIGHT_PIN, HIGH)
+#define SPI_TFT_BLK_L OUT_WRITE(LCD_BACKLIGHT_PIN, LOW)
+
+void LCD_IO_Init(uint8_t cs, uint8_t rs);
+void LCD_IO_WriteData(uint16_t RegValue);
+void LCD_IO_WriteReg(uint16_t Reg);
+uint16_t LCD_IO_ReadData(uint16_t RegValue);
+uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
+#ifdef LCD_USE_DMA_SPI
+ void LCD_IO_WriteMultiple(uint16_t data, uint32_t count);
+ void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
+#endif
+
+void LCD_WR_REG(uint8_t cmd) {
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_L;
+ SPI.send(cmd);
+ SPI_TFT_CS_H;
+}
+void LCD_WR_DATA(uint8_t data) {
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_H;
+ SPI.send(data);
+ SPI_TFT_CS_H;
+}
+
+void spi1Init(uint8_t spiRate) {
+ SPI_TFT_CS_H;
+
+ /**
+ * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
+ * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
+ * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
+ */
+ uint8_t clock;
+ switch (spiRate) {
+ case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break;
+ case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break;
+ case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break;
+ case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
+ case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
+ case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
+ default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
+ }
+ SPI.setModule(1);
+ SPI.begin();
+ SPI.setClockDivider(clock);
+ SPI.setBitOrder(MSBFIRST);
+ SPI.setDataMode(SPI_MODE0);
+}
+
+void LCD_IO_Init(uint8_t cs, uint8_t rs) {
+ spi1Init(SPI_FULL_SPEED);
+}
+
+void LCD_IO_WriteData(uint16_t RegValue) {
+ LCD_WR_DATA(RegValue);
+}
+
+void LCD_IO_WriteReg(uint16_t Reg) {
+ LCD_WR_REG(Reg);
+}
+
+uint16_t LCD_IO_ReadData(uint16_t RegValue) {
+ uint16_t d = 0;
+ SPI_TFT_CS_L;
+
+ SPI_TFT_DC_L;
+ SPI.send(RegValue);
+ SPI_TFT_DC_H;
+
+ SPI.read((uint8_t*)&d, 1); //dummy read
+ SPI.read((uint8_t*)&d, 1);
+
+ SPI_TFT_CS_H;
+ return d >> 7;
+}
+
+uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) {
+ uint32_t data = 0;
+ uint8_t d = 0;
+ SPI_TFT_CS_L;
+
+ SPI_TFT_DC_L;
+ SPI.send(RegValue);
+ SPI_TFT_DC_H;
+
+ SPI.read((uint8_t*)&d, 1); //dummy read
+ SPI.read((uint8_t*)&d, 1);
+ data = d;
+ while (--ReadSize) {
+ data <<= 8;
+ SPI.read((uint8_t*)&d, 1);
+ data |= (d & 0xFF);
+ }
+
+ SPI_TFT_CS_H;
+ return uint32_t(data >> 7);
+}
+
+#ifdef LCD_USE_DMA_SPI
+ void LCD_IO_WriteMultiple(uint16_t data, uint32_t count) {
+ if (SPI.getDataSize() == DATA_SIZE_8BIT) {
+ count *= 2;
+ }
+ while (count > 0) {
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_H;
+ SPI.dmaSend(&data, 1, true);
+ SPI_TFT_CS_H;
+ count--;
+ }
+ }
+
+ void LCD_IO_WriteSequence(uint16_t *data, uint16_t length) {
+ if (SPI.getDataSize() == DATA_SIZE_8BIT) {
+ length *= 2;
+ }
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_H;
+ SPI.dmaSend(data, length, true);
+ SPI_TFT_CS_H;
+ }
+
+ void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length) {
+ if (SPI.getDataSize() == DATA_SIZE_8BIT) {
+ length *= 2;
+ }
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_H;
+ SPI.dmaSendAsync(data, length, true);
+ SPI_TFT_CS_H;
+ }
+
+ void LCD_IO_WaitSequence_Async() {
+ SPI_TFT_CS_L;
+ SPI_TFT_DC_H;
+ SPI.dmaSendAsync(NULL, 0, true);
+ SPI_TFT_CS_H;
+ }
+#endif
+
+static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
+
+#ifndef LCD_READ_ID
+ #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
+#endif
+
+uint8_t u8g_com_stm32duino_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
+ if (msgInitCount) {
+ if (msg == U8G_COM_MSG_INIT) msgInitCount--;
+ if (msgInitCount) return -1;
+ }
+
+ static uint8_t isCommand;
+
+ LCD_IO_Init(-1, -1);
+
+ switch (msg) {
+ case U8G_COM_MSG_STOP: break;
+ case U8G_COM_MSG_INIT:
+ u8g_SetPIOutput(u8g, U8G_PI_RESET);
+
+ u8g_Delay(50);
+
+ if (arg_ptr) {
+ spi1Init(SPI_EIGHTH_SPEED);
+ *((uint32_t *)arg_ptr) = (LCD_READ_ID << 24) | LCD_IO_ReadData(LCD_READ_ID, 3);
+ spi1Init(SPI_FULL_SPEED);
+ }
+ isCommand = 0;
+ break;
+
+ case U8G_COM_MSG_ADDRESS: // define cmd (arg_val = 0) or data mode (arg_val = 1)
+ isCommand = arg_val == 0 ? 1 : 0;
+ break;
+
+ case U8G_COM_MSG_RESET:
+ u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
+ break;
+
+ case U8G_COM_MSG_WRITE_BYTE:
+ if (isCommand)
+ LCD_IO_WriteReg(arg_val);
+ else
+ LCD_IO_WriteData((uint16_t)arg_val);
+ break;
+
+ case U8G_COM_MSG_WRITE_SEQ:
+ for (uint8_t i = 0; i < arg_val; i += 2)
+ LCD_IO_WriteData(*(uint16_t *)(((uint32_t)arg_ptr) + i));
+ break;
+
+ }
+ return 1;
+}
+
+#endif // HAS_GRAPHICAL_LCD
+#endif // STM32F1
diff --git a/Marlin/src/feature/touch/xpt2046.cpp b/Marlin/src/feature/touch/xpt2046.cpp
index 235c17b50..d613fbc89 100644
--- a/Marlin/src/feature/touch/xpt2046.cpp
+++ b/Marlin/src/feature/touch/xpt2046.cpp
@@ -23,10 +23,14 @@
#include "xpt2046.h"
#include "../../inc/MarlinConfig.h"
-#if ENABLED(FSMC_GRAPHICAL_TFT)
+
+#if TFT_SCALED_DOGLCD
#include "../../lcd/dogm/ultralcd_DOGM.h" // for LCD_FULL_PIXEL_WIDTH, etc.
#endif
+#ifndef XPT2046_Z1_THRESHOLD
+ #define XPT2046_Z1_THRESHOLD 10
+#endif
/*
* Draw and Touch processing
@@ -117,10 +121,15 @@ uint8_t XPT2046::read_buttons() {
// We rely on XPT2046 compatible mode to ADS7843, hence no Z1 and Z2 measurements possible.
if (!isTouched()) return 0;
- const uint16_t x = uint16_t(((uint32_t(getInTouch(XPT2046_X))) * tsoffsets[0]) >> 16) + tsoffsets[1],
- y = uint16_t(((uint32_t(getInTouch(XPT2046_Y))) * tsoffsets[2]) >> 16) + tsoffsets[3];
+ uint16_t x = uint16_t(((uint32_t(getInTouch(XPT2046_X))) * tsoffsets[0]) >> 16) + tsoffsets[1],
+ y = uint16_t(((uint32_t(getInTouch(XPT2046_Y))) * tsoffsets[2]) >> 16) + tsoffsets[3];
if (!isTouched()) return 0; // Fingers must still be on the TS for a valid read.
+ #if ENABLED(GRAPHICAL_TFT_ROTATE_180)
+ x = TOUCH_SCREEN_WIDTH - x;
+ y = TOUCH_SCREEN_HEIGHT - y;
+ #endif
+
// Touch within the button area simulates an encoder button
if (y > BUTTON_AREA_TOP && y < BUTTON_AREA_BOT)
return WITHIN(x, 14, 77) ? EN_D
@@ -151,30 +160,69 @@ bool XPT2046::isTouched() {
);
}
+#if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ #include
+
+ static void touch_spi_init(uint8_t spiRate) {
+ /**
+ * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
+ * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
+ * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
+ */
+ uint8_t clock;
+ switch (spiRate) {
+ case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break;
+ case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break;
+ case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break;
+ case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
+ case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
+ case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
+ default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
+ }
+ SPI.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE);
+ SPI.begin();
+ SPI.setClockDivider(clock);
+ SPI.setBitOrder(MSBFIRST);
+ SPI.setDataMode(SPI_MODE0);
+ }
+#endif // TOUCH_BUTTONS_HW_SPI
+
uint16_t XPT2046::getInTouch(const XPTCoordinate coordinate) {
uint16_t data[3];
-
- OUT_WRITE(TOUCH_CS_PIN, LOW);
-
const uint8_t coord = uint8_t(coordinate) | XPT2046_CONTROL | XPT2046_DFR_MODE;
- for (uint16_t i = 0; i < 3 ; i++) {
- for (uint8_t j = 0x80; j; j >>= 1) {
- WRITE(TOUCH_SCK_PIN, LOW);
- WRITE(TOUCH_MOSI_PIN, bool(coord & j));
- WRITE(TOUCH_SCK_PIN, HIGH);
+
+ #if ENABLED(TOUCH_BUTTONS_HW_SPI)
+
+ touch_spi_init(SPI_SPEED_6);
+ for (uint16_t i = 0; i < 3; i++) {
+ OUT_WRITE(TOUCH_CS_PIN, LOW);
+ SPI.transfer(coord);
+ data[i] = (((SPI.transfer(0xFF) << 8) | SPI.transfer(0xFF)) >> 3) & 0x0FFF;
+ WRITE(TOUCH_CS_PIN, HIGH);
}
- data[i] = 0;
- for (uint16_t j = 0x8000; j; j >>= 1) {
- WRITE(TOUCH_SCK_PIN, LOW);
- if (READ(TOUCH_MISO_PIN)) data[i] |= j;
- WRITE(TOUCH_SCK_PIN, HIGH);
- }
- WRITE(TOUCH_SCK_PIN, LOW);
- data[i] >>= 4;
- }
+ #else // !TOUCH_BUTTONS_HW_SPI
- WRITE(TOUCH_CS_PIN, HIGH);
+ OUT_WRITE(TOUCH_CS_PIN, LOW);
+ for (uint16_t i = 0; i < 3; i++) {
+ for (uint8_t j = 0x80; j; j >>= 1) {
+ WRITE(TOUCH_SCK_PIN, LOW);
+ WRITE(TOUCH_MOSI_PIN, bool(coord & j));
+ WRITE(TOUCH_SCK_PIN, HIGH);
+ }
+
+ data[i] = 0;
+ for (uint16_t j = 0x8000; j; j >>= 1) {
+ WRITE(TOUCH_SCK_PIN, LOW);
+ if (READ(TOUCH_MISO_PIN)) data[i] |= j;
+ WRITE(TOUCH_SCK_PIN, HIGH);
+ }
+ WRITE(TOUCH_SCK_PIN, LOW);
+ data[i] >>= 4;
+ }
+ WRITE(TOUCH_CS_PIN, HIGH);
+
+ #endif // !TOUCH_BUTTONS_HW_SPI
uint16_t delta01 = _MAX(data[0], data[1]) - _MIN(data[0], data[1]),
delta02 = _MAX(data[0], data[2]) - _MIN(data[0], data[2]),
diff --git a/Marlin/src/feature/touch/xpt2046.h b/Marlin/src/feature/touch/xpt2046.h
index 347881e0a..467317901 100644
--- a/Marlin/src/feature/touch/xpt2046.h
+++ b/Marlin/src/feature/touch/xpt2046.h
@@ -34,10 +34,6 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40
};
-#ifndef XPT2046_Z1_THRESHOLD
- #define XPT2046_Z1_THRESHOLD 10
-#endif
-
class XPT2046 {
public:
static void init();
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 992a788eb..1605ced3c 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -261,7 +261,11 @@
#endif
// FSMC/SPI TFT Panels
-#if ENABLED(FSMC_GRAPHICAL_TFT)
+#if EITHER(FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT)
+ #define TFT_SCALED_DOGLCD 1
+#endif
+
+#if TFT_SCALED_DOGLCD
#define DOGLCD
#define IS_ULTIPANEL
#define DELAYED_BACKLIGHT_INIT
diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h
index e12310e07..c7171b06d 100644
--- a/Marlin/src/inc/Conditionals_post.h
+++ b/Marlin/src/inc/Conditionals_post.h
@@ -373,7 +373,7 @@
#endif
-#if EITHER(LCD_USE_DMA_FSMC, FSMC_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT)
+#if ANY(LCD_USE_DMA_FSMC, FSMC_GRAPHICAL_TFT, SPI_GRAPHICAL_TFT) || !PIN_EXISTS(SD_DETECT)
#define NO_LCD_REINIT 1 // Suppress LCD re-initialization
#endif
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 9fde639b0..9fb742f50 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -451,8 +451,6 @@
#error "MKS_ROBIN_TFT is now FSMC_GRAPHICAL_TFT. Please update your configuration."
#elif defined(TFT_LVGL_UI)
#error "TFT_LVGL_UI is now TFT_LVGL_UI_FSMC. Please update your configuration."
-#elif defined(SPI_GRAPHICAL_TFT)
- #error "SPI_GRAPHICAL_TFT is now TFT_LVGL_UI_SPI. Please update your configuration."
#elif defined(SDPOWER)
#error "SDPOWER is now SDPOWER_PIN. Please update your configuration and/or pins."
#elif defined(STRING_SPLASH_LINE1) || defined(STRING_SPLASH_LINE2)
@@ -3036,11 +3034,27 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#endif
/**
- * Sanity checks for stepper chunk support
+ * Stepper Chunk support
*/
-#if ENABLED(DIRECT_STEPPING)
- #if ENABLED(LIN_ADVANCE)
- #error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. Enable in external planner if possible."
+#if BOTH(DIRECT_STEPPING, LIN_ADVANCE)
+ #error "DIRECT_STEPPING is incompatible with LIN_ADVANCE. Enable in external planner if possible."
+#endif
+
+/**
+ * Touch Buttons
+ */
+#if ENABLED(TOUCH_BUTTONS)
+ #ifndef XPT2046_X_CALIBRATION
+ #error "XPT2046_X_CALIBRATION must be defined with TOUCH_BUTTONS."
+ #endif
+ #ifndef XPT2046_Y_CALIBRATION
+ #error "XPT2046_Y_CALIBRATION must be defined with TOUCH_BUTTONS."
+ #endif
+ #ifndef XPT2046_X_OFFSET
+ #error "XPT2046_X_OFFSET must be defined with TOUCH_BUTTONS."
+ #endif
+ #ifndef XPT2046_Y_OFFSET
+ #error "XPT2046_Y_OFFSET must be defined with TOUCH_BUTTONS."
#endif
#endif
diff --git a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
index df7f8dd44..1f9621e9c 100644
--- a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
+++ b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h
@@ -87,6 +87,11 @@
#define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_fsmc_fn
#endif
+ #if ENABLED(SPI_GRAPHICAL_TFT)
+ uint8_t u8g_com_stm32duino_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+ #define U8G_COM_HAL_FSMC_FN u8g_com_stm32duino_spi_fn
+ #endif
+
#elif defined(TARGET_LPC1768)
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
index fc7a22b26..33cd5ecca 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
@@ -57,14 +57,21 @@
#include "../../inc/MarlinConfig.h"
-#if HAS_GRAPHICAL_LCD && PIN_EXISTS(FSMC_CS)
+#if HAS_GRAPHICAL_LCD && (PIN_EXISTS(FSMC_CS) || ENABLED(SPI_GRAPHICAL_TFT))
#include "HAL_LCD_com_defines.h"
#include "ultralcd_DOGM.h"
#include
-#ifdef LCD_USE_DMA_FSMC
+#if EITHER(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI)
+ #define HAS_LCD_IO 1
+#endif
+
+#if HAS_LCD_IO
+ extern void LCD_IO_Init(uint8_t cs, uint8_t rs);
+ extern uint16_t LCD_IO_ReadData(uint16_t Reg);
+ extern uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize);
extern void LCD_IO_WriteReg(uint16_t Reg);
extern void LCD_IO_WriteData(uint16_t RegValue);
extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
@@ -148,46 +155,34 @@ static uint32_t lcd_id = 0;
static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
- #ifdef LCD_USE_DMA_FSMC
- LCD_IO_WriteReg(ILI9328_HASTART);
- LCD_IO_WriteData(Ymin);
- LCD_IO_WriteReg(ILI9328_HAEND);
- LCD_IO_WriteData(Ymax);
- LCD_IO_WriteReg(ILI9328_VASTART);
- LCD_IO_WriteData(Xmin);
- LCD_IO_WriteReg(ILI9328_VAEND);
- LCD_IO_WriteData(Xmax);
+ #if HAS_LCD_IO
+ #define IO_REG_DATA(R,D) do { LCD_IO_WriteReg(R); LCD_IO_WriteData(D); }while(0)
+ #else
+ #define IO_REG_DATA(R,D) do { u8g_WriteByte(u8g, dev, R); u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&D); }while(0)
+ #endif
- LCD_IO_WriteReg(ILI9328_HASET);
- LCD_IO_WriteData(Ymin);
- LCD_IO_WriteReg(ILI9328_VASET);
- LCD_IO_WriteData(Xmin);
+ #if NONE(LCD_USE_DMA_FSMC, LCD_USE_DMA_SPI)
+ u8g_SetAddress(u8g, dev, 0);
+ #endif
+ IO_REG_DATA(ILI9328_HASTART, Ymin);
+ IO_REG_DATA(ILI9328_HAEND, Ymax);
+ IO_REG_DATA(ILI9328_VASTART, Xmin);
+ IO_REG_DATA(ILI9328_VAEND, Xmax);
+
+ IO_REG_DATA(ILI9328_HASET, Ymin);
+ IO_REG_DATA(ILI9328_VASET, Xmin);
+
+ #if HAS_LCD_IO
LCD_IO_WriteReg(ILI9328_WRITE_RAM);
#else
- u8g_SetAddress(u8g, dev, 0);
-
- u8g_WriteByte(u8g, dev, ILI9328_HASTART);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
- u8g_WriteByte(u8g, dev, ILI9328_HAEND);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymax);
- u8g_WriteByte(u8g, dev, ILI9328_VASTART);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
- u8g_WriteByte(u8g, dev, ILI9328_VAEND);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmax);
-
- u8g_WriteByte(u8g, dev, ILI9328_HASET);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
- u8g_WriteByte(u8g, dev, ILI9328_VASET);
- u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
-
u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM);
u8g_SetAddress(u8g, dev, 1);
#endif
}
static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
- #ifdef LCD_USE_DMA_FSMC
+ #if HAS_LCD_IO
LCD_IO_WriteReg(ST7789V_CASET);
LCD_IO_WriteData((Xmin >> 8) & 0xFF);
LCD_IO_WriteData(Xmin & 0xFF);
@@ -227,7 +222,7 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
#define ESC_END 0xFFFF, 0x7FFF
#define ESC_FFFF 0xFFFF, 0xFFFF
-#ifdef LCD_USE_DMA_FSMC
+#if HAS_LCD_IO
void writeEscSequence(const uint16_t *sequence) {
uint16_t data;
for (;;) {
@@ -247,6 +242,7 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
}
}
}
+ #define WRITE_ESC_SEQUENCE(V) writeEscSequence(V)
#else
void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
uint16_t data;
@@ -271,6 +267,8 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
}
}
+ #define WRITE_ESC_SEQUENCE(V) writeEscSequence8(u8g, dev, V)
+
void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
uint16_t data;
u8g_SetAddress(u8g, dev, 0);
@@ -381,6 +379,30 @@ static const uint16_t ili9341_init[] = {
ESC_END
};
+static const uint16_t st9677_init[] = {
+ ESC_REG(0x0010), ESC_DELAY(120),
+ ESC_REG(0x0001), ESC_DELAY(120),
+ ESC_REG(0x0011), ESC_DELAY(120),
+ ESC_REG(0x00F0), 0x00C3,
+ ESC_REG(0x00F0), 0x0096,
+ ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x00E8, 0x0028),
+ ESC_REG(0x003A), 0x0055,
+ ESC_REG(0x00B4), 0x0001,
+ ESC_REG(0x00B7), 0x00C6,
+ ESC_REG(0x00E8), 0x0040, 0x008A, 0x0000, 0x0000, 0x0029, 0x0019, 0x00A5, 0x0033,
+ ESC_REG(0x00C1), 0x0006,
+ ESC_REG(0x00C2), 0x00A7,
+ ESC_REG(0x00C5), 0x0018,
+ ESC_REG(0x00E0), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0015, 0x002F, 0x0054, 0x0042, 0x003C, 0x0017, 0x0014, 0x0018, 0x001B,
+ ESC_REG(0x00E1), 0x00F0, 0x0009, 0x000B, 0x0006, 0x0004, 0x0003, 0x002D, 0x0043, 0x0042, 0x003B, 0x0016, 0x0014, 0x0017, 0x001B,
+ ESC_REG(0x00F0), 0x003C,
+ ESC_REG(0x00F0), 0x0069, ESC_DELAY(120),
+ ESC_REG(0x0029),
+ ESC_REG(0x0011),
+ ESC_DELAY(100),
+ ESC_END
+};
+
#if ENABLED(TOUCH_BUTTONS)
static const uint8_t buttonD[] = {
@@ -560,7 +582,7 @@ static const uint16_t ili9341_init[] = {
v = TFT_MARLINBG_COLOR;
LOOP_L_N(n, FSMC_UPSCALE) buffer[k++] = v;
}
- #ifdef LCD_USE_DMA_FSMC
+ #if HAS_LCD_IO
LOOP_S_L_N(n, 1, FSMC_UPSCALE)
for (uint16_t l = 0; l < length * (FSMC_UPSCALE); l++)
buffer[l + (length * (FSMC_UPSCALE) * n)] = buffer[l];
@@ -586,41 +608,39 @@ static uint8_t page;
uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
- #ifdef LCD_USE_DMA_FSMC
+
+ #if ENABLED(SPI_GRAPHICAL_TFT)
+ LCD_IO_Init(-1, -1);
+ #endif
+
+ #if HAS_LCD_IO
static uint16_t bufferA[WIDTH * sq(FSMC_UPSCALE)], bufferB[WIDTH * sq(FSMC_UPSCALE)];
uint16_t* buffer = &bufferA[0];
- bool allow_async = true;
+ bool allow_async = DISABLED(SPI_GRAPHICAL_TFT);
#else
uint16_t buffer[WIDTH*2]; // 16-bit RGB 565 pixel line buffer
#endif
+
switch (msg) {
case U8G_DEV_MSG_INIT:
dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id);
switch (lcd_id & 0xFFFF) {
case 0x8552: // ST7789V
- #ifdef LCD_USE_DMA_FSMC
- writeEscSequence(st7789v_init);
- #else
- writeEscSequence8(u8g, dev, st7789v_init);
- #endif
+ WRITE_ESC_SEQUENCE(st7789v_init);
setWindow = setWindow_st7789v;
break;
case 0x9328: // ILI9328
- #ifdef LCD_USE_DMA_FSMC
- writeEscSequence(ili9328_init);
- #else
- writeEscSequence16(u8g, dev, ili9328_init);
- #endif
+ WRITE_ESC_SEQUENCE(ili9328_init);
setWindow = setWindow_ili9328;
break;
case 0x9341: // ILI9341
case 0x8066: // Anycubic / TronXY TFTs (480x320)
- #ifdef LCD_USE_DMA_FSMC
- writeEscSequence(ili9341_init);
- #else
- writeEscSequence8(u8g, dev, ili9341_init);
- #endif
+ WRITE_ESC_SEQUENCE(ili9341_init);
+ setWindow = setWindow_st7789v;
+ break;
+ case 0x7796:
+ WRITE_ESC_SEQUENCE(TERN(HAS_LCD_IO, st9677_init, ili9341_init));
setWindow = setWindow_st7789v;
break;
case 0x0404: // No connected display on FSMC
@@ -630,10 +650,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
lcd_id = 0;
return 0;
default:
- if (lcd_id && 0xFF000000)
- setWindow = setWindow_st7789v;
- else
- setWindow = setWindow_ili9328;
+ setWindow = (lcd_id & 0xFF000000) ? setWindow_st7789v : setWindow_ili9328;
break;
}
@@ -644,7 +661,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
// Clear Screen
setWindow(u8g, dev, 0, 0, LCD_FULL_PIXEL_WIDTH - 1, LCD_FULL_PIXEL_HEIGHT - 1);
- #ifdef LCD_USE_DMA_FSMC
+ #if HAS_LCD_IO
LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, LCD_FULL_PIXEL_WIDTH * LCD_FULL_PIXEL_HEIGHT);
#else
memset2(buffer, TFT_MARLINBG_COLOR, 160);
@@ -681,7 +698,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
LOOP_L_N(y, PAGE_HEIGHT) {
uint32_t k = 0;
- #ifdef LCD_USE_DMA_FSMC
+ #if HAS_LCD_IO
buffer = (y & 1) ? bufferB : bufferA;
#endif
for (uint16_t i = 0; i < (uint32_t)pb->width; i++) {
@@ -689,7 +706,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR;
LOOP_L_N(n, FSMC_UPSCALE) buffer[k++] = c;
}
- #ifdef LCD_USE_DMA_FSMC
+ #if HAS_LCD_IO
LOOP_S_L_N(n, 1, FSMC_UPSCALE)
for (uint16_t l = 0; l < WIDTH * (FSMC_UPSCALE); l++)
buffer[l + WIDTH * (FSMC_UPSCALE) * n] = buffer[l];
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
index 1b6dd0b9d..5ebff37ed 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.h
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
@@ -182,12 +182,16 @@
#define U8G_CLASS U8GLIB_SH1106_128X64
#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS
-#elif ENABLED(FSMC_GRAPHICAL_TFT)
+#elif TFT_SCALED_DOGLCD
// Unspecified 320x240 TFT pre-initialized by built-in bootloader
#define U8G_CLASS U8GLIB_TFT_320X240_UPSCALE_FROM_128X64
- #define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN
+ #if ENABLED(FSMC_GRAPHICAL_TFT)
+ #define U8G_PARAM FSMC_CS_PIN, FSMC_RS_PIN
+ #else
+ #define U8G_PARAM -1, -1
+ #endif
#else
@@ -210,18 +214,18 @@
// LCD_FULL_PIXEL_WIDTH =
// LCD_PIXEL_OFFSET_X + (LCD_PIXEL_WIDTH * 2) + LCD_PIXEL_OFFSET_X
-#if ENABLED(FSMC_GRAPHICAL_TFT)
+#if TFT_SCALED_DOGLCD
#ifndef LCD_FULL_PIXEL_WIDTH
#define LCD_FULL_PIXEL_WIDTH 320
#endif
#ifndef LCD_PIXEL_OFFSET_X
- #define LCD_PIXEL_OFFSET_X 32
+ #define LCD_PIXEL_OFFSET_X 32
#endif
#ifndef LCD_FULL_PIXEL_HEIGHT
#define LCD_FULL_PIXEL_HEIGHT 240
#endif
#ifndef LCD_PIXEL_OFFSET_Y
- #define LCD_PIXEL_OFFSET_Y 32
+ #define LCD_PIXEL_OFFSET_Y 32
#endif
#endif
diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
index 0a733049b..5a672d29b 100644
--- a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
+++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
@@ -112,10 +112,10 @@
#if ENABLED(FSMC_GRAPHICAL_TFT)
#define FSMC_UPSCALE 3
- #define LCD_FULL_PIXEL_WIDTH 480
- #define LCD_PIXEL_OFFSET_X 48
- #define LCD_FULL_PIXEL_HEIGHT 320
- #define LCD_PIXEL_OFFSET_Y 48
+ #define LCD_FULL_PIXEL_WIDTH 480
+ #define LCD_PIXEL_OFFSET_X 48
+ #define LCD_FULL_PIXEL_HEIGHT 320
+ #define LCD_PIXEL_OFFSET_Y 48
#define LCD_RESET_PIN PF11
#define LCD_BACKLIGHT_PIN PD13
@@ -135,10 +135,19 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
- #define XPT2046_X_CALIBRATION -12316
- #define XPT2046_Y_CALIBRATION 8981
- #define XPT2046_X_OFFSET 340
- #define XPT2046_Y_OFFSET -20
+ #ifndef XPT2046_X_CALIBRATION
+ #define XPT2046_X_CALIBRATION -12316
+ #endif
+ #ifndef XPT2046_Y_CALIBRATION
+ #define XPT2046_Y_CALIBRATION 8981
+ #endif
+ #ifndef XPT2046_X_OFFSET
+ #define XPT2046_X_OFFSET 340
+ #endif
+ #ifndef XPT2046_Y_OFFSET
+ #define XPT2046_Y_OFFSET -20
+ #endif
+
#endif
#endif
diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
index 0fb3a9a87..be71d3f2c 100644
--- a/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
+++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
@@ -118,10 +118,10 @@
//
#if ENABLED(FSMC_GRAPHICAL_TFT)
#define FSMC_UPSCALE 3
- #define LCD_FULL_PIXEL_WIDTH 480
- #define LCD_PIXEL_OFFSET_X 48
- #define LCD_FULL_PIXEL_HEIGHT 320
- #define LCD_PIXEL_OFFSET_Y 48
+ #define LCD_FULL_PIXEL_WIDTH 480
+ #define LCD_PIXEL_OFFSET_X 48
+ #define LCD_FULL_PIXEL_HEIGHT 320
+ #define LCD_PIXEL_OFFSET_Y 48
#define LCD_RESET_PIN PF11
#define LCD_BACKLIGHT_PIN PD13
@@ -141,10 +141,18 @@
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
- #define XPT2046_X_CALIBRATION -12316
- #define XPT2046_Y_CALIBRATION 8981
- #define XPT2046_X_OFFSET 340
- #define XPT2046_Y_OFFSET -20
+ #ifndef XPT2046_X_CALIBRATION
+ #define XPT2046_X_CALIBRATION -12316
+ #endif
+ #ifndef XPT2046_Y_CALIBRATION
+ #define XPT2046_Y_CALIBRATION 8981
+ #endif
+ #ifndef XPT2046_X_OFFSET
+ #define XPT2046_X_OFFSET 340
+ #endif
+ #ifndef XPT2046_Y_OFFSET
+ #define XPT2046_Y_OFFSET -20
+ #endif
#endif
#endif
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h
index ee88962e1..afbcc8f32 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h
@@ -207,6 +207,13 @@
#define MT_DET_2_PIN PE6
#define MT_DET_PIN_INVERTING false
+#ifndef FIL_RUNOUT_PIN
+ #define FIL_RUNOUT_PIN MT_DET_1_PIN
+#endif
+#ifndef FIL_RUNOUT2_PIN
+ #define FIL_RUNOUT2_PIN MT_DET_2_PIN
+#endif
+
#define WIFI_IO0_PIN PC13
//
@@ -224,7 +231,9 @@
//
// LCD / Controller
//
-#define BEEPER_PIN PC5
+#ifndef BEEPER_PIN
+ #define BEEPER_PIN PC5
+#endif
/**
* Note: MKS Robin TFT screens use various TFT controllers.
@@ -250,7 +259,6 @@
#define BTN_EN1 PE8
#define BTN_EN2 PE11
- #define BEEPER_PIN PC5
#define BTN_ENC PE13
#elif ENABLED(TFT_LITTLE_VGL_UI)
@@ -269,16 +277,71 @@
#if HAS_SPI_LCD
- #define BEEPER_PIN PC5
- #define BTN_ENC PE13
- #define LCD_PINS_ENABLE PD13
- #define LCD_PINS_RS PC6
- #define BTN_EN1 PE8
- #define BTN_EN2 PE11
- #define LCD_BACKLIGHT_PIN -1
+ #if ENABLED(SPI_GRAPHICAL_TFT) // Emulated DOGM SPI
+ #define SPI_TFT_CS_PIN PD11
+ #define SPI_TFT_SCK_PIN PA5
+ #define SPI_TFT_MISO_PIN PA6
+ #define SPI_TFT_MOSI_PIN PA7
+ #define SPI_TFT_DC_PIN PD10
+ #define SPI_TFT_RST_PIN PC6
+
+ #define LCD_BACKLIGHT_PIN PD13
+
+ #define LCD_READ_ID 0xD3
+ #define LCD_USE_DMA_SPI
+
+ #define TOUCH_BUTTONS_HW_SPI
+ #define TOUCH_BUTTONS_HW_SPI_DEVICE 1
+
+ //#define TOUCH_BUTTONS
+ #if ENABLED(TOUCH_BUTTONS)
+ #define TOUCH_CS_PIN PE14 // SPI1_NSS
+ #define TOUCH_SCK_PIN PA5 // SPI1_SCK
+ #define TOUCH_MISO_PIN PA6 // SPI1_MISO
+ #define TOUCH_MOSI_PIN PA7 // SPI1_MOSI
+
+ #ifndef XPT2046_X_CALIBRATION
+ #define XPT2046_X_CALIBRATION -5481
+ #endif
+ #ifndef XPT2046_Y_CALIBRATION
+ #define XPT2046_Y_CALIBRATION 4000
+ #endif
+ #ifndef XPT2046_X_OFFSET
+ #define XPT2046_X_OFFSET 343
+ #endif
+ #ifndef XPT2046_Y_OFFSET
+ #define XPT2046_Y_OFFSET 0
+ #endif
+ #endif
+
+ #ifndef FSMC_UPSCALE
+ #define FSMC_UPSCALE 3
+ #endif
+ #ifndef LCD_FULL_PIXEL_WIDTH
+ #define LCD_FULL_PIXEL_WIDTH 480
+ #endif
+ #ifndef LCD_PIXEL_OFFSET_X
+ #define LCD_PIXEL_OFFSET_X 48
+ #endif
+ #ifndef LCD_FULL_PIXEL_HEIGHT
+ #define LCD_FULL_PIXEL_HEIGHT 320
+ #endif
+ #ifndef LCD_PIXEL_OFFSET_Y
+ #define LCD_PIXEL_OFFSET_Y 32
+ #endif
+
+ #define BTN_ENC PE13
+ #define BTN_EN1 PE8
+ #define BTN_EN2 PE11
+
+ #define LCD_PINS_ENABLE PD13
+ #define LCD_PINS_RS PC6
+
+ #elif ENABLED(MKS_MINI_12864)
+
+ // MKS MINI12864 and MKS LCD12864B
+ // If using MKS LCD12864A (Need to remove RPK2 resistor)
- // MKS MINI12864 and MKS LCD12864B; If using MKS LCD12864A (Need to remove RPK2 resistor)
- #if ENABLED(MKS_MINI_12864)
#define LCD_BACKLIGHT_PIN -1
#define LCD_RESET_PIN -1
#define DOGLCD_A0 PD11
@@ -320,3 +383,7 @@
#define W25QXX_MISO_PIN PB14
#define W25QXX_SCK_PIN PB13
#endif
+
+#if ENABLED(SPEAKER) && BEEPER_PIN == PC5
+ #error "MKS Robin nano default BEEPER_PIN is not a SPEAKER."
+#endif