diff --git a/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp b/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cded8a16ae48a3fd7f53328192ed5a9f73c980e6
--- /dev/null
+++ b/Marlin/src/HAL/HAL_LPC1768/DebugMonitor_LPC1768.cpp
@@ -0,0 +1,318 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef TARGET_LPC1768
+
+#include "../../core/macros.h"
+#include "../../core/serial.h"
+#include <stdarg.h>
+
+#include "../shared/backtrace/unwinder.h"
+#include "../shared/backtrace/unwmemaccess.h"
+#include "watchdog.h"
+#include <debug_frmwrk.h>
+
+
+// Debug monitor that dumps to the Programming port all status when
+// an exception or WDT timeout happens - And then resets the board
+
+// All the Monitor routines must run with interrupts disabled and
+// under an ISR execution context. That is why we cannot reuse the
+// Serial interrupt routines or any C runtime, as we don't know the
+// state we are when running them
+
+// A SW memory barrier, to ensure GCC does not overoptimize loops
+#define sw_barrier() __asm__ volatile("": : :"memory");
+
+// (re)initialize UART0 as a monitor output to 250000,n,8,1
+static void TXBegin(void) {
+}
+
+// Send character through UART with no interrupts
+static void TX(char c) {
+  _DBC(c);
+}
+
+// Send String through UART
+static void TX(const char* s) {
+  while (*s) TX(*s++);
+}
+
+static void TXDigit(uint32_t d) {
+  if (d < 10) TX((char)(d+'0'));
+  else if (d < 16) TX((char)(d+'A'-10));
+  else TX('?');
+}
+
+// Send Hex number thru UART
+static void TXHex(uint32_t v) {
+  TX("0x");
+  for (uint8_t i = 0; i < 8; i++, v <<= 4)
+    TXDigit((v >> 28) & 0xF);
+}
+
+// Send Decimal number thru UART
+static void TXDec(uint32_t v) {
+  if (!v) {
+    TX('0');
+    return;
+  }
+
+  char nbrs[14];
+  char *p = &nbrs[0];
+  while (v != 0) {
+    *p++ = '0' + (v % 10);
+    v /= 10;
+  }
+  do {
+    p--;
+    TX(*p);
+  } while (p != &nbrs[0]);
+}
+
+// Dump a backtrace entry
+static bool UnwReportOut(void* ctx, const UnwReport* bte) {
+  int* p = (int*)ctx;
+
+  (*p)++;
+  TX('#'); TXDec(*p); TX(" : ");
+  TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
+  TX('+'); TXDec(bte->address - bte->function);
+  TX(" PC:");TXHex(bte->address); TX('\n');
+  return true;
+}
+
+#ifdef UNW_DEBUG
+  void UnwPrintf(const char* format, ...) {
+    char dest[256];
+    va_list argptr;
+    va_start(argptr, format);
+    vsprintf(dest, format, argptr);
+    va_end(argptr);
+    TX(&dest[0]);
+  }
+#endif
+
+/* Table of function pointers for passing to the unwinder */
+static const UnwindCallbacks UnwCallbacks = {
+  UnwReportOut,
+  UnwReadW,
+  UnwReadH,
+  UnwReadB
+  #if defined(UNW_DEBUG)
+   ,UnwPrintf
+  #endif
+};
+
+
+/**
+ * HardFaultHandler_C:
+ * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
+ * as the parameter. We can then read the values from the stack and place them
+ * into local variables for ease of reading.
+ * We then read the various Fault Status and Address Registers to help decode
+ * cause of the fault.
+ * The function ends with a BKPT instruction to force control back into the debugger
+ */
+extern "C"
+void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
+
+  static const char* causestr[] = {
+    "NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
+  };
+
+  UnwindFrame btf;
+
+  // Dump report to the Programming port (interrupts are DISABLED)
+  TXBegin();
+  TX("\n\n## Software Fault detected ##\n");
+  TX("Cause: "); TX(causestr[cause]); TX('\n');
+
+  TX("R0   : "); TXHex(((unsigned long)sp[0])); TX('\n');
+  TX("R1   : "); TXHex(((unsigned long)sp[1])); TX('\n');
+  TX("R2   : "); TXHex(((unsigned long)sp[2])); TX('\n');
+  TX("R3   : "); TXHex(((unsigned long)sp[3])); TX('\n');
+  TX("R12  : "); TXHex(((unsigned long)sp[4])); TX('\n');
+  TX("LR   : "); TXHex(((unsigned long)sp[5])); TX('\n');
+  TX("PC   : "); TXHex(((unsigned long)sp[6])); TX('\n');
+  TX("PSR  : "); TXHex(((unsigned long)sp[7])); TX('\n');
+
+  // Configurable Fault Status Register
+  // Consists of MMSR, BFSR and UFSR
+  TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
+
+  // Hard Fault Status Register
+  TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
+
+  // Debug Fault Status Register
+  TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
+
+  // Auxiliary Fault Status Register
+  TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
+
+  // Read the Fault Address Registers. These may not contain valid values.
+  // Check BFARVALID/MMARVALID to see if they are valid values
+  // MemManage Fault Address Register
+  TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
+
+  // Bus Fault Address Register
+  TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
+
+  TX("ExcLR: "); TXHex(lr); TX('\n');
+  TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
+
+  btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
+  btf.fp = btf.sp;
+  btf.lr = ((unsigned long)sp[5]);
+  btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
+
+  // Perform a backtrace
+  TX("\nBacktrace:\n\n");
+  int ctr = 0;
+  UnwindStart(&btf, &UnwCallbacks, &ctr);
+
+  // Disable all NVIC interrupts
+  NVIC->ICER[0] = 0xFFFFFFFF;
+  NVIC->ICER[1] = 0xFFFFFFFF;
+
+  // Relocate VTOR table to default position
+  SCB->VTOR = 0;
+
+  // Clear cause of reset to prevent entering smoothie bootstrap
+  HAL_clear_reset_source();
+  // Restart watchdog
+  //WDT_Restart(WDT);
+  watchdog_init();
+
+  // Reset controller
+  NVIC_SystemReset();
+
+  while(1) { watchdog_init(); }
+}
+
+extern "C" {
+__attribute__((naked)) void NMI_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#0")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void HardFault_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#1")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void MemManage_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#2")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void BusFault_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#3")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void UsageFault_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#4")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void DebugMon_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#5")
+    A("b HardFault_HandlerC")
+  );
+}
+
+/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
+__attribute__((naked)) void WDT_IRQHandler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#6")
+    A("b HardFault_HandlerC")
+  );
+}
+
+__attribute__((naked)) void RSTC_Handler(void) {
+  __asm__ __volatile__ (
+    ".syntax unified" "\n\t"
+    A("tst lr, #4")
+    A("ite eq")
+    A("mrseq r0, msp")
+    A("mrsne r0, psp")
+    A("mov r1,lr")
+    A("mov r2,#7")
+    A("b HardFault_HandlerC")
+  );
+}
+}
+#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/HAL_LPC1768/HAL.h
index 4986dcdd7b46c577237585e81f4bb38cf181c60f..cb757bb8cd7fb9421222ec64be8d5cd5a4011b78 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.h
@@ -152,4 +152,7 @@ using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
 // Parse a G-code word into a pin index
 int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
 
