From f7efac57b7ac607405529a71b4e36a6545525c89 Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Sun, 5 Nov 2017 08:49:38 -0600 Subject: [PATCH] Multi-host support --- Marlin/Configuration.h | 9 + Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp | 3 +- Marlin/src/HAL/HAL_AVR/HAL_AVR.h | 18 + Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h | 4 +- Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h | 4 +- .../src/HAL/HAL_DUE/EepromEmulation_Due.cpp | 16 +- Marlin/src/HAL/HAL_DUE/HAL_Due.h | 15 +- Marlin/src/HAL/HAL_LPC1768/HAL.cpp | 12 +- Marlin/src/HAL/HAL_LPC1768/HAL.h | 37 +- Marlin/src/HAL/HAL_LPC1768/arduino.cpp | 2 +- Marlin/src/HAL/HAL_LPC1768/main.cpp | 15 +- Marlin/src/HAL/HAL_LPC1768/serial.h | 155 ++--- Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h | 35 +- Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h | 12 +- Marlin/src/Marlin.cpp | 19 +- Marlin/src/core/serial.cpp | 40 +- Marlin/src/core/serial.h | 178 +++++- Marlin/src/feature/bedlevel/abl/abl.cpp | 9 +- Marlin/src/feature/bedlevel/ubl/ubl.cpp | 31 +- Marlin/src/feature/bedlevel/ubl/ubl.h | 12 +- Marlin/src/feature/tmc_util.cpp | 4 +- Marlin/src/gcode/eeprom/M500-M504.cpp | 28 +- Marlin/src/gcode/feature/trinamic/M122.cpp | 40 +- Marlin/src/gcode/host/M115.cpp | 13 +- Marlin/src/gcode/parser.cpp | 15 +- Marlin/src/gcode/queue.cpp | 272 +++++---- Marlin/src/gcode/queue.h | 7 + .../src/gcode/sdcard/M20-M30_M32-M34_M928.cpp | 32 +- Marlin/src/gcode/stats/M31.cpp | 11 +- Marlin/src/gcode/temperature/M105.cpp | 22 +- Marlin/src/inc/Conditionals_LCD.h | 6 - Marlin/src/module/configuration_store.cpp | 536 ++++++++++-------- Marlin/src/module/configuration_store.h | 44 +- Marlin/src/module/stepper.h | 4 +- Marlin/src/module/temperature.cpp | 54 +- Marlin/src/module/temperature.h | 6 +- Marlin/src/sd/SdBaseFile.cpp | 39 +- Marlin/src/sd/SdFatUtil.cpp | 58 +- Marlin/src/sd/SdFatUtil.h | 8 - Marlin/src/sd/cardreader.cpp | 86 ++- Marlin/src/sd/cardreader.h | 24 +- 41 files changed, 1190 insertions(+), 745 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 7601dd65a3..b8cc3d3869 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -102,6 +102,15 @@ */ #define SERIAL_PORT 0 +/** + * Select a secondary serial port on the board to use for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port -1 is the USB emulated serial port, if avaialble. + * + * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] + */ +#define SERIAL_PORT_2 -1 + /** * This setting determines the communication speed of the printer. * diff --git a/Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp b/Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp index b4619323d1..9c69b90a86 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp +++ b/Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp @@ -33,8 +33,7 @@ // Includes // -------------------------------------------------------------------------- -#include "../HAL.h" -#include "../../core/macros.h" +#include "../../inc/MarlinConfig.h" // -------------------------------------------------------------------------- // Externals diff --git a/Marlin/src/HAL/HAL_AVR/HAL_AVR.h b/Marlin/src/HAL/HAL_AVR/HAL_AVR.h index 2d59323051..8ea43c8154 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_AVR.h +++ b/Marlin/src/HAL/HAL_AVR/HAL_AVR.h @@ -47,6 +47,12 @@ #include "watchdog_AVR.h" #include "math_AVR.h" +#ifdef USBCON + #include "HardwareSerial.h" +#else + #include "MarlinSerial.h" +#endif + // -------------------------------------------------------------------------- // Defines // -------------------------------------------------------------------------- @@ -79,6 +85,18 @@ typedef int8_t pin_t; //extern uint8_t MCUSR; +#define NUM_SERIAL 1 + +#ifdef USBCON + #if ENABLED(BLUETOOTH) + #define MYSERIAL0 bluetoothSerial + #else + #define MYSERIAL0 Serial + #endif +#else + #define MYSERIAL0 customizedSerial +#endif + // -------------------------------------------------------------------------- // Public functions // -------------------------------------------------------------------------- diff --git a/Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h b/Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h index b9e5abc4b3..f66c2ef7f4 100644 --- a/Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h +++ b/Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h @@ -483,9 +483,9 @@ inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = fa for (uint8_t y = 0; y < 28; y++) { // always print pin name temp_char = pgm_read_byte(name_mem_pointer + y); if (temp_char != 0) - MYSERIAL.write(temp_char); + SERIAL_CHAR(temp_char); else { - for (uint8_t i = 0; i < 28 - y; i++) MYSERIAL.write(' '); + for (uint8_t i = 0; i < 28 - y; i++) SERIAL_CHAR(' '); break; } } diff --git a/Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h b/Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h index 5c68f2d994..02f23f05d4 100644 --- a/Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h +++ b/Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h @@ -66,9 +66,9 @@ void PRINT_ARRAY_NAME(uint8_t x) { for (uint8_t y = 0; y < MAX_NAME_LENGTH; y++) { char temp_char = pgm_read_byte(name_mem_pointer + y); if (temp_char != 0) - MYSERIAL.write(temp_char); + SERIAL_CHAR(temp_char); else { - for (uint8_t i = 0; i < MAX_NAME_LENGTH - y; i++) MYSERIAL.write(' '); + for (uint8_t i = 0; i < MAX_NAME_LENGTH - y; i++) SERIAL_CHAR(' '); break; } } diff --git a/Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp b/Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp index a7afb6e6a0..4665565544 100644 --- a/Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp @@ -121,7 +121,7 @@ static uint8_t curGroup = 0xFF; // Current FLASH group char buffer[80]; sprintf(buffer, "Page: %d (0x%04x)\n", page, page); - MYSERIAL.print(buffer); + SERIAL_PROTOCOL(buffer); char* p = &buffer[0]; for (int i = 0; i< PageSize; ++i) { @@ -133,7 +133,7 @@ static uint8_t curGroup = 0xFF; // Current FLASH group if ((i & 15) == 15) { *p++ = '\n'; *p = 0; - MYSERIAL.print(buffer); + SERIAL_PROTOCOL(buffer); p = &buffer[0]; } } @@ -182,7 +182,7 @@ static bool ee_PageWrite(uint16_t page,const void* data) { SERIAL_ECHOLNPAIR("EEPROM PageWrite ",page); SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash); SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0)); - MYSERIAL.flush(); + SERIAL_FLUSH(); #endif // Get the page relative to the start of the EFC controller, and the EFC controller to use @@ -313,7 +313,7 @@ static bool ee_PageErase(uint16_t page) { SERIAL_ECHOLNPAIR("EEPROM PageErase ",page); SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash); SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0)); - MYSERIAL.flush(); + SERIAL_FLUSH(); #endif // Get the page relative to the start of the EFC controller, and the EFC controller to use @@ -943,7 +943,7 @@ static void ee_Init() { #ifdef EE_EMU_DEBUG SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup); - MYSERIAL.flush(); + SERIAL_FLUSH(); #endif // Now, validate that all the other group pages are empty @@ -957,7 +957,7 @@ static void ee_Init() { SERIAL_ECHO_START(); SERIAL_ECHOPAIR("EEPROM Page ",page); SERIAL_ECHOLNPAIR(" not clean on group ",grp); - MYSERIAL.flush(); + SERIAL_FLUSH(); #endif ee_PageErase(grp * PagesPerGroup + page); } @@ -978,7 +978,7 @@ static void ee_Init() { #ifdef EE_EMU_DEBUG SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("EEPROM Active page: ",curPage); - MYSERIAL.flush(); + SERIAL_FLUSH(); #endif // Make sure the pages following the first clean one are also clean @@ -988,7 +988,7 @@ static void ee_Init() { SERIAL_ECHO_START(); SERIAL_ECHOPAIR("EEPROM Page ",page); SERIAL_ECHOLNPAIR(" not clean on active group ",curGroup); - MYSERIAL.flush(); + SERIAL_FLUSH(); ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); #endif ee_PageErase(curGroup * PagesPerGroup + page); diff --git a/Marlin/src/HAL/HAL_DUE/HAL_Due.h b/Marlin/src/HAL/HAL_DUE/HAL_Due.h index 9519a2ba74..8c31ece354 100644 --- a/Marlin/src/HAL/HAL_DUE/HAL_Due.h +++ b/Marlin/src/HAL/HAL_DUE/HAL_Due.h @@ -40,8 +40,15 @@ // // Defines // -#if SERIAL_PORT >= -1 && SERIAL_PORT <= 4 - #define MYSERIAL customizedSerial +#define NUM_SERIAL 1 + +//#undef SERIAL_PORT +//#define SERIAL_PORT -1 + +#if SERIAL_PORT == -1 + #define MYSERIAL0 SerialUSB +#else + #define MYSERIAL0 customizedSerial #endif // We need the previous define before the include, or compilation bombs... @@ -147,6 +154,10 @@ uint16_t HAL_getAdcFreerun(uint8_t chan, bool wait_for_conversion = false); void HAL_enable_AdcFreerun(void); //void HAL_disable_AdcFreerun(uint8_t chan); +/** + * Pin Map + */ + #define GET_PIN_MAP_PIN(index) index #define GET_PIN_MAP_INDEX(pin) pin #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp index 5579810346..71315fdfde 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/HAL.cpp @@ -29,7 +29,7 @@ extern "C" { HalSerial usb_serial; -//u8glib required fucntions +// U8glib required functions extern "C" void u8g_xMicroDelay(uint16_t val) { delayMicroseconds(val); } @@ -85,7 +85,7 @@ void HAL_adc_enable_channel(int ch) { pin_t pin = analogInputToDigitalPin(ch); if (pin == -1) { - MYSERIAL.printf("%sINVALID ANALOG PORT:%d\n", errormagic, ch); + SERIAL_PRINTF("%sINVALID ANALOG PORT:%d\n", errormagic, ch); kill(MSG_KILLED); } @@ -97,15 +97,15 @@ void HAL_adc_enable_channel(int ch) { pin_port == 1 ? 3 : 10; switch (pin_sel_register) { - case 1 : + case 1: LPC_PINCON->PINSEL1 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL1 |= (0x1 << pinsel_start_bit); break; - case 3 : + case 3: LPC_PINCON->PINSEL3 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL3 |= (0x3 << pinsel_start_bit); break; - case 0 : + case 0: LPC_PINCON->PINSEL0 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL0 |= (0x2 << pinsel_start_bit); break; @@ -115,7 +115,7 @@ void HAL_adc_enable_channel(int ch) { uint8_t active_adc = 0; void HAL_adc_start_conversion(const uint8_t ch) { if (analogInputToDigitalPin(ch) == -1) { - MYSERIAL.printf("HAL: HAL_adc_start_conversion: invalid channel %d\n", ch); + SERIAL_PRINTF("HAL: HAL_adc_start_conversion: invalid channel %d\n", ch); return; } diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/HAL_LPC1768/HAL.h index cf54cb1d71..162bb1a597 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL.h +++ b/Marlin/src/HAL/HAL_LPC1768/HAL.h @@ -69,19 +69,44 @@ extern "C" volatile uint32_t _millis; #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 #define ST7920_DELAY_3 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 -//Serial override extern HalSerial usb_serial; +#if !WITHIN(SERIAL_PORT, -1, 3) + #error "SERIAL_PORT must be from -1 to 3" +#endif + #if SERIAL_PORT == -1 - #define MYSERIAL usb_serial + #define MYSERIAL0 usb_serial #elif SERIAL_PORT == 0 - #define MYSERIAL Serial + #define MYSERIAL0 Serial #elif SERIAL_PORT == 1 - #define MYSERIAL Serial1 + #define MYSERIAL0 Serial1 #elif SERIAL_PORT == 2 - #define MYSERIAL Serial2 + #define MYSERIAL0 Serial2 #elif SERIAL_PORT == 3 - #define MYSERIAL Serial3 + #define MYSERIAL0 Serial3 +#endif + +#ifdef SERIAL_PORT_2 + #if !WITHIN(SERIAL_PORT_2, -1, 3) + #error "SERIAL_PORT_2 must be from -1 to 3" + #elif SERIAL_PORT_2 == SERIAL_PORT + #error "SERIAL_PORT_2 must be different than SERIAL_PORT" + #endif + #define NUM_SERIAL 2 + #if SERIAL_PORT_2 == -1 + #define MYSERIAL1 usb_serial + #elif SERIAL_PORT_2 == 0 + #define MYSERIAL1 Serial + #elif SERIAL_PORT_2 == 1 + #define MYSERIAL1 Serial1 + #elif SERIAL_PORT_2 == 2 + #define MYSERIAL1 Serial2 + #elif SERIAL_PORT_2 == 3 + #define MYSERIAL1 Serial3 + #endif +#else + #define NUM_SERIAL 1 #endif #define CRITICAL_SECTION_START uint32_t primask = __get_PRIMASK(); __disable_irq(); diff --git a/Marlin/src/HAL/HAL_LPC1768/arduino.cpp b/Marlin/src/HAL/HAL_LPC1768/arduino.cpp index feab1e8b09..94026f27a7 100644 --- a/Marlin/src/HAL/HAL_LPC1768/arduino.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/arduino.cpp @@ -139,7 +139,7 @@ void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255 if (LPC1768_PWM_attach_pin(pin, 1, LPC_PWM1->MR0, 0xFF)) LPC1768_PWM_write(pin, map(value, 0, 255, 1, LPC_PWM1->MR0)); // map 1-254 onto PWM range else { // out of PWM channels - if (!out_of_PWM_slots) MYSERIAL.printf(".\nWARNING - OUT OF PWM CHANNELS\n.\n"); //only warn once + if (!out_of_PWM_slots) SERIAL_ECHOPGM(".\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/main.cpp b/Marlin/src/HAL/HAL_LPC1768/main.cpp index dd6d24681d..da3e0c6481 100644 --- a/Marlin/src/HAL/HAL_LPC1768/main.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp @@ -88,14 +88,13 @@ int main(void) { #endif } - // 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(); + #if NUM_SERIAL > 0 + MYSERIAL0.begin(BAUDRATE); + #if NUM_SERIAL > 1 + MYSERIAL1.begin(BAUDRATE); + #endif + SERIAL_PRINTF("\n\nLPC1768 (%dMhz) UART0 Initialised\n", SystemCoreClock / 1000000); + SERIAL_FLUSHTX(); #endif HAL_timer_init(); diff --git a/Marlin/src/HAL/HAL_LPC1768/serial.h b/Marlin/src/HAL/HAL_LPC1768/serial.h index d3c3be9127..8f496d3f7f 100644 --- a/Marlin/src/HAL/HAL_LPC1768/serial.h +++ b/Marlin/src/HAL/HAL_LPC1768/serial.h @@ -20,8 +20,8 @@ * */ -#ifndef HAL_SERIAL_H_ -#define HAL_SERIAL_H_ +#ifndef _HAL_SERIAL_H_ +#define _HAL_SERIAL_H_ #include #include @@ -30,7 +30,7 @@ extern "C" { #include } -/* +/** * Generic RingBuffer * T type of the buffer array * S size of the buffer (must be power of 2) @@ -39,46 +39,33 @@ extern "C" { */ template class RingBuffer { public: - RingBuffer() { - index_read = 0; - index_write = 0; - } + RingBuffer() { index_read = index_write = 0; } + uint32_t available() volatile { return buffer_mask & (index_write - index_read); } + uint32_t free() volatile { return buffer_size - available(); } + bool empty() volatile { return (buffer_mask & index_read) == (buffer_mask & index_write); } + bool full() volatile { return index_read == buffer_mask & (index_write + 1); } + void clear() volatile { index_read = index_write = 0; } bool peek(T *value) volatile { - if(value == 0 || available() == 0) + if (value == 0 || available() == 0) return false; *value = buffer[buffer_mask & index_read]; return true; } - uint32_t available() volatile { - return buffer_mask & (index_write - index_read); - } - uint32_t free() volatile { - return buffer_size - available(); - } - T read() volatile { - if((buffer_mask & index_read) == (buffer_mask & index_write)) return T(-1); + int read() volatile { + if ((buffer_mask & index_read) == (buffer_mask & index_write)) return -1; T val = buffer[buffer_mask & index_read]; ++index_read; return val; } - bool write( T value) volatile { + bool write(T value) volatile { uint32_t next_head = buffer_mask & (index_write + 1); - if(next_head != index_read) { + if (next_head != index_read) { buffer[buffer_mask & index_write] = value; index_write = next_head; return true; } return false; } - bool empty() volatile { - return (buffer_mask & index_read) == (buffer_mask & index_write); - } - bool full() volatile { - return index_read == buffer_mask & (index_write + 1); - } - void clear() volatile { - index_read = index_write = 0; - } private: static const uint32_t buffer_size = S; @@ -90,42 +77,35 @@ private: class HalSerial { public: - HalSerial() { - host_connected = false; - } + HalSerial() { host_connected = false; } void begin(int32_t baud) { } - char read() { - return (char)receive_buffer.read(); + int peek() { + uint8_t value; + return receive_buffer.peek(&value) ? value : -1; } - void write(char c) { - _DBC(c); //Duplicate output over uart0 - if(host_connected) transmit_buffer.write((uint8_t)c); - } + int read() { return receive_buffer.read(); } - operator bool() { - return host_connected; - } + size_t write(char c) { return host_connected ? transmit_buffer.write((uint8_t)c) : 0; } + + operator bool() { return host_connected; } uint16_t available() { return (uint16_t)receive_buffer.available(); } - void flush() { - receive_buffer.clear(); - } + void flush() { receive_buffer.clear(); } uint8_t availableForWrite(void){ return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free(); } void flushTX(void){ - if(host_connected) { - while(transmit_buffer.available()); - } + if (host_connected) + while (transmit_buffer.available()) { /* nada */ } } void printf(const char *format, ...) { @@ -135,7 +115,6 @@ public: int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs); va_end(vArgs); if (length > 0 && length < 256) { - _DBG(buffer); //Duplicate output over uart0 if (host_connected) { for (int i = 0; i < length;) { if (transmit_buffer.write(buffer[i])) { @@ -152,108 +131,72 @@ public: #define BIN 2 #define BYTE 0 - void print_bin(uint32_t value, uint8_t num_digits) { uint32_t mask = 1 << (num_digits -1); for (uint8_t i = 0; i < num_digits; i++) { - if (!(i % 4) && i) printf(" "); - if (!(i % 16) && i) printf(" "); - if (value & mask) printf("1"); - else printf("0"); + if (!(i % 4) && i) write(' '); + if (!(i % 16) && i) write(' '); + if (value & mask) write('1'); + else write('0'); value <<= 1; } } - void print(const char value[]) { - printf("%s" , value); - } + void print(const char value[]) { printf("%s" , value); } void print(char value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,8); + if (nbase == BIN) print_bin(value, 8); else if (nbase == OCT) printf("%3o", value); else if (nbase == HEX) printf("%2X", value); else if (nbase == DEC ) printf("%d", value); else printf("%c" , value); } void print(unsigned char value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,8); + if (nbase == BIN) print_bin(value, 8); else if (nbase == OCT) printf("%3o", value); else if (nbase == HEX) printf("%2X", value); else printf("%u" , value); } void print(int value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,16); + if (nbase == BIN) print_bin(value, 16); else if (nbase == OCT) printf("%6o", value); else if (nbase == HEX) printf("%4X", value); else printf("%d", value); } void print(unsigned int value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,16); + if (nbase == BIN) print_bin(value, 16); else if (nbase == OCT) printf("%6o", value); else if (nbase == HEX) printf("%4X", value); else printf("%u" , value); } void print(long value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,32); + if (nbase == BIN) print_bin(value, 32); else if (nbase == OCT) printf("%11o", value); else if (nbase == HEX) printf("%8X", value); else printf("%ld" , value); } void print(unsigned long value, int nbase = BYTE) { - if (nbase == BIN) print_bin(value,32); + if (nbase == BIN) print_bin(value, 32); else if (nbase == OCT) printf("%11o", value); else if (nbase == HEX) printf("%8X", value); else printf("%lu" , value); } - void print(float value, int round = 6) { - printf("%f" , value); - } - void print(double value, int round = 6) { - printf("%f" , value ); - } + void print(float value, int round = 6) { printf("%f" , value); } + void print(double value, int round = 6) { printf("%f" , value); } - - - void println(const char value[]) { - printf("%s\n" , value); - } - void println(char value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(unsigned char value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(int value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(unsigned int value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(long value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(unsigned long value, int nbase = BYTE) { - print(value, nbase); - println(); - } - void println(float value, int round = 6) { - printf("%f\n" , value ); - } - void println(double value, int round = 6) { - printf("%f\n" , value ); - } - void println(void) { - print('\n'); - } + void println(const char value[]) { printf("%s\n" , value); } + void println(char value, int nbase = BYTE) { print(value, nbase); println(); } + void println(unsigned char value, int nbase = BYTE) { print(value, nbase); println(); } + void println(int value, int nbase = BYTE) { print(value, nbase); println(); } + void println(unsigned int value, int nbase = BYTE) { print(value, nbase); println(); } + void println(long value, int nbase = BYTE) { print(value, nbase); println(); } + void println(unsigned long value, int nbase = BYTE) { print(value, nbase); println(); } + void println(float value, int round = 6) { printf("%f\n" , value); } + void println(double value, int round = 6) { printf("%f\n" , value); } + void println(void) { print('\n'); } volatile RingBuffer receive_buffer; volatile RingBuffer transmit_buffer; volatile bool host_connected; }; - -#endif /* MARLIN_SRC_HAL_HAL_SERIAL_H_ */ +#endif // _HAL_SERIAL_H_ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h index d9ff5d8cbc..c5186c9fd8 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h @@ -65,16 +65,41 @@ // Defines // -------------------------------------------------------------------------- +#if !WITHIN(SERIAL_PORT, -1, 3) + #error "SERIAL_PORT must be from -1 to 3" +#endif #if SERIAL_PORT == -1 - #define MYSERIAL SerialUSB + #define MYSERIAL0 SerialUSB #elif SERIAL_PORT == 0 - #define MYSERIAL Serial + #define MYSERIAL0 Serial #elif SERIAL_PORT == 1 - #define MYSERIAL Serial1 + #define MYSERIAL0 Serial1 #elif SERIAL_PORT == 2 - #define MYSERIAL Serial2 + #define MYSERIAL0 Serial2 #elif SERIAL_PORT == 3 - #define MYSERIAL Serial3 + #define MYSERIAL0 Serial3 +#endif + +#ifdef SERIAL_PORT_2 + #if !WITHIN(SERIAL_PORT_2, -1, 3) + #error "SERIAL_PORT_2 must be from -1 to 3" + #elif SERIAL_PORT_2 == SERIAL_PORT + #error "SERIAL_PORT_2 must be different than SERIAL_PORT" + #endif + #define NUM_SERIAL 2 + #if SERIAL_PORT_2 == -1 + #define MYSERIAL1 SerialUSB + #elif SERIAL_PORT_2 == 0 + #define MYSERIAL1 Serial + #elif SERIAL_PORT_2 == 1 + #define MYSERIAL1 Serial1 + #elif SERIAL_PORT_2 == 2 + #define MYSERIAL1 Serial2 + #elif SERIAL_PORT_2 == 3 + #define MYSERIAL1 Serial3 + #endif +#else + #define NUM_SERIAL 1 #endif /** diff --git a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h index b5dfb60802..120772ffd7 100644 --- a/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h +++ b/Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h @@ -57,16 +57,18 @@ #define IS_TEENSY35 defined(__MK64FX512__) #define IS_TEENSY36 defined(__MK66FX1M0__) +#define NUM_SERIAL 1 + #if SERIAL_PORT == -1 - #define MYSERIAL SerialUSB + #define MYSERIAL0 SerialUSB #elif SERIAL_PORT == 0 - #define MYSERIAL Serial + #define MYSERIAL0 Serial #elif SERIAL_PORT == 1 - #define MYSERIAL Serial1 + #define MYSERIAL0 Serial1 #elif SERIAL_PORT == 2 - #define MYSERIAL Serial2 + #define MYSERIAL0 Serial2 #elif SERIAL_PORT == 3 - #define MYSERIAL Serial3 + #define MYSERIAL0 Serial3 #endif #define HAL_SERVO_LIB libServo diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index b801281dd6..012839503f 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -669,9 +669,22 @@ void setup() { disableStepperDrivers(); #endif - MYSERIAL.begin(BAUDRATE); - uint32_t serial_connect_timeout = millis() + 1000; - while(!MYSERIAL && PENDING(millis(), serial_connect_timeout)); + #if NUM_SERIAL > 0 + MYSERIAL0.begin(BAUDRATE); + #if NUM_SERIAL > 1 + MYSERIAL1.begin(BAUDRATE); + #endif + #endif + + #if NUM_SERIAL > 0 + uint32_t serial_connect_timeout = millis() + 1000UL; + while(!MYSERIAL0 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #if NUM_SERIAL > 1 + serial_connect_timeout = millis() + 1000UL; + while(!MYSERIAL1 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } + #endif + #endif + SERIAL_PROTOCOLLNPGM("start"); SERIAL_ECHO_START(); diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index a02d943bd6..f7b9dbf61d 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -27,25 +27,37 @@ uint8_t marlin_debug_flags = DEBUG_NONE; const char errormagic[] PROGMEM = "Error:"; const char echomagic[] PROGMEM = "echo:"; +#if NUM_SERIAL > 1 + void serialprintPGM_P(const int8_t p, const char * str) { + while (char ch = pgm_read_byte(str++)) SERIAL_CHAR_P(p, ch); + } + + void serial_echopair_PGM_P(const int8_t p, const char* s_P, const char *v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, char v) { serialprintPGM_P(p, s_P); SERIAL_CHAR_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, int v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, long v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, float v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, double v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned int v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned long v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); } + + void serial_spaces_P(const int8_t p, uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR_P(p, ' '); } +#endif void serialprintPGM(const char * str) { - #ifdef TARGET_LPC1768 - MYSERIAL.print(str); - #else - while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch); - #endif + while (char ch = pgm_read_byte(str++)) SERIAL_CHAR(ch); } -void serial_echopair_P(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } -void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } +void serial_echopair_PGM(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); } +void serial_echopair_PGM(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); } -void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) MYSERIAL.write(' '); } +void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); } #if ENABLED(DEBUG_LEVELING_FEATURE) diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 04d94829d4..4c04533829 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -75,9 +75,7 @@ enum DebugFlags { #include "../HAL/HAL_AVR/MarlinSerial.h" #define MYSERIAL customizedSerial #endif -#endif - -#ifdef ARDUINO_ARCH_SAM +#elif defined(ARDUINO_ARCH_SAM) // To pull the Serial port definitions and overrides #include "../HAL/HAL_DUE/MarlinSerial_Due.h" #endif @@ -88,17 +86,152 @@ extern uint8_t marlin_debug_flags; extern const char echomagic[] PROGMEM; extern const char errormagic[] PROGMEM; -#define SERIAL_CHAR(x) ((void)MYSERIAL.write(x)) +#if TX_BUFFER_SIZE < 1 + #define SERIAL_FLUSHTX_P(p) + #define SERIAL_FLUSHTX() +#endif + +#if NUM_SERIAL > 1 + #define SERIAL_CHAR_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.write(x) : MYSERIAL1.write(x)) : SERIAL_CHAR(x)) + #define SERIAL_PROTOCOL_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x) : MYSERIAL1.print(x)) : SERIAL_PROTOCOL(x)) + #define SERIAL_PROTOCOL_F_P(p,x,y) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x,y) : MYSERIAL1.print(x,y)) : SERIAL_PROTOCOL_F(x,y)) + #define SERIAL_PROTOCOLLN_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.println(x) : MYSERIAL1.println(x)) : SERIAL_PROTOCOLLN(x)) + #define SERIAL_PRINT_P(p,x,b) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x,b) : MYSERIAL1.print(x,b)) : SERIAL_PRINT(x,b)) + #define SERIAL_PRINTLN_P(p,x,b) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.println(x,b) : MYSERIAL1.println(x,b)) : SERIAL_PRINTLN(x,b)) + #define SERIAL_PRINTF_P(p,args...) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.printf(args) : MYSERIAL1.printf(args)) : SERIAL_PRINTF(args)) + + #define SERIAL_CHAR(x) (MYSERIAL0.write(x), MYSERIAL1.write(x)) + #define SERIAL_PROTOCOL(x) (MYSERIAL0.print(x), MYSERIAL1.print(x)) + #define SERIAL_PROTOCOL_F(x,y) (MYSERIAL0.print(x,y), MYSERIAL1.print(x,y)) + #define SERIAL_PROTOCOLLN(x) (MYSERIAL0.println(x), MYSERIAL1.println(x)) + #define SERIAL_PRINT(x,b) (MYSERIAL0.print(x,b), MYSERIAL1.print(x,b)) + #define SERIAL_PRINTLN(x,b) (MYSERIAL0.println(x,b), MYSERIAL1.println(x,b)) + #define SERIAL_PRINTF(args...) (MYSERIAL0.printf(args), MYSERIAL1.printf(args)) + + #define SERIAL_FLUSH_P(p) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.flush() : MYSERIAL1.flush()) : SERIAL_FLUSH()) + #define SERIAL_FLUSH() (MYSERIAL0.flush(), MYSERIAL1.flush()) + #if TX_BUFFER_SIZE > 0 + #define SERIAL_FLUSHTX_P(p) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.flushTX() : MYSERIAL1.flushTX()) : SERIAL_FLUSHTX()) + #define SERIAL_FLUSHTX() (MYSERIAL0.flushTX(), MYSERIAL1.flushTX()) + #endif + + #define SERIAL_EOL_P(p) SERIAL_CHAR_P(p,'\n') + + #define SERIAL_PROTOCOLCHAR_P(p,x) SERIAL_CHAR_P(p,x) + #define SERIAL_PROTOCOLPGM_P(p,x) (serialprintPGM_P(p,PSTR(x))) + #define SERIAL_PROTOCOLLNPGM_P(p,x) (serialprintPGM_P(p,PSTR(x "\n"))) + #define SERIAL_PROTOCOLPAIR_P(p, pre, value) (serial_echopair_PGM_P(p,PSTR(pre),(value))) + #define SERIAL_PROTOCOLLNPAIR_P(p, pre, value) do { SERIAL_PROTOCOLPAIR_P(p, pre, value); SERIAL_EOL_P(p); } while(0) + + #define SERIAL_ECHO_START_P(p) (serialprintPGM_P(p,echomagic)) + #define SERIAL_ECHO_P(p,x) SERIAL_PROTOCOL_P(p,x) + #define SERIAL_ECHOPGM_P(p,x) SERIAL_PROTOCOLPGM_P(p,x) + #define SERIAL_ECHOLN_P(p,x) SERIAL_PROTOCOLLN_P(p,x) + #define SERIAL_ECHOLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM_P(p,x) + #define SERIAL_ECHOPAIR_P(p,pre,value) SERIAL_PROTOCOLPAIR_P(p, pre, value) + #define SERIAL_ECHOLNPAIR_P(p,pre, value) SERIAL_PROTOCOLLNPAIR_P(p, pre, value) + #define SERIAL_ECHO_F_P(p,x,y) SERIAL_PROTOCOL_F_P(p,x,y) + + #define SERIAL_ERROR_START_P(p) (serialprintPGM_P(p,errormagic)) + #define SERIAL_ERROR_P(p,x) SERIAL_PROTOCOL_P(p,x) + #define SERIAL_ERRORPGM_P(p,x) SERIAL_PROTOCOLPGM_P(p,x) + #define SERIAL_ERRORLN_P(p,x) SERIAL_PROTOCOLLN_P(p,x) + #define SERIAL_ERRORLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM_P(p,x) + + // These macros compensate for float imprecision + #define SERIAL_PROTOCOLPAIR_F_P(p, pre, value) SERIAL_PROTOCOLPAIR_P(p, pre, FIXFLOAT(value)) + #define SERIAL_PROTOCOLLNPAIR_F_P(p, pre, value) SERIAL_PROTOCOLLNPAIR_P(p, pre, FIXFLOAT(value)) + #define SERIAL_ECHOPAIR_F_P(p,pre,value) SERIAL_ECHOPAIR_P(p, pre, FIXFLOAT(value)) + #define SERIAL_ECHOLNPAIR_F_P(p,pre, value) SERIAL_ECHOLNPAIR_P(p, pre, FIXFLOAT(value)) + + void serial_echopair_PGM_P(const int8_t p, const char* s_P, const char *v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, char v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, int v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, long v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, float v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, double v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned int v); + void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned long v); + FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, uint8_t v) { serial_echopair_PGM_P(p, s_P, (int)v); } + FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, bool v) { serial_echopair_PGM_P(p, s_P, (int)v); } + FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, void *v) { serial_echopair_PGM_P(p, s_P, (unsigned long)v); } + + void serial_spaces_P(const int8_t p, uint8_t count); + #define SERIAL_ECHO_SP_P(p,C) serial_spaces_P(p,C) + #define SERIAL_ERROR_SP_P(p,C) serial_spaces_P(p,C) + #define SERIAL_PROTOCOL_SP_P(p,C) serial_spaces_P(p,C) + + void serialprintPGM_P(const int8_t p, const char* str); +#else + #define SERIAL_CHAR_P(p,x) SERIAL_CHAR(x) + #define SERIAL_PROTOCOL_P(p,x) SERIAL_PROTOCOL(x) + #define SERIAL_PROTOCOL_F_P(p,x,y) SERIAL_PROTOCOL_F(x,y) + #define SERIAL_PROTOCOLLN_P(p,x) SERIAL_PROTOCOLLN(x) + #define SERIAL_PRINT_P(p,x,b) SERIAL_PRINT(x,b) + #define SERIAL_PRINTLN_P(p,x,b) SERIAL_PRINTLN(x,b) + #define SERIAL_PRINTF_P(p,args...) SERIAL_PRINTF(args) + + #define SERIAL_CHAR(x) MYSERIAL0.write(x) + #define SERIAL_PROTOCOL(x) MYSERIAL0.print(x) + #define SERIAL_PROTOCOL_F(x,y) MYSERIAL0.print(x,y) + #define SERIAL_PROTOCOLLN(x) MYSERIAL0.println(x) + #define SERIAL_PRINT(x,b) MYSERIAL0.print(x,b) + #define SERIAL_PRINTLN(x,b) MYSERIAL0.println(x,b) + #define SERIAL_PRINTF(args...) MYSERIAL0.printf(args) + + #define SERIAL_FLUSH_P(p) SERIAL_FLUSH() + #define SERIAL_FLUSH() MYSERIAL0.flush() + #if TX_BUFFER_SIZE > 0 + #define SERIAL_FLUSHTX_P(p) SERIAL_FLUSHTX() + #define SERIAL_FLUSHTX() MYSERIAL0.flushTX() + #endif + + #define SERIAL_EOL_P(p) SERIAL_EOL() + + #define SERIAL_PROTOCOLCHAR_P(p,x) SERIAL_PROTOCOLCHAR(x) + #define SERIAL_PROTOCOLPGM_P(p,x) SERIAL_PROTOCOLPGM(x) + #define SERIAL_PROTOCOLLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM(x) + #define SERIAL_PROTOCOLPAIR_P(p, pre, value) SERIAL_PROTOCOLPAIR(pre, value) + #define SERIAL_PROTOCOLLNPAIR_P(p, pre, value) SERIAL_PROTOCOLLNPAIR(pre, value) + + #define SERIAL_ECHO_START_P(p) SERIAL_ECHO_START() + #define SERIAL_ECHO_P(p,x) SERIAL_ECHO(x) + #define SERIAL_ECHOPGM_P(p,x) SERIAL_ECHOPGM(x) + #define SERIAL_ECHOLN_P(p,x) SERIAL_ECHOLN(x) + #define SERIAL_ECHOLNPGM_P(p,x) SERIAL_ECHOLNPGM(x) + #define SERIAL_ECHOPAIR_P(p,pre,value) SERIAL_ECHOPAIR(pre, value) + #define SERIAL_ECHOLNPAIR_P(p,pre, value) SERIAL_ECHOLNPAIR(pre, value) + #define SERIAL_ECHO_F_P(p,x,y) SERIAL_ECHO_F(x,y) + + #define SERIAL_ERROR_START_P(p) SERIAL_ERROR_START() + #define SERIAL_ERROR_P(p,x) SERIAL_ERROR(x) + #define SERIAL_ERRORPGM_P(p,x) SERIAL_ERRORPGM(x) + #define SERIAL_ERRORLN_P(p,x) SERIAL_ERRORLN(x) + #define SERIAL_ERRORLNPGM_P(p,x) SERIAL_ERRORLNPGM(x) + + // These macros compensate for float imprecision + #define SERIAL_PROTOCOLPAIR_F_P(p, pre, value) SERIAL_PROTOCOLPAIR_F(pre, value) + #define SERIAL_PROTOCOLLNPAIR_F_P(p, pre, value) SERIAL_PROTOCOLLNPAIR_F(pre, value) + #define SERIAL_ECHOPAIR_F_P(p,pre,value) SERIAL_ECHOPAIR_F(pre, value) + #define SERIAL_ECHOLNPAIR_F_P(p,pre, value) SERIAL_ECHOLNPAIR_F(pre, value) + + #define serial_echopair_PGM_P(p,s_P,v) serial_echopair_PGM(s_P, v) + + #define serial_spaces_P(p,c) serial_spaces(c) + #define SERIAL_ECHO_SP_P(p,C) SERIAL_ECHO_SP(C) + #define SERIAL_ERROR_SP_P(p,C) SERIAL_ERROR_SP(C) + #define SERIAL_PROTOCOL_SP_P(p,C) SERIAL_PROTOCOL_SP(C) + + #define serialprintPGM_P(p,s) serialprintPGM(s) +#endif + #define SERIAL_EOL() SERIAL_CHAR('\n') #define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x) -#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x)) -#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y)) #define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x))) -#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL(); }while(0) #define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n"))) -#define SERIAL_PROTOCOLPAIR(pre, value) (serial_echopair_P(PSTR(pre),(value))) -#define SERIAL_PROTOCOLLNPAIR(pre, value) do{ SERIAL_PROTOCOLPAIR(pre, value); SERIAL_EOL(); }while(0) +#define SERIAL_PROTOCOLPAIR(pre, value) (serial_echopair_PGM(PSTR(pre), value)) +#define SERIAL_PROTOCOLLNPAIR(pre, value) do { SERIAL_PROTOCOLPAIR(pre, value); SERIAL_EOL(); } while(0) #define SERIAL_ECHO_START() (serialprintPGM(echomagic)) #define SERIAL_ECHO(x) SERIAL_PROTOCOL(x) @@ -107,7 +240,7 @@ extern const char errormagic[] PROGMEM; #define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x) #define SERIAL_ECHOPAIR(pre,value) SERIAL_PROTOCOLPAIR(pre, value) #define SERIAL_ECHOLNPAIR(pre, value) SERIAL_PROTOCOLLNPAIR(pre, value) -#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x,y) +#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x, y) #define SERIAL_ERROR_START() (serialprintPGM(errormagic)) #define SERIAL_ERROR(x) SERIAL_PROTOCOL(x) @@ -121,17 +254,17 @@ extern const char errormagic[] PROGMEM; #define SERIAL_ECHOPAIR_F(pre,value) SERIAL_ECHOPAIR(pre, FIXFLOAT(value)) #define SERIAL_ECHOLNPAIR_F(pre, value) SERIAL_ECHOLNPAIR(pre, FIXFLOAT(value)) -void serial_echopair_P(const char* s_P, const char *v); -void serial_echopair_P(const char* s_P, char v); -void serial_echopair_P(const char* s_P, int v); -void serial_echopair_P(const char* s_P, long v); -void serial_echopair_P(const char* s_P, float v); -void serial_echopair_P(const char* s_P, double v); -void serial_echopair_P(const char* s_P, unsigned int v); -void serial_echopair_P(const char* s_P, unsigned long v); -FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); } -FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); } -FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); } +void serial_echopair_PGM(const char* s_P, const char *v); +void serial_echopair_PGM(const char* s_P, char v); +void serial_echopair_PGM(const char* s_P, int v); +void serial_echopair_PGM(const char* s_P, long v); +void serial_echopair_PGM(const char* s_P, float v); +void serial_echopair_PGM(const char* s_P, double v); +void serial_echopair_PGM(const char* s_P, unsigned int v); +void serial_echopair_PGM(const char* s_P, unsigned long v); +FORCE_INLINE void serial_echopair_PGM(const char* s_P, uint8_t v) { serial_echopair_PGM(s_P, (int)v); } +FORCE_INLINE void serial_echopair_PGM(const char* s_P, bool v) { serial_echopair_PGM(s_P, (int)v); } +FORCE_INLINE void serial_echopair_PGM(const char* s_P, void *v) { serial_echopair_PGM(s_P, (unsigned long)v); } void serial_spaces(uint8_t count); #define SERIAL_ECHO_SP(C) serial_spaces(C) @@ -149,8 +282,7 @@ void serialprintPGM(const char* str); #if HAS_ABL void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz); #endif - #define DEBUG_POS(SUFFIX,VAR) do { \ - print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0) + #define DEBUG_POS(SUFFIX,VAR) do { print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0) #endif #endif // __SERIAL_H__ diff --git a/Marlin/src/feature/bedlevel/abl/abl.cpp b/Marlin/src/feature/bedlevel/abl/abl.cpp index 672a03c3d8..6362608622 100644 --- a/Marlin/src/feature/bedlevel/abl/abl.cpp +++ b/Marlin/src/feature/bedlevel/abl/abl.cpp @@ -64,9 +64,12 @@ static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t c1 = z_values[x1][y1], c2 = z_values[x2][y2]; // Treat far unprobed points as zero, near as equal to far - if (isnan(a2)) a2 = 0.0; if (isnan(a1)) a1 = a2; - if (isnan(b2)) b2 = 0.0; if (isnan(b1)) b1 = b2; - if (isnan(c2)) c2 = 0.0; if (isnan(c1)) c1 = c2; + if (isnan(a2)) a2 = 0.0; + if (isnan(a1)) a1 = a2; + if (isnan(b2)) b2 = 0.0; + if (isnan(b1)) b1 = b2; + if (isnan(c2)) c2 = 0.0; + if (isnan(c1)) c1 = c2; const float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2; diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.cpp b/Marlin/src/feature/bedlevel/ubl/ubl.cpp index 89739822f3..683848f364 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl.cpp @@ -36,13 +36,27 @@ uint8_t ubl_cnt = 0; - void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); } + void unified_bed_leveling::echo_name( + #if NUM_SERIAL > 1 + const int8_t port/*= -1*/ + #endif + ) { + SERIAL_PROTOCOLPGM_P(port, "Unified Bed Leveling"); + } - void unified_bed_leveling::report_state() { - echo_name(); - SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " "); - if (!planner.leveling_active) SERIAL_PROTOCOLPGM("in"); - SERIAL_PROTOCOLLNPGM("active."); + void unified_bed_leveling::report_state( + #if NUM_SERIAL > 1 + const int8_t port/*= -1*/ + #endif + ) { + echo_name( + #if NUM_SERIAL > 1 + port + #endif + ); + SERIAL_PROTOCOLPGM_P(port, " System v" UBL_VERSION " "); + if (!planner.leveling_active) SERIAL_PROTOCOLPGM_P(port, "in"); + SERIAL_PROTOCOLLNPGM_P(port, "active."); safe_delay(50); } @@ -198,10 +212,7 @@ } idle(); if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(','); - - #if TX_BUFFER_SIZE > 0 - MYSERIAL.flushTX(); - #endif + SERIAL_FLUSHTX(); safe_delay(15); if (map_type == 0) { SERIAL_CHAR(is_current ? ']' : ' '); diff --git a/Marlin/src/feature/bedlevel/ubl/ubl.h b/Marlin/src/feature/bedlevel/ubl/ubl.h index 01e93769d3..82bdbce870 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl.h +++ b/Marlin/src/feature/bedlevel/ubl/ubl.h @@ -104,8 +104,16 @@ class unified_bed_leveling { public: - static void echo_name(); - static void report_state(); + static void echo_name( + #if NUM_SERIAL > 1 + const int8_t port = -1 + #endif + ); + static void report_state( + #if NUM_SERIAL > 1 + const int8_t port = -1 + #endif + ); static void save_ubl_active_state_and_disable(); static void restore_ubl_active_state_and_leave(); static void display_map(const int); diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index ef80495f6d..b799462d35 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -146,12 +146,12 @@ char extended_axis_codes[11][3] = { "X", "X2", "Y", "Y2", "Z", "Z2", "E0", "E1", const uint32_t pwm_scale = get_pwm_scale(st); SERIAL_ECHO(axisID); SERIAL_ECHOPAIR(":", pwm_scale); - SERIAL_ECHO(" |0b"); MYSERIAL.print(get_status_response(st), BIN); + SERIAL_ECHO(" |0b"); SERIAL_PRINT(get_status_response(st), BIN); SERIAL_ECHO("| "); if (data.is_error) SERIAL_ECHO('E'); else if (data.is_ot) SERIAL_ECHO('O'); else if (data.is_otpw) SERIAL_ECHO('W'); - else if (otpw_cnt>0) MYSERIAL.print(otpw_cnt, DEC); + else if (otpw_cnt>0) SERIAL_PRINT(otpw_cnt, DEC); else if (st.flag_otpw) SERIAL_ECHO('F'); SERIAL_ECHO("\t"); } diff --git a/Marlin/src/gcode/eeprom/M500-M504.cpp b/Marlin/src/gcode/eeprom/M500-M504.cpp index 74140eee15..c67f860a00 100644 --- a/Marlin/src/gcode/eeprom/M500-M504.cpp +++ b/Marlin/src/gcode/eeprom/M500-M504.cpp @@ -24,25 +24,41 @@ #include "../../module/configuration_store.h" #include "../../inc/MarlinConfig.h" +#if NUM_SERIAL > 1 + #include "../../gcode/queue.h" +#endif + /** * M500: Store settings in EEPROM */ void GcodeSuite::M500() { - (void)settings.save(); + (void)settings.save( + #if ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1 + command_queue_port[cmd_queue_index_r] + #endif + ); } /** * M501: Read settings from EEPROM */ void GcodeSuite::M501() { - (void)settings.load(); + (void)settings.load( + #if ENABLED(EEPROM_SETTINGS) && ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1 + command_queue_port[cmd_queue_index_r] + #endif + ); } /** * M502: Revert to default settings */ void GcodeSuite::M502() { - (void)settings.reset(); + (void)settings.reset( + #if ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1 + command_queue_port[cmd_queue_index_r] + #endif + ); } #if DISABLED(DISABLE_M503) @@ -51,7 +67,11 @@ void GcodeSuite::M502() { * M503: print settings currently in memory */ void GcodeSuite::M503() { - (void)settings.report(parser.seen('S') && !parser.value_bool()); + (void)settings.report(parser.seen('S') && !parser.value_bool() + #if NUM_SERIAL > 1 + , command_queue_port[cmd_queue_index_r] + #endif + ); } #endif // !DISABLE_M503 diff --git a/Marlin/src/gcode/feature/trinamic/M122.cpp b/Marlin/src/gcode/feature/trinamic/M122.cpp index 843e2e7e9a..dc6d51eed9 100644 --- a/Marlin/src/gcode/feature/trinamic/M122.cpp +++ b/Marlin/src/gcode/feature/trinamic/M122.cpp @@ -79,21 +79,21 @@ static void drv_status_print_hex(const char name[], const uint32_t drv_status) { SERIAL_ECHO(name); SERIAL_ECHOPGM(" = 0x"); for(int B=24; B>=8; B-=8){ - MYSERIAL.print((drv_status>>(B+4))&0xF, HEX); - MYSERIAL.print((drv_status>>B)&0xF, HEX); - MYSERIAL.print(':'); + SERIAL_PRINT((drv_status>>(B+4))&0xF, HEX); + SERIAL_PRINT((drv_status>>B)&0xF, HEX); + SERIAL_CHAR(':'); } - MYSERIAL.print((drv_status>>4)&0xF, HEX); - MYSERIAL.print((drv_status)&0xF, HEX); + SERIAL_PRINT((drv_status>>4)&0xF, HEX); + SERIAL_PRINT((drv_status)&0xF, HEX); SERIAL_EOL(); } #if ENABLED(HAVE_TMC2130) static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) { switch(i) { - case TMC_PWM_SCALE: MYSERIAL.print(st.PWM_SCALE(), DEC); break; + case TMC_PWM_SCALE: SERIAL_PRINT(st.PWM_SCALE(), DEC); break; case TMC_TSTEP: SERIAL_ECHO(st.TSTEP()); break; - case TMC_SGT: MYSERIAL.print(st.sgt(), DEC); break; + case TMC_SGT: SERIAL_PRINT(st.sgt(), DEC); break; case TMC_STEALTHCHOP: serialprintPGM(st.stealthChop() ? PSTR("true") : PSTR("false")); break; default: break; } @@ -101,7 +101,7 @@ static void drv_status_print_hex(const char name[], const uint32_t drv_status) { static void tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) { switch(i) { case TMC_STALLGUARD: if (st.stallguard()) SERIAL_ECHOPGM("X"); break; - case TMC_SG_RESULT: MYSERIAL.print(st.sg_result(), DEC); break; + case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break; case TMC_FSACTIVE: if (st.fsactive()) SERIAL_ECHOPGM("X"); break; default: break; } @@ -113,10 +113,10 @@ static void drv_status_print_hex(const char name[], const uint32_t drv_status) { case TMC_TSTEP: { uint32_t data = 0; st.TSTEP(&data); - MYSERIAL.print(data); + SERIAL_PROTOCOL(data); break; } - case TMC_PWM_SCALE: MYSERIAL.print(st.pwm_scale_sum(), DEC); break; + case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; case TMC_STEALTHCHOP: serialprintPGM(st.stealth() ? PSTR("true") : PSTR("false")); break; case TMC_S2VSA: if (st.s2vsa()) SERIAL_ECHOPGM("X"); break; case TMC_S2VSB: if (st.s2vsb()) SERIAL_ECHOPGM("X"); break; @@ -140,18 +140,18 @@ static void tmc_status(TMC &st, TMC_AxisEnum axis, const TMC_debug_enum i, const case TMC_CODES: SERIAL_ECHO(extended_axis_codes[axis]); break; case TMC_ENABLED: serialprintPGM(st.isEnabled() ? PSTR("true") : PSTR("false")); break; case TMC_CURRENT: SERIAL_ECHO(st.getCurrent()); break; - case TMC_RMS_CURRENT: MYSERIAL.print(st.rms_current()); break; - case TMC_MAX_CURRENT: MYSERIAL.print((float)st.rms_current()*1.41, 0); break; + case TMC_RMS_CURRENT: SERIAL_PROTOCOL(st.rms_current()); break; + case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current()*1.41, 0); break; case TMC_IRUN: - MYSERIAL.print(st.irun(), DEC); + SERIAL_PRINT(st.irun(), DEC); SERIAL_ECHOPGM("/31"); break; case TMC_IHOLD: - MYSERIAL.print(st.ihold(), DEC); + SERIAL_PRINT(st.ihold(), DEC); SERIAL_ECHOPGM("/31"); break; case TMC_CS_ACTUAL: - MYSERIAL.print(st.cs_actual(), DEC); + SERIAL_PRINT(st.cs_actual(), DEC); SERIAL_ECHOPGM("/31"); break; @@ -170,10 +170,10 @@ static void tmc_status(TMC &st, TMC_AxisEnum axis, const TMC_debug_enum i, const break; case TMC_OTPW: serialprintPGM(st.otpw() ? PSTR("true") : PSTR("false")); break; case TMC_OTPW_TRIGGERED: serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); break; - case TMC_TOFF: MYSERIAL.print(st.toff(), DEC); break; - case TMC_TBL: MYSERIAL.print(st.blank_time(), DEC); break; - case TMC_HEND: MYSERIAL.print(st.hysterisis_end(), DEC); break; - case TMC_HSTRT: MYSERIAL.print(st.hysterisis_start(), DEC); break; + case TMC_TOFF: SERIAL_PRINT(st.toff(), DEC); break; + case TMC_TBL: SERIAL_PRINT(st.blank_time(), DEC); break; + case TMC_HEND: SERIAL_PRINT(st.hysterisis_end(), DEC); break; + case TMC_HSTRT: SERIAL_PRINT(st.hysterisis_start(), DEC); break; default: tmc_status(st, i); break; } } @@ -189,7 +189,7 @@ static void tmc_parse_drv_status(TMC &st, TMC_AxisEnum axis, const TMC_drv_statu case TMC_S2GA: if (st.s2ga()) SERIAL_ECHOPGM("X"); break; case TMC_DRV_OTPW: if (st.otpw()) SERIAL_ECHOPGM("X"); break; case TMC_OT: if (st.ot()) SERIAL_ECHOPGM("X"); break; - case TMC_DRV_CS_ACTUAL: MYSERIAL.print(st.cs_actual(), DEC); break; + case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break; case TMC_DRV_STATUS_HEX:drv_status_print_hex(extended_axis_codes[axis], st.DRV_STATUS()); break; default: tmc_parse_drv_status(st, i); break; } diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index b5e8bd788b..b67238f2b2 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -23,6 +23,10 @@ #include "../gcode.h" #include "../../inc/MarlinConfig.h" +#if NUM_SERIAL > 1 + #include "../../gcode/queue.h" +#endif + #if ENABLED(EXTENDED_CAPABILITIES_REPORT) static void cap_line(const char * const name, bool ena=false) { SERIAL_PROTOCOLPGM("Cap:"); @@ -36,7 +40,14 @@ * M115: Capabilities string */ void GcodeSuite::M115() { - SERIAL_PROTOCOLLNPGM(MSG_M115_REPORT); + #if NUM_SERIAL > 1 + const int8_t port = command_queue_port[cmd_queue_index_r]; + #define CAPLINE(STR,...) cap_line(PSTR(STR), port, __VA_ARGS__) + #else + #define CAPLINE(STR,...) cap_line(PSTR(STR), __VA_ARGS__) + #endif + + SERIAL_PROTOCOLLNPGM_P(port, MSG_M115_REPORT); #if ENABLED(EXTENDED_CAPABILITIES_REPORT) diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index c02ddff4a8..807ad3ad2d 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -32,6 +32,10 @@ #include "../libs/hex_print_routines.h" #endif +#if NUM_SERIAL > 1 + #include "queue.h" +#endif + // Must be declared for allocation and to satisfy the linker // Zero values need no initialization. @@ -265,10 +269,13 @@ void GCodeParser::parse(char *p) { #endif // CNC_COORDINATE_SYSTEMS void GCodeParser::unknown_command_error() { - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR(MSG_UNKNOWN_COMMAND, command_ptr); - SERIAL_CHAR('"'); - SERIAL_EOL(); + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + #endif + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPAIR_P(port, MSG_UNKNOWN_COMMAND, command_ptr); + SERIAL_CHAR_P(port, '"'); + SERIAL_EOL_P(port); } #if ENABLED(DEBUG_GCODE_PARSER) diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 6a7916c538..11fd46fa75 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -58,12 +58,19 @@ uint8_t commands_in_queue = 0, // Count of commands in the queue char command_queue[BUFSIZE][MAX_CMD_SIZE]; +/* + * The port that the command was received on + */ +#if NUM_SERIAL > 1 + int16_t command_queue_port[BUFSIZE]; +#endif + /** * Serial command injection */ // Number of characters read in the current line of serial input -static int serial_count = 0; +static int serial_count[NUM_SERIAL] = { 0 }; bool send_ok[BUFSIZE]; @@ -90,8 +97,15 @@ void clear_command_queue() { /** * Once a new command is in the ring buffer, call this to commit it */ -inline void _commit_command(bool say_ok) { +inline void _commit_command(bool say_ok + #if NUM_SERIAL > 1 + , int16_t port = -1 + #endif +) { send_ok[cmd_queue_index_w] = say_ok; + #if NUM_SERIAL > 1 + command_queue_port[cmd_queue_index_w] = port; + #endif if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0; commands_in_queue++; } @@ -101,10 +115,18 @@ inline void _commit_command(bool say_ok) { * Return true if the command was successfully added. * Return false for a full buffer, or if the 'command' is a comment. */ -inline bool _enqueuecommand(const char* cmd, bool say_ok/*=false*/) { +inline bool _enqueuecommand(const char* cmd, bool say_ok + #if NUM_SERIAL > 1 + , int16_t port = -1 + #endif +) { if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false; strcpy(command_queue[cmd_queue_index_w], cmd); - _commit_command(say_ok); + _commit_command(say_ok + #if NUM_SERIAL > 1 + , port + #endif + ); return true; } @@ -178,21 +200,25 @@ void enqueue_and_echo_commands_P(const char * const pgcode) { * B Block queue space remaining */ void ok_to_send() { + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + if (port < 0) return; + #endif gcode.refresh_cmd_timeout(); if (!send_ok[cmd_queue_index_r]) return; - SERIAL_PROTOCOLPGM(MSG_OK); + SERIAL_PROTOCOLPGM_P(port, MSG_OK); #if ENABLED(ADVANCED_OK) char* p = command_queue[cmd_queue_index_r]; if (*p == 'N') { - SERIAL_PROTOCOL(' '); - SERIAL_ECHO(*p++); + SERIAL_PROTOCOL_P(port, ' '); + SERIAL_ECHO_P(port, *p++); while (NUMERIC_SIGNED(*p)) - SERIAL_ECHO(*p++); + SERIAL_ECHO_P(port, *p++); } - SERIAL_PROTOCOLPGM(" P"); SERIAL_PROTOCOL(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1)); - SERIAL_PROTOCOLPGM(" B"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue); + SERIAL_PROTOCOLPGM_P(port, " P"); SERIAL_PROTOCOL_P(port, int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1)); + SERIAL_PROTOCOLPGM_P(port, " B"); SERIAL_PROTOCOL_P(port, BUFSIZE - commands_in_queue); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); } /** @@ -200,20 +226,39 @@ void ok_to_send() { * indicate that a command needs to be re-sent. */ void flush_and_request_resend() { - //char command_queue[cmd_queue_index_r][100]="Resend:"; - MYSERIAL.flush(); - SERIAL_PROTOCOLPGM(MSG_RESEND); - SERIAL_PROTOCOLLN(gcode_LastN + 1); - ok_to_send(); + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + if (port < 0) return; + #endif + SERIAL_FLUSH_P(port); + SERIAL_PROTOCOLPGM_P(port, MSG_RESEND); + SERIAL_PROTOCOLLN_P(port, gcode_LastN + 1); } -void gcode_line_error(const char* err, bool doFlush = true) { - SERIAL_ERROR_START(); - serialprintPGM(err); - SERIAL_ERRORLN(gcode_LastN); - //Serial.println(gcode_N); - if (doFlush) flush_and_request_resend(); - serial_count = 0; +void gcode_line_error(const char* err, uint8_t port) { + SERIAL_ERROR_START_P(port); + serialprintPGM_P(port, err); + SERIAL_ERRORLN_P(port, gcode_LastN); + flush_and_request_resend(); + serial_count[port] = 0; +} + +static bool serial_data_available() { + return (MYSERIAL0.available() ? true : + #if NUM_SERIAL > 1 + MYSERIAL1.available() ? true : + #endif + false); +} + +static int read_serial(const int index) { + switch (index) { + case 0: return MYSERIAL0.read(); + #if NUM_SERIAL > 1 + case 1: return MYSERIAL1.read(); + #endif + default: return -1; + } } /** @@ -222,15 +267,15 @@ void gcode_line_error(const char* err, bool doFlush = true) { * left on the serial port. */ inline void get_serial_commands() { - static char serial_line_buffer[MAX_CMD_SIZE]; - static bool serial_comment_mode = false; + static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE]; + static bool serial_comment_mode[NUM_SERIAL] = { false }; // If the command buffer is empty for too long, // send "wait" to indicate Marlin is still waiting. #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 static millis_t last_command_time = 0; const millis_t ms = millis(); - if (commands_in_queue == 0 && !MYSERIAL.available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { + if (commands_in_queue == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) { SERIAL_ECHOLNPGM(MSG_WAIT); last_command_time = ms; } @@ -239,110 +284,117 @@ inline void get_serial_commands() { /** * Loop while serial characters are incoming and the queue is not full */ - int c; - while (commands_in_queue < BUFSIZE && (c = MYSERIAL.read()) >= 0) { - char serial_char = c; + while (commands_in_queue < BUFSIZE && serial_data_available()) { + for (uint8_t i = 0; i < NUM_SERIAL; ++i) { + int c; + if ((c = read_serial(i)) < 0) continue; - /** - * If the character ends the line - */ - if (serial_char == '\n' || serial_char == '\r') { + char serial_char = c; - serial_comment_mode = false; // end of line == end of comment + /** + * If the character ends the line + */ + if (serial_char == '\n' || serial_char == '\r') { - if (!serial_count) continue; // Skip empty lines + serial_comment_mode[i] = false; // end of line == end of comment - serial_line_buffer[serial_count] = 0; // Terminate string - serial_count = 0; // Reset buffer + if (!serial_count[i]) continue; // Skip empty lines - char* command = serial_line_buffer; + serial_line_buffer[i][serial_count[i]] = 0; // Terminate string + serial_count[i] = 0; // Reset buffer - while (*command == ' ') command++; // Skip leading spaces - char *npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line + char* command = serial_line_buffer[i]; - if (npos) { + while (*command == ' ') command++; // Skip leading spaces + char *npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line - bool M110 = strstr_P(command, PSTR("M110")) != NULL; + if (npos) { - if (M110) { - char* n2pos = strchr(command + 4, 'N'); - if (n2pos) npos = n2pos; - } + bool M110 = strstr_P(command, PSTR("M110")) != NULL; - gcode_N = strtol(npos + 1, NULL, 10); + if (M110) { + char* n2pos = strchr(command + 4, 'N'); + if (n2pos) npos = n2pos; + } - if (gcode_N != gcode_LastN + 1 && !M110) { - gcode_line_error(PSTR(MSG_ERR_LINE_NO)); - return; - } + gcode_N = strtol(npos + 1, NULL, 10); - char *apos = strrchr(command, '*'); - if (apos) { - uint8_t checksum = 0, count = uint8_t(apos - command); - while (count) checksum ^= command[--count]; - if (strtol(apos + 1, NULL, 10) != checksum) { - gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH)); + if (gcode_N != gcode_LastN + 1 && !M110) { + gcode_line_error(PSTR(MSG_ERR_LINE_NO), i); return; } - } - else { - gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM)); - return; - } - - gcode_LastN = gcode_N; - } - // Movement commands alert when stopped - if (IsStopped()) { - char* gpos = strchr(command, 'G'); - if (gpos) { - const int codenum = strtol(gpos + 1, NULL, 10); - switch (codenum) { - case 0: - case 1: - case 2: - case 3: - SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); - LCD_MESSAGEPGM(MSG_STOPPED); - break; + char *apos = strrchr(command, '*'); + if (apos) { + uint8_t checksum = 0, count = uint8_t(apos - command); + while (count) checksum ^= command[--count]; + if (strtol(apos + 1, NULL, 10) != checksum) { + gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH), i); + return; + } + } + else { + gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i); + return; } - } - } - #if DISABLED(EMERGENCY_PARSER) - // If command was e-stop process now - if (strcmp(command, "M108") == 0) { - wait_for_heatup = false; - #if ENABLED(ULTIPANEL) - wait_for_user = false; - #endif + gcode_LastN = gcode_N; } - if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); - if (strcmp(command, "M410") == 0) { quickstop_stepper(); } - #endif - - #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 - last_command_time = ms; - #endif - // Add the command to the queue - _enqueuecommand(serial_line_buffer, true); - } - else if (serial_count >= MAX_CMD_SIZE - 1) { - // Keep fetching, but ignore normal characters beyond the max length - // The command will be injected when EOL is reached - } - else if (serial_char == '\\') { // Handle escapes - // if we have one more character, copy it over - if ((c = MYSERIAL.read()) >= 0 && !serial_comment_mode) - serial_line_buffer[serial_count++] = serial_char; - } - else { // it's not a newline, carriage return or escape char - if (serial_char == ';') serial_comment_mode = true; - if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; - } + // Movement commands alert when stopped + if (IsStopped()) { + char* gpos = strchr(command, 'G'); + if (gpos) { + const int codenum = strtol(gpos + 1, NULL, 10); + switch (codenum) { + case 0: + case 1: + case 2: + case 3: + SERIAL_ERRORLNPGM_P(i, MSG_ERR_STOPPED); + LCD_MESSAGEPGM(MSG_STOPPED); + break; + } + } + } + #if DISABLED(EMERGENCY_PARSER) + // If command was e-stop process now + if (strcmp(command, "M108") == 0) { + wait_for_heatup = false; + #if ENABLED(ULTIPANEL) + wait_for_user = false; + #endif + } + if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); + if (strcmp(command, "M410") == 0) { quickstop_stepper(); } + #endif + + #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 + last_command_time = ms; + #endif + + // Add the command to the queue + _enqueuecommand(serial_line_buffer[i], true + #if NUM_SERIAL > 1 + , i + #endif + ); + } + else if (serial_count[i] >= MAX_CMD_SIZE - 1) { + // Keep fetching, but ignore normal characters beyond the max length + // The command will be injected when EOL is reached + } + else if (serial_char == '\\') { // Handle escapes + // if we have one more character, copy it over + if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i]) + serial_line_buffer[i][serial_count[i]++] = serial_char; + } + else { // it's not a newline, carriage return or escape char + if (serial_char == ';') serial_comment_mode[i] = true; + if (!serial_comment_mode[i]) serial_line_buffer[i][serial_count[i]++] = serial_char; + } + } // for NUM_SERIAL } // queue has space, serial has data } diff --git a/Marlin/src/gcode/queue.h b/Marlin/src/gcode/queue.h index f2e2ef7074..68e9de65aa 100644 --- a/Marlin/src/gcode/queue.h +++ b/Marlin/src/gcode/queue.h @@ -51,6 +51,13 @@ extern uint8_t commands_in_queue, // Count of commands in the queue extern char command_queue[BUFSIZE][MAX_CMD_SIZE]; +/* + * The port that the command was received on + */ +#if NUM_SERIAL > 1 + extern int16_t command_queue_port[BUFSIZE]; +#endif + /** * Initialization of queue for setup() */ diff --git a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp index 566a880103..993e328d21 100644 --- a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp +++ b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp @@ -34,13 +34,25 @@ #include "../queue.h" #endif +#if NUM_SERIAL > 1 + #include "../../gcode/queue.h" +#endif + /** * M20: List SD card to serial output */ void GcodeSuite::M20() { - SERIAL_PROTOCOLLNPGM(MSG_BEGIN_FILE_LIST); - card.ls(); - SERIAL_PROTOCOLLNPGM(MSG_END_FILE_LIST); + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + #endif + + SERIAL_PROTOCOLLNPGM_P(port, MSG_BEGIN_FILE_LIST); + card.ls( + #if NUM_SERIAL > 1 + port + #endif + ); + SERIAL_PROTOCOLLNPGM_P(port, MSG_END_FILE_LIST); } /** @@ -97,7 +109,13 @@ void GcodeSuite::M26() { /** * M27: Get SD Card status */ -void GcodeSuite::M27() { card.getStatus(); } +void GcodeSuite::M27() { + card.getStatus( + #if NUM_SERIAL > 1 + command_queue_port[cmd_queue_index_r] + #endif + ); +} /** * M28: Start SD Write @@ -164,7 +182,11 @@ void GcodeSuite::M32() { * /Miscellaneous/Armchair/Armchair.gcode */ void GcodeSuite::M33() { - card.printLongPath(parser.string_arg); + card.printLongPath(parser.string_arg + #if NUM_SERIAL > 1 + , command_queue_port[cmd_queue_index_r] + #endif + ); } #endif // LONG_FILENAME_HOST_SUPPORT diff --git a/Marlin/src/gcode/stats/M31.cpp b/Marlin/src/gcode/stats/M31.cpp index 327ff8c37d..958556e544 100644 --- a/Marlin/src/gcode/stats/M31.cpp +++ b/Marlin/src/gcode/stats/M31.cpp @@ -26,15 +26,22 @@ #include "../../libs/duration_t.h" #include "../../lcd/ultralcd.h" +#if NUM_SERIAL > 1 + #include "../../gcode/queue.h" +#endif + /** * M31: Get the time since the start of SD Print (or last M109) */ void GcodeSuite::M31() { + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + #endif char buffer[21]; duration_t elapsed = print_job_timer.duration(); elapsed.toString(buffer); lcd_setstatus(buffer); - SERIAL_ECHO_START(); - SERIAL_ECHOLNPAIR("Print time: ", buffer); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOLNPAIR_P(port, "Print time: ", buffer); } diff --git a/Marlin/src/gcode/temperature/M105.cpp b/Marlin/src/gcode/temperature/M105.cpp index e4417c6afa..36d4d67ac5 100644 --- a/Marlin/src/gcode/temperature/M105.cpp +++ b/Marlin/src/gcode/temperature/M105.cpp @@ -23,19 +23,31 @@ #include "../gcode.h" #include "../../module/temperature.h" +#if NUM_SERIAL > 1 + #include "../../gcode/queue.h" +#endif + /** * M105: Read hot end and bed temperature */ void GcodeSuite::M105() { if (get_target_extruder_from_command()) return; + #if NUM_SERIAL > 1 + const int16_t port = command_queue_port[cmd_queue_index_r]; + #endif + #if HAS_TEMP_HOTEND || HAS_TEMP_BED - SERIAL_PROTOCOLPGM(MSG_OK); - thermalManager.print_heaterstates(); + SERIAL_PROTOCOLPGM_P(port, MSG_OK); + thermalManager.print_heaterstates( + #if NUM_SERIAL > 1 + port + #endif + ); #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED - SERIAL_ERROR_START(); - SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); + SERIAL_ERROR_START_P(port); + SERIAL_ERRORLNPGM_P(port, MSG_ERR_NO_THERMISTORS); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); } diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index ee7e1126f8..fa85e5c1f8 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -494,10 +494,4 @@ #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 !defined(RE_ARM_FORCE_SERIAL_PORT) && (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)) - #undef SERIAL_PORT - #define SERIAL_PORT -1 -#endif - #endif // CONDITIONALS_LCD_H diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 1ab2a26cf2..d2680229a9 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -322,7 +322,7 @@ void MarlinSettings::postprocess() { #define EEPROM_WRITE(VAR) HAL::PersistentStore::write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) #define EEPROM_READ(VAR) HAL::PersistentStore::read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc, !validating) #define EEPROM_READ_ALWAYS(VAR) HAL::PersistentStore::read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) - #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(ERR); eeprom_error = true; }while(0) + #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START_P(port); SERIAL_ERRORLNPGM_P(port, ERR); eeprom_error = true; }while(0) #if ENABLED(DEBUG_EEPROM_READWRITE) #define _FIELD_TEST(FIELD) \ @@ -338,10 +338,16 @@ void MarlinSettings::postprocess() { bool MarlinSettings::eeprom_error, MarlinSettings::validating; - bool MarlinSettings::size_error(const uint16_t size) { + bool MarlinSettings::size_error(const uint16_t size + #if ADD_PORT_ARG + , const int8_t port/*=-1*/ + #endif + ) { if (size != datasize()) { - SERIAL_ERROR_START(); - SERIAL_ERRORLNPGM("EEPROM datasize error."); + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ERROR_START_P(port); + SERIAL_ERRORLNPGM_P(port, "EEPROM datasize error."); + #endif return true; } return false; @@ -350,7 +356,11 @@ void MarlinSettings::postprocess() { /** * M500 - Store Configuration */ - bool MarlinSettings::save() { + bool MarlinSettings::save( + #if ADD_PORT_ARG + const int8_t port/*=-1*/ + #endif + ) { float dummy = 0.0f; char ver[4] = "ERR"; @@ -810,10 +820,10 @@ void MarlinSettings::postprocess() { // Report storage size #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR("Settings Stored (", eeprom_size); - SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)final_crc); - SERIAL_ECHOLNPGM(")"); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPAIR_P(port, "Settings Stored (", eeprom_size); + SERIAL_ECHOPAIR_P(port, " bytes; crc ", (uint32_t)final_crc); + SERIAL_ECHOLNPGM_P(port, ")"); #endif eeprom_error |= size_error(eeprom_size); @@ -834,7 +844,11 @@ void MarlinSettings::postprocess() { /** * M501 - Retrieve Configuration */ - bool MarlinSettings::_load() { + bool MarlinSettings::_load( + #if ADD_PORT_ARG + const int8_t port/*=-1*/ + #endif + ) { uint16_t working_crc = 0; EEPROM_START(); @@ -852,10 +866,10 @@ void MarlinSettings::postprocess() { stored_ver[1] = '\0'; } #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("EEPROM version mismatch "); - SERIAL_ECHOPAIR("(EEPROM=", stored_ver); - SERIAL_ECHOLNPGM(" Marlin=" EEPROM_VERSION ")"); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPGM_P(port, "EEPROM version mismatch "); + SERIAL_ECHOPAIR_P(port, "(EEPROM=", stored_ver); + SERIAL_ECHOLNPGM_P(port, " Marlin=" EEPROM_VERSION ")"); #endif if (!validating) reset(); eeprom_error = true; @@ -1334,28 +1348,28 @@ void MarlinSettings::postprocess() { eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET)); if (eeprom_error) { - SERIAL_ECHO_START(); - SERIAL_ECHOPAIR("Index: ", int(eeprom_index - (EEPROM_OFFSET))); - SERIAL_ECHOLNPAIR(" Size: ", datasize()); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPAIR_P(port, "Index: ", int(eeprom_index - (EEPROM_OFFSET))); + SERIAL_ECHOLNPAIR_P(port, " Size: ", datasize()); } else if (working_crc != stored_crc) { eeprom_error = true; #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ERROR_START(); - SERIAL_ERRORPGM("EEPROM CRC mismatch - (stored) "); - SERIAL_ERROR(stored_crc); - SERIAL_ERRORPGM(" != "); - SERIAL_ERROR(working_crc); - SERIAL_ERRORLNPGM(" (calculated)!"); + SERIAL_ERROR_START_P(port); + SERIAL_ERRORPGM_P(port, "EEPROM CRC mismatch - (stored) "); + SERIAL_ERROR_P(port, stored_crc); + SERIAL_ERRORPGM_P(port, " != "); + SERIAL_ERROR_P(port, working_crc); + SERIAL_ERRORLNPGM_P(port, " (calculated)!"); #endif } else if (!validating) { #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHO_START(); - SERIAL_ECHO(version); - SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET)); - SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)working_crc); - SERIAL_ECHOLNPGM(")"); + SERIAL_ECHO_START_P(port); + SERIAL_ECHO_P(port, version); + SERIAL_ECHOPAIR_P(port, " stored settings retrieved (", eeprom_index - (EEPROM_OFFSET)); + SERIAL_ECHOPAIR_P(port, " bytes; crc ", (uint32_t)working_crc); + SERIAL_ECHOLNPGM_P(port, ")"); #endif } @@ -1368,18 +1382,18 @@ void MarlinSettings::postprocess() { if (!validating) { if (!ubl.sanity_check()) { - SERIAL_EOL(); + SERIAL_EOL_P(port); #if ENABLED(EEPROM_CHITCHAT) ubl.echo_name(); - SERIAL_ECHOLNPGM(" initialized.\n"); + SERIAL_ECHOLNPGM_P(port, " initialized.\n"); #endif } else { eeprom_error = true; #if ENABLED(EEPROM_CHITCHAT) - SERIAL_PROTOCOLPGM("?Can't enable "); + SERIAL_PROTOCOLPGM_P(port, "?Can't enable "); ubl.echo_name(); - SERIAL_PROTOCOLLNPGM("."); + SERIAL_PROTOCOLLNPGM_P(port, "."); #endif ubl.reset(); } @@ -1387,14 +1401,14 @@ void MarlinSettings::postprocess() { if (ubl.storage_slot >= 0) { load_mesh(ubl.storage_slot); #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHOPAIR("Mesh ", ubl.storage_slot); - SERIAL_ECHOLNPGM(" loaded from storage."); + SERIAL_ECHOPAIR_P(port, "Mesh ", ubl.storage_slot); + SERIAL_ECHOLNPGM_P(port, " loaded from storage."); #endif } else { ubl.reset(); #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHOLNPGM("UBL System reset()"); + SERIAL_ECHOLNPGM_P(port, "UBL System reset()"); #endif } } @@ -1402,22 +1416,42 @@ void MarlinSettings::postprocess() { } #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) - if (!validating) report(); + if (!validating) report( + #if NUM_SERIAL > 1 + port + #endif + ); #endif EEPROM_FINISH(); return !eeprom_error; } - bool MarlinSettings::validate() { + bool MarlinSettings::validate( + #if NUM_SERIAL > 1 + const int8_t port/*=-1*/ + #endif + ) { validating = true; - const bool success = _load(); + const bool success = _load( + #if NUM_SERIAL > 1 + port + #endif + ); validating = false; return success; } - bool MarlinSettings::load() { - if (validate()) return _load(); + bool MarlinSettings::load( + #if ADD_PORT_ARG + const int8_t port/*=-1*/ + #endif + ) { + if (validate()) return _load( + #if ADD_PORT_ARG + port + #endif + ); reset(); return true; } @@ -1524,9 +1558,15 @@ void MarlinSettings::postprocess() { #else // !EEPROM_SETTINGS - bool MarlinSettings::save() { - SERIAL_ERROR_START(); - SERIAL_ERRORLNPGM("EEPROM disabled"); + bool MarlinSettings::save( + #if ADD_PORT_ARG + const int8_t port/*=-1*/ + #endif + ) { + #if ENABLED(EEPROM_CHITCHAT) + SERIAL_ERROR_START_P(port); + SERIAL_ERRORLNPGM_P(port, "EEPROM disabled"); + #endif return false; } @@ -1535,7 +1575,11 @@ void MarlinSettings::postprocess() { /** * M502 - Reset Configuration */ -void MarlinSettings::reset() { +void MarlinSettings::reset( + #if ADD_PORT_ARG + const int8_t port/*=-1*/ + #endif +) { static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE; static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION; LOOP_XYZE_N(i) { @@ -1775,22 +1819,25 @@ void MarlinSettings::reset() { postprocess(); #if ENABLED(EEPROM_CHITCHAT) - SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOLNPGM_P(port, "Hardcoded Default Settings Loaded"); #endif } #if DISABLED(DISABLE_M503) - #define CONFIG_ECHO_START do{ if (!forReplay) SERIAL_ECHO_START(); }while(0) + #define CONFIG_ECHO_START do{ if (!forReplay) SERIAL_ECHO_START_P(port); }while(0) /** * M503 - Report current settings in RAM * * Unless specifically disabled, M503 is available even without EEPROM */ - void MarlinSettings::report(const bool forReplay) { - + void MarlinSettings::report(const bool forReplay + #if NUM_SERIAL > 1 + , const int8_t port/*=-1*/ + #endif + ) { /** * Announce current units, in case inches are being displayed */ @@ -1798,14 +1845,14 @@ void MarlinSettings::reset() { #if ENABLED(INCH_MODE_SUPPORT) #define LINEAR_UNIT(N) (float(N) / parser.linear_unit_factor) #define VOLUMETRIC_UNIT(N) (float(N) / (parser.volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) - SERIAL_ECHOPGM(" G2"); - SERIAL_CHAR(parser.linear_unit_factor == 1.0 ? '1' : '0'); - SERIAL_ECHOPGM(" ; Units in "); + SERIAL_ECHOPGM_P(port, " G2"); + SERIAL_CHAR_P(port, parser.linear_unit_factor == 1.0 ? '1' : '0'); + SERIAL_ECHOPGM_P(port, " ; Units in "); serialprintPGM(parser.linear_unit_factor == 1.0 ? PSTR("mm\n") : PSTR("inches\n")); #else #define LINEAR_UNIT(N) (N) #define VOLUMETRIC_UNIT(N) (N) - SERIAL_ECHOLNPGM(" G21 ; Units in mm"); + SERIAL_ECHOLNPGM_P(port, " G21 ; Units in mm"); #endif #if ENABLED(ULTIPANEL) @@ -1815,18 +1862,18 @@ void MarlinSettings::reset() { CONFIG_ECHO_START; #if ENABLED(TEMPERATURE_UNITS_SUPPORT) #define TEMP_UNIT(N) parser.to_temp_units(N) - SERIAL_ECHOPGM(" M149 "); - SERIAL_CHAR(parser.temp_units_code()); - SERIAL_ECHOPGM(" ; Units in "); - serialprintPGM(parser.temp_units_name()); + SERIAL_ECHOPGM_P(port, " M149 "); + SERIAL_CHAR_P(port, parser.temp_units_code()); + SERIAL_ECHOPGM_P(port, " ; Units in "); + serialprintPGM_P(port, parser.temp_units_name()); #else #define TEMP_UNIT(N) (N) - SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius"); + SERIAL_ECHOLNPGM_P(port, " M149 C ; Units in Celsius"); #endif #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #if DISABLED(NO_VOLUMETRICS) @@ -1835,32 +1882,32 @@ void MarlinSettings::reset() { */ if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOPGM("Filament settings:"); + SERIAL_ECHOPGM_P(port, "Filament settings:"); if (parser.volumetric_enabled) - SERIAL_EOL(); + SERIAL_EOL_P(port); else - SERIAL_ECHOLNPGM(" Disabled"); + SERIAL_ECHOLNPGM_P(port, " Disabled"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 D", LINEAR_UNIT(planner.filament_size[0])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M200 D", LINEAR_UNIT(planner.filament_size[0])); + SERIAL_EOL_P(port); #if EXTRUDERS > 1 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T1 D", LINEAR_UNIT(planner.filament_size[1])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M200 T1 D", LINEAR_UNIT(planner.filament_size[1])); + SERIAL_EOL_P(port); #if EXTRUDERS > 2 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T2 D", LINEAR_UNIT(planner.filament_size[2])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M200 T2 D", LINEAR_UNIT(planner.filament_size[2])); + SERIAL_EOL_P(port); #if EXTRUDERS > 3 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T3 D", LINEAR_UNIT(planner.filament_size[3])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M200 T3 D", LINEAR_UNIT(planner.filament_size[3])); + SERIAL_EOL_P(port); #if EXTRUDERS > 4 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T4 D", LINEAR_UNIT(planner.filament_size[4])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M200 T4 D", LINEAR_UNIT(planner.filament_size[4])); + SERIAL_EOL_P(port); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 @@ -1868,118 +1915,118 @@ void MarlinSettings::reset() { if (!parser.volumetric_enabled) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM(" M200 D0"); + SERIAL_ECHOLNPGM_P(port, " M200 D0"); } #endif // !NO_VOLUMETRICS if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Steps per unit:"); + SERIAL_ECHOLNPGM_P(port, "Steps per unit:"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS])); - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS])); + SERIAL_ECHOPAIR_P(port, " M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS])); #if DISABLED(DISTINCT_E_FACTORS) - SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS])); + SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS])); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #if ENABLED(DISTINCT_E_FACTORS) CONFIG_ECHO_START; for (uint8_t i = 0; i < E_STEPPERS; i++) { - SERIAL_ECHOPAIR(" M92 T", (int)i); - SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i])); + SERIAL_ECHOPAIR_P(port, " M92 T", (int)i); + SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i])); } #endif if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Maximum feedrates (units/s):"); + SERIAL_ECHOLNPGM_P(port, "Maximum feedrates (units/s):"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS])); - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS])); + SERIAL_ECHOPAIR_P(port, " M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS])); #if DISABLED(DISTINCT_E_FACTORS) - SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS])); + SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS])); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #if ENABLED(DISTINCT_E_FACTORS) CONFIG_ECHO_START; for (uint8_t i = 0; i < E_STEPPERS; i++) { - SERIAL_ECHOPAIR(" M203 T", (int)i); - SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i])); + SERIAL_ECHOPAIR_P(port, " M203 T", (int)i); + SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i])); } #endif if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Maximum Acceleration (units/s2):"); + SERIAL_ECHOLNPGM_P(port, "Maximum Acceleration (units/s2):"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS])); - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS])); + SERIAL_ECHOPAIR_P(port, " M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS])); #if DISABLED(DISTINCT_E_FACTORS) - SERIAL_ECHOPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS])); + SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS])); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #if ENABLED(DISTINCT_E_FACTORS) CONFIG_ECHO_START; for (uint8_t i = 0; i < E_STEPPERS; i++) { - SERIAL_ECHOPAIR(" M201 T", (int)i); - SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i])); + SERIAL_ECHOPAIR_P(port, " M201 T", (int)i); + SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i])); } #endif if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Acceleration (units/s2): P R T"); + SERIAL_ECHOLNPGM_P(port, "Acceleration (units/s2): P R T"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M204 P", LINEAR_UNIT(planner.acceleration)); - SERIAL_ECHOPAIR(" R", LINEAR_UNIT(planner.retract_acceleration)); - SERIAL_ECHOLNPAIR(" T", LINEAR_UNIT(planner.travel_acceleration)); + SERIAL_ECHOPAIR_P(port, " M204 P", LINEAR_UNIT(planner.acceleration)); + SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(planner.retract_acceleration)); + SERIAL_ECHOLNPAIR_P(port, " T", LINEAR_UNIT(planner.travel_acceleration)); if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Advanced: S T B X Z E"); + SERIAL_ECHOLNPGM_P(port, "Advanced: S T B X Z E"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s)); - SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); - SERIAL_ECHOPAIR(" B", planner.min_segment_time_us); - SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS])); - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS])); - SERIAL_ECHOLNPAIR(" E", LINEAR_UNIT(planner.max_jerk[E_AXIS])); + SERIAL_ECHOPAIR_P(port, " M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s)); + SERIAL_ECHOPAIR_P(port, " T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); + SERIAL_ECHOPAIR_P(port, " B", planner.min_segment_time_us); + SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(planner.max_jerk[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS])); + SERIAL_ECHOLNPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS])); #if HAS_M206_COMMAND if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Home offset:"); + SERIAL_ECHOLNPGM_P(port, "Home offset:"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M206 X", LINEAR_UNIT(home_offset[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(home_offset[Y_AXIS])); - SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(home_offset[Z_AXIS])); + SERIAL_ECHOPAIR_P(port, " M206 X", LINEAR_UNIT(home_offset[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(home_offset[Y_AXIS])); + SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(home_offset[Z_AXIS])); #endif #if HOTENDS > 1 if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Hotend offsets:"); + SERIAL_ECHOLNPGM_P(port, "Hotend offsets:"); } CONFIG_ECHO_START; for (uint8_t e = 1; e < HOTENDS; e++) { - SERIAL_ECHOPAIR(" M218 T", (int)e); - SERIAL_ECHOPAIR(" X", LINEAR_UNIT(hotend_offset[X_AXIS][e])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(hotend_offset[Y_AXIS][e])); + SERIAL_ECHOPAIR_P(port, " M218 T", (int)e); + SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(hotend_offset[X_AXIS][e])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(hotend_offset[Y_AXIS][e])); #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(SWITCHING_NOZZLE) ||ENABLED(PARKING_EXTRUDER) - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(hotend_offset[Z_AXIS][e])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(hotend_offset[Z_AXIS][e])); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); } #endif @@ -1992,7 +2039,7 @@ void MarlinSettings::reset() { if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Mesh Bed Leveling:"); + SERIAL_ECHOLNPGM_P(port, "Mesh Bed Leveling:"); } #elif ENABLED(AUTO_BED_LEVELING_UBL) @@ -2000,46 +2047,46 @@ void MarlinSettings::reset() { if (!forReplay) { CONFIG_ECHO_START; ubl.echo_name(); - SERIAL_ECHOLNPGM(":"); + SERIAL_ECHOLNPGM_P(port, ":"); } #elif HAS_ABL if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Auto Bed Leveling:"); + SERIAL_ECHOLNPGM_P(port, "Auto Bed Leveling:"); } #endif CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M420 S", planner.leveling_active ? 1 : 0); + SERIAL_ECHOPAIR_P(port, " M420 S", planner.leveling_active ? 1 : 0); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.z_fade_height)); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.z_fade_height)); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #if ENABLED(MESH_BED_LEVELING) for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) { for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" G29 S3 X", (int)px + 1); - SERIAL_ECHOPAIR(" Y", (int)py + 1); - SERIAL_ECHOPGM(" Z"); - SERIAL_PROTOCOL_F(LINEAR_UNIT(mbl.z_values[px][py]), 5); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " G29 S3 X", (int)px + 1); + SERIAL_ECHOPAIR_P(port, " Y", (int)py + 1); + SERIAL_ECHOPGM_P(port, " Z"); + SERIAL_PROTOCOL_F_P(port, LINEAR_UNIT(mbl.z_values[px][py]), 5); + SERIAL_EOL_P(port); } } #elif ENABLED(AUTO_BED_LEVELING_UBL) if (!forReplay) { - SERIAL_EOL(); + SERIAL_EOL_P(port); ubl.report_state(); - SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.storage_slot); - SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes()); - SERIAL_ECHOLNPGM(" meshes.\n"); + SERIAL_ECHOLNPAIR_P(port, "\nActive Mesh Slot: ", ubl.storage_slot); + SERIAL_ECHOPAIR_P(port, "EEPROM can hold ", calc_num_meshes()); + SERIAL_ECHOLNPGM_P(port, " meshes.\n"); } #endif @@ -2047,59 +2094,62 @@ void MarlinSettings::reset() { #endif // HAS_LEVELING #if ENABLED(DELTA) + if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Endstop adjustment:"); + SERIAL_ECHOLNPGM_P(port, "Endstop adjustment:"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M666 X", LINEAR_UNIT(delta_endstop_adj[X_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_endstop_adj[Y_AXIS])); - SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(delta_endstop_adj[Z_AXIS])); + SERIAL_ECHOPAIR_P(port, " M666 X", LINEAR_UNIT(delta_endstop_adj[X_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(delta_endstop_adj[Y_AXIS])); + SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(delta_endstop_adj[Z_AXIS])); if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Delta settings: L R H S B XYZ"); + SERIAL_ECHOLNPGM_P(port, "Delta settings: L R H S B XYZ"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M665 L", LINEAR_UNIT(delta_diagonal_rod)); - SERIAL_ECHOPAIR(" R", LINEAR_UNIT(delta_radius)); - SERIAL_ECHOPAIR(" H", LINEAR_UNIT(delta_height)); - SERIAL_ECHOPAIR(" S", delta_segments_per_second); - SERIAL_ECHOPAIR(" B", LINEAR_UNIT(delta_calibration_radius)); - SERIAL_ECHOPAIR(" X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS])); - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M665 L", LINEAR_UNIT(delta_diagonal_rod)); + SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(delta_radius)); + SERIAL_ECHOPAIR_P(port, " H", LINEAR_UNIT(delta_height)); + SERIAL_ECHOPAIR_P(port, " S", delta_segments_per_second); + SERIAL_ECHOPAIR_P(port, " B", LINEAR_UNIT(delta_calibration_radius)); + SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS])); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); + SERIAL_EOL_P(port); #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Endstop adjustment:"); + SERIAL_ECHOLNPGM_P(port, "Endstop adjustment:"); } CONFIG_ECHO_START; - SERIAL_ECHOPGM(" M666"); + SERIAL_ECHOPGM_P(port, " M666"); #if ENABLED(X_DUAL_ENDSTOPS) - SERIAL_ECHOPAIR(" X", LINEAR_UNIT(endstops.x_endstop_adj)); + SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(endstops.x_endstop_adj)); #endif #if ENABLED(Y_DUAL_ENDSTOPS) - SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(endstops.y_endstop_adj)); + SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(endstops.y_endstop_adj)); #endif #if ENABLED(Z_DUAL_ENDSTOPS) - SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(endstops.z_endstop_adj)); + SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(endstops.z_endstop_adj)); #endif - SERIAL_EOL(); - #endif // DELTA + SERIAL_EOL_P(port); + + #endif // [XYZ]_DUAL_ENDSTOPS #if ENABLED(ULTIPANEL) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Material heatup parameters:"); + SERIAL_ECHOLNPGM_P(port, "Material heatup parameters:"); } for (uint8_t i = 0; i < COUNT(lcd_preheat_hotend_temp); i++) { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M145 S", (int)i); - SERIAL_ECHOPAIR(" H", TEMP_UNIT(lcd_preheat_hotend_temp[i])); - SERIAL_ECHOPAIR(" B", TEMP_UNIT(lcd_preheat_bed_temp[i])); - SERIAL_ECHOLNPAIR(" F", lcd_preheat_fan_speed[i]); + SERIAL_ECHOPAIR_P(port, " M145 S", (int)i); + SERIAL_ECHOPAIR_P(port, " H", TEMP_UNIT(lcd_preheat_hotend_temp[i])); + SERIAL_ECHOPAIR_P(port, " B", TEMP_UNIT(lcd_preheat_bed_temp[i])); + SERIAL_ECHOLNPAIR_P(port, " F", lcd_preheat_fan_speed[i]); } #endif // ULTIPANEL @@ -2107,22 +2157,22 @@ void MarlinSettings::reset() { if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("PID settings:"); + SERIAL_ECHOLNPGM_P(port, "PID settings:"); } #if ENABLED(PIDTEMP) #if HOTENDS > 1 if (forReplay) { HOTEND_LOOP() { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M301 E", e); - SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); - SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); - SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); + SERIAL_ECHOPAIR_P(port, " M301 E", e); + SERIAL_ECHOPAIR_P(port, " P", PID_PARAM(Kp, e)); + SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(PID_PARAM(Ki, e))); + SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(PID_PARAM(Kd, e))); #if ENABLED(PID_EXTRUSION_SCALING) - SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); - if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); + SERIAL_ECHOPAIR_P(port, " C", PID_PARAM(Kc, e)); + if (e == 0) SERIAL_ECHOPAIR_P(port, " L", lpq_len); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); } } else @@ -2130,23 +2180,23 @@ void MarlinSettings::reset() { // !forReplay || HOTENDS == 1 { CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echo values for E0 - SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0))); - SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0))); + SERIAL_ECHOPAIR_P(port, " M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echo values for E0 + SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(PID_PARAM(Ki, 0))); + SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(PID_PARAM(Kd, 0))); #if ENABLED(PID_EXTRUSION_SCALING) - SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, 0)); - SERIAL_ECHOPAIR(" L", lpq_len); + SERIAL_ECHOPAIR_P(port, " C", PID_PARAM(Kc, 0)); + SERIAL_ECHOPAIR_P(port, " L", lpq_len); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); } #endif // PIDTEMP #if ENABLED(PIDTEMPBED) CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M304 P", thermalManager.bedKp); - SERIAL_ECHOPAIR(" I", unscalePID_i(thermalManager.bedKi)); - SERIAL_ECHOPAIR(" D", unscalePID_d(thermalManager.bedKd)); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M304 P", thermalManager.bedKp); + SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(thermalManager.bedKi)); + SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(thermalManager.bedKd)); + SERIAL_EOL_P(port); #endif #endif // PIDTEMP || PIDTEMPBED @@ -2154,39 +2204,39 @@ void MarlinSettings::reset() { #if HAS_LCD_CONTRAST if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("LCD Contrast:"); + SERIAL_ECHOLNPGM_P(port, "LCD Contrast:"); } CONFIG_ECHO_START; - SERIAL_ECHOLNPAIR(" M250 C", lcd_contrast); + SERIAL_ECHOLNPAIR_P(port, " M250 C", lcd_contrast); #endif #if ENABLED(FWRETRACT) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Retract: S F Z"); + SERIAL_ECHOLNPGM_P(port, "Retract: S F Z"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M207 S", LINEAR_UNIT(fwretract.retract_length)); - SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_length)); - SERIAL_ECHOPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s))); - SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(fwretract.retract_zlift)); + SERIAL_ECHOPAIR_P(port, " M207 S", LINEAR_UNIT(fwretract.retract_length)); + SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_length)); + SERIAL_ECHOPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s))); + SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(fwretract.retract_zlift)); if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Recover: S F"); + SERIAL_ECHOLNPGM_P(port, "Recover: S F"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M208 S", LINEAR_UNIT(fwretract.retract_recover_length)); - SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_recover_length)); - SERIAL_ECHOLNPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s))); + SERIAL_ECHOPAIR_P(port, " M208 S", LINEAR_UNIT(fwretract.retract_recover_length)); + SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_recover_length)); + SERIAL_ECHOLNPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s))); if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover"); + SERIAL_ECHOLNPGM_P(port, "Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover"); } CONFIG_ECHO_START; - SERIAL_ECHOLNPAIR(" M209 S", fwretract.autoretract_enabled ? 1 : 0); + SERIAL_ECHOLNPAIR_P(port, " M209 S", fwretract.autoretract_enabled ? 1 : 0); #endif // FWRETRACT @@ -2196,10 +2246,10 @@ void MarlinSettings::reset() { #if HAS_BED_PROBE if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); + SERIAL_ECHOLNPGM_P(port, "Z-Probe Offset (mm):"); } CONFIG_ECHO_START; - SERIAL_ECHOLNPAIR(" M851 Z", LINEAR_UNIT(zprobe_zoffset)); + SERIAL_ECHOLNPAIR_P(port, " M851 Z", LINEAR_UNIT(zprobe_zoffset)); #endif /** @@ -2208,18 +2258,18 @@ void MarlinSettings::reset() { #if ENABLED(SKEW_CORRECTION_GCODE) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Skew Factor: "); + SERIAL_ECHOLNPGM_P(port, "Skew Factor: "); } CONFIG_ECHO_START; #if ENABLED(SKEW_CORRECTION_FOR_Z) - SERIAL_ECHO(" M852 I"); - SERIAL_ECHO_F(LINEAR_UNIT(planner.xy_skew_factor), 6); - SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.xz_skew_factor)); - SERIAL_ECHOLNPAIR(" K", LINEAR_UNIT(planner.yz_skew_factor)); + SERIAL_ECHO_P(port, " M852 I"); + SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6); + SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.xz_skew_factor)); + SERIAL_ECHOLNPAIR_P(port, " K", LINEAR_UNIT(planner.yz_skew_factor)); #else - SERIAL_ECHO(" M852 S"); - SERIAL_ECHO_F(LINEAR_UNIT(planner.xy_skew_factor), 6); - SERIAL_EOL(); + SERIAL_ECHO_P(port, " M852 S"); + SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6); + SERIAL_EOL_P(port); #endif #endif @@ -2229,44 +2279,44 @@ void MarlinSettings::reset() { #if HAS_TRINAMIC if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Stepper driver current:"); + SERIAL_ECHOLNPGM_P(port, "Stepper driver current:"); } CONFIG_ECHO_START; - SERIAL_ECHO(" M906"); + SERIAL_ECHO_P(port, " M906"); #if ENABLED(X_IS_TMC2130) || ENABLED(X_IS_TMC2208) - SERIAL_ECHOPAIR(" X ", stepperX.getCurrent()); + SERIAL_ECHOPAIR_P(port, " X ", stepperX.getCurrent()); #endif #if ENABLED(Y_IS_TMC2130) || ENABLED(Y_IS_TMC2208) - SERIAL_ECHOPAIR(" Y ", stepperY.getCurrent()); + SERIAL_ECHOPAIR_P(port, " Y ", stepperY.getCurrent()); #endif #if ENABLED(Z_IS_TMC2130) || ENABLED(Z_IS_TMC2208) - SERIAL_ECHOPAIR(" Z ", stepperZ.getCurrent()); + SERIAL_ECHOPAIR_P(port, " Z ", stepperZ.getCurrent()); #endif #if ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208) - SERIAL_ECHOPAIR(" X2 ", stepperX2.getCurrent()); + SERIAL_ECHOPAIR_P(port, " X2 ", stepperX2.getCurrent()); #endif #if ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208) - SERIAL_ECHOPAIR(" Y2 ", stepperY2.getCurrent()); + SERIAL_ECHOPAIR_P(port, " Y2 ", stepperY2.getCurrent()); #endif #if ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208) - SERIAL_ECHOPAIR(" Z2 ", stepperZ2.getCurrent()); + SERIAL_ECHOPAIR_P(port, " Z2 ", stepperZ2.getCurrent()); #endif #if ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208) - SERIAL_ECHOPAIR(" E0 ", stepperE0.getCurrent()); + SERIAL_ECHOPAIR_P(port, " E0 ", stepperE0.getCurrent()); #endif #if ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208) - SERIAL_ECHOPAIR(" E1 ", stepperE1.getCurrent()); + SERIAL_ECHOPAIR_P(port, " E1 ", stepperE1.getCurrent()); #endif #if ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208) - SERIAL_ECHOPAIR(" E2 ", stepperE2.getCurrent()); + SERIAL_ECHOPAIR_P(port, " E2 ", stepperE2.getCurrent()); #endif #if ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208) - SERIAL_ECHOPAIR(" E3 ", stepperE3.getCurrent()); + SERIAL_ECHOPAIR_P(port, " E3 ", stepperE3.getCurrent()); #endif #if ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208) - SERIAL_ECHOPAIR(" E4 ", stepperE4.getCurrent()); + SERIAL_ECHOPAIR_P(port, " E4 ", stepperE4.getCurrent()); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #endif /** @@ -2275,23 +2325,23 @@ void MarlinSettings::reset() { #if ENABLED(SENSORLESS_HOMING) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Sensorless homing threshold:"); + SERIAL_ECHOLNPGM_P(port, "Sensorless homing threshold:"); } CONFIG_ECHO_START; - SERIAL_ECHO(" M914"); + SERIAL_ECHO_P(port, " M914"); #if ENABLED(X_IS_TMC2130) - SERIAL_ECHOPAIR(" X", stepperX.sgt()); + SERIAL_ECHOPAIR_P(port, " X", stepperX.sgt()); #endif #if ENABLED(X2_IS_TMC2130) - SERIAL_ECHOPAIR(" X2 ", stepperX2.sgt()); + SERIAL_ECHOPAIR_P(port, " X2 ", stepperX2.sgt()); #endif #if ENABLED(Y_IS_TMC2130) - SERIAL_ECHOPAIR(" Y", stepperY.sgt()); + SERIAL_ECHOPAIR_P(port, " Y", stepperY.sgt()); #endif #if ENABLED(X2_IS_TMC2130) - SERIAL_ECHOPAIR(" Y2 ", stepperY2.sgt()); + SERIAL_ECHOPAIR_P(port, " Y2 ", stepperY2.sgt()); #endif - SERIAL_EOL(); + SERIAL_EOL_P(port); #endif /** @@ -2300,23 +2350,23 @@ void MarlinSettings::reset() { #if ENABLED(LIN_ADVANCE) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Linear Advance:"); + SERIAL_ECHOLNPGM_P(port, "Linear Advance:"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M900 K", planner.extruder_advance_k); - SERIAL_ECHOLNPAIR(" R", planner.advance_ed_ratio); + SERIAL_ECHOPAIR_P(port, " M900 K", planner.extruder_advance_k); + SERIAL_ECHOLNPAIR_P(port, " R", planner.advance_ed_ratio); #endif #if HAS_MOTOR_CURRENT_PWM CONFIG_ECHO_START; if (!forReplay) { - SERIAL_ECHOLNPGM("Stepper motor currents:"); + SERIAL_ECHOLNPGM_P(port, "Stepper motor currents:"); CONFIG_ECHO_START; } - SERIAL_ECHOPAIR(" M907 X", stepper.motor_current_setting[0]); - SERIAL_ECHOPAIR(" Z", stepper.motor_current_setting[1]); - SERIAL_ECHOPAIR(" E", stepper.motor_current_setting[2]); - SERIAL_EOL(); + SERIAL_ECHOPAIR_P(port, " M907 X", stepper.motor_current_setting[0]); + SERIAL_ECHOPAIR_P(port, " Z", stepper.motor_current_setting[1]); + SERIAL_ECHOPAIR_P(port, " E", stepper.motor_current_setting[2]); + SERIAL_EOL_P(port); #endif /** @@ -2325,30 +2375,30 @@ void MarlinSettings::reset() { #if ENABLED(ADVANCED_PAUSE_FEATURE) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Filament load/unload lengths:"); + SERIAL_ECHOLNPGM_P(port, "Filament load/unload lengths:"); } CONFIG_ECHO_START; #if EXTRUDERS == 1 - SERIAL_ECHOPAIR(" M603 L", LINEAR_UNIT(filament_change_load_length[0])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[0])); + SERIAL_ECHOPAIR_P(port, " M603 L", LINEAR_UNIT(filament_change_load_length[0])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0])); #else - SERIAL_ECHOPAIR(" M603 T0 L", LINEAR_UNIT(filament_change_load_length[0])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[0])); + SERIAL_ECHOPAIR_P(port, " M603 T0 L", LINEAR_UNIT(filament_change_load_length[0])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0])); CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M603 T1 L", LINEAR_UNIT(filament_change_load_length[1])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[1])); + SERIAL_ECHOPAIR_P(port, " M603 T1 L", LINEAR_UNIT(filament_change_load_length[1])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[1])); #if EXTRUDERS > 2 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M603 T2 L", LINEAR_UNIT(filament_change_load_length[2])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[2])); + SERIAL_ECHOPAIR_P(port, " M603 T2 L", LINEAR_UNIT(filament_change_load_length[2])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[2])); #if EXTRUDERS > 3 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M603 T3 L", LINEAR_UNIT(filament_change_load_length[3])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[3])); + SERIAL_ECHOPAIR_P(port, " M603 T3 L", LINEAR_UNIT(filament_change_load_length[3])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[3])); #if EXTRUDERS > 4 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M603 T4 L", LINEAR_UNIT(filament_change_load_length[4])); - SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[4])); + SERIAL_ECHOPAIR_P(port, " M603 T4 L", LINEAR_UNIT(filament_change_load_length[4])); + SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[4])); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 diff --git a/Marlin/src/module/configuration_store.h b/Marlin/src/module/configuration_store.h index 361a51e94a..fdbf917493 100644 --- a/Marlin/src/module/configuration_store.h +++ b/Marlin/src/module/configuration_store.h @@ -25,14 +25,24 @@ #include "../inc/MarlinConfig.h" +#define ADD_PORT_ARG ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1 + class MarlinSettings { public: MarlinSettings() { } static uint16_t datasize(); - static void reset(); - static bool save(); // Return 'true' if data was saved + static void reset( + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); + static bool save( + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); // Return 'true' if data was saved FORCE_INLINE static bool init_eeprom() { bool success = true; @@ -47,8 +57,16 @@ class MarlinSettings { } #if ENABLED(EEPROM_SETTINGS) - static bool load(); // Return 'true' if data was loaded ok - static bool validate(); // Return 'true' if EEPROM data is ok + static bool load( + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); // Return 'true' if data was loaded ok + static bool validate( + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); // Return 'true' if EEPROM data is ok #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system // That can store is enabled @@ -67,7 +85,11 @@ class MarlinSettings { #endif #if DISABLED(DISABLE_M503) - static void report(const bool forReplay=false); + static void report(const bool forReplay=false + #if ADD_PORT_ARG + , const int8_t port=-1 + #endif + ); #else FORCE_INLINE static void report(const bool forReplay=false) { UNUSED(forReplay); } @@ -87,8 +109,16 @@ class MarlinSettings { #endif - static bool _load(); - static bool size_error(const uint16_t size); + static bool _load( + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); + static bool size_error(const uint16_t size + #if ADD_PORT_ARG + const int8_t port=-1 + #endif + ); #endif }; diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 77e180a2a1..73c3dd8b66 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -337,8 +337,8 @@ class Stepper { } if (timer < 100) { // (20kHz - this should never happen) timer = 100; - MYSERIAL.print(MSG_STEPPER_TOO_HIGH); - MYSERIAL.println(step_rate); + SERIAL_ECHOPGM(MSG_STEPPER_TOO_HIGH); + SERIAL_ECHOLN(step_rate); } #endif diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 887b0717ef..c859e414fe 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -2121,18 +2121,21 @@ void Temperature::isr() { #include "../gcode/gcode.h" - void print_heater_state(const float &c, const float &t, + static void print_heater_state(const float &c, const float &t #if ENABLED(SHOW_TEMP_ADC_VALUES) - const float r, + , const float r #endif - const int8_t e=-2 + #if NUM_SERIAL > 1 + , const int8_t port=-1 + #endif + , const int8_t e=-2 ) { #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 UNUSED(e); #endif - SERIAL_PROTOCOLCHAR(' '); - SERIAL_PROTOCOLCHAR( + SERIAL_PROTOCOLCHAR_P(port, ' '); + SERIAL_PROTOCOLCHAR_P(port, #if HAS_TEMP_BED && HAS_TEMP_HOTEND e == -1 ? 'B' : 'T' #elif HAS_TEMP_HOTEND @@ -2142,23 +2145,30 @@ void Temperature::isr() { #endif ); #if HOTENDS > 1 - if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); + if (e >= 0) SERIAL_PROTOCOLCHAR_P(port, '0' + e); #endif - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(c); - SERIAL_PROTOCOLPAIR(" /" , t); + SERIAL_PROTOCOLCHAR_P(port, ':'); + SERIAL_PROTOCOL_P(port, c); + SERIAL_PROTOCOLPAIR_P(port, " /" , t); #if ENABLED(SHOW_TEMP_ADC_VALUES) - SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); - SERIAL_PROTOCOLCHAR(')'); + SERIAL_PROTOCOLPAIR_P(port, " (", r / OVERSAMPLENR); + SERIAL_PROTOCOLCHAR_P(port, ')'); #endif } - void Temperature::print_heaterstates() { + void Temperature::print_heaterstates( + #if NUM_SERIAL > 1 + const int8_t port + #endif + ) { #if HAS_TEMP_HOTEND print_heater_state(degHotend(gcode.target_extruder), degTargetHotend(gcode.target_extruder) #if ENABLED(SHOW_TEMP_ADC_VALUES) , rawHotendTemp(gcode.target_extruder) #endif + #if NUM_SERIAL > 1 + , port + #endif ); #endif #if HAS_TEMP_BED @@ -2166,6 +2176,9 @@ void Temperature::isr() { #if ENABLED(SHOW_TEMP_ADC_VALUES) , rawBedTemp() #endif + #if NUM_SERIAL > 1 + , port + #endif , -1 // BED ); #endif @@ -2174,20 +2187,23 @@ void Temperature::isr() { #if ENABLED(SHOW_TEMP_ADC_VALUES) , rawHotendTemp(e) #endif + #if NUM_SERIAL > 1 + , port + #endif , e ); #endif - SERIAL_PROTOCOLPGM(" @:"); - SERIAL_PROTOCOL(getHeaterPower(gcode.target_extruder)); + SERIAL_PROTOCOLPGM_P(port, " @:"); + SERIAL_PROTOCOL_P(port, getHeaterPower(gcode.target_extruder)); #if HAS_TEMP_BED - SERIAL_PROTOCOLPGM(" B@:"); - SERIAL_PROTOCOL(getHeaterPower(-1)); + SERIAL_PROTOCOLPGM_P(port, " B@:"); + SERIAL_PROTOCOL_P(port, getHeaterPower(-1)); #endif #if HOTENDS > 1 HOTEND_LOOP() { - SERIAL_PROTOCOLPAIR(" @", e); - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(getHeaterPower(e)); + SERIAL_PROTOCOLPAIR_P(port, " @", e); + SERIAL_PROTOCOLCHAR_P(port, ':'); + SERIAL_PROTOCOL_P(port, getHeaterPower(e)); } #endif } diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 107fa67249..147a2df24f 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -547,7 +547,11 @@ class Temperature { #endif // HEATER_IDLE_HANDLER #if HAS_TEMP_HOTEND || HAS_TEMP_BED - static void print_heaterstates(); + static void print_heaterstates( + #if NUM_SERIAL > 1 + const int8_t port = -1 + #endif + ); #if ENABLED(AUTO_REPORT_TEMPERATURES) static uint8_t auto_report_temp_interval; static millis_t next_temp_report_ms; diff --git a/Marlin/src/sd/SdBaseFile.cpp b/Marlin/src/sd/SdBaseFile.cpp index b25a7f9f5c..ddde1d0d1f 100644 --- a/Marlin/src/sd/SdBaseFile.cpp +++ b/Marlin/src/sd/SdBaseFile.cpp @@ -339,38 +339,38 @@ int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) { && DIR_IS_FILE_OR_SUBDIR(&dir)) break; } // indent for dir level - for (uint8_t i = 0; i < indent; i++) MYSERIAL.write(' '); + for (uint8_t i = 0; i < indent; i++) SERIAL_CHAR(' '); // print name for (uint8_t i = 0; i < 11; i++) { if (dir.name[i] == ' ')continue; if (i == 8) { - MYSERIAL.write('.'); + SERIAL_CHAR('.'); w++; } - MYSERIAL.write(dir.name[i]); + SERIAL_CHAR(dir.name[i]); w++; } if (DIR_IS_SUBDIR(&dir)) { - MYSERIAL.write('/'); + SERIAL_CHAR('/'); w++; } if (flags & (LS_DATE | LS_SIZE)) { - while (w++ < 14) MYSERIAL.write(' '); + while (w++ < 14) SERIAL_CHAR(' '); } // print modify date/time if requested if (flags & LS_DATE) { - MYSERIAL.write(' '); + SERIAL_CHAR(' '); printFatDate(dir.lastWriteDate); - MYSERIAL.write(' '); + SERIAL_CHAR(' '); printFatTime(dir.lastWriteTime); } // print size if requested if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { - MYSERIAL.write(' '); - MYSERIAL.print(dir.fileSize); + SERIAL_CHAR(' '); + SERIAL_ECHO(dir.fileSize); } - MYSERIAL.println(); + SERIAL_EOL(); return DIR_IS_FILE(&dir) ? 1 : 2; } @@ -902,11 +902,10 @@ int SdBaseFile::peek() { return c; } - // print uint8_t with width 2 -static void print2u(uint8_t v) { - if (v < 10) MYSERIAL.write('0'); - MYSERIAL.print(v, DEC); +static void print2u(const uint8_t v) { + if (v < 10) SERIAL_CHAR('0'); + SERIAL_ECHO_F(v, DEC); } /** @@ -927,10 +926,10 @@ static void print2u(uint8_t v) { * \param[in] fatDate The date field from a directory entry. */ void SdBaseFile::printFatDate(uint16_t fatDate) { - MYSERIAL.print(FAT_YEAR(fatDate)); - MYSERIAL.write('-'); + SERIAL_ECHO(FAT_YEAR(fatDate)); + SERIAL_CHAR('-'); print2u(FAT_MONTH(fatDate)); - MYSERIAL.write('-'); + SERIAL_CHAR('-'); print2u(FAT_DAY(fatDate)); } @@ -945,9 +944,9 @@ void SdBaseFile::printFatDate(uint16_t fatDate) { */ void SdBaseFile::printFatTime(uint16_t fatTime) { print2u(FAT_HOUR(fatTime)); - MYSERIAL.write(':'); + SERIAL_CHAR(':'); print2u(FAT_MINUTE(fatTime)); - MYSERIAL.write(':'); + SERIAL_CHAR(':'); print2u(FAT_SECOND(fatTime)); } @@ -959,7 +958,7 @@ void SdBaseFile::printFatTime(uint16_t fatTime) { bool SdBaseFile::printName() { char name[FILENAME_LENGTH]; if (!getFilename(name)) return false; - MYSERIAL.print(name); + SERIAL_ECHO(name); return true; } diff --git a/Marlin/src/sd/SdFatUtil.cpp b/Marlin/src/sd/SdFatUtil.cpp index 329a59decc..1110d1dc9c 100644 --- a/Marlin/src/sd/SdFatUtil.cpp +++ b/Marlin/src/sd/SdFatUtil.cpp @@ -38,54 +38,22 @@ * \return The number of free bytes. */ #ifdef __arm__ -extern "C" char* sbrk(int incr); -int SdFatUtil::FreeRam() { - char top; - return &top - reinterpret_cast(sbrk(0)); -} -#else // __arm__ -extern char* __brkval; -extern char __bss_end; -/** - * Amount of free RAM - * \return The number of free bytes. - */ -int SdFatUtil::FreeRam() { - char top; - return __brkval ? &top - __brkval : &top - &__bss_end; -} -#endif // __arm -/** - * %Print a string in flash memory. - * - * \param[in] pr Print object for output. - * \param[in] str Pointer to string stored in flash memory. - */ -void SdFatUtil::print_P(PGM_P str) { - for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c); -} + extern "C" char* sbrk(int incr); + int SdFatUtil::FreeRam() { + char top; + return &top - reinterpret_cast(sbrk(0)); + } -/** - * %Print a string in flash memory followed by a CR/LF. - * - * \param[in] pr Print object for output. - * \param[in] str Pointer to string stored in flash memory. - */ -void SdFatUtil::println_P(PGM_P str) { print_P(str); MYSERIAL.println(); } +#else -/** - * %Print a string in flash memory to Serial. - * - * \param[in] str Pointer to string stored in flash memory. - */ -void SdFatUtil::SerialPrint_P(PGM_P str) { print_P(str); } + extern char* __brkval; + extern char __bss_end; + int SdFatUtil::FreeRam() { + char top; + return __brkval ? &top - __brkval : &top - &__bss_end; + } -/** - * %Print a string in flash memory to Serial followed by a CR/LF. - * - * \param[in] str Pointer to string stored in flash memory. - */ -void SdFatUtil::SerialPrintln_P(PGM_P str) { println_P(str); } +#endif #endif // SDSUPPORT diff --git a/Marlin/src/sd/SdFatUtil.h b/Marlin/src/sd/SdFatUtil.h index 825d6d29d6..1deb1eb8f3 100644 --- a/Marlin/src/sd/SdFatUtil.h +++ b/Marlin/src/sd/SdFatUtil.h @@ -35,17 +35,9 @@ * \file * \brief Useful utility functions. */ -/** Store and print a string in flash memory.*/ -#define PgmPrint(x) SerialPrint_P(PSTR(x)) -/** Store and print a string in flash memory followed by a CR/LF.*/ -#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) namespace SdFatUtil { int FreeRam(); - void print_P(PGM_P str); - void println_P(PGM_P str); - void SerialPrint_P(PGM_P str); - void SerialPrintln_P(PGM_P str); } using namespace SdFatUtil; // NOLINT diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 7d5959d10f..62e2b1466c 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -85,7 +85,11 @@ char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters uint16_t nrFile_index; -void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { +void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/ + #if NUM_SERIAL > 1 + , const int8_t port/*= -1*/ + #endif +) { dir_t p; uint8_t cnt = 0; @@ -118,12 +122,16 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m SdFile dir; if (!dir.open(parent, lfilename, O_READ)) { if (lsAction == LS_SerialPrint) { - SERIAL_ECHO_START(); - SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); - SERIAL_ECHOLN(lfilename); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHOLN_P(port, lfilename); } } - lsDive(path, dir); + lsDive(path, dir + #if NUM_SERIAL > 1 + , NULL, port + #endif + ); // close() is done automatically by destructor of SdFile } else { @@ -145,10 +153,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m case LS_SerialPrint: createFilename(filename, p); - SERIAL_PROTOCOL(prepend); - SERIAL_PROTOCOL(filename); - SERIAL_PROTOCOLCHAR(' '); - SERIAL_PROTOCOLLN(p.fileSize); + SERIAL_PROTOCOL_P(port, prepend); + SERIAL_PROTOCOL_P(port, filename); + SERIAL_PROTOCOLCHAR_P(port, ' '); + SERIAL_PROTOCOLLN_P(port, p.fileSize); break; case LS_GetFilename: @@ -165,10 +173,18 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m } // while readDir } -void CardReader::ls() { +void CardReader::ls( + #if NUM_SERIAL > 1 + const int8_t port + #endif +) { lsAction = LS_SerialPrint; root.rewind(); - lsDive("", root); + lsDive("", root + #if NUM_SERIAL > 1 + , NULL, port + #endif + ); } #if ENABLED(LONG_FILENAME_HOST_SUPPORT) @@ -176,12 +192,16 @@ void CardReader::ls() { /** * Get a long pretty path based on a DOS 8.3 path */ - void CardReader::printLongPath(char *path) { + void CardReader::printLongPath(char *path + #if NUM_SERIAL > 1 + , const int8_t port/*= -1*/ + #endif + ) { lsAction = LS_GetFilename; int i, pathLen = strlen(path); - // SERIAL_ECHOPGM("Full Path: "); SERIAL_ECHOLN(path); + // SERIAL_ECHOPGM_P(port, "Full Path: "); SERIAL_ECHOLN_P(port, path); // Zero out slashes to make segments for (i = 0; i < pathLen; i++) if (path[i] == '/') path[i] = '\0'; @@ -199,28 +219,32 @@ void CardReader::ls() { // Go to the next segment while (path[++i]) { } - // SERIAL_ECHOPGM("Looking for segment: "); SERIAL_ECHOLN(segment); + // SERIAL_ECHOPGM_P(port, "Looking for segment: "); SERIAL_ECHOLN_P(port, segment); // Find the item, setting the long filename diveDir.rewind(); - lsDive("", diveDir, segment); + lsDive("", diveDir, segment + #if NUM_SERIAL > 1 + , port + #endif + ); // Print /LongNamePart to serial output - SERIAL_PROTOCOLCHAR('/'); - SERIAL_PROTOCOL(longFilename[0] ? longFilename : "???"); + SERIAL_PROTOCOLCHAR_P(port, '/'); + SERIAL_PROTOCOL_P(port, longFilename[0] ? longFilename : "???"); // If the filename was printed then that's it if (!filenameIsDir) break; - // SERIAL_ECHOPGM("Opening dir: "); SERIAL_ECHOLN(segment); + // SERIAL_ECHOPGM_P(port, "Opening dir: "); SERIAL_ECHOLN_P(port, segment); // Open the sub-item as the new dive parent SdFile dir; if (!dir.open(diveDir, segment, O_READ)) { - SERIAL_EOL(); - SERIAL_ECHO_START(); - SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); - SERIAL_ECHO(segment); + SERIAL_EOL_P(port); + SERIAL_ECHO_START_P(port); + SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR); + SERIAL_ECHO_P(port, segment); break; } @@ -229,7 +253,7 @@ void CardReader::ls() { } // while i 1 + const int8_t port/*= -1*/ + #endif +) { if (cardOK) { - SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); - SERIAL_PROTOCOL(sdpos); - SERIAL_PROTOCOLCHAR('/'); - SERIAL_PROTOCOLLN(filesize); + SERIAL_PROTOCOLPGM_P(port, MSG_SD_PRINTING_BYTE); + SERIAL_PROTOCOL_P(port, sdpos); + SERIAL_PROTOCOLCHAR_P(port, '/'); + SERIAL_PROTOCOLLN_P(port, filesize); } else - SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); + SERIAL_PROTOCOLLNPGM_P(port, MSG_SD_NOT_PRINTING); } void CardReader::write_command(char *buf) { diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 4d8b5b4b36..915a639ed8 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -49,11 +49,19 @@ public: void openAndPrintFile(const char *name); void startFileprint(); void stopSDPrint(); - void getStatus(); + void getStatus( + #if NUM_SERIAL > 1 + const int8_t port = -1 + #endif + ); void printingHasFinished(); #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - void printLongPath(char *path); + void printLongPath(char *path + #if NUM_SERIAL > 1 + , const int8_t port = -1 + #endif + ); #endif void getfilename(uint16_t nr, const char* const match=NULL); @@ -61,7 +69,11 @@ public: void getAbsFilename(char *t); - void ls(); + void ls( + #if NUM_SERIAL > 1 + const int8_t port = -1 + #endif + ); void chdir(const char *relpath); int8_t updir(); void setroot(); @@ -162,7 +174,11 @@ private: LsAction lsAction; //stored for recursion. uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. char* diveDirName; - void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); + void lsDive(const char *prepend, SdFile parent, const char * const match=NULL + #if NUM_SERIAL > 1 + , const int8_t port = -1 + #endif + ); #if ENABLED(SDCARD_SORT_ALPHA) void flush_presort();