From 3ea56ba4c72fb1e9c4bb4a896b8cf87361a48f4b Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Fri, 5 Mar 2021 04:30:52 -0600
Subject: [PATCH] Tweak tests, consolidate pins target validation (#21254)

---
 Marlin/src/pins/esp32/env_validate.h          | 26 ++++++++++++
 Marlin/src/pins/esp32/pins_E4D.h              |  6 +--
 Marlin/src/pins/esp32/pins_ESP32.h            |  4 +-
 Marlin/src/pins/esp32/pins_FYSETC_E4.h        |  6 +--
 Marlin/src/pins/esp32/pins_MRR_ESPA.h         |  6 +--
 Marlin/src/pins/esp32/pins_MRR_ESPE.h         |  6 +--
 Marlin/src/pins/lpc1768/env_validate.h        | 30 +++++++++++++
 Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h     |  4 +-
 Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h |  4 +-
 Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h  |  4 +-
 Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h   |  6 +--
 Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h |  8 +---
 Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h |  4 +-
 Marlin/src/pins/lpc1768/pins_MKS_SBASE.h      |  6 +--
 Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h     |  4 +-
 Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h   |  4 +-
 Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h |  4 +-
 Marlin/src/pins/lpc1769/env_validate.h        | 26 ++++++++++++
 Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h   |  4 +-
 Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h |  5 +--
 .../pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h   |  6 +--
 .../src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h  |  2 +
 .../pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h    |  2 +-
 .../src/pins/lpc1769/pins_COHESION3D_MINI.h   |  4 +-
 .../src/pins/lpc1769/pins_COHESION3D_REMIX.h  |  4 +-
 Marlin/src/pins/lpc1769/pins_FLY_CDY.h        |  4 +-
 Marlin/src/pins/lpc1769/pins_MKS_SGEN.h       |  6 +--
 Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h  |  4 +-
 Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h  |  4 +-
 Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h   |  4 +-
 Marlin/src/pins/mega/env_validate.h           | 30 +++++++++++++
 Marlin/src/pins/mega/pins_CHEAPTRONIC.h       |  4 +-
 Marlin/src/pins/mega/pins_CHEAPTRONICv2.h     |  4 +-
 Marlin/src/pins/mega/pins_CNCONTROLS_11.h     |  5 +--
 Marlin/src/pins/mega/pins_CNCONTROLS_12.h     |  5 +--
 Marlin/src/pins/mega/pins_CNCONTROLS_15.h     |  5 +--
 Marlin/src/pins/mega/pins_EINSTART-S.h        |  5 +--
 Marlin/src/pins/mega/pins_ELEFU_3.h           |  4 +-
 Marlin/src/pins/mega/pins_GT2560_REV_A.h      |  5 +--
 Marlin/src/pins/mega/pins_GT2560_V3.h         |  5 +--
 Marlin/src/pins/mega/pins_HJC2560C_REV2.h     |  4 +-
 Marlin/src/pins/mega/pins_INTAMSYS40.h        |  4 +-
 Marlin/src/pins/mega/pins_LEAPFROG.h          |  5 +--
 Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h |  4 +-
 Marlin/src/pins/mega/pins_MEGACONTROLLER.h    |  6 +--
 Marlin/src/pins/mega/pins_MEGATRONICS.h       |  4 +-
 Marlin/src/pins/mega/pins_MEGATRONICS_2.h     |  4 +-
 Marlin/src/pins/mega/pins_MEGATRONICS_3.h     |  4 +-
 Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h  |  5 +--
 Marlin/src/pins/mega/pins_OVERLORD.h          |  6 +--
 Marlin/src/pins/mega/pins_PICA.h              |  6 +--
 Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h    |  4 +-
 Marlin/src/pins/pins.h                        |  2 +-
 Marlin/src/pins/pinsDebug.h                   |  4 +-
 Marlin/src/pins/rambo/env_validate.h          | 26 ++++++++++++
 Marlin/src/pins/rambo/pins_EINSY_RAMBO.h      |  4 +-
 Marlin/src/pins/rambo/pins_EINSY_RETRO.h      |  4 +-
 Marlin/src/pins/rambo/pins_MINIRAMBO.h        |  4 +-
 Marlin/src/pins/rambo/pins_RAMBO.h            |  4 +-
 Marlin/src/pins/rambo/pins_SCOOVO_X9H.h       |  4 +-
 Marlin/src/pins/ramps/env_validate.h          | 35 ++++++++++++++++
 Marlin/src/pins/ramps/pins_AZTEEG_X3.h        |  7 ++--
 Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h    |  7 ++--
 Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h   |  5 +--
 .../src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h  |  5 +--
 Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h   |  7 ++--
 .../src/pins/ramps/pins_FORMBOT_TREX2PLUS.h   |  7 ++--
 Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h    |  7 ++--
 Marlin/src/pins/ramps/pins_K8800.h            |  4 +-
 Marlin/src/pins/ramps/pins_LONGER3D_LKx_PRO.h | 10 ++---
 Marlin/src/pins/ramps/pins_RAMPS.h            | 13 +-----
 Marlin/src/pins/ramps/pins_RAMPS_OLD.h        |  4 +-
 Marlin/src/pins/ramps/pins_RAMPS_PLUS.h       |  4 +-
 Marlin/src/pins/ramps/pins_RAMPS_S_12.h       |  7 +---
 Marlin/src/pins/ramps/pins_RUMBA.h            |  7 ++--
 Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h   |  7 ++--
 Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h    |  7 ++--
 Marlin/src/pins/ramps/pins_TT_OSCAR.h         |  4 +-
 Marlin/src/pins/ramps/pins_ULTIMAIN_2.h       |  5 +--
 Marlin/src/pins/ramps/pins_ULTIMAKER.h        |  4 +-
 Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h    |  4 +-
 Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h  |  7 ++--
 Marlin/src/pins/sam/env_validate.h            | 33 +++++++++++++++
 Marlin/src/pins/sam/pins_ADSK.h               |  6 +--
 Marlin/src/pins/sam/pins_ALLIGATOR_R2.h       |  4 +-
 Marlin/src/pins/sam/pins_CNCONTROLS_15D.h     |  4 +-
 Marlin/src/pins/sam/pins_DUE3DOM.h            |  4 +-
 Marlin/src/pins/sam/pins_DUE3DOM_MINI.h       |  4 +-
 Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h     |  4 +-
 Marlin/src/pins/sam/pins_RADDS.h              |  4 +-
 Marlin/src/pins/sam/pins_RAMPS4DUE.h          |  7 +---
 Marlin/src/pins/sam/pins_RAMPS_DUO.h          |  7 +---
 Marlin/src/pins/sam/pins_RAMPS_FD_V1.h        |  4 +-
 Marlin/src/pins/sam/pins_RAMPS_SMART.h        |  6 +--
 Marlin/src/pins/sam/pins_RURAMPS4D_11.h       |  4 +-
 Marlin/src/pins/sam/pins_RURAMPS4D_13.h       |  4 +-
 Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h   |  4 +-
 Marlin/src/pins/sanguino/env_validate.h       | 42 +++++++++++++++++++
 .../src/pins/sanguino/pins_GEN3_MONOLITHIC.h  |  5 +--
 Marlin/src/pins/sanguino/pins_GEN3_PLUS.h     |  5 +--
 Marlin/src/pins/sanguino/pins_GEN6.h          |  5 +--
 Marlin/src/pins/sanguino/pins_GEN7_12.h       |  5 +--
 Marlin/src/pins/sanguino/pins_GEN7_14.h       |  5 +--
 Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h   |  5 +--
 Marlin/src/pins/sanguino/pins_OMCA_A.h        |  2 +-
 .../src/pins/sanguino/pins_SANGUINOLOLU_11.h  |  5 +--
 Marlin/src/pins/sanguino/pins_SETHI.h         |  5 +--
 Marlin/src/pins/sanguino/pins_ZMIB_V2.h       |  5 +--
 Marlin/src/pins/stm32f1/env_validate.h        | 26 ++++++++++++
 Marlin/src/pins/stm32f1/pins_BEAST.h          |  4 +-
 Marlin/src/pins/stm32f1/pins_BTT_SKR_CR6.h    |  4 +-
 Marlin/src/pins/stm32f1/pins_CHITU3D.h        |  4 +-
 Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h     |  4 +-
 Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h     |  4 +-
 Marlin/src/pins/stm32f1/pins_CREALITY_V4.h    |  6 +--
 Marlin/src/pins/stm32f1/pins_CREALITY_V4210.h |  6 +--
 Marlin/src/pins/stm32f1/pins_CREALITY_V45x.h  |  4 +-
 Marlin/src/pins/stm32f1/pins_FLY_MINI.h       |  4 +-
 Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h  |  4 +-
 Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h |  4 +-
 .../pins/stm32f1/pins_FYSETC_CHEETAH_V12.h    |  4 +-
 Marlin/src/pins/stm32f1/pins_GTM32_MINI.h     |  4 +-
 Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h |  4 +-
 Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h   |  4 +-
 Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h    |  4 +-
 .../src/pins/stm32f1/pins_JGAURORA_A5S_A1.h   |  6 +--
 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h  |  6 +--
 .../pins/stm32f1/pins_MKS_ROBIN_E3_common.h   |  4 +-
 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h |  6 +--
 .../src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h   |  6 +--
 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h |  6 +--
 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h  |  6 +--
 Marlin/src/pins/stm32f1/pins_STM32F1R.h       |  4 +-
 Marlin/src/pins/stm32f1/pins_STM3R_MINI.h     |  4 +-
 Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h |  6 +--
 Marlin/src/pins/stm32f4/env_validate.h        | 28 +++++++++++++
 Marlin/src/pins/stm32f4/pins_ANET_ET4.h       |  8 ++--
 Marlin/src/pins/stm32f4/pins_ARMED.h          |  6 +--
 .../src/pins/stm32f4/pins_BLACK_STM32F407VE.h |  7 ++--
 .../src/pins/stm32f4/pins_BTT_BTT002_V1_0.h   |  6 +--
 Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h   |  6 +--
 .../pins/stm32f4/pins_BTT_SKR_PRO_common.h    |  4 +-
 Marlin/src/pins/stm32f4/pins_FLYF407ZG.h      |  7 ++--
 .../pins/stm32f4/pins_FYSETC_CHEETAH_V20.h    |  4 +-
 Marlin/src/pins/stm32f4/pins_FYSETC_S6.h      |  6 +--
 Marlin/src/pins/stm32f4/pins_LERDGE_K.h       |  7 ++--
 Marlin/src/pins/stm32f4/pins_LERDGE_S.h       |  7 ++--
 Marlin/src/pins/stm32f4/pins_LERDGE_X.h       |  7 ++--
 Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h     |  6 +--
 .../src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h |  7 ++--
 .../src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h  |  7 ++--
 Marlin/src/pins/stm32f4/pins_RUMBA32_common.h |  6 +--
 .../src/pins/stm32f4/pins_STEVAL_3DP001V1.h   |  4 +-
 Marlin/src/pins/stm32f4/pins_VAKE403D.h       |  7 ++--
 Marlin/src/pins/teensy2/env_validate.h        | 28 +++++++++++++
 Marlin/src/pins/teensy2/pins_5DPRINT.h        |  4 +-
 Marlin/src/pins/teensy2/pins_BRAINWAVE.h      |  2 +-
 Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h  |  4 +-
 Marlin/src/pins/teensy2/pins_PRINTRBOARD.h    |  4 +-
 .../src/pins/teensy2/pins_PRINTRBOARD_REVF.h  |  4 +-
 Marlin/src/pins/teensy2/pins_SAV_MKI.h        |  4 +-
 Marlin/src/pins/teensy2/pins_TEENSY2.h        |  4 +-
 Marlin/src/pins/teensy2/pins_TEENSYLU.h       |  3 ++
 buildroot/bin/mftest                          | 11 +++--
 buildroot/{tests => bin}/run_tests            | 16 +++----
 .../scripts/common-dependencies-post.py       | 16 -------
 .../PlatformIO/scripts/preflight-checks.py    |  3 +-
 buildroot/tests/{ARMED-tests => ARMED}        |  0
 .../{BIGTREE_BTT002-tests => BIGTREE_BTT002}  |  0
 ...IGTREE_GTR_V1_0-tests => BIGTREE_GTR_V1_0} |  0
 ...tests => BIGTREE_GTR_V1_0_usb_flash_drive} |  0
 ...{BIGTREE_SKR_PRO-tests => BIGTREE_SKR_PRO} |  0
 buildroot/tests/{DUE-tests => DUE}            |  0
 .../tests/{DUE_archim-tests => DUE_archim}    |  0
 .../tests/{FLYF407ZG-tests => FLYF407ZG}      |  0
 .../tests/{FYSETC_F6-tests => FYSETC_F6}      |  0
 .../tests/{FYSETC_S6-tests => FYSETC_S6}      |  0
 buildroot/tests/{LERDGEX-tests => LERDGEX}    |  0
 buildroot/tests/{LPC1768-tests => LPC1768}    |  0
 buildroot/tests/{LPC1769-tests => LPC1769}    |  0
 .../{NUCLEO_F767ZI-tests => NUCLEO_F767ZI}    |  0
 .../tests/{REMRAM_V1-tests => REMRAM_V1}      |  0
 ...entral_m4-tests => SAMD51_grandcentral_m4} |  0
 ...F070CB_malyan-tests => STM32F070CB_malyan} |  0
 ...F070RB_malyan-tests => STM32F070RB_malyan} |  0
 ...F103CB_malyan-tests => STM32F103CB_malyan} |  0
 ...{STM32F103RC_btt-tests => STM32F103RC_btt} |  0
 ...03RC_btt_USB-tests => STM32F103RC_btt_USB} |  0
 ...F103RC_fysetc-tests => STM32F103RC_fysetc} |  0
 ...TM32F103RC_meeb-tests => STM32F103RC_meeb} |  0
 .../tests/{STM32F103RE-tests => STM32F103RE}  |  0
 ..._creality-tests => STM32F103RET6_creality} |  0
 ...{STM32F103RE_btt-tests => STM32F103RE_btt} |  0
 ...03RE_btt_USB-tests => STM32F103RE_btt_USB} |  0
 ...F103VE_longer-tests => STM32F103VE_longer} |  0
 ...F401VE_STEVAL-tests => STM32F401VE_STEVAL} |  0
 ...32F407VE_black-tests => STM32F407VE_black} |  0
 ...{at90usb1286_cdc-tests => at90usb1286_cdc} |  0
 ...{at90usb1286_dfu-tests => at90usb1286_dfu} |  0
 buildroot/tests/{esp32-tests => esp32}        |  0
 ...{jgaurora_a5s_a1-tests => jgaurora_a5s_a1} |  0
 .../{linux_native-tests => linux_native}      |  0
 .../tests/{malyan_M300-tests => malyan_M300}  |  0
 buildroot/tests/{mega1280-tests => mega1280}  |  0
 buildroot/tests/{mega2560-tests => mega2560}  |  0
 .../tests/{mks_robin-tests => mks_robin}      |  0
 .../{mks_robin_lite-tests => mks_robin_lite}  |  0
 .../{mks_robin_mini-tests => mks_robin_mini}  |  0
 ...ks_robin_nano35-tests => mks_robin_nano35} |  0
 ...o35_stm32-tests => mks_robin_nano35_stm32} |  0
 .../{mks_robin_pro-tests => mks_robin_pro}    |  0
 ...{mks_robin_stm32-tests => mks_robin_stm32} |  0
 buildroot/tests/{rambo-tests => rambo}        |  0
 buildroot/tests/{rumba32-tests => rumba32}    |  0
 .../{sanguino1284p-tests => sanguino1284p}    |  0
 .../{sanguino644p-tests => sanguino644p}      |  0
 buildroot/tests/{teensy31-tests => teensy31}  |  0
 buildroot/tests/{teensy35-tests => teensy35}  |  0
 buildroot/tests/{teensy41-tests => teensy41}  |  0
 platformio.ini                                |  7 +++-
 220 files changed, 631 insertions(+), 509 deletions(-)
 create mode 100644 Marlin/src/pins/esp32/env_validate.h
 create mode 100644 Marlin/src/pins/lpc1768/env_validate.h
 create mode 100644 Marlin/src/pins/lpc1769/env_validate.h
 create mode 100644 Marlin/src/pins/mega/env_validate.h
 create mode 100644 Marlin/src/pins/rambo/env_validate.h
 create mode 100644 Marlin/src/pins/ramps/env_validate.h
 create mode 100644 Marlin/src/pins/sam/env_validate.h
 create mode 100644 Marlin/src/pins/sanguino/env_validate.h
 create mode 100644 Marlin/src/pins/stm32f1/env_validate.h
 create mode 100644 Marlin/src/pins/stm32f4/env_validate.h
 create mode 100644 Marlin/src/pins/teensy2/env_validate.h
 rename buildroot/{tests => bin}/run_tests (79%)
 delete mode 100644 buildroot/share/PlatformIO/scripts/common-dependencies-post.py
 rename buildroot/tests/{ARMED-tests => ARMED} (100%)
 rename buildroot/tests/{BIGTREE_BTT002-tests => BIGTREE_BTT002} (100%)
 rename buildroot/tests/{BIGTREE_GTR_V1_0-tests => BIGTREE_GTR_V1_0} (100%)
 rename buildroot/tests/{BIGTREE_GTR_V1_0_usb_flash_drive-tests => BIGTREE_GTR_V1_0_usb_flash_drive} (100%)
 rename buildroot/tests/{BIGTREE_SKR_PRO-tests => BIGTREE_SKR_PRO} (100%)
 rename buildroot/tests/{DUE-tests => DUE} (100%)
 rename buildroot/tests/{DUE_archim-tests => DUE_archim} (100%)
 rename buildroot/tests/{FLYF407ZG-tests => FLYF407ZG} (100%)
 rename buildroot/tests/{FYSETC_F6-tests => FYSETC_F6} (100%)
 rename buildroot/tests/{FYSETC_S6-tests => FYSETC_S6} (100%)
 rename buildroot/tests/{LERDGEX-tests => LERDGEX} (100%)
 rename buildroot/tests/{LPC1768-tests => LPC1768} (100%)
 rename buildroot/tests/{LPC1769-tests => LPC1769} (100%)
 rename buildroot/tests/{NUCLEO_F767ZI-tests => NUCLEO_F767ZI} (100%)
 rename buildroot/tests/{REMRAM_V1-tests => REMRAM_V1} (100%)
 rename buildroot/tests/{SAMD51_grandcentral_m4-tests => SAMD51_grandcentral_m4} (100%)
 rename buildroot/tests/{STM32F070CB_malyan-tests => STM32F070CB_malyan} (100%)
 rename buildroot/tests/{STM32F070RB_malyan-tests => STM32F070RB_malyan} (100%)
 rename buildroot/tests/{STM32F103CB_malyan-tests => STM32F103CB_malyan} (100%)
 rename buildroot/tests/{STM32F103RC_btt-tests => STM32F103RC_btt} (100%)
 rename buildroot/tests/{STM32F103RC_btt_USB-tests => STM32F103RC_btt_USB} (100%)
 rename buildroot/tests/{STM32F103RC_fysetc-tests => STM32F103RC_fysetc} (100%)
 rename buildroot/tests/{STM32F103RC_meeb-tests => STM32F103RC_meeb} (100%)
 rename buildroot/tests/{STM32F103RE-tests => STM32F103RE} (100%)
 rename buildroot/tests/{STM32F103RET6_creality-tests => STM32F103RET6_creality} (100%)
 rename buildroot/tests/{STM32F103RE_btt-tests => STM32F103RE_btt} (100%)
 rename buildroot/tests/{STM32F103RE_btt_USB-tests => STM32F103RE_btt_USB} (100%)
 rename buildroot/tests/{STM32F103VE_longer-tests => STM32F103VE_longer} (100%)
 rename buildroot/tests/{STM32F401VE_STEVAL-tests => STM32F401VE_STEVAL} (100%)
 rename buildroot/tests/{STM32F407VE_black-tests => STM32F407VE_black} (100%)
 rename buildroot/tests/{at90usb1286_cdc-tests => at90usb1286_cdc} (100%)
 rename buildroot/tests/{at90usb1286_dfu-tests => at90usb1286_dfu} (100%)
 rename buildroot/tests/{esp32-tests => esp32} (100%)
 rename buildroot/tests/{jgaurora_a5s_a1-tests => jgaurora_a5s_a1} (100%)
 rename buildroot/tests/{linux_native-tests => linux_native} (100%)
 rename buildroot/tests/{malyan_M300-tests => malyan_M300} (100%)
 rename buildroot/tests/{mega1280-tests => mega1280} (100%)
 rename buildroot/tests/{mega2560-tests => mega2560} (100%)
 rename buildroot/tests/{mks_robin-tests => mks_robin} (100%)
 rename buildroot/tests/{mks_robin_lite-tests => mks_robin_lite} (100%)
 rename buildroot/tests/{mks_robin_mini-tests => mks_robin_mini} (100%)
 rename buildroot/tests/{mks_robin_nano35-tests => mks_robin_nano35} (100%)
 rename buildroot/tests/{mks_robin_nano35_stm32-tests => mks_robin_nano35_stm32} (100%)
 rename buildroot/tests/{mks_robin_pro-tests => mks_robin_pro} (100%)
 rename buildroot/tests/{mks_robin_stm32-tests => mks_robin_stm32} (100%)
 rename buildroot/tests/{rambo-tests => rambo} (100%)
 rename buildroot/tests/{rumba32-tests => rumba32} (100%)
 rename buildroot/tests/{sanguino1284p-tests => sanguino1284p} (100%)
 rename buildroot/tests/{sanguino644p-tests => sanguino644p} (100%)
 rename buildroot/tests/{teensy31-tests => teensy31} (100%)
 rename buildroot/tests/{teensy35-tests => teensy35} (100%)
 rename buildroot/tests/{teensy41-tests => teensy41} (100%)