+#define HAL_IDLETASK 1
+void HAL_idletask(void);
+
 #endif // _HAL_LPC1768_H_
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
index c8fe029d39bcf020041bf8ee580c4f7f5374dbc5..2765bb553a5668230bcabe1bc9bcd6ad84ee30de 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp
@@ -49,7 +49,6 @@
 #ifdef TARGET_LPC1768
 
 #include "../../inc/MarlinConfig.h"
-
 // --------------------------------------------------------------------------
 // Includes
 // --------------------------------------------------------------------------
@@ -59,7 +58,6 @@
 // --------------------------------------------------------------------------
 // Public functions
 // --------------------------------------------------------------------------
-
 #if ENABLED(LPC_SOFTWARE_SPI)
 
   #include "SoftwareSPI.h"
@@ -127,8 +125,25 @@
   #include <lpc17xx_ssp.h>
   #include <lpc17xx_clkpwr.h>
 
-  void spiBegin() {  // setup SCK, MOSI & MISO pins for SSP0
+  // decide which HW SPI device to use
+  #ifndef LPC_HW_SPI_DEV
+    #if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
+      #define LPC_HW_SPI_DEV 1
+    #else
+      #if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18)
+        #define LPC_HW_SPI_DEV 0
+      #else
+        #error "Invalid pins selected for hardware SPI"
+      #endif
+    #endif
+  #endif
+  #if (LPC_HW_SPI_DEV == 0)
+    #define LPC_SSPn LPC_SSP0
+  #else
+    #define LPC_SSPn LPC_SSP1
+  #endif
 
+  void spiBegin() {  // setup SCK, MOSI & MISO pins for SSP0
     PINSEL_CFG_Type PinCfg;  // data structure to hold init values
     PinCfg.Funcnum = 2;
     PinCfg.OpenDrain = 0;
@@ -147,10 +162,13 @@
     PinCfg.Portnum = LPC1768_PIN_PORT(MOSI_PIN);
     PINSEL_ConfigPin(&PinCfg);
     SET_OUTPUT(MOSI_PIN);
+    // divide PCLK by 2 for SSP0
+    CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
+    spiInit(0);
+    SSP_Cmd(LPC_SSPn, ENABLE);  // start SSP running
   }
 
   void spiInit(uint8_t spiRate) {
-    SSP_Cmd(LPC_SSP0, DISABLE); // Disable SSP0 before changing rate
     // table to convert Marlin spiRates (0-5 plus default) into bit rates
     uint32_t Marlin_speed[7]; // CPSR is always 2
     Marlin_speed[0] = 8333333; //(SCR:  2)  desired: 8,000,000  actual: 8,333,333  +4.2%  SPI_FULL_SPEED
@@ -160,33 +178,32 @@
     Marlin_speed[4] =  500000; //(SCR: 49)  desired:   500,000  actual:   500,000         SPI_SPEED_5
     Marlin_speed[5] =  250000; //(SCR: 99)  desired:   250,000  actual:   250,000         SPI_SPEED_6
     Marlin_speed[6] =  125000; //(SCR:199)  desired:   125,000  actual:   125,000         Default from HAL.h
-
-    // divide PCLK by 2 for SSP0
-    CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_SSP0, CLKPWR_PCLKSEL_CCLK_DIV_2);
-
     // setup for SPI mode
     SSP_CFG_Type HW_SPI_init; // data structure to hold init values
     SSP_ConfigStructInit(&HW_SPI_init);  // set values for SPI mode
     HW_SPI_init.ClockRate = Marlin_speed[MIN(spiRate, 6)]; // put in the specified bit rate
-    SSP_Init(LPC_SSP0, &HW_SPI_init);  // puts the values into the proper bits in the SSP0 registers
+    HW_SPI_init.Mode |= SSP_CR1_SSP_EN;
+    SSP_Init(LPC_SSPn, &HW_SPI_init);  // puts the values into the proper bits in the SSP0 registers
+  }
+
 
