From 51fafccc16f4e58814b1e6e601a3e8f449f54f89 Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Tue, 24 Oct 2017 17:28:33 -0500 Subject: [PATCH] [2.0.x] Enable hardware serial ports on LPC1768 (#8004) * Enable hardware serial ports on LPC1768 * Fix compilation errors with other HALs * FIx order of includes in LPC1768 HAL main.cpp * Add support for RX_BUFFER_SIZE and TX_BUFFER_SIZE options in Configuration_adv.h --- Marlin/src/HAL/HAL_AVR/MarlinSerial.h | 27 +- Marlin/src/HAL/HAL_LPC1768/HAL.cpp | 9 +- Marlin/src/HAL/HAL_LPC1768/HAL.h | 19 +- Marlin/src/HAL/HAL_LPC1768/HAL_timers.cpp | 2 +- Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp | 799 ++++++------------ Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h | 67 +- Marlin/src/HAL/HAL_LPC1768/SoftwareSerial.cpp | 3 +- Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp | 3 +- Marlin/src/HAL/HAL_LPC1768/arduino.cpp | 7 +- .../HAL/HAL_LPC1768/lpc1768_flag_script.py | 1 + Marlin/src/HAL/HAL_LPC1768/main.cpp | 21 +- Marlin/src/HAL/HAL_LPC1768/pinmap_re_arm.h | 54 +- Marlin/src/gcode/feature/pause/M125.cpp | 4 + Marlin/src/gcode/parser.h | 2 +- Marlin/src/inc/Conditionals_LCD.h | 8 + Marlin/src/inc/Conditionals_adv.h | 42 + Marlin/src/inc/MarlinConfig.h | 1 + Marlin/src/inc/SanityCheck.h | 18 + .../CMSIS/LPC1768/driver/debug_frmwrk.c | 72 +- frameworks/CMSIS/LPC1768/lib/Print.h | 4 +- frameworks/CMSIS/LPC1768/lib/Printable.h | 4 +- 21 files changed, 499 insertions(+), 668 deletions(-) create mode 100644 Marlin/src/inc/Conditionals_adv.h diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h index e289e7cf1f..6a9fd776fa 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 037899675f..29c0964e9b 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 +#include "../../inc/MarlinConfig.h" extern "C" { //#include @@ -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 e1b52a6819..907b550c3c 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 c46e80f4b8..c9e25693e2 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 6438acd228..cd76e8f704 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(&((LPC_UART1_TypeDef *) UARTx)->FIFOLVL)); + else + fifolvl = *(reinterpret_cast(&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 b40597b3ec..8507396223 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h +++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h @@ -28,54 +28,51 @@ #include extern "C" { - #include - //#include + #include + #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 51883a4002..bfc5fbebb3 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 -#include "../../core/macros.h" -#include "../HAL.h" +#include "../../inc/MarlinConfig.h" #include #include #include "arduino.h" diff --git a/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp b/Marlin/src/HAL/HAL_LPC1768/WInterrupts.cpp index 8c2ca1d5e4..d3e91ce553 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 810a557af7..32c4341660 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 -#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 30781e99d3..a3138dfc07 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 eebac4a2cc..788193c5b1 100644 --- a/Marlin/src/HAL/HAL_LPC1768/main.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp @@ -24,6 +24,8 @@ extern "C" { #include } +#include "../../inc/MarlinConfig.h" +#include "HAL.h" #include "fastio.h" #include "HAL_timers.h" #include @@ -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 6fefcc128f..dad9a5735b 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 06e3895e8d..bbaf4d3b90 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 a8b7a54e8d..dcd019a99c 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 3653396bb7..f50d2f0075 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 0000000000..8799d22d54 --- /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 . + * + */ + +/** + * 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 25d56cf006..1b471051e6 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 f75be67e96..f2e9d20633 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 972e80611a..7d7bae4b86 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 f27fbb0777..b18c2d3113 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 diff --git a/frameworks/CMSIS/LPC1768/lib/Printable.h b/frameworks/CMSIS/LPC1768/lib/Printable.h index 4284e992b4..590fb78399 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 #include