diff --git a/Marlin/src/pins/esp32/env_validate.h b/Marlin/src/pins/esp32/env_validate.h
new file mode 100644
index 00000000000..ce14c33414a
--- /dev/null
+++ b/Marlin/src/pins/esp32/env_validate.h
@@ -0,0 +1,26 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(ARDUINO_ARCH_ESP32)
+  #error "Oops! Select an ESP32 board in 'Tools > Board.'"
+#endif
diff --git a/Marlin/src/pins/esp32/pins_E4D.h b/Marlin/src/pins/esp32/pins_E4D.h
index 4a5a2bf9b0a..9e28af2190a 100644
--- a/Marlin/src/pins/esp32/pins_E4D.h
+++ b/Marlin/src/pins/esp32/pins_E4D.h
@@ -27,9 +27,9 @@
  * for more info check https://atbox.tech/ and join to Facebook page E4d@box.
  */
 
-#if NOT_TARGET(ARDUINO_ARCH_ESP32)
-  #error "Oops! Select an ESP32 board in 'Tools > Board.'"
-#elif EXTRUDERS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if EXTRUDERS > 1 || E_STEPPERS > 1
   #error "E4d@box only supports one E Stepper. Comment out this line to continue."
 #elif HOTENDS > 1
   #error "E4d@box only supports one hotend / E-stepper. Comment out this line to continue."
diff --git a/Marlin/src/pins/esp32/pins_ESP32.h b/Marlin/src/pins/esp32/pins_ESP32.h
index d54a92b9c4e..6578770ba0e 100644
--- a/Marlin/src/pins/esp32/pins_ESP32.h
+++ b/Marlin/src/pins/esp32/pins_ESP32.h
@@ -25,9 +25,7 @@
  * Espressif ESP32 (Tensilica Xtensa LX6) pin assignments
  */
 
-#if NOT_TARGET(ARDUINO_ARCH_ESP32)
-  "Oops! Select an ESP32 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Espressif ESP32"
 
diff --git a/Marlin/src/pins/esp32/pins_FYSETC_E4.h b/Marlin/src/pins/esp32/pins_FYSETC_E4.h
index 50a8587b1ec..7dd7f94ae56 100644
--- a/Marlin/src/pins/esp32/pins_FYSETC_E4.h
+++ b/Marlin/src/pins/esp32/pins_FYSETC_E4.h
@@ -27,9 +27,9 @@
  * Supports 4 stepper drivers, heated bed, single hotend.
  */
 
-#ifndef ARDUINO_ARCH_ESP32
-  #error "Oops! Select an ESP32 board in 'Tools > Board.'"
-#elif EXTRUDERS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if EXTRUDERS > 1 || E_STEPPERS > 1
   #error "FYSETC E4 only supports one E Stepper. Comment out this line to continue."
 #elif HOTENDS > 1
   #error "FYSETC E4 only supports one hotend / E-stepper. Comment out this line to continue."
diff --git a/Marlin/src/pins/esp32/pins_MRR_ESPA.h b/Marlin/src/pins/esp32/pins_MRR_ESPA.h
index fe67f753720..38f43b53d32 100644
--- a/Marlin/src/pins/esp32/pins_MRR_ESPA.h
+++ b/Marlin/src/pins/esp32/pins_MRR_ESPA.h
@@ -27,9 +27,9 @@
  * Supports 4 stepper drivers, heated bed, single hotend.
  */
 
-#if NOT_TARGET(ARDUINO_ARCH_ESP32)
-  #error "Oops! Select an ESP32 board in 'Tools > Board.'"
-#elif EXTRUDERS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if EXTRUDERS > 1 || E_STEPPERS > 1
   #error "MRR ESPA only supports one E Stepper. Comment out this line to continue."
 #elif HOTENDS > 1
   #error "MRR ESPA only supports one hotend / E-stepper. Comment out this line to continue."
diff --git a/Marlin/src/pins/esp32/pins_MRR_ESPE.h b/Marlin/src/pins/esp32/pins_MRR_ESPE.h
index 3f9a6a0af3a..f156efd2e8a 100644
--- a/Marlin/src/pins/esp32/pins_MRR_ESPE.h
+++ b/Marlin/src/pins/esp32/pins_MRR_ESPE.h
@@ -28,9 +28,9 @@
  * single hotend, and LCD controller.
  */
 
-#if NOT_TARGET(ARDUINO_ARCH_ESP32)
-  #error "Oops! Select an ESP32 board in 'Tools > Board.'"
-#elif EXTRUDERS > 2 || E_STEPPERS > 2
+#include "env_validate.h"
+
+#if EXTRUDERS > 2 || E_STEPPERS > 2
   #error "MRR ESPE only supports two E Steppers. Comment out this line to continue."
 #elif HOTENDS > 1
   #error "MRR ESPE only supports one hotend / E-stepper. Comment out this line to continue."
diff --git a/Marlin/src/pins/lpc1768/env_validate.h b/Marlin/src/pins/lpc1768/env_validate.h
new file mode 100644
index 00000000000..adb3ea938dc
--- /dev/null
+++ b/Marlin/src/pins/lpc1768/env_validate.h
@@ -0,0 +1,30 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if ENABLED(REQUIRE_LPC1769) && NOT_TARGET(MCU_LPC1769)
+  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
+#elif DISABLED(REQUIRE_LPC1769) && NOT_TARGET(MCU_LPC1768)
+  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
+#endif
+
+#undef REQUIRE_LPC1769
diff --git a/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h b/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h
index 70682ad1518..0760eee0abe 100644
--- a/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h
+++ b/Marlin/src/pins/lpc1768/pins_AZSMZ_MINI.h
@@ -25,9 +25,7 @@
  * AZSMZ MINI pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "AZSMZ MINI"
 
diff --git a/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h b/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h
index 5ac119f398b..10a610ff95f 100644
--- a/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h
+++ b/Marlin/src/pins/lpc1768/pins_BIQU_B300_V1.0.h
@@ -29,9 +29,7 @@
  *  BOARD_BIQU_BQ111_A4 (Hotend, Fan, Bed)
  */
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "BIQU Thunder B300 V1.0"
diff --git a/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h b/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h
index 3b2137b400f..f94381e13a4 100644
--- a/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h
+++ b/Marlin/src/pins/lpc1768/pins_BIQU_BQ111_A4.h
@@ -29,9 +29,7 @@
  *  BOARD_BIQU_BQ111_A4 (Hotend, Fan, Bed)
  */
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "BIQU BQ111-A4"
 
diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h
index c7555a779d8..c555ef7863e 100644
--- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h
+++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_V1_4.h
@@ -21,14 +21,12 @@
  */
 #pragma once
 
+#include "env_validate.h"
+
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "BTT SKR V1.4"
 #endif
 
-#ifndef BOARD_CUSTOM_BUILD_FLAGS
-  #define BOARD_CUSTOM_BUILD_FLAGS -DLPC_PINCFG_UART3_P4_28
-#endif
-
 //
 // SD Connection
 //