-    SSP_Cmd(LPC_SSP0, ENABLE);  // start SSP0 running
+  static uint8_t doio(uint8_t b) {
+    /* send and receive a single byte */
+    SSP_SendData(LPC_SSPn, b & 0x00FF);
+    while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY));  // wait for it to finish
+    return SSP_ReceiveData(LPC_SSPn) & 0x00FF;
   }
 
   void spiSend(uint8_t b) {
-    while (!SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL));   // wait for room in the buffer
-    SSP_SendData(LPC_SSP0, b & 0x00FF);
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
+    doio(b);
   }
 
 
   void spiSend(const uint8_t* buf, size_t n) {
     if (n == 0) return;
     for (uint16_t i = 0; i < n; i++) {
-      while (!SSP_GetStatus(LPC_SSP0, SSP_STAT_TXFIFO_NOTFULL));   // wait for room in the buffer
-      SSP_SendData(LPC_SSP0, buf[i] & 0x00FF);
+      doio(buf[i]);
     }
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
   }
 
   void spiSend(uint32_t chan, byte b) {
@@ -195,17 +212,9 @@
   void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
   }
 
-  static uint8_t get_one_byte() {
-    // send a dummy byte so can clock in receive data
-    SSP_SendData(LPC_SSP0,0x00FF);
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
-    return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
-  }
-
   // Read single byte from SPI
   uint8_t spiRec() {
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
-    return get_one_byte();
+    return doio(0xff);
   }
 
   uint8_t spiRec(uint32_t chan) {
@@ -214,22 +223,25 @@
 
   // Read from SPI into buffer
   void spiRead(uint8_t*buf, uint16_t nbyte) {
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
     if (nbyte == 0) return;
     for (int i = 0; i < nbyte; i++) {
-      buf[i] = get_one_byte();
+      buf[i] = doio(0xff);
     }
   }
 
   static uint8_t spiTransfer(uint8_t b) {
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_RXFIFO_NOTEMPTY) || SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY)) SSP_ReceiveData(LPC_SSP0);  //flush the receive buffer
-    SSP_SendData(LPC_SSP0, b);  // send the byte
-    while (SSP_GetStatus(LPC_SSP0, SSP_STAT_BUSY));  // wait for it to finish
-    return SSP_ReceiveData(LPC_SSP0) & 0x00FF;
+    return doio(b);
   }
 
   // Write from buffer to SPI
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
+    uint8_t response;
+    response = spiTransfer(token);
+
+    for (uint16_t i = 0; i < 512; i++) {
+      response = spiTransfer(buf[i]);
+    }
+    UNUSED(response);
   }
 
   /** Begin SPI transaction, set clock, bit order, data mode */
