diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h
index e289e7cf1f67d880f0af665d29857fe440b49388..6a9fd776fa551f95934f3560d626847515379801 100644
--- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h
+++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h
@@ -78,30 +78,9 @@
 #define BYTE 0
 
 #ifndef USBCON
-  // Define constants and variables for buffering incoming serial data.  We're
-  // using a ring buffer (I think), in which rx_buffer_head is the index of the
-  // location to which to write the next incoming character and rx_buffer_tail
-  // is the index of the location from which to read.
-  // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
-  #ifndef RX_BUFFER_SIZE
-    #define RX_BUFFER_SIZE 128
-  #endif
-  #ifndef TX_BUFFER_SIZE
-    #define TX_BUFFER_SIZE 32
-  #endif
-
-  #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
-    #error "XON/XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops."
-  #endif
-
-  #if !IS_POWER_OF_2(RX_BUFFER_SIZE) || RX_BUFFER_SIZE < 2
-    #error "RX_BUFFER_SIZE must be a power of 2 greater than 1."
-  #endif
-
-  #if TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE))
-    #error "TX_BUFFER_SIZE must be 0 or a power of 2 greater than 1."
-  #endif
-
+  // We're using a ring buffer (I think), in which rx_buffer_head is the index of the
+  // location to which to write the next incoming character and rx_buffer_tail is the
+  // index of the location from which to read.
   #if RX_BUFFER_SIZE > 256
     typedef uint16_t ring_buffer_pos_t;
   #else
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
index 037899675f4ad0a8e6db121f419e8b302f975ade..29c0964e9b47599e8cb4ed4bdfbd2409e45d9641 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp
@@ -20,10 +20,7 @@
 
 #ifdef TARGET_LPC1768
 