diff --git a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h
index 82799c1cd0f..98e4f8ee267 100644
--- a/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h
+++ b/Marlin/src/pins/lpc1768/pins_BTT_SKR_common.h
@@ -21,13 +21,7 @@
  */
 #pragma once
 
-#if ENABLED(SKR_HAS_LPC1769)
-  #if NOT_TARGET(MCU_LPC1769)
-    #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-  #endif
-#elif NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 // If you have the Big tree tech driver expansion module, enable HAS_BTT_EXP_MOT
 // https://github.com/bigtreetech/BTT-Expansion-module/tree/master/BTT%20EXP-MOT
diff --git a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h
index 1970c0c479f..0df8b10292f 100644
--- a/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h
+++ b/Marlin/src/pins/lpc1768/pins_GMARSH_X6_REV1.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "GMARSH X6 REV1"
 
diff --git a/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h b/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h
index fbddc66e7ce..71d7ad30370 100644
--- a/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h
+++ b/Marlin/src/pins/lpc1768/pins_MKS_SBASE.h
@@ -25,11 +25,7 @@
  * MKS SBASE pin assignments
  */
 
-#if defined(MKS_HAS_LPC1769) && NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#elif !defined(MKS_HAS_LPC1769) && NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME   "MKS SBASE"
diff --git a/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h b/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h
index b919ecad85a..40fac4e7fa3 100644
--- a/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h
+++ b/Marlin/src/pins/lpc1768/pins_MKS_SGEN_L.h
@@ -25,9 +25,7 @@
  * MKS SGEN-L pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "MKS SGen-L"
 #define BOARD_WEBSITE_URL "github.com/makerbase-mks/MKS-SGEN_L"
diff --git a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h
index 65840308ca9..83fcf36e4e1 100644
--- a/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h
+++ b/Marlin/src/pins/lpc1768/pins_RAMPS_RE_ARM.h
@@ -35,9 +35,7 @@
 
 // Numbers in parentheses () are the corresponding mega2560 pin numbers
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Re-ARM RAMPS 1.4"
 
diff --git a/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h b/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h
index 700e79de9cc..29fe3b528c0 100644
--- a/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h
+++ b/Marlin/src/pins/lpc1768/pins_SELENA_COMPACT.h
@@ -25,9 +25,7 @@
  * Selena Compact pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1768)
-  #error "Oops! Make sure you have the LPC1768 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "Selena Compact"
 #define BOARD_WEBSITE_URL "github.com/Ales2-k/Selena"
diff --git a/Marlin/src/pins/lpc1769/env_validate.h b/Marlin/src/pins/lpc1769/env_validate.h
new file mode 100644
index 00000000000..2e2b63d5203
--- /dev/null
+++ b/Marlin/src/pins/lpc1769/env_validate.h
@@ -0,0 +1,26 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(MCU_LPC1769)
+  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
+#endif
diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h
index adf9085262a..7ce78ad2832 100644
--- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h
+++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_GT.h
@@ -25,9 +25,7 @@
  * Azteeg X5 GT pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "Azteeg X5 GT"
 #define BOARD_WEBSITE_URL "tinyurl.com/yx8tdqa3"
diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h
index fdd64878fbc..80a91d2cbc4 100644
--- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h
+++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI.h
@@ -24,10 +24,7 @@
 /**
  * Azteeg X5 MINI pin assignments
  */
-
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Azteeg X5 MINI"
diff --git a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h
index 99ff0fd25a1..086bacbac0f 100644
--- a/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h
+++ b/Marlin/src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h
@@ -22,12 +22,10 @@
 #pragma once
 
 /**
- * Azteeg X5 MINI pin assignments
+ * Azteeg X5 MINI WIFI pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Azteeg X5 MINI WIFI"
 
diff --git a/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h
index 7c63ba20beb..2e1e02f9913 100644
--- a/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h
+++ b/Marlin/src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h
@@ -21,6 +21,8 @@
  */
 #pragma once
 
+#include "env_validate.h"
+
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "BTT SKR E3 Turbo"
 #endif
diff --git a/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h b/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h
index a751286e3a8..5af1dfec3f6 100644
--- a/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h
+++ b/Marlin/src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h
@@ -22,9 +22,9 @@
 #pragma once
 
 #define BOARD_INFO_NAME "BTT SKR V1.4 TURBO"
-#define SKR_HAS_LPC1769
 
 //
 // Include SKR 1.4 pins
 //
+#define REQUIRE_LPC1769
 #include "../lpc1768/pins_BTT_SKR_V1_4.h"
diff --git a/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h b/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h
index d66ffbe4e5d..237dfaec36f 100644
--- a/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h
+++ b/Marlin/src/pins/lpc1769/pins_COHESION3D_MINI.h
@@ -25,9 +25,7 @@
  * Cohesion3D Mini pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Cohesion3D Mini"
 
diff --git a/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h b/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h
index edf13cee298..57b45214535 100644
--- a/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h
+++ b/Marlin/src/pins/lpc1769/pins_COHESION3D_REMIX.h
@@ -25,9 +25,7 @@
  * Cohesion3D ReMix pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Cohesion3D ReMix"
 
diff --git a/Marlin/src/pins/lpc1769/pins_FLY_CDY.h b/Marlin/src/pins/lpc1769/pins_FLY_CDY.h
index 3982d76a012..b90443403cc 100644
--- a/Marlin/src/pins/lpc1769/pins_FLY_CDY.h
+++ b/Marlin/src/pins/lpc1769/pins_FLY_CDY.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "FLY-CDY"
 #define BOARD_WEBSITE_URL "github.com/FLYmaker/FLY-CDY"
diff --git a/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h b/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h
index d67549997be..ddfee63cd08 100644
--- a/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h
+++ b/Marlin/src/pins/lpc1769/pins_MKS_SGEN.h
@@ -28,14 +28,10 @@
  * https://github.com/makerbase-mks/MKS-SGen/blob/master/Hardware/MKS%20SGEN%20V1.0_001/MKS%20SGEN%20V1.0_001%20PIN.pdf
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
-
 #define BOARD_INFO_NAME   "MKS SGen"
 #define BOARD_WEBSITE_URL "github.com/makerbase-mks/MKS-SGEN"
 
-#define MKS_HAS_LPC1769
+#define REQUIRE_LPC1769
 #include "../lpc1768/pins_MKS_SBASE.h"
 
 #if HAS_TMC_UART
diff --git a/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h b/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h
index abf5be3c899..a6160794039 100644
--- a/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h
+++ b/Marlin/src/pins/lpc1769/pins_MKS_SGEN_L_V2.h
@@ -25,9 +25,7 @@
  * MKS SGen pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "MKS SGEN_L V2"
 #define BOARD_WEBSITE_URL "github.com/makerbase-mks"
diff --git a/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h b/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h
index c5ce3f87958..f7bc9602d79 100644
--- a/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h
+++ b/Marlin/src/pins/lpc1769/pins_SMOOTHIEBOARD.h
@@ -25,9 +25,7 @@
  * Smoothieboard pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "Smoothieboard"
 #define BOARD_WEBSITE_URL "smoothieware.org/smoothieboard"
diff --git a/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h b/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h
index d4f3e5bc21b..4d725bc7d16 100644
--- a/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h
+++ b/Marlin/src/pins/lpc1769/pins_TH3D_EZBOARD.h
@@ -25,9 +25,7 @@
  * TH3D EZBoard pin assignments
  */
 
-#if NOT_TARGET(MCU_LPC1769)
-  #error "Oops! Make sure you have the LPC1769 environment selected in your IDE."
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "TH3D EZBoard"
 #define BOARD_WEBSITE_URL "th3dstudio.com"
diff --git a/Marlin/src/pins/mega/env_validate.h b/Marlin/src/pins/mega/env_validate.h
new file mode 100644
index 00000000000..fe4a39a612e
--- /dev/null
+++ b/Marlin/src/pins/mega/env_validate.h
@@ -0,0 +1,30 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if ENABLED(ALLOW_MEGA1280) && NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560 or 1280' in 'Tools > Board.'"
+#elif NOT_TARGET(__AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
+#endif
+
+#undef ALLOW_MEGA1280
diff --git a/Marlin/src/pins/mega/pins_CHEAPTRONIC.h b/Marlin/src/pins/mega/pins_CHEAPTRONIC.h
index 98427d9e592..8bcb263bc1f 100644
--- a/Marlin/src/pins/mega/pins_CHEAPTRONIC.h
+++ b/Marlin/src/pins/mega/pins_CHEAPTRONIC.h
@@ -25,9 +25,7 @@
  * Cheaptronic v1.0 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Cheaptronic v1.0"
 //
diff --git a/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h b/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h
index 3f18bc8bbea..01438975b97 100644
--- a/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h
+++ b/Marlin/src/pins/mega/pins_CHEAPTRONICv2.h
@@ -27,9 +27,7 @@
  *          www.reprapobchod.cz
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Cheaptronic v2.0"
 
diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_11.h b/Marlin/src/pins/mega/pins_CNCONTROLS_11.h
index f80e6144ce1..6f9e5e8e6c4 100644
--- a/Marlin/src/pins/mega/pins_CNCONTROLS_11.h
+++ b/Marlin/src/pins/mega/pins_CNCONTROLS_11.h
@@ -25,9 +25,8 @@
  * CartesioV11 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "CN Controls V11"
 
diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_12.h b/Marlin/src/pins/mega/pins_CNCONTROLS_12.h
index 540f5c29f51..f1200e09018 100644
--- a/Marlin/src/pins/mega/pins_CNCONTROLS_12.h
+++ b/Marlin/src/pins/mega/pins_CNCONTROLS_12.h
@@ -25,9 +25,8 @@
  * CartesioV12 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "CN Controls V12"
 
diff --git a/Marlin/src/pins/mega/pins_CNCONTROLS_15.h b/Marlin/src/pins/mega/pins_CNCONTROLS_15.h
index 8bafbdf0005..6de3b7172eb 100644
--- a/Marlin/src/pins/mega/pins_CNCONTROLS_15.h
+++ b/Marlin/src/pins/mega/pins_CNCONTROLS_15.h
@@ -25,9 +25,8 @@
  * CNControls V15 for HMS434 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "CN Controls V15"
 
diff --git a/Marlin/src/pins/mega/pins_EINSTART-S.h b/Marlin/src/pins/mega/pins_EINSTART-S.h
index 40d65c353e8..d42efe73617 100644
--- a/Marlin/src/pins/mega/pins_EINSTART-S.h
+++ b/Marlin/src/pins/mega/pins_EINSTART-S.h
@@ -26,9 +26,8 @@
  * PCB Silkscreen: 3DPrinterCon_v3.5
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Einstart-S"
 
diff --git a/Marlin/src/pins/mega/pins_ELEFU_3.h b/Marlin/src/pins/mega/pins_ELEFU_3.h
index af93c408a25..f5e146cff99 100644
--- a/Marlin/src/pins/mega/pins_ELEFU_3.h
+++ b/Marlin/src/pins/mega/pins_ELEFU_3.h
@@ -25,9 +25,7 @@
  * Elefu RA Board Pin Assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Elefu Ra v3"
 
diff --git a/Marlin/src/pins/mega/pins_GT2560_REV_A.h b/Marlin/src/pins/mega/pins_GT2560_REV_A.h
index dcd829f7a7a..2fb43a299f2 100644
--- a/Marlin/src/pins/mega/pins_GT2560_REV_A.h
+++ b/Marlin/src/pins/mega/pins_GT2560_REV_A.h
@@ -27,9 +27,8 @@
  * Richard Smith <galorin@gmail.com>
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "GT2560 Rev.A"
diff --git a/Marlin/src/pins/mega/pins_GT2560_V3.h b/Marlin/src/pins/mega/pins_GT2560_V3.h
index 66b2804ff61..65642464d9f 100644
--- a/Marlin/src/pins/mega/pins_GT2560_V3.h
+++ b/Marlin/src/pins/mega/pins_GT2560_V3.h
@@ -25,9 +25,8 @@
  * Geeetech GT2560 RevB + GT2560 3.0/3.1 + GT2560 4.0/4.1 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "GT2560 RevB/3.x/4.x"
diff --git a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h
index dc4b78d9c10..27ec9988918 100644
--- a/Marlin/src/pins/mega/pins_HJC2560C_REV2.h
+++ b/Marlin/src/pins/mega/pins_HJC2560C_REV2.h
@@ -25,9 +25,7 @@
  * Geeetech HJC2560-C Rev 2.x board pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define DEFAULT_MACHINE_NAME "ADIMLab Gantry v2"
 #define BOARD_INFO_NAME      "HJC2560-C"
diff --git a/Marlin/src/pins/mega/pins_INTAMSYS40.h b/Marlin/src/pins/mega/pins_INTAMSYS40.h
index be5f461dda3..2e2a9b85db1 100644
--- a/Marlin/src/pins/mega/pins_INTAMSYS40.h
+++ b/Marlin/src/pins/mega/pins_INTAMSYS40.h
@@ -27,9 +27,7 @@
  * 2208 version exists and may or may not work
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Intamsys 4.0"
 
diff --git a/Marlin/src/pins/mega/pins_LEAPFROG.h b/Marlin/src/pins/mega/pins_LEAPFROG.h
index 9e6802b24bd..4700fd6729b 100644
--- a/Marlin/src/pins/mega/pins_LEAPFROG.h
+++ b/Marlin/src/pins/mega/pins_LEAPFROG.h
@@ -25,9 +25,8 @@
  * Leapfrog Driver board pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Mega 1280' or 'Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Leapfrog"
 
diff --git a/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h b/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h
index 9c316aa7595..af5cfd6a2ee 100644
--- a/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h
+++ b/Marlin/src/pins/mega/pins_LEAPFROG_XEED2015.h
@@ -29,9 +29,7 @@
  * printer models. As such this file is currently specific to the Xeed.
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Leapfrog Xeed 2015"
 
diff --git a/Marlin/src/pins/mega/pins_MEGACONTROLLER.h b/Marlin/src/pins/mega/pins_MEGACONTROLLER.h
index 938ad82eff0..69c60b29ec5 100644
--- a/Marlin/src/pins/mega/pins_MEGACONTROLLER.h
+++ b/Marlin/src/pins/mega/pins_MEGACONTROLLER.h
@@ -25,12 +25,12 @@
  * Mega controller pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Mega Controller supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