@@ -270,4 +282,3 @@ uint16_t SPIClass::transfer16(uint16_t data) {
 SPIClass SPI;
 
 #endif // TARGET_LPC1768
-
diff --git a/Marlin/src/HAL/HAL_LPC1768/fastio.h b/Marlin/src/HAL/HAL_LPC1768/fastio.h
index e5acaa4e62456ce26a59e1124657caa81893ff05..1374e6aafa9c57f316c048d57661556223616d82 100644
--- a/Marlin/src/HAL/HAL_LPC1768/fastio.h
+++ b/Marlin/src/HAL/HAL_LPC1768/fastio.h
@@ -39,19 +39,19 @@
 
 #define USEABLE_HARDWARE_PWM(pin) useable_hardware_PWM(pin)
 
-#define LPC_PIN(pin)            (gpio_pin(pin))
-#define LPC_GPIO(port)          (gpio_port(port))
+#define LPC_PIN(pin)            gpio_pin(pin)
+#define LPC_GPIO(port)          gpio_port(port)
 
-#define SET_DIR_INPUT(IO)       (gpio_set_input(IO))
-#define SET_DIR_OUTPUT(IO)      (gpio_set_output(IO))
+#define SET_DIR_INPUT(IO)       gpio_set_input(IO)
+#define SET_DIR_OUTPUT(IO)      gpio_set_output(IO)
 
-#define SET_MODE(IO, mode)      (pinMode(IO, mode))
+#define SET_MODE(IO, mode)      pinMode(IO, mode)
 
-#define WRITE_PIN_SET(IO)       (gpio_set(IO))
-#define WRITE_PIN_CLR(IO)       (gpio_clear(IO))
+#define WRITE_PIN_SET(IO)       gpio_set(IO)
+#define WRITE_PIN_CLR(IO)       gpio_clear(IO)
 
-#define READ_PIN(IO)            (gpio_get(IO))
-#define WRITE_PIN(IO,V)         (gpio_set(IO, V))
+#define READ_PIN(IO)            gpio_get(IO)
+#define WRITE_PIN(IO,V)         gpio_set(IO, V)
 
 /**
  * Magic I/O routines
diff --git a/Marlin/src/HAL/HAL_LPC1768/main.cpp b/Marlin/src/HAL/HAL_LPC1768/main.cpp
index cd9f55c50c6304bbaf031d595e0f0e83274f804a..0a0df269785696177027a5f98614444bf39ce3a2 100644
--- a/Marlin/src/HAL/HAL_LPC1768/main.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp
@@ -9,7 +9,13 @@
 #include <usb/cdcuser.h>
 #include <usb/mscuser.h>
 #include <CDCSerial.h>
+#include <usb/mscuser.h>
+
+extern "C" {
+  #include <debug_frmwrk.h>
+}
 
+#include "../../sd/cardreader.h"
 #include "../../inc/MarlinConfig.h"
 #include "HAL.h"
 #include "HAL_timers.h"
@@ -41,15 +47,28 @@ void HAL_init() {
       delay(100);
     }
   #endif
-
-  (void)MSC_SD_Init(0);
-
-  USB_Init();
+  //debug_frmwrk_init();
+  //_DBG("\n\nDebug running\n");
+  // Initialise the SD card chip select pins as soon as possible
+  #ifdef SS_PIN
+    digitalWrite(SS_PIN, HIGH);
+    pinMode(SS_PIN, OUTPUT);
+  #endif
+  #ifdef ONBOARD_SD_CS
+    digitalWrite(ONBOARD_SD_CS, HIGH);
+    pinMode(ONBOARD_SD_CS, OUTPUT);
+  #endif
+  USB_Init();                               // USB Initialization
+  USB_Connect(FALSE);                       // USB clear connection
+  delay(1000);                              // Give OS time to notice
   USB_Connect(TRUE);
-
+  #ifndef USB_SD_DISABLED
+    MSC_SD_Init(0);                         // Enable USB SD card access
+  #endif
   const uint32_t usb_timeout = millis() + 2000;
   while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
     delay(50);
+    HAL_idletask();
     #if PIN_EXISTS(LED)
       TOGGLE(LED_PIN);     // Flash quickly during USB initialization
     #endif
@@ -68,4 +87,23 @@ void HAL_init() {
   LPC1768_PWM_init();
 }
 
+// HAL idle task
+void HAL_idletask(void) {
+  #if ENABLED(SDSUPPORT) && defined(SHARED_SD_CARD)
+    // If Marlin is using the SD card we need to lock it to prevent access from
+    // a PC via USB.
+    // Other HALs use IS_SD_PRINTING and IS_SD_FILE_OPEN to check for access but
+    // this will not reliably detect delete operations. To be safe we will lock
+    // the disk if Marlin has it mounted. Unfortuately there is currently no way
+    // to unmount the disk from the LCD menu.
+    // if (IS_SD_PRINTING || IS_SD_FILE_OPEN)
+    if (card.cardOK)
+      MSC_Aquire_Lock();
+    else
+      MSC_Release_Lock();
+  #endif
+  // Perform USB stack housekeeping
+  MSC_RunDeferredCommands();
+}
+
 #endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h b/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h
index 9f6d626491944ee1379a96cafd17569e99a641ab..fb659b396cc7c8531de3b377f2353b7aae9c3bfc 100644
--- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h
+++ b/Marlin/src/HAL/HAL_LPC1768/persistent_store_api.h
@@ -21,4 +21,4 @@
  */
 #include "../shared/persistent_store_api.h"
 
-//#define FLASH_EEPROM
+#define FLASH_EEPROM
diff --git a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp b/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
index daffddf079e6460068e0a04dbd99d9d7e543117b..101cd7f10514b5be744cd2b7d2db27006d42054e 100644
--- a/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/persistent_store_flash.cpp
@@ -116,7 +116,7 @@ bool PersistentStore::access_finish() {
 }
 
 bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
-  for (int i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
+  for (size_t i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
   eeprom_dirty = true;
   crc16(crc, value, size);
   pos += size;
@@ -125,7 +125,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
 
 bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
   const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
-  if (writing) for (int i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
+  if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
   crc16(crc, buff, size);
   pos += size;
   return false;  // return true for any error
diff --git a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h b/Marlin/src/HAL/HAL_LPC1768/spi_pins.h
index 841a3f845f1a41ec2c072d90ef749f6342ffaedd..d67a70700a069c74910f8924dab86b847191d31f 100644
--- a/Marlin/src/HAL/HAL_LPC1768/spi_pins.h
+++ b/Marlin/src/HAL/HAL_LPC1768/spi_pins.h
@@ -50,7 +50,8 @@
 #ifndef SS_PIN
   #define SS_PIN            P1_23
 #endif
-#ifndef SDSS
+#if !defined(SDSS) || SDSS == P_NC // get defaulted in pins.h
+  #undef SDSS
   #define SDSS              SS_PIN
 #endif
 
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
index 3ead62dc2337abf1b2f30cfe719bcd90826de2e4..9e9b76439a765b8be2d2889f906d6f48ac1bda11 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
@@ -63,6 +63,7 @@
 #include "SoftwareSPI.h"
 #include "../../shared/Delay.h"
 
+#undef SPI_SPEED
 #define SPI_SPEED 3  // About 1 MHz
 
 static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index 1d3c7f18dd6b7f3221567b883bed5b4a26edf2e1..43b46d5ddf484bb3b048ea7f2de4d6595d870454 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -62,6 +62,7 @@
 #include <U8glib.h>
 #include "SoftwareSPI.h"
 
+#undef SPI_SPEED
 #define SPI_SPEED 2  // About 2 MHz
 
 static uint8_t SPI_speed = 0;
diff --git a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
index 589e05ebd602ec7d0eb491f4f246ab9947cfffba..9138c04ac2897737aa25dc0e7f89730d7000bb36 100644
--- a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp
@@ -30,7 +30,29 @@
 #include "watchdog.h"
 
 void watchdog_init(void) {
-  WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
+  #if ENABLED(WATCHDOG_RESET_MANUAL)
+    // We enable the watchdog timer, but only for the interrupt.
+
+    // Configure WDT to only trigger an interrupt
+    // Disable WDT interrupt (just in case, to avoid triggering it!)
+    NVIC_DisableIRQ(WDT_IRQn);
+
+    // We NEED memory barriers to ensure Interrupts are actually disabled!
+    // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
+    __DSB();
+    __ISB();
+
+    // Configure WDT to only trigger an interrupt
+    // Initialize WDT with the given parameters
+    WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY);
+
+    // Configure and enable WDT interrupt.
+    NVIC_ClearPendingIRQ(WDT_IRQn);
+    NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
+    NVIC_EnableIRQ(WDT_IRQn);
+  #else
+    WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
+  #endif
   WDT_Start(WDT_TIMEOUT);
 }
 
diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h
index e8d9f4a7c8dba723c05380d1675142835e52e442..48e8ac0ba2abac3b7afbcc1fec0eba3fed4a84a7 100644
--- a/Marlin/src/pins/pins.h
+++ b/Marlin/src/pins/pins.h
@@ -299,19 +299,19 @@
 #elif MB(AZSMZ_MINI)
   #include "pins_AZSMZ_MINI.h"        // LPC1768                                    env:LPC1768
 #elif MB(AZTEEG_X5_GT)
-  #include "pins_AZTEEG_X5_GT.h"      // LPC1769                                    env:LPC1768
+  #include "pins_AZTEEG_X5_GT.h"      // LPC1769                                    env:LPC1769
 #elif MB(AZTEEG_X5_MINI_WIFI)
-  #include "pins_AZTEEG_X5_MINI_WIFI.h" // LPC1769                                  env:LPC1768
+  #include "pins_AZTEEG_X5_MINI_WIFI.h" // LPC1769                                  env:LPC1769
 #elif MB(BIQU_BQ111_A4)
   #include "pins_BIQU_BQ111_A4.h"     // LPC1768                                    env:LPC1768
 #elif MB(SELENA_COMPACT)
   #include "pins_SELENA_COMPACT.h"    // LPC1768                                    env:LPC1768
 #elif MB(COHESION3D_REMIX)
-  #include "pins_COHESION3D_REMIX.h"  // LPC1769                                    env:LPC1768
+  #include "pins_COHESION3D_REMIX.h"  // LPC1769                                    env:LPC1769
 #elif MB(COHESION3D_MINI)
-  #include "pins_COHESION3D_MINI.h"   // LPC1769                                    env:LPC1768
+  #include "pins_COHESION3D_MINI.h"   // LPC1769                                    env:LPC1769
 #elif MB(SMOOTHIEBOARD)
-  #include "pins_SMOOTHIEBOARD.h"     // LPC1769                                    env:LPC1768
+  #include "pins_SMOOTHIEBOARD.h"     // LPC1769                                    env:LPC1769
 
 //
 // Other 32-bit Boards
diff --git a/Marlin/src/pins/pins_MKS_SBASE.h b/Marlin/src/pins/pins_MKS_SBASE.h
index 7a58198342f02b70f3ee933da5bcb44a8ec06a8d..be84367e42d8fb085acb0b084f76e15494a87614 100644
--- a/Marlin/src/pins/pins_MKS_SBASE.h
+++ b/Marlin/src/pins/pins_MKS_SBASE.h
@@ -141,8 +141,6 @@
 // Misc. Functions
 //
 #define PS_ON_PIN          P0_25 //TH3 Connector
-#define LPC_SOFTWARE_SPI  // MKS_SBASE needs a software SPI because the
-                          // selected pins are not on a hardware SPI controller
 
 /**
  * Smart LCD adapter
@@ -185,14 +183,77 @@
 #define ENET_TXD0          P1_00   // J12-11
 #define ENET_TXD1          P1_01   // J12-12
 
-// A custom cable is needed. See the README file in the
-// Marlin\src\config\examples\Mks\Sbase directory
 
-#define SCK_PIN            P1_22   // J8-2 (moved from EXP2 P0.7)
-#define MISO_PIN           P1_23   // J8-3 (moved from EXP2 P0.8)
-#define MOSI_PIN           P2_12   // J8-4 (moved from EXP2 P0.5)
-#define SS_PIN             P0_28
-#define SDSS               P0_06
+/*
+ * The SBase can share the on-board SD card with a PC via USB the following
+ * definitions control this feature:
+ */
+//#define USB_SD_DISABLED
+#define USB_SD_ONBOARD
+
+/*
+ * There are a number of configurations available for the SBase SD card reader.
+ * A custom cable can be used to allow access to the LCD based SD card.
+ * A standard cable can be used for access to the LCD SD card (but no SD detect).
+ * The onboard SD card can be used and optionally shared with a PC via USB.
+ */
+
+//#define SBASE_SD_CUSTOM_CABLE // Use a custom cable to access the SD
+//#define SBASE_SD_LCD          // Use the SD drive attached to the LCD
+#define SBASE_SD_ONBOARD        // Use the SD drive on the control board
+
+#ifdef SBASE_SD_CUSTOM_CABLE
+  /**
+   * A custom cable is needed. See the README file in the
+   * Marlin\src\config\examples\Mks\Sbase directory
+   * P0.27 is on EXP2 and the on-board SD card's socket. That means it can't be
+   * used as the SD_DETECT for the LCD's SD card.
+   *
+   * The best solution is to use the custom cable to connect the LCD's SD_DETECT
+   * to a pin NOT on EXP2.
+   *
+   * If you can't find a pin to use for the LCD's SD_DETECT then comment out
+   * SD_DETECT_PIN entirely and remove that wire from the the custom cable.
+   */
+  #define SD_DETECT_PIN      P2_11   // J8-5 (moved from EXP2 P0.27)
+  #define SCK_PIN            P1_22   // J8-2 (moved from EXP2 P0.7)
+  #define MISO_PIN           P1_23   // J8-3 (moved from EXP2 P0.8)
+  #define MOSI_PIN           P2_12   // J8-4 (moved from EXP2 P0.9)
+  #define SS_PIN             P0_28   // Chip select for SD card used by Marlin
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
+  #define LPC_SOFTWARE_SPI  // With a custom cable we need software SPI because the
+                            // selected pins are not on a hardware SPI controller
+#endif
+
+#ifdef SBASE_SD_LCD
+  // use standard cable and header, SPI and SD detect sre shared with on-board SD card
+  // hardware SPI is used for both SD cards. The detect pin is shred between the
+  // LCD and onboard SD readers so we disable it.
+  #define SD_DETECT_PIN      P0_27
+  #undef SD_DETECT_PIN
+  #define SCK_PIN            P0_07
+  #define MISO_PIN           P0_08
+  #define MOSI_PIN           P0_09
+  #define SS_PIN             P0_28   // Chip select for SD card used by Marlin
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
+#endif
+
+#ifdef SBASE_SD_ONBOARD
+  // The external SD card is not used. Hardware SPI is used to access the card.
+  #ifdef USB_SD_ONBOARD
+    // When sharing the SD card with a PC we want the menu options to
+    // mount/unmount the card and refresh it. So we disable card detect.
+    #define SHARED_SD_CARD
+    #undef SD_DETECT_PIN
+  #else
+    #define SD_DETECT_PIN      P0_27
+  #endif
+  #define SCK_PIN            P0_07
+  #define MISO_PIN           P0_08
+  #define MOSI_PIN           P0_09
+  #define SS_PIN             P0_06   // Chip select for SD card used by Marlin
+  #define ONBOARD_SD_CS      P0_06   // Chip select for "System" SD card
+#endif
 
 /**
  * Example for trinamic drivers using the J8 connector on MKs Sbase.
@@ -237,18 +298,6 @@
   #define E0_SERIAL_RX_PIN P0_26   // TH4
 #endif
 
-/**
- * P0.27 is on EXP2 and the on-board SD card's socket. That means it can't be
- * used as the SD_DETECT for the LCD's SD card.
- *
- * The best solution is to use the custom cable to connect the LCD's SD_DETECT
- * to a pin NOT on EXP2.
- *
- * If you can't find a pin to use for the LCD's SD_DETECT then comment out
- * SD_DETECT_PIN entirely and remove that wire from the the custom cable.
- */
-#define SD_DETECT_PIN      P2_11   // J8-5 (moved from EXP2 P0.27)
-
 /**
  *  PWMs
  *
diff --git a/platformio.ini b/platformio.ini
index 743bed6439c80550871040404f0a71cb191d12e5..31047a8a06e3bc7028ad9987e16376dd399f0ea7 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -153,6 +153,9 @@ platform          = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/ma
 framework         = arduino
 board             = nxp_lpc1768
 build_flags       = -DTARGET_LPC1768 -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags}
+# debug options for backtrace
+#  -funwind-tables
+#  -mpoke-function-name
 lib_ldf_mode      = off
 extra_scripts     = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
 src_filter        = ${common.default_src_filter} +<src/HAL/HAL_LPC1768>
@@ -165,6 +168,9 @@ platform          = https://github.com/p3p/pio-nxplpc-arduino-lpc176x/archive/ma
 framework         = arduino
 board             = nxp_lpc1769
 build_flags       = -DTARGET_LPC1768 -DU8G_HAL_LINKS -IMarlin/src/HAL/HAL_LPC1768/include -IMarlin/src/HAL/HAL_LPC1768/u8g ${common.build_flags}
+# debug options for backtrace
+#  -funwind-tables
+#  -mpoke-function-name
 lib_ldf_mode      = off
 extra_scripts     = Marlin/src/HAL/HAL_LPC1768/upload_extra_script.py
 src_filter        = ${common.default_src_filter} +<src/HAL/HAL_LPC1768>