-#include "../../core/macros.h"
-#include "../HAL.h"
-
-#include <stdint.h>
+#include "../../inc/MarlinConfig.h"
 
 extern "C" {
   //#include <lpc17xx_adc.h>
@@ -86,7 +83,7 @@ extern const char errormagic[];
 
 void HAL_adc_enable_channel(int pin) {
   if (!WITHIN(pin, 0, NUM_ANALOG_INPUTS - 1)) {
-    usb_serial.printf("%sINVALID ANALOG PORT:%d\n", errormagic, pin);
+    MYSERIAL.printf("%sINVALID ANALOG PORT:%d\n", errormagic, pin);
     kill(MSG_KILLED);
   }
 
@@ -116,7 +113,7 @@ void HAL_adc_enable_channel(int pin) {
 uint8_t active_adc = 0;
 void HAL_adc_start_conversion(const uint8_t adc_pin) {
   if (adc_pin >= (NUM_ANALOG_INPUTS) || adc_pin_map[adc_pin].port == 0xFF) {
-    usb_serial.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
+    MYSERIAL.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
     return;
   }
   LPC_ADC->ADCR &= ~0xFF;                       // Reset
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/HAL_LPC1768/HAL.h
index e1b52a6819b9171a9ab04fbb3f6c5a445c83604f..907b550c3cce784b2a1df98ac048e8d9ced145e9 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.h
@@ -41,9 +41,7 @@ void _printf (const  char *format, ...);
 void _putc(uint8_t c);
 uint8_t _getc();
 
-extern volatile uint32_t _millis;
-
-#define USBCON
+extern "C" volatile uint32_t _millis;
 
 //arduino: Print.h
 #define DEC 10
@@ -60,7 +58,7 @@ extern volatile uint32_t _millis;
 #include "watchdog.h"
 #include "serial.h"
 #include "HAL_timers.h"
-
+#include "HardwareSerial.h"
 
 #define ST7920_DELAY_1 DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP
 #define ST7920_DELAY_2 DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP
@@ -68,7 +66,18 @@ extern volatile uint32_t _millis;
 
 //Serial override
 extern HalSerial usb_serial;
-#define MYSERIAL usb_serial
+
+#if SERIAL_PORT == -1
+  #define MYSERIAL usb_serial
+#elif SERIAL_PORT == 0
+  #define MYSERIAL Serial
+#elif SERIAL_PORT == 1
+  #define MYSERIAL Serial1
+#elif SERIAL_PORT == 2
+  #define MYSERIAL Serial2
+#elif SERIAL_PORT == 3
+  #define MYSERIAL Serial3
+#endif
 
 #define CRITICAL_SECTION_START  uint32_t primask = __get_PRIMASK(); __disable_irq();
 #define CRITICAL_SECTION_END    if (!primask) __enable_irq();
diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.cpp
index c46e80f4b882c4436daca0ae235093d5c0680caa..c9e25693e2fb18fb1ed4d80404a9c3da36aa35ee 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.cpp
@@ -28,7 +28,7 @@
 
 #ifdef TARGET_LPC1768
 
-#include "../HAL.h"
+#include "../../inc/MarlinConfig.h"
 #include "HAL_timers.h"
 
 void HAL_timer_init(void) {
diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp
index 6438acd228f4377bf78eb45a6a8ff0d6b01f924c..cd76e8f704e072e635c5b1eb4cab73d7f281b955 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp
@@ -22,391 +22,297 @@
 
 #ifdef TARGET_LPC1768
 
-#include "../../core/macros.h"
-#include "../HAL.h"
+#include "../../inc/MarlinConfig.h"
 #include "HardwareSerial.h"
-#define UART3 3
-HardwareSerial Serial3 = HardwareSerial(UART3);
-
-volatile uint32_t UART0Status, UART1Status, UART2Status, UART3Status;
-volatile uint8_t UART0TxEmpty = 1, UART1TxEmpty = 1, UART2TxEmpty=1, UART3TxEmpty=1;
-volatile uint8_t UART0Buffer[UARTRXQUEUESIZE], UART1Buffer[UARTRXQUEUESIZE], UART2Buffer[UARTRXQUEUESIZE], UART3Buffer[UARTRXQUEUESIZE];
-volatile uint32_t UART0RxQueueWritePos = 0, UART1RxQueueWritePos = 0, UART2RxQueueWritePos = 0, UART3RxQueueWritePos = 0;
-volatile uint32_t UART0RxQueueReadPos = 0, UART1RxQueueReadPos = 0, UART2RxQueueReadPos = 0, UART3RxQueueReadPos = 0;
-volatile uint8_t dummy;
-
-  void HardwareSerial::begin(uint32_t baudrate) {
-    uint32_t Fdiv;
-     uint32_t pclkdiv, pclk;
-
-     if ( PortNum == 0 )
-     {
-   	LPC_PINCON->PINSEL0 &= ~0x000000F0;
-   	LPC_PINCON->PINSEL0 |= 0x00000050;  /* RxD0 is P0.3 and TxD0 is P0.2 */
-   	/* By default, the PCLKSELx value is zero, thus, the PCLK for
-   	all the peripherals is 1/4 of the SystemFrequency. */
-   	/* Bit 6~7 is for UART0 */
-   	pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03;
-   	switch ( pclkdiv )
-   	{
-   	  case 0x00:
-   	  default:
-   		pclk = SystemCoreClock/4;
-   		break;
-   	  case 0x01:
-   		pclk = SystemCoreClock;
-   		break;
-   	  case 0x02:
-   		pclk = SystemCoreClock/2;
-   		break;
-   	  case 0x03:
-   		pclk = SystemCoreClock/8;
-   		break;
-   	}
-
-       LPC_UART0->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
-   	Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
-       LPC_UART0->DLM = Fdiv / 256;
-       LPC_UART0->DLL = Fdiv % 256;
-   	LPC_UART0->LCR = 0x03;		/* DLAB = 0 */
-       LPC_UART0->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
-
-      	NVIC_EnableIRQ(UART0_IRQn);
-
-       LPC_UART0->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART0 interrupt */
-     }
-     else if ( PortNum == 1 )
-     {
-   	LPC_PINCON->PINSEL4 &= ~0x0000000F;
-   	LPC_PINCON->PINSEL4 |= 0x0000000A;	/* Enable RxD1 P2.1, TxD1 P2.0 */
-
-   	/* By default, the PCLKSELx value is zero, thus, the PCLK for
-   	all the peripherals is 1/4 of the SystemFrequency. */
-   	/* Bit 8,9 are for UART1 */
-   	pclkdiv = (LPC_SC->PCLKSEL0 >> 8) & 0x03;
-   	switch ( pclkdiv )
-   	{
-   	  case 0x00:
-   	  default:
-   		pclk = SystemCoreClock/4;
-   		break;
-   	  case 0x01:
-   		pclk = SystemCoreClock;
-   		break;
-   	  case 0x02:
-   		pclk = SystemCoreClock/2;
-   		break;
-   	  case 0x03:
-   		pclk = SystemCoreClock/8;
-   		break;
-   	}
-
-       LPC_UART1->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
-   	Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
-       LPC_UART1->DLM = Fdiv / 256;
-       LPC_UART1->DLL = Fdiv % 256;
-   	LPC_UART1->LCR = 0x03;		/* DLAB = 0 */
-       LPC_UART1->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
-
-      	NVIC_EnableIRQ(UART1_IRQn);
-
-       LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART1 interrupt */
-     }
-     else if ( PortNum == 2 )
-     {
-   	  //LPC_PINCON->PINSEL4 &= ~0x000F0000;  /*Pinsel4 Bits 16-19*/
-   	  //LPC_PINCON->PINSEL4 |=  0x000A0000;  /* RxD2 is P2.9 and TxD2 is P2.8, value 10*/
-   	  LPC_PINCON->PINSEL0 &= ~0x00F00000;  /*Pinsel0 Bits 20-23*/
-   	  LPC_PINCON->PINSEL0 |=  0x00500000;  /* RxD2 is P0.11 and TxD2 is P0.10, value 01*/
-
-   	  LPC_SC->PCONP |= 1<<24; //Enable PCUART2
-   	  /* By default, the PCLKSELx value is zero, thus, the PCLK for
-   		all the peripherals is 1/4 of the SystemFrequency. */
-   	  /* Bit 6~7 is for UART3 */
-   	  pclkdiv = (LPC_SC->PCLKSEL1 >> 16) & 0x03;
-   	  switch ( pclkdiv )
-   	  {
-   	  case 0x00:
-   	  default:
-   		  pclk = SystemCoreClock/4;
-   		  break;
-   	  case 0x01:
-   		  pclk = SystemCoreClock;
-   		  break;
-   	  case 0x02:
-   		  pclk = SystemCoreClock/2;
-   		  break;
-   	  case 0x03:
-   		  pclk = SystemCoreClock/8;
-   		  break;
-   	  }
-   	  LPC_UART2->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
-   	  Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
-   	  LPC_UART2->DLM = Fdiv / 256;
-   	  LPC_UART2->DLL = Fdiv % 256;
-   	  LPC_UART2->LCR = 0x03;		/* DLAB = 0 */
-   	  LPC_UART2->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
-
-   	  NVIC_EnableIRQ(UART2_IRQn);
-
-   	  LPC_UART2->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART3 interrupt */
-     }
-     else if ( PortNum == 3 )
-     {
-   	  LPC_PINCON->PINSEL0 &= ~0x0000000F;
-   	  LPC_PINCON->PINSEL0 |=  0x0000000A;  /* RxD3 is P0.1 and TxD3 is P0.0 */
-   	  LPC_SC->PCONP |= 1<<4 | 1<<25; //Enable PCUART1
-   	  /* By default, the PCLKSELx value is zero, thus, the PCLK for
-   		all the peripherals is 1/4 of the SystemFrequency. */
-   	  /* Bit 6~7 is for UART3 */
-   	  pclkdiv = (LPC_SC->PCLKSEL1 >> 18) & 0x03;
-   	  switch ( pclkdiv )
-   	  {
-   	  case 0x00:
-   	  default:
-   		  pclk = SystemCoreClock/4;
-   		  break;
-   	  case 0x01:
-   		  pclk = SystemCoreClock;
-   		  break;
-   	  case 0x02:
-   		  pclk = SystemCoreClock/2;
-   		  break;
-   	  case 0x03:
-   		  pclk = SystemCoreClock/8;
-   		  break;
-   	  }
-   	  LPC_UART3->LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
-   	  Fdiv = ( pclk / 16 ) / baudrate ;	/*baud rate */
-   	  LPC_UART3->DLM = Fdiv / 256;
-   	  LPC_UART3->DLL = Fdiv % 256;
-   	  LPC_UART3->LCR = 0x03;		/* DLAB = 0 */
-   	  LPC_UART3->FCR = 0x07;		/* Enable and reset TX and RX FIFO. */
-
-   	  NVIC_EnableIRQ(UART3_IRQn);
-
-   	  LPC_UART3->IER = IER_RBR | IER_THRE | IER_RLS;	/* Enable UART3 interrupt */
-     }
-  }
 
-  int HardwareSerial::read() {
-    uint8_t rx;
-  	if ( PortNum == 0 )
-  	  {
-  		  if (UART0RxQueueReadPos == UART0RxQueueWritePos)
-  		    return -1;
-
-  		  // Read from "head"
-  		  rx = UART0Buffer[UART0RxQueueReadPos]; // grab next byte
-  		  UART0RxQueueReadPos = (UART0RxQueueReadPos + 1) % UARTRXQUEUESIZE;
-  		  return rx;
-  	  }
-  	  if ( PortNum == 1 )
-  	  {
-  		  if (UART1RxQueueReadPos == UART1RxQueueWritePos)
-  		    return -1;
-
-  		  // Read from "head"
-  		  rx = UART1Buffer[UART1RxQueueReadPos]; // grab next byte
-  		  UART1RxQueueReadPos = (UART1RxQueueReadPos + 1) % UARTRXQUEUESIZE;
-  		  return rx;
-  	  }
-  	  if ( PortNum == 2 )
-  	  {
-  		  if (UART2RxQueueReadPos == UART2RxQueueWritePos)
-  		    return -1;
-
-  		  // Read from "head"
-  		  rx = UART2Buffer[UART2RxQueueReadPos]; // grab next byte
-  		  UART2RxQueueReadPos = (UART2RxQueueReadPos + 1) % UARTRXQUEUESIZE;
-  		  return rx;
-  	  }
-  	  if ( PortNum == 3 )
-  	  {
-  		  if (UART3RxQueueReadPos == UART3RxQueueWritePos)
-  		    return -1;
-
-  		  // Read from "head"
-  		  rx = UART3Buffer[UART3RxQueueReadPos]; // grab next byte
-  		  UART3RxQueueReadPos = (UART3RxQueueReadPos + 1) % UARTRXQUEUESIZE;
-  		  return rx;
-  	  }
-  	  return 0;
+HardwareSerial Serial = HardwareSerial(LPC_UART0);
+HardwareSerial Serial1 = HardwareSerial((LPC_UART_TypeDef *) LPC_UART1);
+HardwareSerial Serial2 = HardwareSerial(LPC_UART2);
+HardwareSerial Serial3 = HardwareSerial(LPC_UART3);
+
+void HardwareSerial::begin(uint32_t baudrate) {
+
+  UART_CFG_Type UARTConfigStruct;
+  PINSEL_CFG_Type PinCfg;
+  UART_FIFO_CFG_Type FIFOConfig;
+
+  if (UARTx == LPC_UART0) {
+    /*
+    * Initialize UART0 pin connect
+    */
+    PinCfg.Funcnum = 1;
+    PinCfg.OpenDrain = 0;
+    PinCfg.Pinmode = 0;
+    PinCfg.Pinnum = 2;
+    PinCfg.Portnum = 0;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 3;
+    PINSEL_ConfigPin(&PinCfg);
   }
-
-  size_t HardwareSerial::write(uint8_t send) {
-    if ( PortNum == 0 )
-     {
-   	  /* THRE status, contain valid data */
-   	  while ( !(UART0TxEmpty & 0x01) );
-   	  LPC_UART0->THR = send;
-   	  UART0TxEmpty = 0;	/* not empty in the THR until it shifts out */
-     }
-     else if (PortNum == 1)
-     {
-
-   	  /* THRE status, contain valid data */
-   	  while ( !(UART1TxEmpty & 0x01) );
-   	  LPC_UART1->THR = send;
-   	  UART1TxEmpty = 0;	/* not empty in the THR until it shifts out */
-
-
-     }
-     else if ( PortNum == 2 )
-     {
-   	  /* THRE status, contain valid data */
-   	  while ( !(UART2TxEmpty & 0x01) );
-   	  LPC_UART2->THR = send;
-   	  UART2TxEmpty = 0;	/* not empty in the THR until it shifts out */
-
-     }
-     else if ( PortNum == 3 )
-     {
-   	  /* THRE status, contain valid data */
-   	  while ( !(UART3TxEmpty & 0x01) );
-   	  LPC_UART3->THR = send;
-   	  UART3TxEmpty = 0;	/* not empty in the THR until it shifts out */
-
-     }
-     return 0;
+  else if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1) {
+    /*
+    * Initialize UART1 pin connect
+    */
+    PinCfg.Funcnum = 1;
+    PinCfg.OpenDrain = 0;
+    PinCfg.Pinmode = 0;
+    PinCfg.Pinnum = 15;
+    PinCfg.Portnum = 0;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 16;
+    PINSEL_ConfigPin(&PinCfg);
+  }
+  else if (UARTx == LPC_UART2) {
+    /*
+    * Initialize UART2 pin connect
+    */
+    PinCfg.Funcnum = 1;
+    PinCfg.OpenDrain = 0;
+    PinCfg.Pinmode = 0;
+    PinCfg.Pinnum = 10;
+    PinCfg.Portnum = 0;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 11;
+    PINSEL_ConfigPin(&PinCfg);
+  }
+  else if (UARTx == LPC_UART3) {
+    /*
+    * Initialize UART2 pin connect
+    */
+    PinCfg.Funcnum = 1;
+    PinCfg.OpenDrain = 0;
+    PinCfg.Pinmode = 0;
+    PinCfg.Pinnum = 0;
+    PinCfg.Portnum = 0;
+    PINSEL_ConfigPin(&PinCfg);
+    PinCfg.Pinnum = 1;
+    PINSEL_ConfigPin(&PinCfg);
   }
 
-  int HardwareSerial::available() {
-    if ( PortNum == 0 )
-{
-  return (UART0RxQueueWritePos + UARTRXQUEUESIZE - UART0RxQueueReadPos) % UARTRXQUEUESIZE;
-}
-if ( PortNum == 1 )
-{
-  return (UART1RxQueueWritePos + UARTRXQUEUESIZE - UART1RxQueueReadPos) % UARTRXQUEUESIZE;
-}
-if ( PortNum == 2 )
-{
-  return (UART2RxQueueWritePos + UARTRXQUEUESIZE - UART2RxQueueReadPos) % UARTRXQUEUESIZE;
-}
-if ( PortNum == 3 )
-{
-  return (UART3RxQueueWritePos + UARTRXQUEUESIZE - UART3RxQueueReadPos) % UARTRXQUEUESIZE;
+	/* Initialize UART Configuration parameter structure to default state:
+	 * Baudrate = 9600bps
+	 * 8 data bit
+	 * 1 Stop bit
+	 * None parity
+	 */
+	UART_ConfigStructInit(&UARTConfigStruct);
+
+	// Re-configure baudrate
+	UARTConfigStruct.Baud_rate = baudrate;
+
+	// Initialize eripheral with given to corresponding parameter
+  UART_Init(UARTx, &UARTConfigStruct);
+  
+  // Enable and reset the TX and RX FIFOs
+  UART_FIFOConfigStructInit(&FIFOConfig);
+  UART_FIFOConfig(UARTx, &FIFOConfig);
+
+	// Enable UART Transmit
+  UART_TxCmd(UARTx, ENABLE);
+
+  // Configure Interrupts
+  UART_IntConfig(UARTx, UART_INTCFG_RBR, ENABLE);
+  UART_IntConfig(UARTx, UART_INTCFG_RLS, ENABLE);
+  
+  if (UARTx == LPC_UART0)
+    NVIC_EnableIRQ(UART0_IRQn);
+  else if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
+    NVIC_EnableIRQ(UART1_IRQn);
+  else if (UARTx == LPC_UART2)
+    NVIC_EnableIRQ(UART2_IRQn);
+  else if (UARTx == LPC_UART3)
+    NVIC_EnableIRQ(UART3_IRQn);
+
+  RxQueueWritePos = RxQueueReadPos = 0;
+  #if TX_BUFFER_SIZE > 0
+    TxQueueWritePos = TxQueueReadPos = 0;
+  #endif
 }
-return 0;
-  }
 
-  void HardwareSerial::flush() {
-    if ( PortNum == 0 )
-{
-  UART0RxQueueWritePos = 0;
-  UART0RxQueueReadPos = 0;
+int HardwareSerial::peek() {
+  int byte = -1;
 
+  /* Temporarily lock out UART receive interrupts during this read so the UART receive
+     interrupt won't cause problems with the index values */
+  UART_IntConfig(UARTx, UART_INTCFG_RBR, DISABLE);
+  
+  if (RxQueueReadPos != RxQueueWritePos)
+    byte = RxBuffer[RxQueueReadPos];
+
+  /* Re-enable UART interrupts */
+  UART_IntConfig(UARTx, UART_INTCFG_RBR, ENABLE);
+  
+  return byte;
 }
-if ( PortNum == 1 )
-{
-  UART1RxQueueWritePos = 0;
-  UART1RxQueueReadPos = 0;
-}
-if ( PortNum == 2 )
-{
-  UART2RxQueueWritePos = 0;
-  UART2RxQueueReadPos = 0;
-}
-if ( PortNum == 3 )
-{
-  UART3RxQueueWritePos = 0;
-  UART3RxQueueReadPos = 0;
-}
-return;
+
+int HardwareSerial::read() {
+  int byte = -1;
+
+  /* Temporarily lock out UART receive interrupts during this read so the UART receive
+     interrupt won't cause problems with the index values */
+  UART_IntConfig(UARTx, UART_INTCFG_RBR, DISABLE);
+  
+  if (RxQueueReadPos != RxQueueWritePos) {
+    byte = RxBuffer[RxQueueReadPos];
+    RxQueueReadPos = (RxQueueReadPos + 1) % RX_BUFFER_SIZE;
   }
 
-  void HardwareSerial::printf(const char *format, ...) {
-    static char buffer[256];
-    va_list vArgs;
-    va_start(vArgs, format);
-    int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
-    va_end(vArgs);
-    if (length > 0 && length < 256) {
-        for (int i = 0; i < length;) {
-          write(buffer[i]);
-            ++i;
-          }
-        }
+  /* Re-enable UART interrupts */
+  UART_IntConfig(UARTx, UART_INTCFG_RBR, ENABLE);
+  
+  return byte;
+}
+
+size_t HardwareSerial::write(uint8_t send) {
+  #if TX_BUFFER_SIZE > 0
+    size_t   bytes = 0;
+    uint32_t fifolvl = 0;
+
+    /* If the Tx Buffer is full, wait for space to clear */
+    if ((TxQueueWritePos+1) % TX_BUFFER_SIZE == TxQueueReadPos) flushTX();
+  
+    /* Temporarily lock out UART transmit interrupts during this read so the UART transmit interrupt won't
+       cause problems with the index values */
+    UART_IntConfig(UARTx, UART_INTCFG_THRE, DISABLE);
+
+    /* LPC17xx.h incorrectly defines FIFOLVL as a uint8_t, when it's actually a 32-bit register */
+    if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
+      fifolvl = *(reinterpret_cast<volatile uint32_t *>(&((LPC_UART1_TypeDef *) UARTx)->FIFOLVL));
+    else
+      fifolvl = *(reinterpret_cast<volatile uint32_t *>(&UARTx->FIFOLVL));
+  
+    /* If the queue is empty and there's space in the FIFO, immediately send the byte */
+    if (TxQueueWritePos == TxQueueReadPos && fifolvl < UART_TX_FIFO_SIZE) {
+      bytes = UART_Send(UARTx, &send, 1, BLOCKING);
     }
+    /* Otherwiise, write the byte to the transmit buffer */
+    else if ((TxQueueWritePos+1) % TX_BUFFER_SIZE != TxQueueReadPos) {
+      TxBuffer[TxQueueWritePos] = send;
+      TxQueueWritePos = (TxQueueWritePos+1) % TX_BUFFER_SIZE;
+      bytes++;
+    }
+  
+    /* Re-enable the TX Interrupt */
+    UART_IntConfig(UARTx, UART_INTCFG_THRE, ENABLE);
+  
+    return bytes;
+  #else
+    return UART_Send(UARTx, &send, 1, BLOCKING);
+  #endif
+}
 
-#ifdef __cplusplus
-extern "C" {
+#if TX_BUFFER_SIZE > 0
+  void HardwareSerial::flushTX() {
+    /* Wait for the tx buffer and FIFO to drain */
+    while (TxQueueWritePos != TxQueueReadPos && UART_CheckBusy(UARTx) == SET);
+  }
 #endif
 
-/*****************************************************************************
-** Function name:		UART0_IRQHandler
-**
-** Descriptions:		UART0 interrupt handler
-**
-** parameters:			None
-** Returned value:		None
-**
-*****************************************************************************/
-void UART0_IRQHandler (void)
-{
-  uint8_t IIRValue, LSRValue;
+int HardwareSerial::available() {
+  return (RxQueueWritePos + RX_BUFFER_SIZE - RxQueueReadPos) % RX_BUFFER_SIZE;
+}
+
+void HardwareSerial::flush() {
+  RxQueueWritePos = 0;
+  RxQueueReadPos = 0;
+}
+
+void HardwareSerial::printf(const char *format, ...) {
+  char RxBuffer[256];
+  va_list vArgs;
+  va_start(vArgs, format);
+  int length = vsnprintf(RxBuffer, 256, format, vArgs);
+  va_end(vArgs);
+  if (length > 0 && length < 256) {
+    for (int i = 0; i < length; ++i)
+      write(RxBuffer[i]);
+  }
+}
+
+void HardwareSerial::IRQHandler() {
+  uint32_t IIRValue;
+  uint8_t LSRValue, byte;
 
-  IIRValue = LPC_UART0->IIR;
+  IIRValue = UART_GetIntId(UARTx);
+  IIRValue &= UART_IIR_INTID_MASK;		/* check bit 1~3, interrupt identification */
 
-  IIRValue >>= 1;			/* skip pending bit in IIR */
-  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
-  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
+  if ( IIRValue == UART_IIR_INTID_RLS )		/* Receive Line Status */
   {
-    LSRValue = LPC_UART0->LSR;
+    LSRValue = UART_GetLineStatus(UARTx);
+
     /* Receive Line Status */
-    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
+    if ( LSRValue & (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_RXFE|UART_LSR_BI) )
     {
       /* There are errors or break interrupt */
       /* Read LSR will clear the interrupt */
-      UART0Status = LSRValue;
-      dummy = LPC_UART0->RBR;		/* Dummy read on RX to clear
-                                   interrupt, then bail out */
+      Status = LSRValue;
+      byte = UART_ReceiveByte(UARTx);		/* Dummy read on RX to clear
+                                           interrupt, then bail out */
       return;
     }
-    if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
-    {
-      /* If no error on RLS, normal ready, save into the data buffer. */
-      /* Note: read RBR will clear the interrupt */
-      if ((UART0RxQueueWritePos+1) % UARTRXQUEUESIZE != UART0RxQueueReadPos)
+  }
+  
+  if ( IIRValue == UART_IIR_INTID_RDA )	/* Receive Data Available */
+  {
+    /* Clear the FIFO */
+    while ( UART_Receive(UARTx, &byte, 1, NONE_BLOCKING) ) {
+      if ((RxQueueWritePos+1) % RX_BUFFER_SIZE != RxQueueReadPos)
       {
-        UART0Buffer[UART0RxQueueWritePos] = LPC_UART0->RBR;
-        UART0RxQueueWritePos = (UART0RxQueueWritePos+1) % UARTRXQUEUESIZE;
+        RxBuffer[RxQueueWritePos] = byte;
+        RxQueueWritePos = (RxQueueWritePos+1) % RX_BUFFER_SIZE;
       }
       else
-        dummy = LPC_UART0->RBR;
+        break;
     }
   }
-  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
-  {
-	  /* Receive Data Available */
-	  if ((UART0RxQueueWritePos+1) % UARTRXQUEUESIZE != UART0RxQueueReadPos)
-	  {
-		  UART0Buffer[UART0RxQueueWritePos] = LPC_UART0->RBR;
-		  UART0RxQueueWritePos = (UART0RxQueueWritePos+1) % UARTRXQUEUESIZE;
-	  }
-	  else
-		  dummy = LPC_UART1->RBR;
-  }
-  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
+  else if ( IIRValue == UART_IIR_INTID_CTI )	/* Character timeout indicator */
   {
     /* Character Time-out indicator */
-    UART0Status |= 0x100;		/* Bit 9 as the CTI error */
+    Status |= 0x100;		/* Bit 9 as the CTI error */
   }
-  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
-  {
-    /* THRE interrupt */
-    LSRValue = LPC_UART0->LSR;		/* Check status in the LSR to see if
-                                     valid data in U0THR or not */
-    if ( LSRValue & LSR_THRE )
-    {
-      UART0TxEmpty = 1;
-    }
-    else
-    {
-      UART0TxEmpty = 0;
+
+  #if TX_BUFFER_SIZE > 0
+    if (IIRValue == UART_IIR_INTID_THRE) {
+      /* Disable THRE interrupt */
+      UART_IntConfig(UARTx, UART_INTCFG_THRE, DISABLE);
+
+      /* Wait for FIFO buffer empty */
+      while (UART_CheckBusy(UARTx) == SET);
+    
+      /* Transfer up to UART_TX_FIFO_SIZE bytes of data */
+      for (int i = 0; i < UART_TX_FIFO_SIZE && TxQueueWritePos != TxQueueReadPos; i++) {
+        /* Move a piece of data into the transmit FIFO */
+        if (UART_Send(UARTx, &TxBuffer[TxQueueReadPos], 1, NONE_BLOCKING))
+          TxQueueReadPos = (TxQueueReadPos+1) % TX_BUFFER_SIZE;
+        else
+          break;
+      }
+    
+      /* If there is no more data to send, disable the transmit interrupt - else enable it or keep it enabled */
+      if (TxQueueWritePos == TxQueueReadPos)
+        UART_IntConfig(UARTx, UART_INTCFG_THRE, DISABLE);
+      else
+        UART_IntConfig(UARTx, UART_INTCFG_THRE, ENABLE);
     }
-  }
+  #endif
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+** Function name:		UART0_IRQHandler
+**
+** Descriptions:		UART0 interrupt handler
+**
+** parameters:			None
+** Returned value:		None
+**
+*****************************************************************************/
+void UART0_IRQHandler (void)
+{
+  Serial.IRQHandler();
 }
 
 /*****************************************************************************
@@ -420,69 +326,9 @@ void UART0_IRQHandler (void)
 *****************************************************************************/
 void UART1_IRQHandler (void)
 {
-  uint8_t IIRValue, LSRValue;
-
-  IIRValue = LPC_UART1->IIR;
-
-  IIRValue >>= 1;			/* skip pending bit in IIR */
-  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
-  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
-  {
-    LSRValue = LPC_UART1->LSR;
-    /* Receive Line Status */
-    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
-    {
-      /* There are errors or break interrupt */
-      /* Read LSR will clear the interrupt */
-      UART1Status = LSRValue;
-      dummy = LPC_UART1->RBR;		/* Dummy read on RX to clear
-                                   interrupt, then bail out */
-      return;
-    }
-    if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
-    {
-      /* If no error on RLS, normal ready, save into the data buffer. */
-      /* Note: read RBR will clear the interrupt */
-      if ((UART1RxQueueWritePos+1) % UARTRXQUEUESIZE != UART1RxQueueReadPos)
-      {
-        UART1Buffer[UART1RxQueueWritePos] = LPC_UART1->RBR;
-        UART1RxQueueWritePos =(UART1RxQueueWritePos+1) % UARTRXQUEUESIZE;
-      }
-      else
-        dummy = LPC_UART1->RBR;
-    }
-  }
-  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
-  {
-	  /* Receive Data Available */
-	  if ((UART1RxQueueWritePos+1) % UARTRXQUEUESIZE != UART1RxQueueReadPos)
-	  {
-		  UART1Buffer[UART1RxQueueWritePos] = LPC_UART1->RBR;
-		  UART1RxQueueWritePos = (UART1RxQueueWritePos+1) % UARTRXQUEUESIZE;
-	  }
-	  else
-		  dummy = LPC_UART1->RBR;
-  }
-  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
-  {
-    /* Character Time-out indicator */
-    UART1Status |= 0x100;		/* Bit 9 as the CTI error */
-    }
-    else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
-    {
-    /* THRE interrupt */
-    LSRValue = LPC_UART1->LSR;		/* Check status in the LSR to see if
-                                     valid data in U0THR or not */
-    if ( LSRValue & LSR_THRE )
-    {
-      UART1TxEmpty = 1;
-    }
-    else
-    {
-      UART1TxEmpty = 0;
-    }
-  }
+  Serial1.IRQHandler();
 }
+
 /*****************************************************************************
 ** Function name:		UART2_IRQHandler
 **
@@ -494,71 +340,13 @@ void UART1_IRQHandler (void)
 *****************************************************************************/
 void UART2_IRQHandler (void)
 {
-  uint8_t IIRValue, LSRValue;
-
-  IIRValue = LPC_UART2->IIR;
-
-  IIRValue >>= 1;			/* skip pending bit in IIR */
-  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
-  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
-  {
-    LSRValue = LPC_UART2->LSR;
-    /* Receive Line Status */
-    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
-    {
-      /* There are errors or break interrupt */
-      /* Read LSR will clear the interrupt */
-      UART2Status = LSRValue;
-      dummy = LPC_UART2->RBR;		/* Dummy read on RX to clear
-                                   interrupt, then bail out */
-      return;
-    }
-    if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
-    {
-      /* If no error on RLS, normal ready, save into the data buffer. */
-      /* Note: read RBR will clear the interrupt */
-      if ((UART2RxQueueWritePos+1) % UARTRXQUEUESIZE != UART2RxQueueReadPos)
-      {
-        UART2Buffer[UART2RxQueueWritePos] = LPC_UART2->RBR;
-        UART2RxQueueWritePos = (UART2RxQueueWritePos+1) % UARTRXQUEUESIZE;
-      }
-    }
-  }
-  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
-  {
-	  /* Receive Data Available */
-	  if ((UART2RxQueueWritePos+1) % UARTRXQUEUESIZE != UART2RxQueueReadPos)
-	  {
-		  UART2Buffer[UART2RxQueueWritePos] = LPC_UART2->RBR;
-		  UART2RxQueueWritePos = (UART2RxQueueWritePos+1) % UARTRXQUEUESIZE;
-	  }
-	  else
-		  dummy = LPC_UART2->RBR;
-  }
-  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
-  {
-    /* Character Time-out indicator */
-    UART2Status |= 0x100;		/* Bit 9 as the CTI error */
-  }
-  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
-  {
-    /* THRE interrupt */
-    LSRValue = LPC_UART2->LSR;		/* Check status in the LSR to see if
-                                     valid data in U0THR or not */
-    if ( LSRValue & LSR_THRE )
-    {
-      UART2TxEmpty = 1;
-    }
-    else
-    {
-      UART2TxEmpty = 0;
-    }
-  }
+  Serial2.IRQHandler();
 }
+
 /*****************************************************************************
 ** Function name:		UART3_IRQHandler
 **
-** Descriptions:		UART0 interrupt handler
+** Descriptions:		UART3 interrupt handler
 **
 ** parameters:			None
 ** Returned value:		None
@@ -566,66 +354,7 @@ void UART2_IRQHandler (void)
 *****************************************************************************/
 void UART3_IRQHandler (void)
 {
-  uint8_t IIRValue, LSRValue;
-
-  IIRValue = LPC_UART3->IIR;
-
-  IIRValue >>= 1;			/* skip pending bit in IIR */
-  IIRValue &= 0x07;			/* check bit 1~3, interrupt identification */
-  if ( IIRValue == IIR_RLS )		/* Receive Line Status */
-  {
-    LSRValue = LPC_UART3->LSR;
-    /* Receive Line Status */
-    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
-    {
-      /* There are errors or break interrupt */
-      /* Read LSR will clear the interrupt */
-      UART3Status = LSRValue;
-      dummy = LPC_UART3->RBR;		/* Dummy read on RX to clear
-                                  interrupt, then bail out */
-      return;
-    }
-    if ( LSRValue & LSR_RDR )	/* Receive Data Ready */
-    {
-      /* If no error on RLS, normal ready, save into the data buffer. */
-      /* Note: read RBR will clear the interrupt */
-      if ((UART3RxQueueWritePos+1) % UARTRXQUEUESIZE != UART3RxQueueReadPos)
-        {
-          UART3Buffer[UART3RxQueueWritePos] = LPC_UART3->RBR;
-          UART3RxQueueWritePos = (UART3RxQueueWritePos+1) % UARTRXQUEUESIZE;
-        }
-    }
-  }
-  else if ( IIRValue == IIR_RDA )	/* Receive Data Available */
-  {
-	  /* Receive Data Available */
-	  if ((UART3RxQueueWritePos+1) % UARTRXQUEUESIZE != UART3RxQueueReadPos)
-	  {
-		  UART3Buffer[UART3RxQueueWritePos] = LPC_UART3->RBR;
-		  UART3RxQueueWritePos = (UART3RxQueueWritePos+1) % UARTRXQUEUESIZE;
-	  }
-	  else
-		  dummy = LPC_UART3->RBR;
-  }
-  else if ( IIRValue == IIR_CTI )	/* Character timeout indicator */
-  {
-    /* Character Time-out indicator */
-    UART3Status |= 0x100;		/* Bit 9 as the CTI error */
-  }
-  else if ( IIRValue == IIR_THRE )	/* THRE, transmit holding register empty */
-  {
-    /* THRE interrupt */
-    LSRValue = LPC_UART3->LSR;		/* Check status in the LSR to see if
-                                     valid data in U0THR or not */
-    if ( LSRValue & LSR_THRE )
-    {
-      UART3TxEmpty = 1;
-    }
-    else
-    {
-      UART3TxEmpty = 0;
-    }
-  }
+  Serial3.IRQHandler();
 }
 
 #ifdef __cplusplus
diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h
index b40597b3ecd0f42c9061b464a2c3b43a0fcb861f..8507396223113fa0d7fda530fe08f7e0a3b5ec38 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h
@@ -28,54 +28,51 @@
 #include <Stream.h>
 
 extern "C" {
-  #include <debug_frmwrk.h>
-  //#include <lpc17xx_uart.h>
+  #include <lpc17xx_uart.h>
+  #include "lpc17xx_pinsel.h"
 }
 
-#define IER_RBR   0x01
-#define IER_THRE  0x02
-#define IER_RLS   0x04
-
-#define IIR_PEND  0x01
-#define IIR_RLS   0x03
-#define IIR_RDA   0x02
-#define IIR_CTI   0x06
-#define IIR_THRE  0x01
-
-#define LSR_RDR   0x01
-#define LSR_OE    0x02
-#define LSR_PE    0x04
-#define LSR_FE    0x08
-#define LSR_BI    0x10
-#define LSR_THRE  0x20
-#define LSR_TEMT  0x40
-#define LSR_RXFE  0x80
-
-#define UARTRXQUEUESIZE   0x10
-
 class HardwareSerial : public Stream {
 private:
-uint8_t PortNum;
-uint32_t baudrate;
+  LPC_UART_TypeDef *UARTx;
+
+  uint32_t Status;
+  uint8_t RxBuffer[RX_BUFFER_SIZE];
+  uint32_t RxQueueWritePos;
+  uint32_t RxQueueReadPos;
+  #if TX_BUFFER_SIZE > 0
+    uint8_t TxBuffer[TX_BUFFER_SIZE];
+    uint32_t TxQueueWritePos;
+    uint32_t TxQueueReadPos;
+  #endif
 
 public:
-  HardwareSerial(uint32_t uart) :
-    PortNum(uart)
-    {
-    }
+  HardwareSerial(LPC_UART_TypeDef *UARTx)
+    : UARTx(UARTx)
+    , RxQueueWritePos(0)
+    , RxQueueReadPos(0)
+    #if TX_BUFFER_SIZE > 0
+      , TxQueueWritePos(0)
+      , TxQueueReadPos(0)
+    #endif
+  {
+  }
 
   void begin(uint32_t baudrate);
+  int peek();
   int read();
   size_t write(uint8_t send);
+  #if TX_BUFFER_SIZE > 0
+    void flushTX();
+  #endif
   int available();
   void flush();
   void printf(const char *format, ...);
-  int peek() {
-    return 0;
-  };
 
   operator bool() { return true; }
 
+  void IRQHandler();
+
   void print(const char value[])              { printf("%s" , value); }
   void print(char value, int = 0)             { printf("%c" , value); }
   void print(unsigned char value, int = 0)    { printf("%u" , value); }
@@ -100,9 +97,9 @@ public:
 
 };
 
-//extern HardwareSerial Serial0;
-//extern HardwareSerial Serial1;
-//extern HardwareSerial Serial2;
+extern HardwareSerial Serial;
+extern HardwareSerial Serial1;
+extern HardwareSerial Serial2;
 extern HardwareSerial Serial3;
 
 #endif // MARLIN_SRC_HAL_HAL_SERIAL_H_
diff --git a/Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp b/Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp
index 51883a4002e4c84c905c2dcb16a985480a1a1317..bfc5fbebb3ebe2d52f5fffe421356875ddde83db 100644
--- a/Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp
@@ -35,8 +35,7 @@ http://arduiniana.org.
 // Includes
 //
 //#include <WInterrupts.h>
-#include "../../core/macros.h"
-#include "../HAL.h"
+#include "../../inc/MarlinConfig.h"
 #include <stdint.h>
 #include <stdarg.h>
 #include "arduino.h"
diff --git a/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp b/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp
index 8c2ca1d5e47540f1a30a16d1d1b39395e53833d1..d3e91ce5533c2780c9174a96807c9da78214718f 100644
--- a/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp
@@ -18,8 +18,7 @@
 
 #ifdef TARGET_LPC1768
 
-#include "../../core/macros.h"
-#include "../HAL.h"
+#include "../../inc/MarlinConfig.h"
 #include "arduino.h"
 #include "pinmapping.h"
 //#include "HAL_timers.h"
diff --git a/Marlin/src/HAL/HAL_LPC1768/arduino.cpp b/Marlin/src/HAL/HAL_LPC1768/arduino.cpp
index 810a557af7272b7dc4884994185c360592b5004e..32c43416607acb33c30201a3c8e5ceb3b7934a84 100644
--- a/Marlin/src/HAL/HAL_LPC1768/arduino.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/arduino.cpp
@@ -22,10 +22,9 @@
 
 #ifdef TARGET_LPC1768
 
+#include "../../inc/MarlinConfig.h"
+
 #include <lpc17xx_pinsel.h>
-#include "HAL.h"
-#include "../../core/macros.h"
-#include "../../core/types.h"
 
 // Interrupts
 void cli(void) { __disable_irq(); } // Disable
@@ -147,7 +146,7 @@ void analogWrite(uint8_t pin, int pwm_value) {  // 1 - 254: pwm_value, 0: LOW, 2
     if (LPC1768_PWM_attach_pin(pin, 1, (LPC_PWM1->MR0 - MR0_MARGIN),  0xff))   // locks up if get too close to MR0 value
       LPC1768_PWM_write(pin, map(value, 1, 254, 1, (LPC_PWM1->MR0 - MR0_MARGIN)));  // map 1-254 onto PWM range
     else {                                                                 // out of PWM channels
-      if (!out_of_PWM_slots) usb_serial.printf(".\nWARNING - OUT OF PWM CHANNELS\n.\n");  //only warn once
+      if (!out_of_PWM_slots) MYSERIAL.printf(".\nWARNING - OUT OF PWM CHANNELS\n.\n");  //only warn once
       out_of_PWM_slots = true;
       digitalWrite(pin, value);  // treat as a digital pin if out of channels
     }
diff --git a/Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py b/Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
index 30781e99d39e4e2815b09422a6c84c2d1eb58fb0..a3138dfc07ecf8906c728ba36483edb4ee66acdb 100644
--- a/Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
+++ b/Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py
@@ -12,6 +12,7 @@ if __name__ == "__main__":
                     "-ffreestanding",
                     "-fsigned-char",
                     "-fno-move-loop-invariants",
+                    "-fno-strict-aliasing",
 
                     "--specs=nano.specs",
                     "--specs=nosys.specs",
diff --git a/Marlin/src/HAL/HAL_LPC1768/main.cpp b/Marlin/src/HAL/HAL_LPC1768/main.cpp
index eebac4a2cc5ad764c3cab661bdd907b376ba068e..788193c5b16ba1265e06540386ec2f2a7700d1b1 100644
--- a/Marlin/src/HAL/HAL_LPC1768/main.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp
@@ -24,6 +24,8 @@ extern "C" {
 #include <chanfs/ff.h>
 }
 
+#include "../../inc/MarlinConfig.h"
+#include "HAL.h"
 #include "fastio.h"
 #include "HAL_timers.h"
 #include <stdio.h>
@@ -69,21 +71,32 @@ extern "C" void SystemPostInit() {
 }
 
 extern uint32_t MSC_SD_Init(uint8_t pdrv);
-extern HalSerial usb_serial;
+
 int main(void) {
 
   (void)MSC_SD_Init(0);
+
   USB_Init();                               // USB Initialization
   USB_Connect(TRUE);                        // USB Connect
 
   volatile uint32_t usb_timeout = millis() + 2000;
   while (!USB_Configuration && millis() < usb_timeout) {
     delay(50);
-    TOGGLE(13);     // Flash fast while USB initialisation completes
+
+    #if PIN_EXISTS(LED)
+      TOGGLE(LED_PIN);     // Flash fast while USB initialisation completes
+    #endif
   }
 
-  debug_frmwrk_init();
-  usb_serial.printf("\n\nRe-ARM (LPC1768 @ %dMhz) UART0 Initialised\n", SystemCoreClock / 1000000);
+  // Only initialize the debug framework if using the USB emulated serial port
+  if ((HalSerial*) &MYSERIAL == &usb_serial)
+    debug_frmwrk_init();
+
+  MYSERIAL.begin(BAUDRATE);
+  MYSERIAL.printf("\n\nLPC1768 (%dMhz) UART0 Initialised\n", SystemCoreClock / 1000000);
+  #if TX_BUFFER_SIZE > 0
+    MYSERIAL.flushTX();
+  #endif
 
   HAL_timer_init();
 
diff --git a/Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h b/Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h
index 6fefcc128f3072c2559db2834780d30a8b23e696..dad9a5735b280a12e1691055c6f10d49ae46b6c5 100644
--- a/Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h
+++ b/Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h
@@ -27,7 +27,11 @@
 // Runtime pinmapping
 // ******************
 
-#define NUM_ANALOG_INPUTS 8
+#if SERIAL_PORT == 0
+  #define NUM_ANALOG_INPUTS 6
+#else
+  #define NUM_ANALOG_INPUTS 8
+#endif
 
 const adc_pin_data adc_pin_map[] = {
   {0, 23, 0},         //A0 (T0) - D67 - TEMP_0_PIN
@@ -36,27 +40,39 @@ const adc_pin_data adc_pin_map[] = {
   {0, 26, 3},         //A3 - D63
   {1, 30, 4},         //A4 - D37 - BUZZER_PIN
   {1, 31, 5},         //A5 - D49 - SD_DETECT_PIN
-  {0,  3, 6},         //A6 - D0  - RXD0
-  {0,  2, 7}          //A7 - D1  - TXD0
+  #if SERIAL_PORT != 0
+    {0,  3, 6},       //A6 - D0  - RXD0
+    {0,  2, 7}        //A7 - D1  - TXD0
+  #endif
 };
 
-#define analogInputToDigitalPin(p) (p == 0 ? 67: \
-                                    p == 1 ? 68: \
-                                    p == 2 ? 69: \
-                                    p == 3 ? 63: \
-                                    p == 4 ? 37: \
-                                    p == 5 ? 49: \
-                                    p == 6 ?  0: \
-                                    p == 7 ?  1: -1)
+constexpr FORCE_INLINE int8_t analogInputToDigitalPin(int8_t p) {
+  return (p == 0 ? 67:
+          p == 1 ? 68:
+          p == 2 ? 69:
+          p == 3 ? 63:
+          p == 4 ? 37:
+          p == 5 ? 49:
+          #if SERIAL_PORT != 0
+            p == 6 ?  0:
+            p == 7 ?  1:
+          #endif
+          -1);
+}
 
-#define DIGITAL_PIN_TO_ANALOG_PIN(p) (p == 67 ? 0: \
-                                      p == 68 ? 1: \
-                                      p == 69 ? 2: \
-                                      p == 63 ? 3: \
-                                      p == 37 ? 4: \
-                                      p == 49 ? 5: \
-                                      p == 0  ? 6: \
-                                      p == 1  ? 7: -1)
+constexpr FORCE_INLINE int8_t DIGITAL_PIN_TO_ANALOG_PIN(int8_t p) {
+  return (p == 67 ? 0:
+          p == 68 ? 1:
+          p == 69 ? 2:
+          p == 63 ? 3:
+          p == 37 ? 4:
+          p == 49 ? 5:
+          #if SERIAL_PORT != 0
+            p == 0  ? 6:
+            p == 1  ? 7:
+          #endif
+          -1);
+}
 
 #define NUM_DIGITAL_PINS 84
 
diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp
index 06e3895e8d6a1fe633ecf008274c0901089af7f3..bbaf4d3b90451a94e801faf610961c1b10ccfcc3 100644
--- a/Marlin/src/gcode/feature/pause/M125.cpp
+++ b/Marlin/src/gcode/feature/pause/M125.cpp
@@ -29,6 +29,10 @@
 #include "../../../feature/pause.h"
 #include "../../../module/motion.h"
 
+#if DISABLED(SDSUPPORT)
+  #include "../../../module/printcounter.h"
+#endif
+
 /**
  * M125: Store current position and move to filament change position.
  *       Called on pause (by M25) to prevent material leaking onto the
diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h
index a8b7a54e8d8733d98454234c2b3a0d9d59f7e79b..dcd019a99caf2c618475455346fe05de645a300f 100644
--- a/Marlin/src/gcode/parser.h
+++ b/Marlin/src/gcode/parser.h
@@ -135,7 +135,7 @@ public:
     // Code is found in the string. If not found, value_ptr is unchanged.
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
     static bool seen(const char c) {
-      const char *p = strchr(command_args, c);
+      char *p = strchr(command_args, c);
       const bool b = !!p;
       if (b) value_ptr = DECIMAL_SIGNED(p[1]) ? &p[1] : (char*)NULL;
       return b;
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 3653396bb7cf368f6fe7e2eb9b0bc19456382314..f50d2f0075c58cfbcc782c873ecc4d65e5f3e1cb 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -491,4 +491,12 @@
   #define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER))
   #define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED))
 
+  // For Re-ARM boards, always use the USB Emulated Serial Port unless RE_ARM_FORCE_SERIAL_PORT is defined
+  #if MB(RAMPS_14_RE_ARM_EFB) || MB(RAMPS_14_RE_ARM_EEB) || MB(RAMPS_14_RE_ARM_EFF) || MB(RAMPS_14_RE_ARM_EEF) || MB(RAMPS_14_RE_ARM_SF)
+    #ifndef RE_ARM_FORCE_SERIAL_PORT
+      #undef SERIAL_PORT
+      #define SERIAL_PORT -1
+    #endif
+  #endif
+
 #endif // CONDITIONALS_LCD_H
diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h
new file mode 100644
index 0000000000000000000000000000000000000000..8799d22d546b28003b2a5557dd92790fc9a7b99e
--- /dev/null
+++ b/Marlin/src/inc/Conditionals_adv.h
@@ -0,0 +1,42 @@
+/**
+ * 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/>.
+ *
+ */
+
+/**
+ * Conditionals_adv.h
+ * Defines that depend on advanced onfiguration.
+ */
+
+#ifndef CONDITIONALS_ADV_H
+#define CONDITIONALS_ADV_H
+
+  #ifndef USBCON
+    // Define constants and variables for buffering incoming serial data.
+    // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
+    #ifndef RX_BUFFER_SIZE
+      #define RX_BUFFER_SIZE 128
+    #endif
+    #ifndef TX_BUFFER_SIZE
+      #define TX_BUFFER_SIZE 32
+    #endif
+  #endif
+
+#endif // CONDITIONALS_ADV_H
diff --git a/Marlin/src/inc/MarlinConfig.h b/Marlin/src/inc/MarlinConfig.h
index 25d56cf0064d7af141d87fd239bcdde8b36194bb..1b471051e6453b71c24e34b77cd6d954fa3eecee 100644
--- a/Marlin/src/inc/MarlinConfig.h
+++ b/Marlin/src/inc/MarlinConfig.h
@@ -30,6 +30,7 @@
 #include "../../Configuration.h"
 #include "Conditionals_LCD.h"
 #include "../../Configuration_adv.h"
+#include "Conditionals_adv.h"
 #include "../HAL/HAL.h"
 #include "../pins/pins.h"
 #if defined(__AVR__) && !defined(USBCON)
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index f75be67e96c90a1b0002487fa9df355ae9baae79..f2e9d20633d2294755874d90b421b529056d452e 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -235,6 +235,24 @@
   #error "WEBSITE_URL must be specified."
 #endif
 
+/**
+ * Serial
+ */
+#ifndef USBCON
+  #if ENABLED(SERIAL_XON_XOFF) && RX_BUFFER_SIZE < 1024
+    #error "XON/XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops."
+  #endif
+
+  #if !IS_POWER_OF_2(RX_BUFFER_SIZE) || RX_BUFFER_SIZE < 2
+    #error "RX_BUFFER_SIZE must be a power of 2 greater than 1."
+  #endif
+
+  // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
+  #if TX_BUFFER_SIZE && (TX_BUFFER_SIZE < 2 || TX_BUFFER_SIZE > 256 || !IS_POWER_OF_2(TX_BUFFER_SIZE))
+    #error "TX_BUFFER_SIZE must be 0 or a power of 2 greater than 1."
+  #endif
+#endif
+
 /**
  * Dual Stepper Drivers
  */
diff --git a/frameworks/CMSIS/LPC1768/driver/debug_frmwrk.c b/frameworks/CMSIS/LPC1768/driver/debug_frmwrk.c
index 972e80611a8c3c9c4155707a61040d9f88ab9d1c..7d7bae4b862e53f3eacef5b72ecceb8e56110a45 100644
--- a/frameworks/CMSIS/LPC1768/driver/debug_frmwrk.c
+++ b/frameworks/CMSIS/LPC1768/driver/debug_frmwrk.c
@@ -44,17 +44,18 @@
 
 #ifdef _DBGFWK
 /* Debug framework */
+static Bool debug_frmwrk_initialized = FALSE;
 
-void (*_db_msg)(LPC_UART_TypeDef *UARTx, const void *s);
-void (*_db_msg_)(LPC_UART_TypeDef *UARTx, const void *s);
-void (*_db_char)(LPC_UART_TypeDef *UARTx, uint8_t ch);
-void (*_db_dec)(LPC_UART_TypeDef *UARTx, uint8_t decn);
-void (*_db_dec_16)(LPC_UART_TypeDef *UARTx, uint16_t decn);
-void (*_db_dec_32)(LPC_UART_TypeDef *UARTx, uint32_t decn);
-void (*_db_hex)(LPC_UART_TypeDef *UARTx, uint8_t hexn);
-void (*_db_hex_16)(LPC_UART_TypeDef *UARTx, uint16_t hexn);
-void (*_db_hex_32)(LPC_UART_TypeDef *UARTx, uint32_t hexn);
-uint8_t (*_db_get_char)(LPC_UART_TypeDef *UARTx);
+void (*_db_msg)(LPC_UART_TypeDef *UARTx, const void *s) = UARTPuts;
+void (*_db_msg_)(LPC_UART_TypeDef *UARTx, const void *s) = UARTPuts_;
+void (*_db_char)(LPC_UART_TypeDef *UARTx, uint8_t ch) = UARTPutChar;
+void (*_db_dec)(LPC_UART_TypeDef *UARTx, uint8_t decn) = UARTPutHex;
+void (*_db_dec_16)(LPC_UART_TypeDef *UARTx, uint16_t decn) = UARTPutHex16;
+void (*_db_dec_32)(LPC_UART_TypeDef *UARTx, uint32_t decn) = UARTPutHex32;
+void (*_db_hex)(LPC_UART_TypeDef *UARTx, uint8_t hexn) = UARTPutDec;
+void (*_db_hex_16)(LPC_UART_TypeDef *UARTx, uint16_t hexn) = UARTPutDec16;
+void (*_db_hex_32)(LPC_UART_TypeDef *UARTx, uint32_t hexn) = UARTPutDec32;
+uint8_t (*_db_get_char)(LPC_UART_TypeDef *UARTx) = UARTGetChar;
 
 
 /*********************************************************************//**
@@ -65,7 +66,8 @@ uint8_t (*_db_get_char)(LPC_UART_TypeDef *UARTx);
  **********************************************************************/
 void UARTPutChar (LPC_UART_TypeDef *UARTx, uint8_t ch)
 {
-	UART_Send(UARTx, &ch, 1, BLOCKING);
+  if (debug_frmwrk_initialized)
+	  UART_Send(UARTx, &ch, 1, BLOCKING);
 }
 
 
@@ -76,8 +78,11 @@ void UARTPutChar (LPC_UART_TypeDef *UARTx, uint8_t ch)
  **********************************************************************/
 uint8_t UARTGetChar (LPC_UART_TypeDef *UARTx)
 {
-	uint8_t tmp = 0;
-	UART_Receive(UARTx, &tmp, 1, BLOCKING);
+  uint8_t tmp = 0;
+  
+  if (debug_frmwrk_initialized)
+    UART_Receive(UARTx, &tmp, 1, BLOCKING);
+    
 	return(tmp);
 }
 
@@ -90,7 +95,10 @@ uint8_t UARTGetChar (LPC_UART_TypeDef *UARTx)
  **********************************************************************/
 void UARTPuts(LPC_UART_TypeDef *UARTx, const void *str)
 {
-	uint8_t *s = (uint8_t *) str;
+  uint8_t *s = (uint8_t *) str;
+  
+  if (!debug_frmwrk_initialized)
+    return;
 
 	while (*s)
 	{
@@ -107,6 +115,9 @@ void UARTPuts(LPC_UART_TypeDef *UARTx, const void *str)
  **********************************************************************/
 void UARTPuts_(LPC_UART_TypeDef *UARTx, const void *str)
 {
+  if (!debug_frmwrk_initialized)
+    return;
+
 	UARTPuts (UARTx, str);
 	UARTPuts (UARTx, "\n\r");
 }
@@ -120,6 +131,9 @@ void UARTPuts_(LPC_UART_TypeDef *UARTx, const void *str)
  **********************************************************************/
 void UARTPutDec(LPC_UART_TypeDef *UARTx, uint8_t decnum)
 {
+  if (!debug_frmwrk_initialized)
+    return;
+
 	uint8_t c1=decnum%10;
 	uint8_t c2=(decnum/10)%10;
 	uint8_t c3=(decnum/100)%10;
@@ -135,7 +149,10 @@ void UARTPutDec(LPC_UART_TypeDef *UARTx, uint8_t decnum)
  * @return		None
  **********************************************************************/
 void UARTPutDec16(LPC_UART_TypeDef *UARTx, uint16_t decnum)
-{
+{  
+  if (!debug_frmwrk_initialized)
+    return;
+
 	uint8_t c1=decnum%10;
 	uint8_t c2=(decnum/10)%10;
 	uint8_t c3=(decnum/100)%10;
@@ -156,6 +173,9 @@ void UARTPutDec16(LPC_UART_TypeDef *UARTx, uint16_t decnum)
  **********************************************************************/
 void UARTPutDec32(LPC_UART_TypeDef *UARTx, uint32_t decnum)
 {
+  if (!debug_frmwrk_initialized)
+    return;
+
 	uint8_t c1=decnum%10;
 	uint8_t c2=(decnum/10)%10;
 	uint8_t c3=(decnum/100)%10;
@@ -187,6 +207,9 @@ void UARTPutDec32(LPC_UART_TypeDef *UARTx, uint32_t decnum)
 void UARTPutHex (LPC_UART_TypeDef *UARTx, uint8_t hexnum)
 {
 	uint8_t nibble, i;
+  
+  if (!debug_frmwrk_initialized)
+    return;
 
 	UARTPuts(UARTx, "0x");
 	i = 1;
@@ -206,6 +229,9 @@ void UARTPutHex (LPC_UART_TypeDef *UARTx, uint8_t hexnum)
 void UARTPutHex16 (LPC_UART_TypeDef *UARTx, uint16_t hexnum)
 {
 	uint8_t nibble, i;
+  
+  if (!debug_frmwrk_initialized)
+    return;
 
 	UARTPuts(UARTx, "0x");
 	i = 3;
@@ -223,7 +249,10 @@ void UARTPutHex16 (LPC_UART_TypeDef *UARTx, uint16_t hexnum)
  **********************************************************************/
 void UARTPutHex32 (LPC_UART_TypeDef *UARTx, uint32_t hexnum)
 {
-	uint8_t nibble, i;
+  uint8_t nibble, i;
+  
+  if (!debug_frmwrk_initialized)
+    return;
 
 	UARTPuts(UARTx, "0x");
 	i = 7;
@@ -305,16 +334,7 @@ void debug_frmwrk_init(void)
 	// Enable UART Transmit
 	UART_TxCmd((LPC_UART_TypeDef *)DEBUG_UART_PORT, ENABLE);
 
-	_db_msg	= UARTPuts;
-	_db_msg_ = UARTPuts_;
-	_db_char = UARTPutChar;
-	_db_hex = UARTPutHex;
-	_db_hex_16 = UARTPutHex16;
-	_db_hex_32 = UARTPutHex32;
-	_db_dec = UARTPutDec;
-	_db_dec_16 = UARTPutDec16;
-	_db_dec_32 = UARTPutDec32;
-	_db_get_char = UARTGetChar;
+  debug_frmwrk_initialized = TRUE;
 }
 #endif /*_DBGFWK */
 
diff --git a/frameworks/CMSIS/LPC1768/lib/Print.h b/frameworks/CMSIS/LPC1768/lib/Print.h
index f27fbb077755f66ea7ec7fffb551a26373f2770b..b18c2d311386e2a8d162a1815da905f6f4b8235f 100644
--- a/frameworks/CMSIS/LPC1768/lib/Print.h
+++ b/frameworks/CMSIS/LPC1768/lib/Print.h
@@ -17,8 +17,8 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#ifndef Print_h
-#define Print_h
+#ifndef CMSIS_Print_h
+#define CMSIS_Print_h
 
 
 #include <inttypes.h>
diff --git a/frameworks/CMSIS/LPC1768/lib/Printable.h b/frameworks/CMSIS/LPC1768/lib/Printable.h
index 4284e992b4bbf1cfb91ca8f2f995e7eee63d602e..590fb783992b5c4e50e3c3d133968516d81156f7 100644
--- a/frameworks/CMSIS/LPC1768/lib/Printable.h
+++ b/frameworks/CMSIS/LPC1768/lib/Printable.h
@@ -17,8 +17,8 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#ifndef Printable_h
-#define Printable_h
+#ifndef CMSIS_Printable_h
+#define CMSIS_Printable_h
 
 #include <stdlib.h>
 #include <inttypes.h>