+#include "env_validate.h"
+
 #define BOARD_INFO_NAME "Mega Controller"
 
 //
diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS.h b/Marlin/src/pins/mega/pins_MEGATRONICS.h
index f813366a14e..0308175b2a3 100644
--- a/Marlin/src/pins/mega/pins_MEGATRONICS.h
+++ b/Marlin/src/pins/mega/pins_MEGATRONICS.h
@@ -25,9 +25,7 @@
  * MegaTronics pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Megatronics"
 //
diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS_2.h b/Marlin/src/pins/mega/pins_MEGATRONICS_2.h
index ef4605edd43..e5270359106 100644
--- a/Marlin/src/pins/mega/pins_MEGATRONICS_2.h
+++ b/Marlin/src/pins/mega/pins_MEGATRONICS_2.h
@@ -25,9 +25,7 @@
  * MegaTronics v2.0 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Megatronics v2.0"
 //
diff --git a/Marlin/src/pins/mega/pins_MEGATRONICS_3.h b/Marlin/src/pins/mega/pins_MEGATRONICS_3.h
index 9f85d46a544..5dea438d704 100644
--- a/Marlin/src/pins/mega/pins_MEGATRONICS_3.h
+++ b/Marlin/src/pins/mega/pins_MEGATRONICS_3.h
@@ -25,9 +25,7 @@
  * MegaTronics v3.0 / v3.1 / v3.2 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #if MB(MEGATRONICS_32)
   #define BOARD_INFO_NAME "Megatronics v3.2"
diff --git a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h
index b260a27867d..2531f10a7ae 100644
--- a/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h
+++ b/Marlin/src/pins/mega/pins_MIGHTYBOARD_REVE.h
@@ -37,9 +37,8 @@
  *  number (B5) agrees with the schematic but B5 is assigned to logical pin 11.
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Mega 1280' or 'Mega 2560' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "Mightyboard"
 #define DEFAULT_MACHINE_NAME "MB Replicator"
diff --git a/Marlin/src/pins/mega/pins_OVERLORD.h b/Marlin/src/pins/mega/pins_OVERLORD.h
index 18bb1f27bf4..161820b67a8 100644
--- a/Marlin/src/pins/mega/pins_OVERLORD.h
+++ b/Marlin/src/pins/mega/pins_OVERLORD.h
@@ -25,12 +25,12 @@
  * Dreammaker Overlord v1.1 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Overlord Controller supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
+#include "env_validate.h"
+
 #define BOARD_INFO_NAME         "OVERLORD"
 #define DEFAULT_MACHINE_NAME    BOARD_INFO_NAME
 
diff --git a/Marlin/src/pins/mega/pins_PICA.h b/Marlin/src/pins/mega/pins_PICA.h
index ff4d3e834d0..81f63193770 100644
--- a/Marlin/src/pins/mega/pins_PICA.h
+++ b/Marlin/src/pins/mega/pins_PICA.h
@@ -29,6 +29,8 @@
  * Applies to PICA, PICA_REVB
  */
 
+#include "env_validate.h"
+
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "PICA"
 #endif
@@ -42,10 +44,6 @@
   AD12 = 66;  AD13 = 67;  AD14 = 68;  AD15 = 69;
 */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops!  Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
-#endif
-
 //
 // Servos
 //
diff --git a/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h b/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h
index 715e823393c..503dd9ec814 100644
--- a/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h
+++ b/Marlin/src/pins/mega/pins_WANHAO_ONEPLUS.h
@@ -25,9 +25,7 @@
  * Wanhao 0ne+ pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "Wanhao i3 Mini 0ne+"
 #define DEFAULT_MACHINE_NAME "i3 Mini"
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index b8cf695fb59..55240021fae 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -378,7 +378,7 @@
 #elif MB(BTT_SKR_V1_3)
   #include "lpc1768/pins_BTT_SKR_V1_3.h"        // LPC1768                                env:LPC1768
 #elif MB(BTT_SKR_V1_4)
-  #include "lpc1768/pins_BTT_SKR_V1_4.h"        // LPC1768                                env:LPC1768
+  #include "lpc1768/pins_BTT_SKR_V1_4.h"        // LPC1768                                env:LPC1768_btt_skr_v1_4
 
 //
 // LPC1769 ARM Cortex M3
diff --git a/Marlin/src/pins/pinsDebug.h b/Marlin/src/pins/pinsDebug.h
index e2e56081b71..72e31b7b252 100644
--- a/Marlin/src/pins/pinsDebug.h
+++ b/Marlin/src/pins/pinsDebug.h
@@ -41,7 +41,7 @@
 #define REPORT_NAME_ANALOG(COUNTER, NAME) _ADD_PIN(#NAME, COUNTER)
 
 #include "pinsDebug_list.h"
-#line 46
+#line 45
 
 // manually add pins that have names that are macros which don't play well with these macros
 #if ANY(AVR_ATmega2560_FAMILY, AVR_ATmega1284_FAMILY, ARDUINO_ARCH_SAM, TARGET_LPC1768)
@@ -227,7 +227,7 @@ const PinInfo pin_array[] PROGMEM = {
   #endif
 
   #include "pinsDebug_list.h"
-  #line 172
+  #line 231
 
 };
 
diff --git a/Marlin/src/pins/rambo/env_validate.h b/Marlin/src/pins/rambo/env_validate.h
new file mode 100644
index 00000000000..84cf8392cdf
--- /dev/null
+++ b/Marlin/src/pins/rambo/env_validate.h
@@ -0,0 +1,26 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(__AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino Mega 2560 or Rambo' in 'Tools > Board.'"
+#endif
diff --git a/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h b/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h
index 2ca2cc9c8d0..7b05d454af3 100644
--- a/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h
+++ b/Marlin/src/pins/rambo/pins_EINSY_RAMBO.h
@@ -25,9 +25,7 @@
  * Einsy-Rambo pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Mega 2560 or Rambo' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Einsy Rambo"
 
diff --git a/Marlin/src/pins/rambo/pins_EINSY_RETRO.h b/Marlin/src/pins/rambo/pins_EINSY_RETRO.h
index a6a4b65e05b..ee537495ea2 100644
--- a/Marlin/src/pins/rambo/pins_EINSY_RETRO.h
+++ b/Marlin/src/pins/rambo/pins_EINSY_RETRO.h
@@ -25,9 +25,7 @@
  * Einsy-Retro pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Mega 2560 or Rambo' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Einsy Retro"
 
diff --git a/Marlin/src/pins/rambo/pins_MINIRAMBO.h b/Marlin/src/pins/rambo/pins_MINIRAMBO.h
index 4dcf35827cb..ec44cc3b366 100644
--- a/Marlin/src/pins/rambo/pins_MINIRAMBO.h
+++ b/Marlin/src/pins/rambo/pins_MINIRAMBO.h
@@ -25,9 +25,7 @@
  * Mini-RAMBo pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'RAMBo' in 'Tools > Board' or the Mega2560 environment in PlatformIO."
-#endif
+#include "env_validate.h"
 
 #if MB(MINIRAMBO_10A)
   #define BOARD_INFO_NAME "Mini RAMBo 1.0a"
diff --git a/Marlin/src/pins/rambo/pins_RAMBO.h b/Marlin/src/pins/rambo/pins_RAMBO.h
index 65fc4b5af8e..5d6f9c1fd09 100644
--- a/Marlin/src/pins/rambo/pins_RAMBO.h
+++ b/Marlin/src/pins/rambo/pins_RAMBO.h
@@ -41,9 +41,7 @@
  * Rambo pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Rambo"
diff --git a/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h b/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h
index 5680b00df69..c2a691a3b73 100644
--- a/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h
+++ b/Marlin/src/pins/rambo/pins_SCOOVO_X9H.h
@@ -25,9 +25,7 @@
  * Rambo pin assignments MODIFIED FOR Scoovo X9H
  ************************************************/
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_target.h"
 
 #define BOARD_INFO_NAME "Scoovo X9H"
 
diff --git a/Marlin/src/pins/ramps/env_validate.h b/Marlin/src/pins/ramps/env_validate.h
new file mode 100644
index 00000000000..6006a78f013
--- /dev/null
+++ b/Marlin/src/pins/ramps/env_validate.h
@@ -0,0 +1,35 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if ENABLED(ALLOW_SAM3X8E)
+  #if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__)
+    #error "Oops! Select 'Arduino Due' or 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
+  #endif
+#elif ENABLED(REQUIRE_MEGA2560) && NOT_TARGET(__AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
+#elif DISABLED(REQUIRE_MEGA2560) && NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560 or 1280' in 'Tools > Board.'"
+#endif
+
+#undef ALLOW_SAM3X8E
+#undef REQUIRE_MEGA2560
diff --git a/Marlin/src/pins/ramps/pins_AZTEEG_X3.h b/Marlin/src/pins/ramps/pins_AZTEEG_X3.h
index 6ddd2a5165e..07af61e6938 100644
--- a/Marlin/src/pins/ramps/pins_AZTEEG_X3.h
+++ b/Marlin/src/pins/ramps/pins_AZTEEG_X3.h
@@ -25,9 +25,10 @@
  * AZTEEG_X3 Arduino Mega with RAMPS v1.4 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Azteeg X3 supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h b/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h
index 9ba6a0c1ac4..c2896146e64 100644
--- a/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h
+++ b/Marlin/src/pins/ramps/pins_AZTEEG_X3_PRO.h
@@ -25,9 +25,10 @@
  * AZTEEG_X3_PRO (Arduino Mega) pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 5 || E_STEPPERS > 5
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 5 || E_STEPPERS > 5
   #error "Azteeg X3 Pro supports up to 5 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h b/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h
index f120e9c44f5..99cf484de7f 100644
--- a/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h
+++ b/Marlin/src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h
@@ -25,9 +25,8 @@
  * bq ZUM Mega 3D board definition
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "ZUM Mega 3D"
 
diff --git a/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h b/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h
index 93ec3d60702..1a4b83f02dc 100644
--- a/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h
+++ b/Marlin/src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h
@@ -25,9 +25,8 @@
  * Wanhao Duplicator i3 Plus pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Duplicator i3 Plus"
 
diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h
index 5b724787e94..383501caaaf 100644
--- a/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h
+++ b/Marlin/src/pins/ramps/pins_FORMBOT_RAPTOR.h
@@ -25,9 +25,10 @@
  * Formbot Raptor pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 3 || E_STEPPERS > 3
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 3 || E_STEPPERS > 3
   #error "Formbot supports up to 3 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h
index 81b6ea16d7f..ac0b7428f49 100644
--- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h
+++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX2PLUS.h
@@ -25,9 +25,10 @@
  * Formbot pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Formbot supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h
index a97b0d2d122..76a9fbe6280 100644
--- a/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h
+++ b/Marlin/src/pins/ramps/pins_FORMBOT_TREX3.h
@@ -25,9 +25,10 @@
  * Formbot pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Formbot supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_K8800.h b/Marlin/src/pins/ramps/pins_K8800.h
index 5388c9621da..9bc74943b47 100644
--- a/Marlin/src/pins/ramps/pins_K8800.h
+++ b/Marlin/src/pins/ramps/pins_K8800.h
@@ -25,9 +25,7 @@
  * Velleman K8800 (Vertex)
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "K8800"
 #define DEFAULT_MACHINE_NAME "Vertex Delta"
diff --git a/Marlin/src/pins/ramps/pins_LONGER3D_LKx_PRO.h b/Marlin/src/pins/ramps/pins_LONGER3D_LKx_PRO.h
index 6fcb7b94e0c..2fd599e6198 100644
--- a/Marlin/src/pins/ramps/pins_LONGER3D_LKx_PRO.h
+++ b/Marlin/src/pins/ramps/pins_LONGER3D_LKx_PRO.h
@@ -25,9 +25,10 @@
  * Longer3D LK1/LK4/LK5 Pro board pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "Longer3D LGT KIT V1.0 board only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
@@ -42,9 +43,6 @@
   #warning "Serial 3 is originally reserved to Y limit switches. Hardware changes are required to use it."
 #endif
 
-// Custom flags and defines for the build
-//#define BOARD_CUSTOM_BUILD_FLAGS -D__FOO__
-
 #define BOARD_INFO_NAME "LGT KIT V1.0"
 
 //
diff --git a/Marlin/src/pins/ramps/pins_RAMPS.h b/Marlin/src/pins/ramps/pins_RAMPS.h
index fe416dfb681..f56a9ec38ed 100644
--- a/Marlin/src/pins/ramps/pins_RAMPS.h
+++ b/Marlin/src/pins/ramps/pins_RAMPS.h
@@ -45,18 +45,7 @@
  *         7 | 11
  */
 
-#ifdef TARGET_LPC1768
-  #error "Oops! Set MOTHERBOARD to an LPC1768-based board when building for LPC1768."
-#elif defined(__STM32F1__)
-  #error "Oops! Set MOTHERBOARD to an STM32F1-based board when building for STM32F1."
-#endif
-
-#if NOT_TARGET(IS_RAMPS_SMART, IS_RAMPS_DUO, IS_RAMPS4DUE, TARGET_LPC1768, __AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' (or other appropriate target) in 'Tools > Board.'"
-#endif
-
-// Custom flags and defines for the build
-//#define BOARD_CUSTOM_BUILD_FLAGS -D__FOO__
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "RAMPS 1.4"
diff --git a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h
index 6d2dad23149..a43ee3c6ca5 100644
--- a/Marlin/src/pins/ramps/pins_RAMPS_OLD.h
+++ b/Marlin/src/pins/ramps/pins_RAMPS_OLD.h
@@ -25,9 +25,7 @@
  * Arduino Mega with RAMPS v1.0, v1.1, v1.2 pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "RAMPS <1.2"
 
diff --git a/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h b/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h
index 23b1dfa3469..43a769b34db 100644
--- a/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h
+++ b/Marlin/src/pins/ramps/pins_RAMPS_PLUS.h
@@ -37,9 +37,7 @@
  *  RAMPS_PLUS_SF  (Spindle, Controller Fan)
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
- #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "RAMPS 1.4 Plus"
 
diff --git a/Marlin/src/pins/ramps/pins_RAMPS_S_12.h b/Marlin/src/pins/ramps/pins_RAMPS_S_12.h
index 1bcf310bc17..62b6e3ff940 100644
--- a/Marlin/src/pins/ramps/pins_RAMPS_S_12.h
+++ b/Marlin/src/pins/ramps/pins_RAMPS_S_12.h
@@ -34,12 +34,7 @@
  * Other pins_MYBOARD.h files may override these defaults
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
-
-// Custom flags and defines for the build
-//#define BOARD_CUSTOM_BUILD_FLAGS -D__FOO__
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "RAMPS S 1.2"
diff --git a/Marlin/src/pins/ramps/pins_RUMBA.h b/Marlin/src/pins/ramps/pins_RUMBA.h
index 4af49d9164d..942afafd7a6 100644
--- a/Marlin/src/pins/ramps/pins_RUMBA.h
+++ b/Marlin/src/pins/ramps/pins_RUMBA.h
@@ -25,9 +25,10 @@
  * RUMBA pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 3 || E_STEPPERS > 3
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 3 || E_STEPPERS > 3
   #error "RUMBA supports up to 3 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h
index 84e7e311264..53e419af00c 100644
--- a/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h
+++ b/Marlin/src/pins/ramps/pins_TENLOG_D3_HERO.h
@@ -25,9 +25,10 @@
  * Tenlog pin assignments
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Tenlog supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h b/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h
index f342eff8aa6..ffe6d56eb8b 100644
--- a/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h
+++ b/Marlin/src/pins/ramps/pins_TRONXY_V3_1_0.h
@@ -25,9 +25,10 @@
  * Arduino Mega for Tronxy X5S-2E, etc.
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "TRONXY-V3-1.0 supports only 2 hotends/E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/ramps/pins_TT_OSCAR.h b/Marlin/src/pins/ramps/pins_TT_OSCAR.h
index ca402553e11..18d0f1770e1 100644
--- a/Marlin/src/pins/ramps/pins_TT_OSCAR.h
+++ b/Marlin/src/pins/ramps/pins_TT_OSCAR.h
@@ -20,9 +20,7 @@
  *
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #if HOTENDS > 5 || E_STEPPERS > 5
   #error "TTOSCAR supports up to 5 hotends / E-steppers. Comment out this line to continue."
diff --git a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h
index 211caddba0e..128f1974e0e 100644
--- a/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h
+++ b/Marlin/src/pins/ramps/pins_ULTIMAIN_2.h
@@ -33,9 +33,8 @@
  *    case light
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME         "Ultimaker 2.x"
 #define DEFAULT_MACHINE_NAME    "Ultimaker"
diff --git a/Marlin/src/pins/ramps/pins_ULTIMAKER.h b/Marlin/src/pins/ramps/pins_ULTIMAKER.h
index 22c7fd95b47..0bc04d962aa 100644
--- a/Marlin/src/pins/ramps/pins_ULTIMAKER.h
+++ b/Marlin/src/pins/ramps/pins_ULTIMAKER.h
@@ -33,9 +33,7 @@
  *    case light
  */
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME         "Ultimaker"
 #define DEFAULT_MACHINE_NAME    BOARD_INFO_NAME
diff --git a/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h b/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h
index 37c28ece4ce..091356a11f8 100644
--- a/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h
+++ b/Marlin/src/pins/ramps/pins_ULTIMAKER_OLD.h
@@ -60,9 +60,7 @@
 //#define BOARD_REV_1_0
 //#define BOARD_REV_1_5
 
-#if NOT_TARGET(__AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #ifdef BOARD_REV_1_1_TO_1_3
   #define BOARD_INFO_NAME       "Ultimaker 1.1-1.3"
diff --git a/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h b/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h
index 096d970871f..26ad5fd6580 100644
--- a/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h
+++ b/Marlin/src/pins/ramps/pins_Z_BOLT_X_SERIES.h
@@ -25,9 +25,10 @@
  *  Z-Bolt X Series board – based on Arduino Mega2560
  */
 
-#if NOT_TARGET(__AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#elif HOTENDS > 4 || E_STEPPERS > 4
+#define REQUIRE_MEGA2560
+#include "env_validate.h"
+
+#if HOTENDS > 4 || E_STEPPERS > 4
   #error "Z-Bolt X Series board supports up to 4 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/sam/env_validate.h b/Marlin/src/pins/sam/env_validate.h
new file mode 100644
index 00000000000..09bcd136492
--- /dev/null
+++ b/Marlin/src/pins/sam/env_validate.h
@@ -0,0 +1,33 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if BOTH(ALLOW_MEGA1280, ALLOW_MEGA2560) && NOT_TARGET(__SAM3X8E__, __AVR_ATmega1280__, __AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino Due or Mega' in 'Tools > Board.'"
+#elif ENABLED(ALLOW_MEGA2560) && NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__)
+  #error "Oops! Select 'Arduino Due or Mega' in 'Tools > Board.'"
+#elif ENABLED(ALLOW_MEGA1280) && NOT_TARGET(__SAM3X8E__, __AVR_ATmega1280__)
+  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
+#endif
+
+#undef ALLOW_MEGA1280
+#undef ALLOW_MEGA2560
diff --git a/Marlin/src/pins/sam/pins_ADSK.h b/Marlin/src/pins/sam/pins_ADSK.h
index b0e171cf171..9026ca7771d 100644
--- a/Marlin/src/pins/sam/pins_ADSK.h
+++ b/Marlin/src/pins/sam/pins_ADSK.h
@@ -27,9 +27,9 @@
 
 #define BOARD_INFO_NAME "ADSK"
 
-#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega1280__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Due or Mega' in 'Tools > Board.'"
-#endif
+#define ALLOW_MEGA1280
+#define ALLOW_MEGA2560
+#include "env_validate.h"
 
 /* CNC shield modifications:
 FROM THE BOTTOM CUT THE 5V PIN THAT GOES TO ARDUINO!!!
diff --git a/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h b/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h
index b01d1aafdfe..c273edfc6b4 100644
--- a/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h
+++ b/Marlin/src/pins/sam/pins_ALLIGATOR_R2.h
@@ -26,9 +26,7 @@
  * https://reprap.org/wiki/Alligator_Board
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME    "Alligator Board R2"
 
diff --git a/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h b/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h
index 5bf31450b70..a63c3378804 100644
--- a/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h
+++ b/Marlin/src/pins/sam/pins_CNCONTROLS_15D.h
@@ -24,9 +24,7 @@
  * CNControls V15 for HMS434 with DUE pin assignments
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "CN Controls V15D"
 
diff --git a/Marlin/src/pins/sam/pins_DUE3DOM.h b/Marlin/src/pins/sam/pins_DUE3DOM.h
index 90d6bdc3403..4ebece58e4c 100644
--- a/Marlin/src/pins/sam/pins_DUE3DOM.h
+++ b/Marlin/src/pins/sam/pins_DUE3DOM.h
@@ -25,9 +25,7 @@
  * DUE3DOM pin assignments
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "DUE3DOM"
 
diff --git a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h
index 5a205423ed5..dd8f2636760 100644
--- a/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h
+++ b/Marlin/src/pins/sam/pins_DUE3DOM_MINI.h
@@ -25,9 +25,7 @@
  * DUE3DOM MINI pin assignments
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "DUE3DOM MINI"
 
diff --git a/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h b/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h
index 424d858a851..874950f34b8 100644
--- a/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h
+++ b/Marlin/src/pins/sam/pins_PRINTRBOARD_G2.h
@@ -25,9 +25,7 @@
  * PRINTRBOARD_G2
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Printrboard G2"
diff --git a/Marlin/src/pins/sam/pins_RADDS.h b/Marlin/src/pins/sam/pins_RADDS.h
index 7b9c7f1b281..7b0ec5ab68e 100644
--- a/Marlin/src/pins/sam/pins_RADDS.h
+++ b/Marlin/src/pins/sam/pins_RADDS.h
@@ -25,9 +25,7 @@
  * RADDS
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "RADDS"
 
diff --git a/Marlin/src/pins/sam/pins_RAMPS4DUE.h b/Marlin/src/pins/sam/pins_RAMPS4DUE.h
index 54548333b5f..6d9d06a1756 100644
--- a/Marlin/src/pins/sam/pins_RAMPS4DUE.h
+++ b/Marlin/src/pins/sam/pins_RAMPS4DUE.h
@@ -39,14 +39,9 @@
  *       A15 | NC
  */
 
-#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Due' or 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
-
+#define ALLOW_SAM3X8E
 #define BOARD_INFO_NAME "RAMPS4DUE"
 
-#define IS_RAMPS4DUE
-
 //
 // Temperature Sensors
 //
diff --git a/Marlin/src/pins/sam/pins_RAMPS_DUO.h b/Marlin/src/pins/sam/pins_RAMPS_DUO.h
index d2ab5c96b22..b1a6680c506 100644
--- a/Marlin/src/pins/sam/pins_RAMPS_DUO.h
+++ b/Marlin/src/pins/sam/pins_RAMPS_DUO.h
@@ -43,14 +43,9 @@
  *       A15 | A11
  */
 
-#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Due' or 'Arduino/Genuino Mega or Mega 2560' in 'Tools > Board.'"
-#endif
-
 #define BOARD_INFO_NAME "RAMPS Duo"
 
-#define IS_RAMPS_DUO
-
+#define ALLOW_SAM3X8E
 #include "../ramps/pins_RAMPS.h"
 
 //
diff --git a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h
index 80e8f0dc7e9..e4c53530f7b 100644
--- a/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h
+++ b/Marlin/src/pins/sam/pins_RAMPS_FD_V1.h
@@ -28,9 +28,7 @@
  * Use 4k7 thermistor tables
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "RAMPS-FD v1"
diff --git a/Marlin/src/pins/sam/pins_RAMPS_SMART.h b/Marlin/src/pins/sam/pins_RAMPS_SMART.h
index 17dd32399a9..3882dfb9442 100644
--- a/Marlin/src/pins/sam/pins_RAMPS_SMART.h
+++ b/Marlin/src/pins/sam/pins_RAMPS_SMART.h
@@ -60,12 +60,8 @@
  * (Search the web for "Arduino DUE Board Pinout" to see the correct header.)
  */
 
-#if NOT_TARGET(__SAM3X8E__, __AVR_ATmega2560__)
-  #error "Oops! Select 'Arduino Due' or 'Mega 2560' in 'Tools > Board.'"
-#endif
-
 #define BOARD_INFO_NAME "RAMPS-SMART"
-#define IS_RAMPS_SMART
+#define ALLOW_SAM3X8E
 #include "../ramps/pins_RAMPS.h"
 
 // I2C EEPROM with 4K of space
diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h
index 6a283401f45..908bbc6b229 100644
--- a/Marlin/src/pins/sam/pins_RURAMPS4D_11.h
+++ b/Marlin/src/pins/sam/pins_RURAMPS4D_11.h
@@ -32,9 +32,7 @@
  *           |
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "RuRAMPS4Due v1.1"
 
diff --git a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h
index 6ec10f64af7..3e73c33acbc 100644
--- a/Marlin/src/pins/sam/pins_RURAMPS4D_13.h
+++ b/Marlin/src/pins/sam/pins_RURAMPS4D_13.h
@@ -32,9 +32,7 @@
  *           |
  */
 
-#if NOT_TARGET(__SAM3X8E__)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "RuRAMPS4Due v1.3"
 
diff --git a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h
index ea096187f71..e567b0f5e11 100644
--- a/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h
+++ b/Marlin/src/pins/sam/pins_ULTRATRONICS_PRO.h
@@ -26,9 +26,7 @@
  * https://reprapworld.com/documentation/datasheet_ultratronics10_05.pdf
  */
 
-#if NOT_TARGET(ARDUINO_ARCH_SAM)
-  #error "Oops! Select 'Arduino Due' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Ultratronics v1.0"
 
diff --git a/Marlin/src/pins/sanguino/env_validate.h b/Marlin/src/pins/sanguino/env_validate.h
new file mode 100644
index 00000000000..d229b6f102e
--- /dev/null
+++ b/Marlin/src/pins/sanguino/env_validate.h
@@ -0,0 +1,42 @@
+  /**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if ENABLED(ALLOW_MEGA644)
+  #if NOT_TARGET(__AVR_ATmega644__, __AVR_ATmega644P__, __AVR_ATmega1284P__)
+    #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'"
+  #endif
+#elif ENABLED(ALLOW_MEGA644P)
+  #if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
+    #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'"
+  #endif
+#elif ENABLED(REQUIRE_MEGA644P)
+  #if NOT_TARGET(__AVR_ATmega644P__)
+    #error "Oops! Select 'Sanguino' in 'Tools > Board' and 'ATmega644P' in 'Tools > Processor.'"
+  #endif
+#elif NOT_TARGET(__AVR_ATmega1284P__)
+  #error "Oops! Select 'Sanguino' in 'Tools > Board' and 'ATmega1284P' in 'Tools > Processor.' (For PlatformIO, use 'melzi' or 'melzi_optiboot.')"
+#endif
+
+#undef ALLOW_MEGA644
+#undef ALLOW_MEGA644P
+#undef REQUIRE_MEGA644P
diff --git a/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h b/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h
index 29905c10895..1343739a119 100644
--- a/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h
+++ b/Marlin/src/pins/sanguino/pins_GEN3_MONOLITHIC.h
@@ -48,9 +48,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Board.'"
-#endif
+#define REQUIRE_MEGA644P
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Gen3 Monolithic"
 #define DEBUG_PIN                              0
diff --git a/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h b/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h
index 33fc233f7ab..7cab1bd762c 100644
--- a/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h
+++ b/Marlin/src/pins/sanguino/pins_GEN3_PLUS.h
@@ -48,9 +48,8 @@
  * Once installed select the SANGUINO board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644P
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Gen3+"
 
diff --git a/Marlin/src/pins/sanguino/pins_GEN6.h b/Marlin/src/pins/sanguino/pins_GEN6.h
index bfca8e90d9c..51e8200b957 100644
--- a/Marlin/src/pins/sanguino/pins_GEN6.h
+++ b/Marlin/src/pins/sanguino/pins_GEN6.h
@@ -50,9 +50,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644P
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Gen6"
diff --git a/Marlin/src/pins/sanguino/pins_GEN7_12.h b/Marlin/src/pins/sanguino/pins_GEN7_12.h
index 9db7d7214a5..0834da78c45 100644
--- a/Marlin/src/pins/sanguino/pins_GEN7_12.h
+++ b/Marlin/src/pins/sanguino/pins_GEN7_12.h
@@ -50,9 +50,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Gen7 v1.1 / 1.2"
diff --git a/Marlin/src/pins/sanguino/pins_GEN7_14.h b/Marlin/src/pins/sanguino/pins_GEN7_14.h
index 66dba533e98..97bfdd28a72 100644
--- a/Marlin/src/pins/sanguino/pins_GEN7_14.h
+++ b/Marlin/src/pins/sanguino/pins_GEN7_14.h
@@ -50,9 +50,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Gen7 v1.4"
 
diff --git a/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h b/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h
index 0c4871fb27d..6d7678e6e3d 100644
--- a/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h
+++ b/Marlin/src/pins/sanguino/pins_GEN7_CUSTOM.h
@@ -53,9 +53,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Gen7 Custom"
 
diff --git a/Marlin/src/pins/sanguino/pins_OMCA_A.h b/Marlin/src/pins/sanguino/pins_OMCA_A.h
index 77073205190..a3ceb76a0de 100644
--- a/Marlin/src/pins/sanguino/pins_OMCA_A.h
+++ b/Marlin/src/pins/sanguino/pins_OMCA_A.h
@@ -74,7 +74,7 @@
  */
 
 #if NOT_TARGET(__AVR_ATmega644__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Board' and ATmega644 in 'Tools > Processor.'"
+  #error "Oops! Select 'Sanguino' in 'Tools > Board' and 'ATmega644' in 'Tools > Processor.'"
 #endif
 
 #define BOARD_INFO_NAME "Alpha OMCA"
diff --git a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h
index af27159936f..d79ad7a3dda 100644
--- a/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h
+++ b/Marlin/src/pins/sanguino/pins_SANGUINOLOLU_11.h
@@ -50,9 +50,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644P
+#include "env_validate.h"
 
 #ifndef BOARD_INFO_NAME
   #define BOARD_INFO_NAME "Sanguinololu <1.2"
diff --git a/Marlin/src/pins/sanguino/pins_SETHI.h b/Marlin/src/pins/sanguino/pins_SETHI.h
index dc2133e441d..a2240b385b2 100644
--- a/Marlin/src/pins/sanguino/pins_SETHI.h
+++ b/Marlin/src/pins/sanguino/pins_SETHI.h
@@ -49,9 +49,8 @@
  * Once installed select the Sanguino board and then select the CPU.
  */
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega644__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644', 'ATmega644P', or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Sethi 3D_1"
 
diff --git a/Marlin/src/pins/sanguino/pins_ZMIB_V2.h b/Marlin/src/pins/sanguino/pins_ZMIB_V2.h
index d064d801329..0265ae0a64f 100644
--- a/Marlin/src/pins/sanguino/pins_ZMIB_V2.h
+++ b/Marlin/src/pins/sanguino/pins_ZMIB_V2.h
@@ -21,9 +21,8 @@
  */
 #pragma once
 
-#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
-  #error "Oops! Select 'Sanguino' in 'Tools > Boards' and 'ATmega644P' or 'ATmega1284P' in 'Tools > Processor.'"
-#endif
+#define ALLOW_MEGA644P
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "Zonestar ZMIB_V2"
 #define BOARD_WEBSITE_URL "www.aliexpress.com/item/32957490744.html"
diff --git a/Marlin/src/pins/stm32f1/env_validate.h b/Marlin/src/pins/stm32f1/env_validate.h
new file mode 100644
index 00000000000..62ccf7edcc4
--- /dev/null
+++ b/Marlin/src/pins/stm32f1/env_validate.h
@@ -0,0 +1,26 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(__STM32F1__)
+  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
+#endif
diff --git a/Marlin/src/pins/stm32f1/pins_BEAST.h b/Marlin/src/pins/stm32f1/pins_BEAST.h
index bf2cf6463a2..05f77f10291 100644
--- a/Marlin/src/pins/stm32f1/pins_BEAST.h
+++ b/Marlin/src/pins/stm32f1/pins_BEAST.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 21017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_BTT_SKR_CR6.h b/Marlin/src/pins/stm32f1/pins_BTT_SKR_CR6.h
index 73a18faf05b..e76c77e7068 100644
--- a/Marlin/src/pins/stm32f1/pins_BTT_SKR_CR6.h
+++ b/Marlin/src/pins/stm32f1/pins_BTT_SKR_CR6.h
@@ -28,9 +28,7 @@
 #define DEFAULT_MACHINE_NAME "Creality3D"
 #define BOARD_INFO_NAME "BTT SKR CR-6"
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 //
 // Release PB4 (Z_STEP_PIN) from JTAG NRST role
diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D.h b/Marlin/src/pins/stm32f1/pins_CHITU3D.h
index bb6f5719246..dd6edf9024b 100644
--- a/Marlin/src/pins/stm32f1/pins_CHITU3D.h
+++ b/Marlin/src/pins/stm32f1/pins_CHITU3D.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 2017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
index c90ae84acbb..d25a1f34f9f 100644
--- a/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
+++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V5.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 2017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
index 96cf36629a5..5afa6531170 100644
--- a/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
+++ b/Marlin/src/pins/stm32f1/pins_CHITU3D_V6.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 2017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h
index 88806bdb18f..733e24cfac9 100644
--- a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h
+++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h
@@ -24,9 +24,9 @@
  * Creality 4.2.x (STM32F103RET6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "Creality V4 only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4210.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4210.h
index 025e68d4da0..6585d40d45d 100644
--- a/Marlin/src/pins/stm32f1/pins_CREALITY_V4210.h
+++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4210.h
@@ -24,9 +24,9 @@
  * CREALITY 4.2.10 (STM32F103) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "CREALITY supports up to 1 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V45x.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V45x.h
index f2be2895305..c73c92080e8 100644
--- a/Marlin/src/pins/stm32f1/pins_CREALITY_V45x.h
+++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V45x.h
@@ -24,9 +24,7 @@
  * Creality v4.5.2 and v4.5.3 (STM32F103RET6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define DEFAULT_MACHINE_NAME "Creality3D"
 
diff --git a/Marlin/src/pins/stm32f1/pins_FLY_MINI.h b/Marlin/src/pins/stm32f1/pins_FLY_MINI.h
index 2278d558702..b94ec0c7f35 100644
--- a/Marlin/src/pins/stm32f1/pins_FLY_MINI.h
+++ b/Marlin/src/pins/stm32f1/pins_FLY_MINI.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "FLY_MINI"
 #define BOARD_WEBSITE_URL "github.com/FLYmaker"
diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h
index 3919723f378..7ffe67c4f86 100644
--- a/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h
+++ b/Marlin/src/pins/stm32f1/pins_FYSETC_AIO_II.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME   "FYSETC AIO II"
 #define BOARD_WEBSITE_URL "fysetc.com"
diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h
index c978092ab22..552ad9ac571 100644
--- a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h
+++ b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define DEFAULT_MACHINE_NAME "3D Printer"
 
diff --git a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h
index 65b16755ca3..ba35265d10a 100644
--- a/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h
+++ b/Marlin/src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #include "pins_FYSETC_CHEETAH.h"
 
diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h b/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h
index f67dc85b40f..4edd67a14df 100644
--- a/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h
+++ b/Marlin/src/pins/stm32f1/pins_GTM32_MINI.h
@@ -25,9 +25,7 @@
  * Geeetech GTM32 Mini board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "GTM32 Pro VB"
 #define DEFAULT_MACHINE_NAME "STM32F103VET6"
diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h b/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h
index 27b0362758a..f346c3a9fdf 100644
--- a/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h
+++ b/Marlin/src/pins/stm32f1/pins_GTM32_MINI_A30.h
@@ -25,9 +25,7 @@
  * Geeetech GTM32 Mini A30 board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "GTM32 Pro VB"
 #define DEFAULT_MACHINE_NAME "STM32F103VET6"
diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h b/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h
index d4ab2ff3e5f..18156fc0ff1 100644
--- a/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h
+++ b/Marlin/src/pins/stm32f1/pins_GTM32_PRO_VB.h
@@ -26,9 +26,7 @@
  * http://www.geeetech.com/wiki/index.php/File:Hardware_GTM32_PRO_VB.pdf
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "GTM32 Pro VB/VD"
 #define DEFAULT_MACHINE_NAME "STM32F103VET6"
diff --git a/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h b/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h
index 8e96327816a..865de809e20 100644
--- a/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h
+++ b/Marlin/src/pins/stm32f1/pins_GTM32_REV_B.h
@@ -25,9 +25,7 @@
  * Geeetech GTM32 Rev. B board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME      "GTM32 Rev B"
 #define DEFAULT_MACHINE_NAME "M201"
diff --git a/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h b/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h
index 4f02b0e23cd..9f08f18bf7f 100644
--- a/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h
+++ b/Marlin/src/pins/stm32f1/pins_JGAURORA_A5S_A1.h
@@ -28,9 +28,9 @@
   *   Pin assignments for 32-bit JGAurora A5S & A1
   */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "JGAurora A5S A1 only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h
index 3118a521bbe..14664bda394 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3P.h
@@ -25,9 +25,9 @@
  * MKS Robin nano (STM32F130VET6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "MKS Robin E3P only supports one hotend / E-stepper. Comment out this line to continue."
 #elif HAS_FSMC_TFT
   #error "MKS Robin E3P doesn't support FSMC-based TFT displays."
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h
index c4a7e9f4086..da7bdc79e50 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h
@@ -25,9 +25,7 @@
  * MKS Robin E3 & E3D (STM32F103RCT6) common board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_NO_NATIVE_USB
 
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h
index 13c2d41d577..fad36e83848 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE.h
@@ -21,9 +21,9 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "MKS Robin Lite only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h
index f814052fa80..73fefddf8fb 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h
@@ -25,9 +25,9 @@
  * MKS Robin Lite 3 (STM32F103RCT6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "MKS Robin Lite3 supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h
index b3cfe5b6baa..be23394af7a 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h
@@ -25,9 +25,9 @@
  * MKS Robin mini (STM32F130VET6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "MKS Robin mini only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h
index 39676bf9d78..10e1633124a 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_PRO.h
@@ -25,9 +25,9 @@
  * MKS Robin pro (STM32F103ZET6) board pin assignments
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 3 || E_STEPPERS > 3
+#include "env_validate.h"
+
+#if HOTENDS > 3 || E_STEPPERS > 3
   #error "MKS Robin pro supports up to 3 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f1/pins_STM32F1R.h b/Marlin/src/pins/stm32f1/pins_STM32F1R.h
index d666755c6ff..c08b707d7e9 100644
--- a/Marlin/src/pins/stm32f1/pins_STM32F1R.h
+++ b/Marlin/src/pins/stm32f1/pins_STM32F1R.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 21017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h b/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h
index 4f8183caf4c..d25ca1bd2ea 100644
--- a/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h
+++ b/Marlin/src/pins/stm32f1/pins_STM3R_MINI.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 /**
  * 21017 Victor Perez Marlin for stm32f1 test
diff --git a/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h b/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h
index ed70d8d28f6..dc603cda54f 100644
--- a/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h
+++ b/Marlin/src/pins/stm32f1/pins_TRIGORILLA_PRO.h
@@ -28,9 +28,9 @@
  * https://github.com/MarlinFirmware/Marlin/files/3401484/x5sa-main_board-2.pdf
  */
 
-#if NOT_TARGET(__STM32F1__)
-  #error "Oops! Select an STM32F1 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Trigorilla Pro supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/env_validate.h b/Marlin/src/pins/stm32f4/env_validate.h
new file mode 100644
index 00000000000..c01401f06c9
--- /dev/null
+++ b/Marlin/src/pins/stm32f4/env_validate.h
@@ -0,0 +1,28 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(STM32F4) && (DISABLED(ALLOW_STM32DUINO) || NOT_TARGET(STM32F4xx))
+  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
+#endif
+
+#undef ALLOW_STM32DUINO
diff --git a/Marlin/src/pins/stm32f4/pins_ANET_ET4.h b/Marlin/src/pins/stm32f4/pins_ANET_ET4.h
index 487080f46b6..1e1f5251c15 100644
--- a/Marlin/src/pins/stm32f4/pins_ANET_ET4.h
+++ b/Marlin/src/pins/stm32f4/pins_ANET_ET4.h
@@ -22,9 +22,11 @@
 
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "Anet ET4 only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_ARMED.h b/Marlin/src/pins/stm32f4/pins_ARMED.h
index db57db14d54..a67af089f20 100644
--- a/Marlin/src/pins/stm32f4/pins_ARMED.h
+++ b/Marlin/src/pins/stm32f4/pins_ARMED.h
@@ -24,9 +24,9 @@
 
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Arm'ed supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h b/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h
index c2ad907e047..d8a83bef3a8 100644
--- a/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h
+++ b/Marlin/src/pins/stm32f4/pins_BLACK_STM32F407VE.h
@@ -27,9 +27,10 @@
  * Shield - https://github.com/jmz52/Hardware
  */
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "Black STM32F4VET6 supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h
index bc69e1fd218..6029031a634 100644
--- a/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h
+++ b/Marlin/src/pins/stm32f4/pins_BTT_BTT002_V1_0.h
@@ -21,9 +21,9 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "BIGTREE BTT002 V1.0 only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h
index cd9d60d2f01..6c59f27c5ef 100644
--- a/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h
+++ b/Marlin/src/pins/stm32f4/pins_BTT_GTR_V1_0.h
@@ -21,9 +21,9 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 8 || E_STEPPERS > 8
+#include "env_validate.h"
+
+#if HOTENDS > 8 || E_STEPPERS > 8
   #error "BIGTREE GTR V1.0 supports up to 8 hotends / E-steppers."
 #elif HOTENDS > MAX_E_STEPPERS || E_STEPPERS > MAX_E_STEPPERS
   #error "Marlin extruder/hotends limit! Increase MAX_E_STEPPERS to continue."
diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
index ab7f5126ff5..863429f2a2a 100644
--- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
+++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 // BigTreeTech driver expansion module https://bit.ly/3ptRRoj
 //#define BTT_MOTOR_EXPANSION
diff --git a/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h b/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h
index 7965d262c3d..34124a9b02e 100644
--- a/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h
+++ b/Marlin/src/pins/stm32f4/pins_FLYF407ZG.h
@@ -21,9 +21,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 6 || E_STEPPERS > 6
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 6 || E_STEPPERS > 6
   #error "FLYF407ZG supports up to 6 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h b/Marlin/src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h
index ad437651354..ef1c14aae0b 100644
--- a/Marlin/src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h
+++ b/Marlin/src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h
@@ -21,9 +21,7 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define DEFAULT_MACHINE_NAME "3D Printer"
 
diff --git a/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h
index a2807756463..d617087e9df 100644
--- a/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h
+++ b/Marlin/src/pins/stm32f4/pins_FYSETC_S6.h
@@ -21,9 +21,9 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 3 || E_STEPPERS > 3
+#include "env_validate.h"
+
+#if HOTENDS > 3 || E_STEPPERS > 3
   #error "RUMBA32 supports up to 3 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
index bf6df035623..fad8d2059e0 100644
--- a/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_K.h
@@ -18,9 +18,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "LERDGE K supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h
index c6cfa98831e..105d0d6f607 100644
--- a/Marlin/src/pins/stm32f4/pins_LERDGE_S.h
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_S.h
@@ -18,9 +18,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "LERDGE S supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
index 606d932c573..974392373f2 100644
--- a/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
+++ b/Marlin/src/pins/stm32f4/pins_LERDGE_X.h
@@ -18,9 +18,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 1 || E_STEPPERS > 1
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 1 || E_STEPPERS > 1
   #error "LERDGE X only supports one hotend / E-stepper. Comment out this line to continue."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h
index c2f5f324ba2..589300f3417 100644
--- a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h
+++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN2.h
@@ -21,9 +21,9 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "MKS_ROBIN2 supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h
index 8308f3998f8..f9e85c49190 100644
--- a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h
+++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h
@@ -21,9 +21,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "MKS Robin Nano V3 supports up to 2 hotends / E-steppers."
 #elif HAS_FSMC_TFT
   #error "MKS Robin Nano V3 doesn't support FSMC-based TFT displays."
diff --git a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h
index 5533e35f07c..f2ddfc2b522 100644
--- a/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h
+++ b/Marlin/src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h
@@ -21,9 +21,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "MKS Robin Nano V3 supports up to 1 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h b/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h
index 2a0cfa897cf..be6e4f8a342 100644
--- a/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h
+++ b/Marlin/src/pins/stm32f4/pins_RUMBA32_common.h
@@ -25,9 +25,9 @@
  * Common pin assignments for all RUMBA32 boards
  */
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 3 || E_STEPPERS > 3
+#include "env_validate.h"
+
+#if HOTENDS > 3 || E_STEPPERS > 3
   #error "RUMBA32 boards support up to 3 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h b/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h
index 25679517c26..dc02fd02eac 100644
--- a/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h
+++ b/Marlin/src/pins/stm32f4/pins_STEVAL_3DP001V1.h
@@ -40,9 +40,7 @@
 
 #pragma once
 
-#if NOT_TARGET(STM32F4)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #ifndef MACHINE_NAME
   #define MACHINE_NAME "STEVAL-3DP001V1"
diff --git a/Marlin/src/pins/stm32f4/pins_VAKE403D.h b/Marlin/src/pins/stm32f4/pins_VAKE403D.h
index 1135af847fa..9d122c26422 100644
--- a/Marlin/src/pins/stm32f4/pins_VAKE403D.h
+++ b/Marlin/src/pins/stm32f4/pins_VAKE403D.h
@@ -21,9 +21,10 @@
  */
 #pragma once
 
-#if NOT_TARGET(STM32F4, STM32F4xx)
-  #error "Oops! Select an STM32F4 board in 'Tools > Board.'"
-#elif HOTENDS > 2 || E_STEPPERS > 2
+#define ALLOW_STM32DUINO
+#include "env_validate.h"
+
+#if HOTENDS > 2 || E_STEPPERS > 2
   #error "STM32F4 supports up to 2 hotends / E-steppers."
 #endif
 
diff --git a/Marlin/src/pins/teensy2/env_validate.h b/Marlin/src/pins/teensy2/env_validate.h
new file mode 100644
index 00000000000..5f0ea4f3b67
--- /dev/null
+++ b/Marlin/src/pins/teensy2/env_validate.h
@@ -0,0 +1,28 @@
+/**
+ * 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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#if NOT_TARGET(__AVR_AT90USB1286__) && (DISABLED(ALLOW_AT90USB1286P) || NOT_TARGET(__AVR_AT90USB1286P__))
+  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
+#endif
+
+#undef ALLOW_AT90USB1286P
diff --git a/Marlin/src/pins/teensy2/pins_5DPRINT.h b/Marlin/src/pins/teensy2/pins_5DPRINT.h
index 908e12e0bae..6e1f9c02174 100644
--- a/Marlin/src/pins/teensy2/pins_5DPRINT.h
+++ b/Marlin/src/pins/teensy2/pins_5DPRINT.h
@@ -68,9 +68,7 @@
  * https://bitbucket.org/makible/5dprint-d8-controller-board
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define DEFAULT_MACHINE_NAME "Makibox"
 #define BOARD_INFO_NAME      "5DPrint D8"
diff --git a/Marlin/src/pins/teensy2/pins_BRAINWAVE.h b/Marlin/src/pins/teensy2/pins_BRAINWAVE.h
index 97d210a0f85..cdcc249c00d 100644
--- a/Marlin/src/pins/teensy2/pins_BRAINWAVE.h
+++ b/Marlin/src/pins/teensy2/pins_BRAINWAVE.h
@@ -69,7 +69,7 @@
  */
 
 #if NOT_TARGET(__AVR_AT90USB646__)
-  #error "Oops! Select 'AT90USB646_TEENSYPP' in 'Tools > Board.'"
+  #error "Oops! Select 'Brainwave' in 'Tools > Board.'"
 #endif
 
 #define BOARD_INFO_NAME "Brainwave"
diff --git a/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h b/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h
index e41fcaab944..319130ef968 100644
--- a/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h
+++ b/Marlin/src/pins/teensy2/pins_BRAINWAVE_PRO.h
@@ -75,9 +75,7 @@
  *   4. The programmer is no longer needed. Remove it.
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Brainwave Pro"
 
diff --git a/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h b/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h
index 2401c976f15..7b3685d08e7 100644
--- a/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h
+++ b/Marlin/src/pins/teensy2/pins_PRINTRBOARD.h
@@ -62,9 +62,7 @@
  *   4. The programmer is no longer needed. Remove it.
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Printrboard"
 
diff --git a/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h b/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h
index d4f9fc76415..0e6842125e1 100644
--- a/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h
+++ b/Marlin/src/pins/teensy2/pins_PRINTRBOARD_REVF.h
@@ -63,9 +63,7 @@
  *   4. The programmer is no longer needed. Remove it.
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #if !defined(__MARLIN_DEPS__) && !defined(USBCON)
   #error "USBCON should be defined by the platform for this board."
diff --git a/Marlin/src/pins/teensy2/pins_SAV_MKI.h b/Marlin/src/pins/teensy2/pins_SAV_MKI.h
index bcc456c16e8..cdba535090e 100644
--- a/Marlin/src/pins/teensy2/pins_SAV_MKI.h
+++ b/Marlin/src/pins/teensy2/pins_SAV_MKI.h
@@ -62,9 +62,7 @@
  *   4. The programmer is no longer needed. Remove it.
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME         "SAV MkI"
 #define DEFAULT_MACHINE_NAME    BOARD_INFO_NAME
diff --git a/Marlin/src/pins/teensy2/pins_TEENSY2.h b/Marlin/src/pins/teensy2/pins_TEENSY2.h
index d43e39b09aa..efb409bf325 100644
--- a/Marlin/src/pins/teensy2/pins_TEENSY2.h
+++ b/Marlin/src/pins/teensy2/pins_TEENSY2.h
@@ -107,9 +107,7 @@
  *       E DIR   35 a7  a3 31 Y DIR
  */
 
-#if NOT_TARGET(__AVR_AT90USB1286__)
-  #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
-#endif
+#include "env_validate.h"
 
 #define BOARD_INFO_NAME "Teensy++2.0"
 
diff --git a/Marlin/src/pins/teensy2/pins_TEENSYLU.h b/Marlin/src/pins/teensy2/pins_TEENSYLU.h
index 54cee137ad2..f551d802cfb 100644
--- a/Marlin/src/pins/teensy2/pins_TEENSYLU.h
+++ b/Marlin/src/pins/teensy2/pins_TEENSYLU.h
@@ -72,6 +72,9 @@
   *  The pin assignments in this file match the silkscreen.
   */
 
+#define ALLOW_AT90USB1286P
+#include "env_validate.h"
+
 #if NOT_TARGET(__AVR_AT90USB1286__, __AVR_AT90USB1286P__)
   #error "Oops! Select 'Teensy++ 2.0' or 'Printrboard' in 'Tools > Board.'"
 #endif
diff --git a/buildroot/bin/mftest b/buildroot/bin/mftest
index 00f7a2e7e03..d769ff8cb80 100755
--- a/buildroot/bin/mftest
+++ b/buildroot/bin/mftest
@@ -21,7 +21,7 @@ Usage: mftest [-t|--env=<env>] [-n|--num=<num>] [-m|--make] [-y|--build=<Y|n>]
 
 OPTIONS
   -t --env         The environment of the test to apply / run. (As named in platformio.ini.)
-  -n --num         The index of the test to run. (In *-tests file order.)
+  -n --num         The index of the test to run. (In file order.)
   -m --make        Use the make / Docker method for the build.
   -y --build       Skip 'Do you want to build this test?' and assume YES.
   -h --help        Print this help.
@@ -204,11 +204,10 @@ fi
 if [[ $TESTENV == '-' ]]; then
   IND=0
   NAMES=()
-  for FILE in $( ls -1 $TESTPATH/*-tests )
+  for FILE in $( ls -1 $TESTPATH/* )
   do
     let IND++
-    TNAME=${FILE/-tests/}
-    TNAME=${TNAME/$TESTPATH\//}
+    TNAME=${FILE/$TESTPATH\//}
     NAMES+=($TNAME)
     (( IND < 10 )) && echo -n " "
     echo " $IND) $TNAME"
@@ -231,7 +230,7 @@ if [[ $TESTENV == '-' ]]; then
 fi
 
 # Get the contents of the test file
-OUT=$( cat $TESTPATH/$TESTENV-tests 2>/dev/null ) || { errout "Can't find test '$TESTENV'." ; exit 1 ; }
+OUT=$( cat $TESTPATH/$TESTENV 2>/dev/null ) || { errout "Can't find test '$TESTENV'." ; exit 1 ; }
 
 # Count up the number of tests
 TESTCOUNT=$( awk "/$ISEXEC/{a++}END{print a}" <<<"$OUT" )
@@ -297,7 +296,7 @@ echo "$OUT" | {
 echo -ne "\033[0m"
 
 # Make clear it's a TEST
-opt_set CUSTOM_MACHINE_NAME "\"$TESTENV-tests ($CHOICE)\""
+opt_set CUSTOM_MACHINE_NAME "\"Test $TESTENV ($CHOICE)\""
 
 # Build the test too?
 if [[ -z "$BUILD_YES" ]]; then
diff --git a/buildroot/tests/run_tests b/buildroot/bin/run_tests
similarity index 79%
rename from buildroot/tests/run_tests
rename to buildroot/bin/run_tests
index c4286f4695a..26284fa6933 100755
--- a/buildroot/tests/run_tests
+++ b/buildroot/bin/run_tests
@@ -2,8 +2,9 @@
 #
 # run_tests
 #
-export PATH="$PATH:$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
-export PATH="$PATH:./buildroot/bin"
+HERE="$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )"
+TESTS="$HERE/../tests"
+export PATH="$HERE:$TESTS:$PATH"
 
 # exit on first failure
 set -e
@@ -40,10 +41,9 @@ export -f exec_test
 printf "Running \033[0;32m$2\033[0m Tests\n"
 
 if [[ $2 = "ALL" ]]; then
-  dir_list=("$(dirname "${BASH_SOURCE[0]}")"/*)
-  declare -a tests=(${dir_list[@]/*run_tests/})
+  tests=("$TESTS"/*)
   for f in "${tests[@]}"; do
-    testenv=$(basename $f | cut -d"-" -f1)
+    testenv=$(basename $f)
     printf "Running \033[0;32m$f\033[0m Tests\n"
     exec_test $1 "$testenv --target clean" "Setup Build Environment"
     if [[ $GIT_RESET_HARD == "true" ]]; then
@@ -58,16 +58,16 @@ else
   # If the test name is 1 or 2 digits, treat it as an index
   if [[ "$test_name" =~ ^[0-9][0-9]?$ ]] ; then
     # Find the test name that corresponds to that index
-    test_name="$(cat buildroot/tests/$2-tests | grep -e '^exec_test' | sed -n "$3p" | sed "s/.*\$1 \$2 \"\([^\"]*\).*/\1/g")"
+    test_name="$(cat $TESTS/$2 | grep -e '^exec_test' | sed -n "$3p" | sed "s/.*\$1 \$2 \"\([^\"]*\).*/\1/g")"
     if [[ -z "$test_name" ]] ; then
       # Fail if none matches
-      printf "\033[0;31mCould not find test \033[0m#$3\033[0;31m in \033[0mbuildroot/tests/$2-tests\n"
+      printf "\033[0;31mCould not find test \033[0m#$3\033[0;31m in \033[0mbuildroot/tests/$2\n"
       exit 1
     else
       printf "\033[0;32mMatching test \033[0m#$3\033[0;32m: '\033[0m$test_name\033[0;32m'\n"
     fi
   fi
-  $2-tests $1 $2 "$test_name"
+  $TESTS/$2 $1 $2 "$test_name"
   if [[ $GIT_RESET_HARD == "true" ]]; then
     git reset --hard HEAD
   else
diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies-post.py b/buildroot/share/PlatformIO/scripts/common-dependencies-post.py
deleted file mode 100644
index 2b1b948119f..00000000000
--- a/buildroot/share/PlatformIO/scripts/common-dependencies-post.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# common-dependencies-post.py
-# Convenience script to add build flags for Marlin Enabled Features
-#
-
-Import("env")
-Import("projenv")
-
-def apply_board_build_flags():
-	if not 'BOARD_CUSTOM_BUILD_FLAGS' in env['MARLIN_FEATURES']:
-		return
-	projenv.Append(CCFLAGS=env['MARLIN_FEATURES']['BOARD_CUSTOM_BUILD_FLAGS'].split())
-
-# We need to add the board build flags in a post script
-# so the platform build script doesn't overwrite the custom CCFLAGS
-apply_board_build_flags()
diff --git a/buildroot/share/PlatformIO/scripts/preflight-checks.py b/buildroot/share/PlatformIO/scripts/preflight-checks.py
index 4c8a00e74c5..969a82aad29 100644
--- a/buildroot/share/PlatformIO/scripts/preflight-checks.py
+++ b/buildroot/share/PlatformIO/scripts/preflight-checks.py
@@ -49,8 +49,7 @@ config = env.GetProjectConfig()
 result = check_envs("env:"+build_env, base_envs, config)
 
 if not result:
-	err = "Error: your selected build environment '%s' is not compatible with MOTHERBOARD=%s in Configuration.h. " \
-		  "Please use one of compatible build environments for this board: %s" % \
+	err = "Error: Build environment '%s' is incompatible with %s. Use one of these: %s" % \
 		  (build_env, motherboard, ",".join([e[4:] for e in base_envs if e.startswith("env:")]))
 	raise SystemExit(err)
 
diff --git a/buildroot/tests/ARMED-tests b/buildroot/tests/ARMED
similarity index 100%
rename from buildroot/tests/ARMED-tests
rename to buildroot/tests/ARMED
diff --git a/buildroot/tests/BIGTREE_BTT002-tests b/buildroot/tests/BIGTREE_BTT002
similarity index 100%
rename from buildroot/tests/BIGTREE_BTT002-tests
rename to buildroot/tests/BIGTREE_BTT002
diff --git a/buildroot/tests/BIGTREE_GTR_V1_0-tests b/buildroot/tests/BIGTREE_GTR_V1_0
similarity index 100%
rename from buildroot/tests/BIGTREE_GTR_V1_0-tests
rename to buildroot/tests/BIGTREE_GTR_V1_0
diff --git a/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive-tests b/buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive
similarity index 100%
rename from buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive-tests
rename to buildroot/tests/BIGTREE_GTR_V1_0_usb_flash_drive
diff --git a/buildroot/tests/BIGTREE_SKR_PRO-tests b/buildroot/tests/BIGTREE_SKR_PRO
similarity index 100%
rename from buildroot/tests/BIGTREE_SKR_PRO-tests
rename to buildroot/tests/BIGTREE_SKR_PRO
diff --git a/buildroot/tests/DUE-tests b/buildroot/tests/DUE
similarity index 100%
rename from buildroot/tests/DUE-tests
rename to buildroot/tests/DUE
diff --git a/buildroot/tests/DUE_archim-tests b/buildroot/tests/DUE_archim
similarity index 100%
rename from buildroot/tests/DUE_archim-tests
rename to buildroot/tests/DUE_archim
diff --git a/buildroot/tests/FLYF407ZG-tests b/buildroot/tests/FLYF407ZG
similarity index 100%
rename from buildroot/tests/FLYF407ZG-tests
rename to buildroot/tests/FLYF407ZG
diff --git a/buildroot/tests/FYSETC_F6-tests b/buildroot/tests/FYSETC_F6
similarity index 100%
rename from buildroot/tests/FYSETC_F6-tests
rename to buildroot/tests/FYSETC_F6
diff --git a/buildroot/tests/FYSETC_S6-tests b/buildroot/tests/FYSETC_S6
similarity index 100%
rename from buildroot/tests/FYSETC_S6-tests
rename to buildroot/tests/FYSETC_S6
diff --git a/buildroot/tests/LERDGEX-tests b/buildroot/tests/LERDGEX
similarity index 100%
rename from buildroot/tests/LERDGEX-tests
rename to buildroot/tests/LERDGEX
diff --git a/buildroot/tests/LPC1768-tests b/buildroot/tests/LPC1768
similarity index 100%
rename from buildroot/tests/LPC1768-tests
rename to buildroot/tests/LPC1768
diff --git a/buildroot/tests/LPC1769-tests b/buildroot/tests/LPC1769
similarity index 100%
rename from buildroot/tests/LPC1769-tests
rename to buildroot/tests/LPC1769
diff --git a/buildroot/tests/NUCLEO_F767ZI-tests b/buildroot/tests/NUCLEO_F767ZI
similarity index 100%
rename from buildroot/tests/NUCLEO_F767ZI-tests
rename to buildroot/tests/NUCLEO_F767ZI
diff --git a/buildroot/tests/REMRAM_V1-tests b/buildroot/tests/REMRAM_V1
similarity index 100%
rename from buildroot/tests/REMRAM_V1-tests
rename to buildroot/tests/REMRAM_V1
diff --git a/buildroot/tests/SAMD51_grandcentral_m4-tests b/buildroot/tests/SAMD51_grandcentral_m4
similarity index 100%
rename from buildroot/tests/SAMD51_grandcentral_m4-tests
rename to buildroot/tests/SAMD51_grandcentral_m4
diff --git a/buildroot/tests/STM32F070CB_malyan-tests b/buildroot/tests/STM32F070CB_malyan
similarity index 100%
rename from buildroot/tests/STM32F070CB_malyan-tests
rename to buildroot/tests/STM32F070CB_malyan
diff --git a/buildroot/tests/STM32F070RB_malyan-tests b/buildroot/tests/STM32F070RB_malyan
similarity index 100%
rename from buildroot/tests/STM32F070RB_malyan-tests
rename to buildroot/tests/STM32F070RB_malyan
diff --git a/buildroot/tests/STM32F103CB_malyan-tests b/buildroot/tests/STM32F103CB_malyan
similarity index 100%
rename from buildroot/tests/STM32F103CB_malyan-tests
rename to buildroot/tests/STM32F103CB_malyan
diff --git a/buildroot/tests/STM32F103RC_btt-tests b/buildroot/tests/STM32F103RC_btt
similarity index 100%
rename from buildroot/tests/STM32F103RC_btt-tests
rename to buildroot/tests/STM32F103RC_btt
diff --git a/buildroot/tests/STM32F103RC_btt_USB-tests b/buildroot/tests/STM32F103RC_btt_USB
similarity index 100%
rename from buildroot/tests/STM32F103RC_btt_USB-tests
rename to buildroot/tests/STM32F103RC_btt_USB
diff --git a/buildroot/tests/STM32F103RC_fysetc-tests b/buildroot/tests/STM32F103RC_fysetc
similarity index 100%
rename from buildroot/tests/STM32F103RC_fysetc-tests
rename to buildroot/tests/STM32F103RC_fysetc
diff --git a/buildroot/tests/STM32F103RC_meeb-tests b/buildroot/tests/STM32F103RC_meeb
similarity index 100%
rename from buildroot/tests/STM32F103RC_meeb-tests
rename to buildroot/tests/STM32F103RC_meeb
diff --git a/buildroot/tests/STM32F103RE-tests b/buildroot/tests/STM32F103RE
similarity index 100%
rename from buildroot/tests/STM32F103RE-tests
rename to buildroot/tests/STM32F103RE
diff --git a/buildroot/tests/STM32F103RET6_creality-tests b/buildroot/tests/STM32F103RET6_creality
similarity index 100%
rename from buildroot/tests/STM32F103RET6_creality-tests
rename to buildroot/tests/STM32F103RET6_creality
diff --git a/buildroot/tests/STM32F103RE_btt-tests b/buildroot/tests/STM32F103RE_btt
similarity index 100%
rename from buildroot/tests/STM32F103RE_btt-tests
rename to buildroot/tests/STM32F103RE_btt
diff --git a/buildroot/tests/STM32F103RE_btt_USB-tests b/buildroot/tests/STM32F103RE_btt_USB
similarity index 100%
rename from buildroot/tests/STM32F103RE_btt_USB-tests
rename to buildroot/tests/STM32F103RE_btt_USB
diff --git a/buildroot/tests/STM32F103VE_longer-tests b/buildroot/tests/STM32F103VE_longer
similarity index 100%
rename from buildroot/tests/STM32F103VE_longer-tests
rename to buildroot/tests/STM32F103VE_longer
diff --git a/buildroot/tests/STM32F401VE_STEVAL-tests b/buildroot/tests/STM32F401VE_STEVAL
similarity index 100%
rename from buildroot/tests/STM32F401VE_STEVAL-tests
rename to buildroot/tests/STM32F401VE_STEVAL
diff --git a/buildroot/tests/STM32F407VE_black-tests b/buildroot/tests/STM32F407VE_black
similarity index 100%
rename from buildroot/tests/STM32F407VE_black-tests
rename to buildroot/tests/STM32F407VE_black
diff --git a/buildroot/tests/at90usb1286_cdc-tests b/buildroot/tests/at90usb1286_cdc
similarity index 100%
rename from buildroot/tests/at90usb1286_cdc-tests
rename to buildroot/tests/at90usb1286_cdc
diff --git a/buildroot/tests/at90usb1286_dfu-tests b/buildroot/tests/at90usb1286_dfu
similarity index 100%
rename from buildroot/tests/at90usb1286_dfu-tests
rename to buildroot/tests/at90usb1286_dfu
diff --git a/buildroot/tests/esp32-tests b/buildroot/tests/esp32
similarity index 100%
rename from buildroot/tests/esp32-tests
rename to buildroot/tests/esp32
diff --git a/buildroot/tests/jgaurora_a5s_a1-tests b/buildroot/tests/jgaurora_a5s_a1
similarity index 100%
rename from buildroot/tests/jgaurora_a5s_a1-tests
rename to buildroot/tests/jgaurora_a5s_a1
diff --git a/buildroot/tests/linux_native-tests b/buildroot/tests/linux_native
similarity index 100%
rename from buildroot/tests/linux_native-tests
rename to buildroot/tests/linux_native
diff --git a/buildroot/tests/malyan_M300-tests b/buildroot/tests/malyan_M300
similarity index 100%
rename from buildroot/tests/malyan_M300-tests
rename to buildroot/tests/malyan_M300
diff --git a/buildroot/tests/mega1280-tests b/buildroot/tests/mega1280
similarity index 100%
rename from buildroot/tests/mega1280-tests
rename to buildroot/tests/mega1280
diff --git a/buildroot/tests/mega2560-tests b/buildroot/tests/mega2560
similarity index 100%
rename from buildroot/tests/mega2560-tests
rename to buildroot/tests/mega2560
diff --git a/buildroot/tests/mks_robin-tests b/buildroot/tests/mks_robin
similarity index 100%
rename from buildroot/tests/mks_robin-tests
rename to buildroot/tests/mks_robin
diff --git a/buildroot/tests/mks_robin_lite-tests b/buildroot/tests/mks_robin_lite
similarity index 100%
rename from buildroot/tests/mks_robin_lite-tests
rename to buildroot/tests/mks_robin_lite
diff --git a/buildroot/tests/mks_robin_mini-tests b/buildroot/tests/mks_robin_mini
similarity index 100%
rename from buildroot/tests/mks_robin_mini-tests
rename to buildroot/tests/mks_robin_mini
diff --git a/buildroot/tests/mks_robin_nano35-tests b/buildroot/tests/mks_robin_nano35
similarity index 100%
rename from buildroot/tests/mks_robin_nano35-tests
rename to buildroot/tests/mks_robin_nano35
diff --git a/buildroot/tests/mks_robin_nano35_stm32-tests b/buildroot/tests/mks_robin_nano35_stm32
similarity index 100%
rename from buildroot/tests/mks_robin_nano35_stm32-tests
rename to buildroot/tests/mks_robin_nano35_stm32
diff --git a/buildroot/tests/mks_robin_pro-tests b/buildroot/tests/mks_robin_pro
similarity index 100%
rename from buildroot/tests/mks_robin_pro-tests
rename to buildroot/tests/mks_robin_pro
diff --git a/buildroot/tests/mks_robin_stm32-tests b/buildroot/tests/mks_robin_stm32
similarity index 100%
rename from buildroot/tests/mks_robin_stm32-tests
rename to buildroot/tests/mks_robin_stm32
diff --git a/buildroot/tests/rambo-tests b/buildroot/tests/rambo
similarity index 100%
rename from buildroot/tests/rambo-tests
rename to buildroot/tests/rambo
diff --git a/buildroot/tests/rumba32-tests b/buildroot/tests/rumba32
similarity index 100%
rename from buildroot/tests/rumba32-tests
rename to buildroot/tests/rumba32
diff --git a/buildroot/tests/sanguino1284p-tests b/buildroot/tests/sanguino1284p
similarity index 100%
rename from buildroot/tests/sanguino1284p-tests
rename to buildroot/tests/sanguino1284p
diff --git a/buildroot/tests/sanguino644p-tests b/buildroot/tests/sanguino644p
similarity index 100%
rename from buildroot/tests/sanguino644p-tests
rename to buildroot/tests/sanguino644p
diff --git a/buildroot/tests/teensy31-tests b/buildroot/tests/teensy31
similarity index 100%
rename from buildroot/tests/teensy31-tests
rename to buildroot/tests/teensy31
diff --git a/buildroot/tests/teensy35-tests b/buildroot/tests/teensy35
similarity index 100%
rename from buildroot/tests/teensy35-tests
rename to buildroot/tests/teensy35
diff --git a/buildroot/tests/teensy41-tests b/buildroot/tests/teensy41
similarity index 100%
rename from buildroot/tests/teensy41-tests
rename to buildroot/tests/teensy41
diff --git a/platformio.ini b/platformio.ini
index aad59362cc6..74452754ad3 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -215,7 +215,6 @@ extra_scripts      =
   pre:buildroot/share/PlatformIO/scripts/common-dependencies.py
   pre:buildroot/share/PlatformIO/scripts/common-cxxflags.py
   pre:buildroot/share/PlatformIO/scripts/preflight-checks.py
-  post:buildroot/share/PlatformIO/scripts/common-dependencies-post.py
 build_flags        = -fmax-errors=5 -g3 -D__MARLIN_FIRMWARE__ -fmerge-constants
 lib_deps           =
 
@@ -728,6 +727,12 @@ platform = ${common_LPC.platform}
 extends  = common_LPC
 board    = nxp_lpc1769
 
+# BTT SKR 1.4 needs a UART3 tweak
+[env:LPC1768_btt_skr_v1_4]
+platform    = ${LPC1768.platform}
+extends     = env:LPC1768
+build_flags = ${env:LPC1768.build_flags} -DLPC_PINCFG_UART3_P4_28
+
 #################################
 #                               #
 #      STM32 Architecture       #