Merge pull request #8148 from tcm0116/2.0.x-multi_host

[2.0.x] Add multi-host support
2.0.x
Scott Lahteine 7 years ago committed by GitHub
commit d7fd78cb91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -33,8 +33,7 @@
// Includes // Includes
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#include "../HAL.h" #include "../../inc/MarlinConfig.h"
#include "../../core/macros.h"
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Externals // Externals

@ -47,6 +47,12 @@
#include "watchdog_AVR.h" #include "watchdog_AVR.h"
#include "math_AVR.h" #include "math_AVR.h"
#ifdef USBCON
#include "HardwareSerial.h"
#else
#include "MarlinSerial.h"
#endif
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Defines // Defines
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -79,6 +85,18 @@ typedef int8_t pin_t;
//extern uint8_t MCUSR; //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 // Public functions
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

@ -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 for (uint8_t y = 0; y < 28; y++) { // always print pin name
temp_char = pgm_read_byte(name_mem_pointer + y); temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0) if (temp_char != 0)
MYSERIAL.write(temp_char); SERIAL_CHAR(temp_char);
else { else {
for (uint8_t i = 0; i < 28 - y; i++) MYSERIAL.write(' '); for (uint8_t i = 0; i < 28 - y; i++) SERIAL_CHAR(' ');
break; break;
} }
} }

@ -66,9 +66,9 @@ void PRINT_ARRAY_NAME(uint8_t x) {
for (uint8_t y = 0; y < MAX_NAME_LENGTH; y++) { for (uint8_t y = 0; y < MAX_NAME_LENGTH; y++) {
char temp_char = pgm_read_byte(name_mem_pointer + y); char temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0) if (temp_char != 0)
MYSERIAL.write(temp_char); SERIAL_CHAR(temp_char);
else { 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; break;
} }
} }

@ -121,7 +121,7 @@ static uint8_t curGroup = 0xFF; // Current FLASH group
char buffer[80]; char buffer[80];
sprintf(buffer, "Page: %d (0x%04x)\n", page, page); sprintf(buffer, "Page: %d (0x%04x)\n", page, page);
MYSERIAL.print(buffer); SERIAL_PROTOCOL(buffer);
char* p = &buffer[0]; char* p = &buffer[0];
for (int i = 0; i< PageSize; ++i) { for (int i = 0; i< PageSize; ++i) {
@ -133,7 +133,7 @@ static uint8_t curGroup = 0xFF; // Current FLASH group
if ((i & 15) == 15) { if ((i & 15) == 15) {
*p++ = '\n'; *p++ = '\n';
*p = 0; *p = 0;
MYSERIAL.print(buffer); SERIAL_PROTOCOL(buffer);
p = &buffer[0]; p = &buffer[0];
} }
} }
@ -182,7 +182,7 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
SERIAL_ECHOLNPAIR("EEPROM PageWrite ",page); SERIAL_ECHOLNPAIR("EEPROM PageWrite ",page);
SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash); SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash);
SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0)); SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0));
MYSERIAL.flush(); SERIAL_FLUSH();
#endif #endif
// Get the page relative to the start of the EFC controller, and the EFC controller to use // 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("EEPROM PageErase ",page);
SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash); SERIAL_ECHOLNPAIR(" in FLASH address ",(uint32_t)addrflash);
SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0)); SERIAL_ECHOLNPAIR(" base address ",(uint32_t)getFlashStorage(0));
MYSERIAL.flush(); SERIAL_FLUSH();
#endif #endif
// Get the page relative to the start of the EFC controller, and the EFC controller to use // 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 #ifdef EE_EMU_DEBUG
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup); SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
MYSERIAL.flush(); SERIAL_FLUSH();
#endif #endif
// Now, validate that all the other group pages are empty // Now, validate that all the other group pages are empty
@ -957,7 +957,7 @@ static void ee_Init() {
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPAIR("EEPROM Page ",page); SERIAL_ECHOPAIR("EEPROM Page ",page);
SERIAL_ECHOLNPAIR(" not clean on group ",grp); SERIAL_ECHOLNPAIR(" not clean on group ",grp);
MYSERIAL.flush(); SERIAL_FLUSH();
#endif #endif
ee_PageErase(grp * PagesPerGroup + page); ee_PageErase(grp * PagesPerGroup + page);
} }
@ -978,7 +978,7 @@ static void ee_Init() {
#ifdef EE_EMU_DEBUG #ifdef EE_EMU_DEBUG
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("EEPROM Active page: ",curPage); SERIAL_ECHOLNPAIR("EEPROM Active page: ",curPage);
MYSERIAL.flush(); SERIAL_FLUSH();
#endif #endif
// Make sure the pages following the first clean one are also clean // Make sure the pages following the first clean one are also clean
@ -988,7 +988,7 @@ static void ee_Init() {
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPAIR("EEPROM Page ",page); SERIAL_ECHOPAIR("EEPROM Page ",page);
SERIAL_ECHOLNPAIR(" not clean on active group ",curGroup); SERIAL_ECHOLNPAIR(" not clean on active group ",curGroup);
MYSERIAL.flush(); SERIAL_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
#endif #endif
ee_PageErase(curGroup * PagesPerGroup + page); ee_PageErase(curGroup * PagesPerGroup + page);

@ -40,8 +40,15 @@
// //
// Defines // Defines
// //
#if SERIAL_PORT >= -1 && SERIAL_PORT <= 4 #define NUM_SERIAL 1
#define MYSERIAL customizedSerial
//#undef SERIAL_PORT
//#define SERIAL_PORT -1
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#else
#define MYSERIAL0 customizedSerial
#endif #endif
// We need the previous define before the include, or compilation bombs... // 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_enable_AdcFreerun(void);
//void HAL_disable_AdcFreerun(uint8_t chan); //void HAL_disable_AdcFreerun(uint8_t chan);
/**
* Pin Map
*/
#define GET_PIN_MAP_PIN(index) index #define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin #define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) #define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)

@ -29,7 +29,7 @@ extern "C" {
HalSerial usb_serial; HalSerial usb_serial;
//u8glib required fucntions // U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) { extern "C" void u8g_xMicroDelay(uint16_t val) {
delayMicroseconds(val); delayMicroseconds(val);
} }
@ -85,7 +85,7 @@ void HAL_adc_enable_channel(int ch) {
pin_t pin = analogInputToDigitalPin(ch); pin_t pin = analogInputToDigitalPin(ch);
if (pin == -1) { if (pin == -1) {
MYSERIAL.printf("%sINVALID ANALOG PORT:%d\n", errormagic, ch); SERIAL_PRINTF("%sINVALID ANALOG PORT:%d\n", errormagic, ch);
kill(MSG_KILLED); kill(MSG_KILLED);
} }
@ -97,15 +97,15 @@ void HAL_adc_enable_channel(int ch) {
pin_port == 1 ? 3 : 10; pin_port == 1 ? 3 : 10;
switch (pin_sel_register) { switch (pin_sel_register) {
case 1 : case 1:
LPC_PINCON->PINSEL1 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL1 &= ~(0x3 << pinsel_start_bit);
LPC_PINCON->PINSEL1 |= (0x1 << pinsel_start_bit); LPC_PINCON->PINSEL1 |= (0x1 << pinsel_start_bit);
break; break;
case 3 : case 3:
LPC_PINCON->PINSEL3 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL3 &= ~(0x3 << pinsel_start_bit);
LPC_PINCON->PINSEL3 |= (0x3 << pinsel_start_bit); LPC_PINCON->PINSEL3 |= (0x3 << pinsel_start_bit);
break; break;
case 0 : case 0:
LPC_PINCON->PINSEL0 &= ~(0x3 << pinsel_start_bit); LPC_PINCON->PINSEL0 &= ~(0x3 << pinsel_start_bit);
LPC_PINCON->PINSEL0 |= (0x2 << pinsel_start_bit); LPC_PINCON->PINSEL0 |= (0x2 << pinsel_start_bit);
break; break;
@ -115,7 +115,7 @@ void HAL_adc_enable_channel(int ch) {
uint8_t active_adc = 0; uint8_t active_adc = 0;
void HAL_adc_start_conversion(const uint8_t ch) { void HAL_adc_start_conversion(const uint8_t ch) {
if (analogInputToDigitalPin(ch) == -1) { 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; return;
} }

@ -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_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 #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; extern HalSerial usb_serial;
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
#endif
#if SERIAL_PORT == -1 #if SERIAL_PORT == -1
#define MYSERIAL usb_serial #define MYSERIAL0 usb_serial
#elif SERIAL_PORT == 0 #elif SERIAL_PORT == 0
#define MYSERIAL Serial #define MYSERIAL0 Serial
#elif SERIAL_PORT == 1 #elif SERIAL_PORT == 1
#define MYSERIAL Serial1 #define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2 #elif SERIAL_PORT == 2
#define MYSERIAL Serial2 #define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3 #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 #endif
#define CRITICAL_SECTION_START uint32_t primask = __get_PRIMASK(); __disable_irq(); #define CRITICAL_SECTION_START uint32_t primask = __get_PRIMASK(); __disable_irq();

@ -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)) 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 LPC1768_PWM_write(pin, map(value, 0, 255, 1, LPC_PWM1->MR0)); // map 1-254 onto PWM range
else { // out of PWM channels 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; out_of_PWM_slots = true;
digitalWrite(pin, value); // treat as a digital pin if out of channels digitalWrite(pin, value); // treat as a digital pin if out of channels
} }

@ -88,14 +88,13 @@ int main(void) {
#endif #endif
} }
// Only initialize the debug framework if using the USB emulated serial port #if NUM_SERIAL > 0
if ((HalSerial*) &MYSERIAL == &usb_serial) MYSERIAL0.begin(BAUDRATE);
debug_frmwrk_init(); #if NUM_SERIAL > 1
MYSERIAL1.begin(BAUDRATE);
MYSERIAL.begin(BAUDRATE); #endif
MYSERIAL.printf("\n\nLPC1768 (%dMhz) UART0 Initialised\n", SystemCoreClock / 1000000); SERIAL_PRINTF("\n\nLPC1768 (%dMhz) UART0 Initialised\n", SystemCoreClock / 1000000);
#if TX_BUFFER_SIZE > 0 SERIAL_FLUSHTX();
MYSERIAL.flushTX();
#endif #endif
HAL_timer_init(); HAL_timer_init();

@ -20,8 +20,8 @@
* *
*/ */
#ifndef HAL_SERIAL_H_ #ifndef _HAL_SERIAL_H_
#define HAL_SERIAL_H_ #define _HAL_SERIAL_H_
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -30,7 +30,7 @@ extern "C" {
#include <debug_frmwrk.h> #include <debug_frmwrk.h>
} }
/* /**
* Generic RingBuffer * Generic RingBuffer
* T type of the buffer array * T type of the buffer array
* S size of the buffer (must be power of 2) * S size of the buffer (must be power of 2)
@ -39,46 +39,33 @@ extern "C" {
*/ */
template <typename T, uint32_t S> class RingBuffer { template <typename T, uint32_t S> class RingBuffer {
public: public:
RingBuffer() { RingBuffer() { index_read = index_write = 0; }
index_read = 0; uint32_t available() volatile { return buffer_mask & (index_write - index_read); }
index_write = 0; 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 { bool peek(T *value) volatile {
if(value == 0 || available() == 0) if (value == 0 || available() == 0)
return false; return false;
*value = buffer[buffer_mask & index_read]; *value = buffer[buffer_mask & index_read];
return true; return true;
} }
uint32_t available() volatile { int read() volatile {
return buffer_mask & (index_write - index_read); if ((buffer_mask & index_read) == (buffer_mask & index_write)) return -1;
}
uint32_t free() volatile {
return buffer_size - available();
}
T read() volatile {
if((buffer_mask & index_read) == (buffer_mask & index_write)) return T(-1);
T val = buffer[buffer_mask & index_read]; T val = buffer[buffer_mask & index_read];
++index_read; ++index_read;
return val; return val;
} }
bool write( T value) volatile { bool write(T value) volatile {
uint32_t next_head = buffer_mask & (index_write + 1); 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; buffer[buffer_mask & index_write] = value;
index_write = next_head; index_write = next_head;
return true; return true;
} }
return false; 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: private:
static const uint32_t buffer_size = S; static const uint32_t buffer_size = S;
@ -90,42 +77,35 @@ private:
class HalSerial { class HalSerial {
public: public:
HalSerial() { HalSerial() { host_connected = false; }
host_connected = false;
}
void begin(int32_t baud) { void begin(int32_t baud) {
} }
char read() { int peek() {
return (char)receive_buffer.read(); uint8_t value;
return receive_buffer.peek(&value) ? value : -1;
} }
void write(char c) { int read() { return receive_buffer.read(); }
_DBC(c); //Duplicate output over uart0
if(host_connected) transmit_buffer.write((uint8_t)c);
}
operator bool() { size_t write(char c) { return host_connected ? transmit_buffer.write((uint8_t)c) : 0; }
return host_connected;
} operator bool() { return host_connected; }
uint16_t available() { uint16_t available() {
return (uint16_t)receive_buffer.available(); return (uint16_t)receive_buffer.available();
} }
void flush() { void flush() { receive_buffer.clear(); }
receive_buffer.clear();
}
uint8_t availableForWrite(void){ uint8_t availableForWrite(void){
return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free(); return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free();
} }
void flushTX(void){ void flushTX(void){
if(host_connected) { if (host_connected)
while(transmit_buffer.available()); while (transmit_buffer.available()) { /* nada */ }
}
} }
void printf(const char *format, ...) { void printf(const char *format, ...) {
@ -135,7 +115,6 @@ public:
int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs); int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
va_end(vArgs); va_end(vArgs);
if (length > 0 && length < 256) { if (length > 0 && length < 256) {
_DBG(buffer); //Duplicate output over uart0
if (host_connected) { if (host_connected) {
for (int i = 0; i < length;) { for (int i = 0; i < length;) {
if (transmit_buffer.write(buffer[i])) { if (transmit_buffer.write(buffer[i])) {
@ -152,108 +131,72 @@ public:
#define BIN 2 #define BIN 2
#define BYTE 0 #define BYTE 0
void print_bin(uint32_t value, uint8_t num_digits) { void print_bin(uint32_t value, uint8_t num_digits) {
uint32_t mask = 1 << (num_digits -1); uint32_t mask = 1 << (num_digits -1);
for (uint8_t i = 0; i < num_digits; i++) { for (uint8_t i = 0; i < num_digits; i++) {
if (!(i % 4) && i) printf(" "); if (!(i % 4) && i) write(' ');
if (!(i % 16) && i) printf(" "); if (!(i % 16) && i) write(' ');
if (value & mask) printf("1"); if (value & mask) write('1');
else printf("0"); else write('0');
value <<= 1; value <<= 1;
} }
} }
void print(const char value[]) { void print(const char value[]) { printf("%s" , value); }
printf("%s" , value);
}
void print(char value, int nbase = BYTE) { 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 == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value); else if (nbase == HEX) printf("%2X", value);
else if (nbase == DEC ) printf("%d", value); else if (nbase == DEC ) printf("%d", value);
else printf("%c" , value); else printf("%c" , value);
} }
void print(unsigned char value, int nbase = BYTE) { 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 == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value); else if (nbase == HEX) printf("%2X", value);
else printf("%u" , value); else printf("%u" , value);
} }
void print(int value, int nbase = BYTE) { 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 == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value); else if (nbase == HEX) printf("%4X", value);
else printf("%d", value); else printf("%d", value);
} }
void print(unsigned int value, int nbase = BYTE) { 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 == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value); else if (nbase == HEX) printf("%4X", value);
else printf("%u" , value); else printf("%u" , value);
} }
void print(long value, int nbase = BYTE) { 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 == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value); else if (nbase == HEX) printf("%8X", value);
else printf("%ld" , value); else printf("%ld" , value);
} }
void print(unsigned long value, int nbase = BYTE) { 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 == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value); else if (nbase == HEX) printf("%8X", value);
else printf("%lu" , value); else printf("%lu" , value);
} }
void print(float value, int round = 6) { void print(float value, int round = 6) { printf("%f" , value); }
printf("%f" , value); void print(double 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(const char value[]) { void println(unsigned char value, int nbase = BYTE) { print(value, nbase); println(); }
printf("%s\n" , value); 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(char value, int nbase = BYTE) { void println(long value, int nbase = BYTE) { print(value, nbase); println(); }
print(value, nbase); void println(unsigned long value, int nbase = BYTE) { print(value, nbase); println(); }
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(unsigned char value, int nbase = BYTE) { void println(void) { print('\n'); }
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<uint8_t, 128> receive_buffer; volatile RingBuffer<uint8_t, 128> receive_buffer;
volatile RingBuffer<uint8_t, 128> transmit_buffer; volatile RingBuffer<uint8_t, 128> transmit_buffer;
volatile bool host_connected; volatile bool host_connected;
}; };
#endif // _HAL_SERIAL_H_
#endif /* MARLIN_SRC_HAL_HAL_SERIAL_H_ */

@ -65,16 +65,41 @@
// Defines // Defines
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
#endif
#if SERIAL_PORT == -1 #if SERIAL_PORT == -1
#define MYSERIAL SerialUSB #define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 0 #elif SERIAL_PORT == 0
#define MYSERIAL Serial #define MYSERIAL0 Serial
#elif SERIAL_PORT == 1 #elif SERIAL_PORT == 1
#define MYSERIAL Serial1 #define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2 #elif SERIAL_PORT == 2
#define MYSERIAL Serial2 #define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3 #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 #endif
/** /**

@ -57,16 +57,18 @@
#define IS_TEENSY35 defined(__MK64FX512__) #define IS_TEENSY35 defined(__MK64FX512__)
#define IS_TEENSY36 defined(__MK66FX1M0__) #define IS_TEENSY36 defined(__MK66FX1M0__)
#define NUM_SERIAL 1
#if SERIAL_PORT == -1 #if SERIAL_PORT == -1
#define MYSERIAL SerialUSB #define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 0 #elif SERIAL_PORT == 0
#define MYSERIAL Serial #define MYSERIAL0 Serial
#elif SERIAL_PORT == 1 #elif SERIAL_PORT == 1
#define MYSERIAL Serial1 #define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2 #elif SERIAL_PORT == 2
#define MYSERIAL Serial2 #define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3 #elif SERIAL_PORT == 3
#define MYSERIAL Serial3 #define MYSERIAL0 Serial3
#endif #endif
#define HAL_SERVO_LIB libServo #define HAL_SERVO_LIB libServo

@ -669,9 +669,22 @@ void setup() {
disableStepperDrivers(); disableStepperDrivers();
#endif #endif
MYSERIAL.begin(BAUDRATE); #if NUM_SERIAL > 0
uint32_t serial_connect_timeout = millis() + 1000; MYSERIAL0.begin(BAUDRATE);
while(!MYSERIAL && PENDING(millis(), serial_connect_timeout)); #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_PROTOCOLLNPGM("start");
SERIAL_ECHO_START(); SERIAL_ECHO_START();

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -101,6 +101,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -107,6 +107,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -101,7 +101,16 @@
* *
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7] * :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
*/ */
#define SERIAL_PORT -1 #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. * This setting determines the communication speed of the printer.

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -132,6 +132,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -118,6 +118,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -118,6 +118,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -106,6 +106,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -102,6 +102,15 @@
*/ */
#define SERIAL_PORT 0 #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. * This setting determines the communication speed of the printer.
* *

@ -27,25 +27,37 @@ uint8_t marlin_debug_flags = DEBUG_NONE;
const char errormagic[] PROGMEM = "Error:"; const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:"; 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) { void serialprintPGM(const char * str) {
#ifdef TARGET_LPC1768 while (char ch = pgm_read_byte(str++)) SERIAL_CHAR(ch);
MYSERIAL.print(str);
#else
while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch);
#endif
} }
void serial_echopair_P(const char* s_P, const char *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_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); } void serial_echopair_PGM(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_PGM(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_PGM(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_PGM(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_PGM(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_PGM(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, 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) #if ENABLED(DEBUG_LEVELING_FEATURE)

@ -75,9 +75,7 @@ enum DebugFlags {
#include "../HAL/HAL_AVR/MarlinSerial.h" #include "../HAL/HAL_AVR/MarlinSerial.h"
#define MYSERIAL customizedSerial #define MYSERIAL customizedSerial
#endif #endif
#endif #elif defined(ARDUINO_ARCH_SAM)
#ifdef ARDUINO_ARCH_SAM
// To pull the Serial port definitions and overrides // To pull the Serial port definitions and overrides
#include "../HAL/HAL_DUE/MarlinSerial_Due.h" #include "../HAL/HAL_DUE/MarlinSerial_Due.h"
#endif #endif
@ -88,17 +86,152 @@ extern uint8_t marlin_debug_flags;
extern const char echomagic[] PROGMEM; extern const char echomagic[] PROGMEM;
extern const char errormagic[] 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_EOL() SERIAL_CHAR('\n')
#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x) #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_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_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n")))
#define SERIAL_PROTOCOLPAIR(pre, value) (serial_echopair_P(PSTR(pre),(value))) #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_PROTOCOLLNPAIR(pre, value) do { SERIAL_PROTOCOLPAIR(pre, value); SERIAL_EOL(); } while(0)
#define SERIAL_ECHO_START() (serialprintPGM(echomagic)) #define SERIAL_ECHO_START() (serialprintPGM(echomagic))
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x) #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_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHOPAIR(pre,value) SERIAL_PROTOCOLPAIR(pre, value) #define SERIAL_ECHOPAIR(pre,value) SERIAL_PROTOCOLPAIR(pre, value)
#define SERIAL_ECHOLNPAIR(pre, value) SERIAL_PROTOCOLLNPAIR(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_START() (serialprintPGM(errormagic))
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x) #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_ECHOPAIR_F(pre,value) SERIAL_ECHOPAIR(pre, FIXFLOAT(value))
#define SERIAL_ECHOLNPAIR_F(pre, value) SERIAL_ECHOLNPAIR(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_PGM(const char* s_P, const char *v);
void serial_echopair_P(const char* s_P, char v); void serial_echopair_PGM(const char* s_P, char v);
void serial_echopair_P(const char* s_P, int v); void serial_echopair_PGM(const char* s_P, int v);
void serial_echopair_P(const char* s_P, long v); void serial_echopair_PGM(const char* s_P, long v);
void serial_echopair_P(const char* s_P, float v); void serial_echopair_PGM(const char* s_P, float v);
void serial_echopair_P(const char* s_P, double v); void serial_echopair_PGM(const char* s_P, double v);
void serial_echopair_P(const char* s_P, unsigned int v); void serial_echopair_PGM(const char* s_P, unsigned int v);
void serial_echopair_P(const char* s_P, unsigned long v); void serial_echopair_PGM(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_PGM(const char* s_P, uint8_t v) { serial_echopair_PGM(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_PGM(const char* s_P, bool v) { serial_echopair_PGM(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)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); void serial_spaces(uint8_t count);
#define SERIAL_ECHO_SP(C) serial_spaces(C) #define SERIAL_ECHO_SP(C) serial_spaces(C)
@ -149,8 +282,7 @@ void serialprintPGM(const char* str);
#if HAS_ABL #if HAS_ABL
void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz); void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz);
#endif #endif
#define DEBUG_POS(SUFFIX,VAR) do { \ #define DEBUG_POS(SUFFIX,VAR) do { print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0)
print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0)
#endif #endif
#endif // __SERIAL_H__ #endif // __SERIAL_H__

@ -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]; c1 = z_values[x1][y1], c2 = z_values[x2][y2];
// Treat far unprobed points as zero, near as equal to far // Treat far unprobed points as zero, near as equal to far
if (isnan(a2)) a2 = 0.0; if (isnan(a1)) a1 = a2; if (isnan(a2)) a2 = 0.0;
if (isnan(b2)) b2 = 0.0; if (isnan(b1)) b1 = b2; if (isnan(a1)) a1 = a2;
if (isnan(c2)) c2 = 0.0; if (isnan(c1)) c1 = c2; 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; const float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2;

@ -36,13 +36,27 @@
uint8_t ubl_cnt = 0; 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() { void unified_bed_leveling::report_state(
echo_name(); #if NUM_SERIAL > 1
SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " "); const int8_t port/*= -1*/
if (!planner.leveling_active) SERIAL_PROTOCOLPGM("in"); #endif
SERIAL_PROTOCOLLNPGM("active."); ) {
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); safe_delay(50);
} }
@ -198,10 +212,7 @@
} }
idle(); idle();
if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(','); if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(',');
SERIAL_FLUSHTX();
#if TX_BUFFER_SIZE > 0
MYSERIAL.flushTX();
#endif
safe_delay(15); safe_delay(15);
if (map_type == 0) { if (map_type == 0) {
SERIAL_CHAR(is_current ? ']' : ' '); SERIAL_CHAR(is_current ? ']' : ' ');

@ -104,8 +104,16 @@ class unified_bed_leveling {
public: public:
static void echo_name(); static void echo_name(
static void report_state(); #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 save_ubl_active_state_and_disable();
static void restore_ubl_active_state_and_leave(); static void restore_ubl_active_state_and_leave();
static void display_map(const int); static void display_map(const int);

@ -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); const uint32_t pwm_scale = get_pwm_scale(st);
SERIAL_ECHO(axisID); SERIAL_ECHO(axisID);
SERIAL_ECHOPAIR(":", pwm_scale); 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("| "); SERIAL_ECHO("| ");
if (data.is_error) SERIAL_ECHO('E'); if (data.is_error) SERIAL_ECHO('E');
else if (data.is_ot) SERIAL_ECHO('O'); else if (data.is_ot) SERIAL_ECHO('O');
else if (data.is_otpw) SERIAL_ECHO('W'); 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'); else if (st.flag_otpw) SERIAL_ECHO('F');
SERIAL_ECHO("\t"); SERIAL_ECHO("\t");
} }

@ -24,25 +24,41 @@
#include "../../module/configuration_store.h" #include "../../module/configuration_store.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
/** /**
* M500: Store settings in EEPROM * M500: Store settings in EEPROM
*/ */
void GcodeSuite::M500() { 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 * M501: Read settings from EEPROM
*/ */
void GcodeSuite::M501() { 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 * M502: Revert to default settings
*/ */
void GcodeSuite::M502() { 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) #if DISABLED(DISABLE_M503)
@ -51,7 +67,11 @@ void GcodeSuite::M502() {
* M503: print settings currently in memory * M503: print settings currently in memory
*/ */
void GcodeSuite::M503() { 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 #endif // !DISABLE_M503

@ -79,21 +79,21 @@ static void drv_status_print_hex(const char name[], const uint32_t drv_status) {
SERIAL_ECHO(name); SERIAL_ECHO(name);
SERIAL_ECHOPGM(" = 0x"); SERIAL_ECHOPGM(" = 0x");
for(int B=24; B>=8; B-=8){ for(int B=24; B>=8; B-=8){
MYSERIAL.print((drv_status>>(B+4))&0xF, HEX); SERIAL_PRINT((drv_status>>(B+4))&0xF, HEX);
MYSERIAL.print((drv_status>>B)&0xF, HEX); SERIAL_PRINT((drv_status>>B)&0xF, HEX);
MYSERIAL.print(':'); SERIAL_CHAR(':');
} }
MYSERIAL.print((drv_status>>4)&0xF, HEX); SERIAL_PRINT((drv_status>>4)&0xF, HEX);
MYSERIAL.print((drv_status)&0xF, HEX); SERIAL_PRINT((drv_status)&0xF, HEX);
SERIAL_EOL(); SERIAL_EOL();
} }
#if ENABLED(HAVE_TMC2130) #if ENABLED(HAVE_TMC2130)
static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) { static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) {
switch(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_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; case TMC_STEALTHCHOP: serialprintPGM(st.stealthChop() ? PSTR("true") : PSTR("false")); break;
default: 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) { static void tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) {
switch(i) { switch(i) {
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_ECHOPGM("X"); break; 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; case TMC_FSACTIVE: if (st.fsactive()) SERIAL_ECHOPGM("X"); break;
default: break; default: break;
} }
@ -113,10 +113,10 @@ static void drv_status_print_hex(const char name[], const uint32_t drv_status) {
case TMC_TSTEP: { case TMC_TSTEP: {
uint32_t data = 0; uint32_t data = 0;
st.TSTEP(&data); st.TSTEP(&data);
MYSERIAL.print(data); SERIAL_PROTOCOL(data);
break; 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_STEALTHCHOP: serialprintPGM(st.stealth() ? PSTR("true") : PSTR("false")); break;
case TMC_S2VSA: if (st.s2vsa()) SERIAL_ECHOPGM("X"); break; case TMC_S2VSA: if (st.s2vsa()) SERIAL_ECHOPGM("X"); break;
case TMC_S2VSB: if (st.s2vsb()) 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_CODES: SERIAL_ECHO(extended_axis_codes[axis]); break;
case TMC_ENABLED: serialprintPGM(st.isEnabled() ? PSTR("true") : PSTR("false")); break; case TMC_ENABLED: serialprintPGM(st.isEnabled() ? PSTR("true") : PSTR("false")); break;
case TMC_CURRENT: SERIAL_ECHO(st.getCurrent()); break; case TMC_CURRENT: SERIAL_ECHO(st.getCurrent()); break;
case TMC_RMS_CURRENT: MYSERIAL.print(st.rms_current()); break; case TMC_RMS_CURRENT: SERIAL_PROTOCOL(st.rms_current()); break;
case TMC_MAX_CURRENT: MYSERIAL.print((float)st.rms_current()*1.41, 0); break; case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current()*1.41, 0); break;
case TMC_IRUN: case TMC_IRUN:
MYSERIAL.print(st.irun(), DEC); SERIAL_PRINT(st.irun(), DEC);
SERIAL_ECHOPGM("/31"); SERIAL_ECHOPGM("/31");
break; break;
case TMC_IHOLD: case TMC_IHOLD:
MYSERIAL.print(st.ihold(), DEC); SERIAL_PRINT(st.ihold(), DEC);
SERIAL_ECHOPGM("/31"); SERIAL_ECHOPGM("/31");
break; break;
case TMC_CS_ACTUAL: case TMC_CS_ACTUAL:
MYSERIAL.print(st.cs_actual(), DEC); SERIAL_PRINT(st.cs_actual(), DEC);
SERIAL_ECHOPGM("/31"); SERIAL_ECHOPGM("/31");
break; break;
@ -170,10 +170,10 @@ static void tmc_status(TMC &st, TMC_AxisEnum axis, const TMC_debug_enum i, const
break; break;
case TMC_OTPW: serialprintPGM(st.otpw() ? PSTR("true") : PSTR("false")); 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_OTPW_TRIGGERED: serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); break;
case TMC_TOFF: MYSERIAL.print(st.toff(), DEC); break; case TMC_TOFF: SERIAL_PRINT(st.toff(), DEC); break;
case TMC_TBL: MYSERIAL.print(st.blank_time(), DEC); break; case TMC_TBL: SERIAL_PRINT(st.blank_time(), DEC); break;
case TMC_HEND: MYSERIAL.print(st.hysterisis_end(), DEC); break; case TMC_HEND: SERIAL_PRINT(st.hysterisis_end(), DEC); break;
case TMC_HSTRT: MYSERIAL.print(st.hysterisis_start(), DEC); break; case TMC_HSTRT: SERIAL_PRINT(st.hysterisis_start(), DEC); break;
default: tmc_status(st, i); 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_S2GA: if (st.s2ga()) SERIAL_ECHOPGM("X"); break;
case TMC_DRV_OTPW: if (st.otpw()) 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_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; 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; default: tmc_parse_drv_status(st, i); break;
} }

@ -23,6 +23,10 @@
#include "../gcode.h" #include "../gcode.h"
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
#if ENABLED(EXTENDED_CAPABILITIES_REPORT) #if ENABLED(EXTENDED_CAPABILITIES_REPORT)
static void cap_line(const char * const name, bool ena=false) { static void cap_line(const char * const name, bool ena=false) {
SERIAL_PROTOCOLPGM("Cap:"); SERIAL_PROTOCOLPGM("Cap:");
@ -36,7 +40,14 @@
* M115: Capabilities string * M115: Capabilities string
*/ */
void GcodeSuite::M115() { 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) #if ENABLED(EXTENDED_CAPABILITIES_REPORT)

@ -32,6 +32,10 @@
#include "../libs/hex_print_routines.h" #include "../libs/hex_print_routines.h"
#endif #endif
#if NUM_SERIAL > 1
#include "queue.h"
#endif
// Must be declared for allocation and to satisfy the linker // Must be declared for allocation and to satisfy the linker
// Zero values need no initialization. // Zero values need no initialization.
@ -265,10 +269,13 @@ void GCodeParser::parse(char *p) {
#endif // CNC_COORDINATE_SYSTEMS #endif // CNC_COORDINATE_SYSTEMS
void GCodeParser::unknown_command_error() { void GCodeParser::unknown_command_error() {
SERIAL_ECHO_START(); #if NUM_SERIAL > 1
SERIAL_ECHOPAIR(MSG_UNKNOWN_COMMAND, command_ptr); const int16_t port = command_queue_port[cmd_queue_index_r];
SERIAL_CHAR('"'); #endif
SERIAL_EOL(); 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) #if ENABLED(DEBUG_GCODE_PARSER)

@ -58,12 +58,19 @@ uint8_t commands_in_queue = 0, // Count of commands in the queue
char command_queue[BUFSIZE][MAX_CMD_SIZE]; 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 * Serial command injection
*/ */
// Number of characters read in the current line of serial input // 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]; 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 * 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; 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; if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0;
commands_in_queue++; commands_in_queue++;
} }
@ -101,10 +115,18 @@ inline void _commit_command(bool say_ok) {
* Return true if the command was successfully added. * Return true if the command was successfully added.
* Return false for a full buffer, or if the 'command' is a comment. * 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; if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
strcpy(command_queue[cmd_queue_index_w], cmd); strcpy(command_queue[cmd_queue_index_w], cmd);
_commit_command(say_ok); _commit_command(say_ok
#if NUM_SERIAL > 1
, port
#endif
);
return true; return true;
} }
@ -178,21 +200,25 @@ void enqueue_and_echo_commands_P(const char * const pgcode) {
* B<int> Block queue space remaining * B<int> Block queue space remaining
*/ */
void ok_to_send() { 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(); gcode.refresh_cmd_timeout();
if (!send_ok[cmd_queue_index_r]) return; if (!send_ok[cmd_queue_index_r]) return;
SERIAL_PROTOCOLPGM(MSG_OK); SERIAL_PROTOCOLPGM_P(port, MSG_OK);
#if ENABLED(ADVANCED_OK) #if ENABLED(ADVANCED_OK)
char* p = command_queue[cmd_queue_index_r]; char* p = command_queue[cmd_queue_index_r];
if (*p == 'N') { if (*p == 'N') {
SERIAL_PROTOCOL(' '); SERIAL_PROTOCOL_P(port, ' ');
SERIAL_ECHO(*p++); SERIAL_ECHO_P(port, *p++);
while (NUMERIC_SIGNED(*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_P(port, " P"); SERIAL_PROTOCOL_P(port, int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1));
SERIAL_PROTOCOLPGM(" B"); SERIAL_PROTOCOL(BUFSIZE - commands_in_queue); SERIAL_PROTOCOLPGM_P(port, " B"); SERIAL_PROTOCOL_P(port, BUFSIZE - commands_in_queue);
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
/** /**
@ -200,20 +226,39 @@ void ok_to_send() {
* indicate that a command needs to be re-sent. * indicate that a command needs to be re-sent.
*/ */
void flush_and_request_resend() { void flush_and_request_resend() {
//char command_queue[cmd_queue_index_r][100]="Resend:"; #if NUM_SERIAL > 1
MYSERIAL.flush(); const int16_t port = command_queue_port[cmd_queue_index_r];
SERIAL_PROTOCOLPGM(MSG_RESEND); if (port < 0) return;
SERIAL_PROTOCOLLN(gcode_LastN + 1); #endif
ok_to_send(); 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) { void gcode_line_error(const char* err, uint8_t port) {
SERIAL_ERROR_START(); SERIAL_ERROR_START_P(port);
serialprintPGM(err); serialprintPGM_P(port, err);
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN_P(port, gcode_LastN);
//Serial.println(gcode_N); flush_and_request_resend();
if (doFlush) flush_and_request_resend(); serial_count[port] = 0;
serial_count = 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. * left on the serial port.
*/ */
inline void get_serial_commands() { inline void get_serial_commands() {
static char serial_line_buffer[MAX_CMD_SIZE]; static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
static bool serial_comment_mode = false; static bool serial_comment_mode[NUM_SERIAL] = { false };
// If the command buffer is empty for too long, // If the command buffer is empty for too long,
// send "wait" to indicate Marlin is still waiting. // send "wait" to indicate Marlin is still waiting.
#if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0 #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0
static millis_t last_command_time = 0; static millis_t last_command_time = 0;
const millis_t ms = millis(); 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); SERIAL_ECHOLNPGM(MSG_WAIT);
last_command_time = ms; 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 * Loop while serial characters are incoming and the queue is not full
*/ */
int c; while (commands_in_queue < BUFSIZE && serial_data_available()) {
while (commands_in_queue < BUFSIZE && (c = MYSERIAL.read()) >= 0) { for (uint8_t i = 0; i < NUM_SERIAL; ++i) {
char serial_char = c; int c;
if ((c = read_serial(i)) < 0) continue;
/** char serial_char = c;
* If the character ends the line
*/
if (serial_char == '\n' || serial_char == '\r') {
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 if (!serial_count[i]) continue; // Skip empty lines
serial_count = 0; // Reset buffer
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* command = serial_line_buffer[i];
char *npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line
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) { bool M110 = strstr_P(command, PSTR("M110")) != NULL;
char* n2pos = strchr(command + 4, 'N');
if (n2pos) npos = n2pos;
}
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_N = strtol(npos + 1, NULL, 10);
gcode_line_error(PSTR(MSG_ERR_LINE_NO));
return;
}
char *apos = strrchr(command, '*'); if (gcode_N != gcode_LastN + 1 && !M110) {
if (apos) { gcode_line_error(PSTR(MSG_ERR_LINE_NO), i);
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));
return; return;
} }
}
else {
gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM));
return;
}
gcode_LastN = gcode_N;
}
// Movement commands alert when stopped char *apos = strrchr(command, '*');
if (IsStopped()) { if (apos) {
char* gpos = strchr(command, 'G'); uint8_t checksum = 0, count = uint8_t(apos - command);
if (gpos) { while (count) checksum ^= command[--count];
const int codenum = strtol(gpos + 1, NULL, 10); if (strtol(apos + 1, NULL, 10) != checksum) {
switch (codenum) { gcode_line_error(PSTR(MSG_ERR_CHECKSUM_MISMATCH), i);
case 0: return;
case 1: }
case 2: }
case 3: else {
SERIAL_ERRORLNPGM(MSG_ERR_STOPPED); gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
LCD_MESSAGEPGM(MSG_STOPPED); return;
break;
} }
}
}
#if DISABLED(EMERGENCY_PARSER) gcode_LastN = gcode_N;
// 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 // Movement commands alert when stopped
_enqueuecommand(serial_line_buffer, true); if (IsStopped()) {
} char* gpos = strchr(command, 'G');
else if (serial_count >= MAX_CMD_SIZE - 1) { if (gpos) {
// Keep fetching, but ignore normal characters beyond the max length const int codenum = strtol(gpos + 1, NULL, 10);
// The command will be injected when EOL is reached switch (codenum) {
} case 0:
else if (serial_char == '\\') { // Handle escapes case 1:
// if we have one more character, copy it over case 2:
if ((c = MYSERIAL.read()) >= 0 && !serial_comment_mode) case 3:
serial_line_buffer[serial_count++] = serial_char; SERIAL_ERRORLNPGM_P(i, MSG_ERR_STOPPED);
} LCD_MESSAGEPGM(MSG_STOPPED);
else { // it's not a newline, carriage return or escape char break;
if (serial_char == ';') serial_comment_mode = true; }
if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char; }
} }
#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 } // queue has space, serial has data
} }

@ -51,6 +51,13 @@ extern uint8_t commands_in_queue, // Count of commands in the queue
extern char command_queue[BUFSIZE][MAX_CMD_SIZE]; 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() * Initialization of queue for setup()
*/ */

@ -34,13 +34,25 @@
#include "../queue.h" #include "../queue.h"
#endif #endif
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
/** /**
* M20: List SD card to serial output * M20: List SD card to serial output
*/ */
void GcodeSuite::M20() { void GcodeSuite::M20() {
SERIAL_PROTOCOLLNPGM(MSG_BEGIN_FILE_LIST); #if NUM_SERIAL > 1
card.ls(); const int16_t port = command_queue_port[cmd_queue_index_r];
SERIAL_PROTOCOLLNPGM(MSG_END_FILE_LIST); #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 * 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 * M28: Start SD Write
@ -164,7 +182,11 @@ void GcodeSuite::M32() {
* /Miscellaneous/Armchair/Armchair.gcode * /Miscellaneous/Armchair/Armchair.gcode
*/ */
void GcodeSuite::M33() { 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 #endif // LONG_FILENAME_HOST_SUPPORT

@ -26,15 +26,22 @@
#include "../../libs/duration_t.h" #include "../../libs/duration_t.h"
#include "../../lcd/ultralcd.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) * M31: Get the time since the start of SD Print (or last M109)
*/ */
void GcodeSuite::M31() { void GcodeSuite::M31() {
#if NUM_SERIAL > 1
const int16_t port = command_queue_port[cmd_queue_index_r];
#endif
char buffer[21]; char buffer[21];
duration_t elapsed = print_job_timer.duration(); duration_t elapsed = print_job_timer.duration();
elapsed.toString(buffer); elapsed.toString(buffer);
lcd_setstatus(buffer); lcd_setstatus(buffer);
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOLNPAIR("Print time: ", buffer); SERIAL_ECHOLNPAIR_P(port, "Print time: ", buffer);
} }

@ -23,19 +23,31 @@
#include "../gcode.h" #include "../gcode.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
/** /**
* M105: Read hot end and bed temperature * M105: Read hot end and bed temperature
*/ */
void GcodeSuite::M105() { void GcodeSuite::M105() {
if (get_target_extruder_from_command()) return; 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 #if HAS_TEMP_HOTEND || HAS_TEMP_BED
SERIAL_PROTOCOLPGM(MSG_OK); SERIAL_PROTOCOLPGM_P(port, MSG_OK);
thermalManager.print_heaterstates(); thermalManager.print_heaterstates(
#if NUM_SERIAL > 1
port
#endif
);
#else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED
SERIAL_ERROR_START(); SERIAL_ERROR_START_P(port);
SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); SERIAL_ERRORLNPGM_P(port, MSG_ERR_NO_THERMISTORS);
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
} }

@ -494,10 +494,4 @@
#define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER)) #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)) #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 #endif // CONDITIONALS_LCD_H

@ -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_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(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_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) #if ENABLED(DEBUG_EEPROM_READWRITE)
#define _FIELD_TEST(FIELD) \ #define _FIELD_TEST(FIELD) \
@ -338,10 +338,16 @@ void MarlinSettings::postprocess() {
bool MarlinSettings::eeprom_error, MarlinSettings::validating; 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()) { if (size != datasize()) {
SERIAL_ERROR_START(); #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ERRORLNPGM("EEPROM datasize error."); SERIAL_ERROR_START_P(port);
SERIAL_ERRORLNPGM_P(port, "EEPROM datasize error.");
#endif
return true; return true;
} }
return false; return false;
@ -350,7 +356,11 @@ void MarlinSettings::postprocess() {
/** /**
* M500 - Store Configuration * M500 - Store Configuration
*/ */
bool MarlinSettings::save() { bool MarlinSettings::save(
#if ADD_PORT_ARG
const int8_t port/*=-1*/
#endif
) {
float dummy = 0.0f; float dummy = 0.0f;
char ver[4] = "ERR"; char ver[4] = "ERR";
@ -810,10 +820,10 @@ void MarlinSettings::postprocess() {
// Report storage size // Report storage size
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOPAIR("Settings Stored (", eeprom_size); SERIAL_ECHOPAIR_P(port, "Settings Stored (", eeprom_size);
SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)final_crc); SERIAL_ECHOPAIR_P(port, " bytes; crc ", (uint32_t)final_crc);
SERIAL_ECHOLNPGM(")"); SERIAL_ECHOLNPGM_P(port, ")");
#endif #endif
eeprom_error |= size_error(eeprom_size); eeprom_error |= size_error(eeprom_size);
@ -834,7 +844,11 @@ void MarlinSettings::postprocess() {
/** /**
* M501 - Retrieve Configuration * M501 - Retrieve Configuration
*/ */
bool MarlinSettings::_load() { bool MarlinSettings::_load(
#if ADD_PORT_ARG
const int8_t port/*=-1*/
#endif
) {
uint16_t working_crc = 0; uint16_t working_crc = 0;
EEPROM_START(); EEPROM_START();
@ -852,10 +866,10 @@ void MarlinSettings::postprocess() {
stored_ver[1] = '\0'; stored_ver[1] = '\0';
} }
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOPGM("EEPROM version mismatch "); SERIAL_ECHOPGM_P(port, "EEPROM version mismatch ");
SERIAL_ECHOPAIR("(EEPROM=", stored_ver); SERIAL_ECHOPAIR_P(port, "(EEPROM=", stored_ver);
SERIAL_ECHOLNPGM(" Marlin=" EEPROM_VERSION ")"); SERIAL_ECHOLNPGM_P(port, " Marlin=" EEPROM_VERSION ")");
#endif #endif
if (!validating) reset(); if (!validating) reset();
eeprom_error = true; eeprom_error = true;
@ -1334,28 +1348,28 @@ void MarlinSettings::postprocess() {
eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET)); eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
if (eeprom_error) { if (eeprom_error) {
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOPAIR("Index: ", int(eeprom_index - (EEPROM_OFFSET))); SERIAL_ECHOPAIR_P(port, "Index: ", int(eeprom_index - (EEPROM_OFFSET)));
SERIAL_ECHOLNPAIR(" Size: ", datasize()); SERIAL_ECHOLNPAIR_P(port, " Size: ", datasize());
} }
else if (working_crc != stored_crc) { else if (working_crc != stored_crc) {
eeprom_error = true; eeprom_error = true;
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ERROR_START(); SERIAL_ERROR_START_P(port);
SERIAL_ERRORPGM("EEPROM CRC mismatch - (stored) "); SERIAL_ERRORPGM_P(port, "EEPROM CRC mismatch - (stored) ");
SERIAL_ERROR(stored_crc); SERIAL_ERROR_P(port, stored_crc);
SERIAL_ERRORPGM(" != "); SERIAL_ERRORPGM_P(port, " != ");
SERIAL_ERROR(working_crc); SERIAL_ERROR_P(port, working_crc);
SERIAL_ERRORLNPGM(" (calculated)!"); SERIAL_ERRORLNPGM_P(port, " (calculated)!");
#endif #endif
} }
else if (!validating) { else if (!validating) {
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHO(version); SERIAL_ECHO_P(port, version);
SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET)); SERIAL_ECHOPAIR_P(port, " stored settings retrieved (", eeprom_index - (EEPROM_OFFSET));
SERIAL_ECHOPAIR(" bytes; crc ", (uint32_t)working_crc); SERIAL_ECHOPAIR_P(port, " bytes; crc ", (uint32_t)working_crc);
SERIAL_ECHOLNPGM(")"); SERIAL_ECHOLNPGM_P(port, ")");
#endif #endif
} }
@ -1368,18 +1382,18 @@ void MarlinSettings::postprocess() {
if (!validating) { if (!validating) {
if (!ubl.sanity_check()) { if (!ubl.sanity_check()) {
SERIAL_EOL(); SERIAL_EOL_P(port);
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
ubl.echo_name(); ubl.echo_name();
SERIAL_ECHOLNPGM(" initialized.\n"); SERIAL_ECHOLNPGM_P(port, " initialized.\n");
#endif #endif
} }
else { else {
eeprom_error = true; eeprom_error = true;
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_PROTOCOLPGM("?Can't enable "); SERIAL_PROTOCOLPGM_P(port, "?Can't enable ");
ubl.echo_name(); ubl.echo_name();
SERIAL_PROTOCOLLNPGM("."); SERIAL_PROTOCOLLNPGM_P(port, ".");
#endif #endif
ubl.reset(); ubl.reset();
} }
@ -1387,14 +1401,14 @@ void MarlinSettings::postprocess() {
if (ubl.storage_slot >= 0) { if (ubl.storage_slot >= 0) {
load_mesh(ubl.storage_slot); load_mesh(ubl.storage_slot);
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHOPAIR("Mesh ", ubl.storage_slot); SERIAL_ECHOPAIR_P(port, "Mesh ", ubl.storage_slot);
SERIAL_ECHOLNPGM(" loaded from storage."); SERIAL_ECHOLNPGM_P(port, " loaded from storage.");
#endif #endif
} }
else { else {
ubl.reset(); ubl.reset();
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHOLNPGM("UBL System reset()"); SERIAL_ECHOLNPGM_P(port, "UBL System reset()");
#endif #endif
} }
} }
@ -1402,22 +1416,42 @@ void MarlinSettings::postprocess() {
} }
#if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503) #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503)
if (!validating) report(); if (!validating) report(
#if NUM_SERIAL > 1
port
#endif
);
#endif #endif
EEPROM_FINISH(); EEPROM_FINISH();
return !eeprom_error; return !eeprom_error;
} }
bool MarlinSettings::validate() { bool MarlinSettings::validate(
#if NUM_SERIAL > 1
const int8_t port/*=-1*/
#endif
) {
validating = true; validating = true;
const bool success = _load(); const bool success = _load(
#if NUM_SERIAL > 1
port
#endif
);
validating = false; validating = false;
return success; return success;
} }
bool MarlinSettings::load() { bool MarlinSettings::load(
if (validate()) return _load(); #if ADD_PORT_ARG
const int8_t port/*=-1*/
#endif
) {
if (validate()) return _load(
#if ADD_PORT_ARG
port
#endif
);
reset(); reset();
return true; return true;
} }
@ -1524,9 +1558,15 @@ void MarlinSettings::postprocess() {
#else // !EEPROM_SETTINGS #else // !EEPROM_SETTINGS
bool MarlinSettings::save() { bool MarlinSettings::save(
SERIAL_ERROR_START(); #if ADD_PORT_ARG
SERIAL_ERRORLNPGM("EEPROM disabled"); const int8_t port/*=-1*/
#endif
) {
#if ENABLED(EEPROM_CHITCHAT)
SERIAL_ERROR_START_P(port);
SERIAL_ERRORLNPGM_P(port, "EEPROM disabled");
#endif
return false; return false;
} }
@ -1535,7 +1575,11 @@ void MarlinSettings::postprocess() {
/** /**
* M502 - Reset Configuration * 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 float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE;
static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION; static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) { LOOP_XYZE_N(i) {
@ -1775,22 +1819,25 @@ void MarlinSettings::reset() {
postprocess(); postprocess();
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); SERIAL_ECHOLNPGM_P(port, "Hardcoded Default Settings Loaded");
#endif #endif
} }
#if DISABLED(DISABLE_M503) #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 * M503 - Report current settings in RAM
* *
* Unless specifically disabled, M503 is available even without EEPROM * 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 * Announce current units, in case inches are being displayed
*/ */
@ -1798,14 +1845,14 @@ void MarlinSettings::reset() {
#if ENABLED(INCH_MODE_SUPPORT) #if ENABLED(INCH_MODE_SUPPORT)
#define LINEAR_UNIT(N) (float(N) / parser.linear_unit_factor) #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)) #define VOLUMETRIC_UNIT(N) (float(N) / (parser.volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor))
SERIAL_ECHOPGM(" G2"); SERIAL_ECHOPGM_P(port, " G2");
SERIAL_CHAR(parser.linear_unit_factor == 1.0 ? '1' : '0'); SERIAL_CHAR_P(port, parser.linear_unit_factor == 1.0 ? '1' : '0');
SERIAL_ECHOPGM(" ; Units in "); SERIAL_ECHOPGM_P(port, " ; Units in ");
serialprintPGM(parser.linear_unit_factor == 1.0 ? PSTR("mm\n") : PSTR("inches\n")); serialprintPGM(parser.linear_unit_factor == 1.0 ? PSTR("mm\n") : PSTR("inches\n"));
#else #else
#define LINEAR_UNIT(N) (N) #define LINEAR_UNIT(N) (N)
#define VOLUMETRIC_UNIT(N) (N) #define VOLUMETRIC_UNIT(N) (N)
SERIAL_ECHOLNPGM(" G21 ; Units in mm"); SERIAL_ECHOLNPGM_P(port, " G21 ; Units in mm");
#endif #endif
#if ENABLED(ULTIPANEL) #if ENABLED(ULTIPANEL)
@ -1815,18 +1862,18 @@ void MarlinSettings::reset() {
CONFIG_ECHO_START; CONFIG_ECHO_START;
#if ENABLED(TEMPERATURE_UNITS_SUPPORT) #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
#define TEMP_UNIT(N) parser.to_temp_units(N) #define TEMP_UNIT(N) parser.to_temp_units(N)
SERIAL_ECHOPGM(" M149 "); SERIAL_ECHOPGM_P(port, " M149 ");
SERIAL_CHAR(parser.temp_units_code()); SERIAL_CHAR_P(port, parser.temp_units_code());
SERIAL_ECHOPGM(" ; Units in "); SERIAL_ECHOPGM_P(port, " ; Units in ");
serialprintPGM(parser.temp_units_name()); serialprintPGM_P(port, parser.temp_units_name());
#else #else
#define TEMP_UNIT(N) (N) #define TEMP_UNIT(N) (N)
SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius"); SERIAL_ECHOLNPGM_P(port, " M149 C ; Units in Celsius");
#endif #endif
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#if DISABLED(NO_VOLUMETRICS) #if DISABLED(NO_VOLUMETRICS)
@ -1835,32 +1882,32 @@ void MarlinSettings::reset() {
*/ */
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPGM("Filament settings:"); SERIAL_ECHOPGM_P(port, "Filament settings:");
if (parser.volumetric_enabled) if (parser.volumetric_enabled)
SERIAL_EOL(); SERIAL_EOL_P(port);
else else
SERIAL_ECHOLNPGM(" Disabled"); SERIAL_ECHOLNPGM_P(port, " Disabled");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M200 D", LINEAR_UNIT(planner.filament_size[0])); SERIAL_ECHOPAIR_P(port, " M200 D", LINEAR_UNIT(planner.filament_size[0]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#if EXTRUDERS > 1 #if EXTRUDERS > 1
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M200 T1 D", LINEAR_UNIT(planner.filament_size[1])); SERIAL_ECHOPAIR_P(port, " M200 T1 D", LINEAR_UNIT(planner.filament_size[1]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#if EXTRUDERS > 2 #if EXTRUDERS > 2
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M200 T2 D", LINEAR_UNIT(planner.filament_size[2])); SERIAL_ECHOPAIR_P(port, " M200 T2 D", LINEAR_UNIT(planner.filament_size[2]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#if EXTRUDERS > 3 #if EXTRUDERS > 3
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M200 T3 D", LINEAR_UNIT(planner.filament_size[3])); SERIAL_ECHOPAIR_P(port, " M200 T3 D", LINEAR_UNIT(planner.filament_size[3]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#if EXTRUDERS > 4 #if EXTRUDERS > 4
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M200 T4 D", LINEAR_UNIT(planner.filament_size[4])); SERIAL_ECHOPAIR_P(port, " M200 T4 D", LINEAR_UNIT(planner.filament_size[4]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif // EXTRUDERS > 4 #endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3 #endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2 #endif // EXTRUDERS > 2
@ -1868,118 +1915,118 @@ void MarlinSettings::reset() {
if (!parser.volumetric_enabled) { if (!parser.volumetric_enabled) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM(" M200 D0"); SERIAL_ECHOLNPGM_P(port, " M200 D0");
} }
#endif // !NO_VOLUMETRICS #endif // !NO_VOLUMETRICS
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Steps per unit:"); SERIAL_ECHOLNPGM_P(port, "Steps per unit:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS])); SERIAL_ECHOPAIR_P(port, " 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_P(port, " 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, " Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR(" M92 T", (int)i); SERIAL_ECHOPAIR_P(port, " M92 T", (int)i);
SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i]));
} }
#endif #endif
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Maximum feedrates (units/s):"); SERIAL_ECHOLNPGM_P(port, "Maximum feedrates (units/s):");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS])); SERIAL_ECHOPAIR_P(port, " 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_P(port, " 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, " Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR(" M203 T", (int)i); SERIAL_ECHOPAIR_P(port, " M203 T", (int)i);
SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i]));
} }
#endif #endif
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Maximum Acceleration (units/s2):"); SERIAL_ECHOLNPGM_P(port, "Maximum Acceleration (units/s2):");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS])); SERIAL_ECHOPAIR_P(port, " 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_P(port, " 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, " Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR(" M201 T", (int)i); SERIAL_ECHOPAIR_P(port, " M201 T", (int)i);
SERIAL_ECHOLNPAIR(" E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i]));
} }
#endif #endif
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Acceleration (units/s2): P<print_accel> R<retract_accel> T<travel_accel>"); SERIAL_ECHOLNPGM_P(port, "Acceleration (units/s2): P<print_accel> R<retract_accel> T<travel_accel>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M204 P", LINEAR_UNIT(planner.acceleration)); SERIAL_ECHOPAIR_P(port, " M204 P", LINEAR_UNIT(planner.acceleration));
SERIAL_ECHOPAIR(" R", LINEAR_UNIT(planner.retract_acceleration)); SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(planner.retract_acceleration));
SERIAL_ECHOLNPAIR(" T", LINEAR_UNIT(planner.travel_acceleration)); SERIAL_ECHOLNPAIR_P(port, " T", LINEAR_UNIT(planner.travel_acceleration));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Advanced: S<min_feedrate> T<min_travel_feedrate> B<min_segment_time_us> X<max_xy_jerk> Z<max_z_jerk> E<max_e_jerk>"); SERIAL_ECHOLNPGM_P(port, "Advanced: S<min_feedrate> T<min_travel_feedrate> B<min_segment_time_us> X<max_xy_jerk> Z<max_z_jerk> E<max_e_jerk>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s)); SERIAL_ECHOPAIR_P(port, " M205 S", LINEAR_UNIT(planner.min_feedrate_mm_s));
SERIAL_ECHOPAIR(" T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); SERIAL_ECHOPAIR_P(port, " T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s));
SERIAL_ECHOPAIR(" B", planner.min_segment_time_us); SERIAL_ECHOPAIR_P(port, " B", planner.min_segment_time_us);
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(planner.max_jerk[X_AXIS])); SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS])); SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
SERIAL_ECHOLNPAIR(" E", LINEAR_UNIT(planner.max_jerk[E_AXIS])); SERIAL_ECHOLNPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
#if HAS_M206_COMMAND #if HAS_M206_COMMAND
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Home offset:"); SERIAL_ECHOLNPGM_P(port, "Home offset:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M206 X", LINEAR_UNIT(home_offset[X_AXIS])); SERIAL_ECHOPAIR_P(port, " M206 X", LINEAR_UNIT(home_offset[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(home_offset[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(home_offset[Y_AXIS]));
SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(home_offset[Z_AXIS])); SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(home_offset[Z_AXIS]));
#endif #endif
#if HOTENDS > 1 #if HOTENDS > 1
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Hotend offsets:"); SERIAL_ECHOLNPGM_P(port, "Hotend offsets:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t e = 1; e < HOTENDS; e++) { for (uint8_t e = 1; e < HOTENDS; e++) {
SERIAL_ECHOPAIR(" M218 T", (int)e); SERIAL_ECHOPAIR_P(port, " M218 T", (int)e);
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(hotend_offset[X_AXIS][e])); SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(hotend_offset[X_AXIS][e]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(hotend_offset[Y_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) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
#endif #endif
@ -1992,7 +2039,7 @@ void MarlinSettings::reset() {
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Mesh Bed Leveling:"); SERIAL_ECHOLNPGM_P(port, "Mesh Bed Leveling:");
} }
#elif ENABLED(AUTO_BED_LEVELING_UBL) #elif ENABLED(AUTO_BED_LEVELING_UBL)
@ -2000,46 +2047,46 @@ void MarlinSettings::reset() {
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
ubl.echo_name(); ubl.echo_name();
SERIAL_ECHOLNPGM(":"); SERIAL_ECHOLNPGM_P(port, ":");
} }
#elif HAS_ABL #elif HAS_ABL
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Auto Bed Leveling:"); SERIAL_ECHOLNPGM_P(port, "Auto Bed Leveling:");
} }
#endif #endif
CONFIG_ECHO_START; 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) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#if ENABLED(MESH_BED_LEVELING) #if ENABLED(MESH_BED_LEVELING)
for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) { for (uint8_t py = 0; py < GRID_MAX_POINTS_Y; py++) {
for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) { for (uint8_t px = 0; px < GRID_MAX_POINTS_X; px++) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" G29 S3 X", (int)px + 1); SERIAL_ECHOPAIR_P(port, " G29 S3 X", (int)px + 1);
SERIAL_ECHOPAIR(" Y", (int)py + 1); SERIAL_ECHOPAIR_P(port, " Y", (int)py + 1);
SERIAL_ECHOPGM(" Z"); SERIAL_ECHOPGM_P(port, " Z");
SERIAL_PROTOCOL_F(LINEAR_UNIT(mbl.z_values[px][py]), 5); SERIAL_PROTOCOL_F_P(port, LINEAR_UNIT(mbl.z_values[px][py]), 5);
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
} }
#elif ENABLED(AUTO_BED_LEVELING_UBL) #elif ENABLED(AUTO_BED_LEVELING_UBL)
if (!forReplay) { if (!forReplay) {
SERIAL_EOL(); SERIAL_EOL_P(port);
ubl.report_state(); ubl.report_state();
SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.storage_slot); SERIAL_ECHOLNPAIR_P(port, "\nActive Mesh Slot: ", ubl.storage_slot);
SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes()); SERIAL_ECHOPAIR_P(port, "EEPROM can hold ", calc_num_meshes());
SERIAL_ECHOLNPGM(" meshes.\n"); SERIAL_ECHOLNPGM_P(port, " meshes.\n");
} }
#endif #endif
@ -2047,59 +2094,62 @@ void MarlinSettings::reset() {
#endif // HAS_LEVELING #endif // HAS_LEVELING
#if ENABLED(DELTA) #if ENABLED(DELTA)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Endstop adjustment:"); SERIAL_ECHOLNPGM_P(port, "Endstop adjustment:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M666 X", LINEAR_UNIT(delta_endstop_adj[X_AXIS])); SERIAL_ECHOPAIR_P(port, " M666 X", LINEAR_UNIT(delta_endstop_adj[X_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_endstop_adj[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(delta_endstop_adj[Y_AXIS]));
SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(delta_endstop_adj[Z_AXIS])); SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(delta_endstop_adj[Z_AXIS]));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Delta settings: L<diagonal_rod> R<radius> H<height> S<segments_per_s> B<calibration radius> XYZ<tower angle corrections>"); SERIAL_ECHOLNPGM_P(port, "Delta settings: L<diagonal_rod> R<radius> H<height> S<segments_per_s> B<calibration radius> XYZ<tower angle corrections>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M665 L", LINEAR_UNIT(delta_diagonal_rod)); SERIAL_ECHOPAIR_P(port, " M665 L", LINEAR_UNIT(delta_diagonal_rod));
SERIAL_ECHOPAIR(" R", LINEAR_UNIT(delta_radius)); SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(delta_radius));
SERIAL_ECHOPAIR(" H", LINEAR_UNIT(delta_height)); SERIAL_ECHOPAIR_P(port, " H", LINEAR_UNIT(delta_height));
SERIAL_ECHOPAIR(" S", delta_segments_per_second); SERIAL_ECHOPAIR_P(port, " S", delta_segments_per_second);
SERIAL_ECHOPAIR(" B", LINEAR_UNIT(delta_calibration_radius)); SERIAL_ECHOPAIR_P(port, " B", LINEAR_UNIT(delta_calibration_radius));
SERIAL_ECHOPAIR(" X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS])); SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(delta_tower_angle_trim[A_AXIS]));
SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS]));
SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS]));
SERIAL_EOL(); SERIAL_EOL_P(port);
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Endstop adjustment:"); SERIAL_ECHOLNPGM_P(port, "Endstop adjustment:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPGM(" M666"); SERIAL_ECHOPGM_P(port, " M666");
#if ENABLED(X_DUAL_ENDSTOPS) #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 #endif
#if ENABLED(Y_DUAL_ENDSTOPS) #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 #endif
#if ENABLED(Z_DUAL_ENDSTOPS) #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 #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif // DELTA
#endif // [XYZ]_DUAL_ENDSTOPS
#if ENABLED(ULTIPANEL) #if ENABLED(ULTIPANEL)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; 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++) { for (uint8_t i = 0; i < COUNT(lcd_preheat_hotend_temp); i++) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M145 S", (int)i); SERIAL_ECHOPAIR_P(port, " M145 S", (int)i);
SERIAL_ECHOPAIR(" H", TEMP_UNIT(lcd_preheat_hotend_temp[i])); SERIAL_ECHOPAIR_P(port, " H", TEMP_UNIT(lcd_preheat_hotend_temp[i]));
SERIAL_ECHOPAIR(" B", TEMP_UNIT(lcd_preheat_bed_temp[i])); SERIAL_ECHOPAIR_P(port, " B", TEMP_UNIT(lcd_preheat_bed_temp[i]));
SERIAL_ECHOLNPAIR(" F", lcd_preheat_fan_speed[i]); SERIAL_ECHOLNPAIR_P(port, " F", lcd_preheat_fan_speed[i]);
} }
#endif // ULTIPANEL #endif // ULTIPANEL
@ -2107,22 +2157,22 @@ void MarlinSettings::reset() {
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("PID settings:"); SERIAL_ECHOLNPGM_P(port, "PID settings:");
} }
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
#if HOTENDS > 1 #if HOTENDS > 1
if (forReplay) { if (forReplay) {
HOTEND_LOOP() { HOTEND_LOOP() {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M301 E", e); SERIAL_ECHOPAIR_P(port, " M301 E", e);
SERIAL_ECHOPAIR(" P", PID_PARAM(Kp, e)); SERIAL_ECHOPAIR_P(port, " P", PID_PARAM(Kp, e));
SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, e))); SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(PID_PARAM(Ki, e)));
SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, e))); SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(PID_PARAM(Kd, e)));
#if ENABLED(PID_EXTRUSION_SCALING) #if ENABLED(PID_EXTRUSION_SCALING)
SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, e)); SERIAL_ECHOPAIR_P(port, " C", PID_PARAM(Kc, e));
if (e == 0) SERIAL_ECHOPAIR(" L", lpq_len); if (e == 0) SERIAL_ECHOPAIR_P(port, " L", lpq_len);
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
} }
else else
@ -2130,23 +2180,23 @@ void MarlinSettings::reset() {
// !forReplay || HOTENDS == 1 // !forReplay || HOTENDS == 1
{ {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echo values for E0 SERIAL_ECHOPAIR_P(port, " 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_P(port, " I", unscalePID_i(PID_PARAM(Ki, 0)));
SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0))); SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(PID_PARAM(Kd, 0)));
#if ENABLED(PID_EXTRUSION_SCALING) #if ENABLED(PID_EXTRUSION_SCALING)
SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, 0)); SERIAL_ECHOPAIR_P(port, " C", PID_PARAM(Kc, 0));
SERIAL_ECHOPAIR(" L", lpq_len); SERIAL_ECHOPAIR_P(port, " L", lpq_len);
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
#endif // PIDTEMP #endif // PIDTEMP
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M304 P", thermalManager.bedKp); SERIAL_ECHOPAIR_P(port, " M304 P", thermalManager.bedKp);
SERIAL_ECHOPAIR(" I", unscalePID_i(thermalManager.bedKi)); SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(thermalManager.bedKi));
SERIAL_ECHOPAIR(" D", unscalePID_d(thermalManager.bedKd)); SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(thermalManager.bedKd));
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif #endif
#endif // PIDTEMP || PIDTEMPBED #endif // PIDTEMP || PIDTEMPBED
@ -2154,39 +2204,39 @@ void MarlinSettings::reset() {
#if HAS_LCD_CONTRAST #if HAS_LCD_CONTRAST
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("LCD Contrast:"); SERIAL_ECHOLNPGM_P(port, "LCD Contrast:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPAIR(" M250 C", lcd_contrast); SERIAL_ECHOLNPAIR_P(port, " M250 C", lcd_contrast);
#endif #endif
#if ENABLED(FWRETRACT) #if ENABLED(FWRETRACT)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Retract: S<length> F<units/m> Z<lift>"); SERIAL_ECHOLNPGM_P(port, "Retract: S<length> F<units/m> Z<lift>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M207 S", LINEAR_UNIT(fwretract.retract_length)); SERIAL_ECHOPAIR_P(port, " M207 S", LINEAR_UNIT(fwretract.retract_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_length)); SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_length));
SERIAL_ECHOPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s))); SERIAL_ECHOPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s)));
SERIAL_ECHOLNPAIR(" Z", LINEAR_UNIT(fwretract.retract_zlift)); SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(fwretract.retract_zlift));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Recover: S<length> F<units/m>"); SERIAL_ECHOLNPGM_P(port, "Recover: S<length> F<units/m>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M208 S", LINEAR_UNIT(fwretract.retract_recover_length)); SERIAL_ECHOPAIR_P(port, " M208 S", LINEAR_UNIT(fwretract.retract_recover_length));
SERIAL_ECHOPAIR(" W", LINEAR_UNIT(fwretract.swap_retract_recover_length)); SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_recover_length));
SERIAL_ECHOLNPAIR(" F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s))); SERIAL_ECHOLNPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s)));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; 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; 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 #endif // FWRETRACT
@ -2196,10 +2246,10 @@ void MarlinSettings::reset() {
#if HAS_BED_PROBE #if HAS_BED_PROBE
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Z-Probe Offset (mm):"); SERIAL_ECHOLNPGM_P(port, "Z-Probe Offset (mm):");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPAIR(" M851 Z", LINEAR_UNIT(zprobe_zoffset)); SERIAL_ECHOLNPAIR_P(port, " M851 Z", LINEAR_UNIT(zprobe_zoffset));
#endif #endif
/** /**
@ -2208,18 +2258,18 @@ void MarlinSettings::reset() {
#if ENABLED(SKEW_CORRECTION_GCODE) #if ENABLED(SKEW_CORRECTION_GCODE)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Skew Factor: "); SERIAL_ECHOLNPGM_P(port, "Skew Factor: ");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
#if ENABLED(SKEW_CORRECTION_FOR_Z) #if ENABLED(SKEW_CORRECTION_FOR_Z)
SERIAL_ECHO(" M852 I"); SERIAL_ECHO_P(port, " M852 I");
SERIAL_ECHO_F(LINEAR_UNIT(planner.xy_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6);
SERIAL_ECHOPAIR(" J", LINEAR_UNIT(planner.xz_skew_factor)); SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.xz_skew_factor));
SERIAL_ECHOLNPAIR(" K", LINEAR_UNIT(planner.yz_skew_factor)); SERIAL_ECHOLNPAIR_P(port, " K", LINEAR_UNIT(planner.yz_skew_factor));
#else #else
SERIAL_ECHO(" M852 S"); SERIAL_ECHO_P(port, " M852 S");
SERIAL_ECHO_F(LINEAR_UNIT(planner.xy_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6);
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif #endif
#endif #endif
@ -2229,44 +2279,44 @@ void MarlinSettings::reset() {
#if HAS_TRINAMIC #if HAS_TRINAMIC
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Stepper driver current:"); SERIAL_ECHOLNPGM_P(port, "Stepper driver current:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHO(" M906"); SERIAL_ECHO_P(port, " M906");
#if ENABLED(X_IS_TMC2130) || ENABLED(X_IS_TMC2208) #if ENABLED(X_IS_TMC2130) || ENABLED(X_IS_TMC2208)
SERIAL_ECHOPAIR(" X ", stepperX.getCurrent()); SERIAL_ECHOPAIR_P(port, " X ", stepperX.getCurrent());
#endif #endif
#if ENABLED(Y_IS_TMC2130) || ENABLED(Y_IS_TMC2208) #if ENABLED(Y_IS_TMC2130) || ENABLED(Y_IS_TMC2208)
SERIAL_ECHOPAIR(" Y ", stepperY.getCurrent()); SERIAL_ECHOPAIR_P(port, " Y ", stepperY.getCurrent());
#endif #endif
#if ENABLED(Z_IS_TMC2130) || ENABLED(Z_IS_TMC2208) #if ENABLED(Z_IS_TMC2130) || ENABLED(Z_IS_TMC2208)
SERIAL_ECHOPAIR(" Z ", stepperZ.getCurrent()); SERIAL_ECHOPAIR_P(port, " Z ", stepperZ.getCurrent());
#endif #endif
#if ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208) #if ENABLED(X2_IS_TMC2130) || ENABLED(X2_IS_TMC2208)
SERIAL_ECHOPAIR(" X2 ", stepperX2.getCurrent()); SERIAL_ECHOPAIR_P(port, " X2 ", stepperX2.getCurrent());
#endif #endif
#if ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208) #if ENABLED(Y2_IS_TMC2130) || ENABLED(Y2_IS_TMC2208)
SERIAL_ECHOPAIR(" Y2 ", stepperY2.getCurrent()); SERIAL_ECHOPAIR_P(port, " Y2 ", stepperY2.getCurrent());
#endif #endif
#if ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208) #if ENABLED(Z2_IS_TMC2130) || ENABLED(Z2_IS_TMC2208)
SERIAL_ECHOPAIR(" Z2 ", stepperZ2.getCurrent()); SERIAL_ECHOPAIR_P(port, " Z2 ", stepperZ2.getCurrent());
#endif #endif
#if ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208) #if ENABLED(E0_IS_TMC2130) || ENABLED(E0_IS_TMC2208)
SERIAL_ECHOPAIR(" E0 ", stepperE0.getCurrent()); SERIAL_ECHOPAIR_P(port, " E0 ", stepperE0.getCurrent());
#endif #endif
#if ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208) #if ENABLED(E1_IS_TMC2130) || ENABLED(E1_IS_TMC2208)
SERIAL_ECHOPAIR(" E1 ", stepperE1.getCurrent()); SERIAL_ECHOPAIR_P(port, " E1 ", stepperE1.getCurrent());
#endif #endif
#if ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208) #if ENABLED(E2_IS_TMC2130) || ENABLED(E2_IS_TMC2208)
SERIAL_ECHOPAIR(" E2 ", stepperE2.getCurrent()); SERIAL_ECHOPAIR_P(port, " E2 ", stepperE2.getCurrent());
#endif #endif
#if ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208) #if ENABLED(E3_IS_TMC2130) || ENABLED(E3_IS_TMC2208)
SERIAL_ECHOPAIR(" E3 ", stepperE3.getCurrent()); SERIAL_ECHOPAIR_P(port, " E3 ", stepperE3.getCurrent());
#endif #endif
#if ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208) #if ENABLED(E4_IS_TMC2130) || ENABLED(E4_IS_TMC2208)
SERIAL_ECHOPAIR(" E4 ", stepperE4.getCurrent()); SERIAL_ECHOPAIR_P(port, " E4 ", stepperE4.getCurrent());
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif #endif
/** /**
@ -2275,23 +2325,23 @@ void MarlinSettings::reset() {
#if ENABLED(SENSORLESS_HOMING) #if ENABLED(SENSORLESS_HOMING)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Sensorless homing threshold:"); SERIAL_ECHOLNPGM_P(port, "Sensorless homing threshold:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHO(" M914"); SERIAL_ECHO_P(port, " M914");
#if ENABLED(X_IS_TMC2130) #if ENABLED(X_IS_TMC2130)
SERIAL_ECHOPAIR(" X", stepperX.sgt()); SERIAL_ECHOPAIR_P(port, " X", stepperX.sgt());
#endif #endif
#if ENABLED(X2_IS_TMC2130) #if ENABLED(X2_IS_TMC2130)
SERIAL_ECHOPAIR(" X2 ", stepperX2.sgt()); SERIAL_ECHOPAIR_P(port, " X2 ", stepperX2.sgt());
#endif #endif
#if ENABLED(Y_IS_TMC2130) #if ENABLED(Y_IS_TMC2130)
SERIAL_ECHOPAIR(" Y", stepperY.sgt()); SERIAL_ECHOPAIR_P(port, " Y", stepperY.sgt());
#endif #endif
#if ENABLED(X2_IS_TMC2130) #if ENABLED(X2_IS_TMC2130)
SERIAL_ECHOPAIR(" Y2 ", stepperY2.sgt()); SERIAL_ECHOPAIR_P(port, " Y2 ", stepperY2.sgt());
#endif #endif
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif #endif
/** /**
@ -2300,23 +2350,23 @@ void MarlinSettings::reset() {
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Linear Advance:"); SERIAL_ECHOLNPGM_P(port, "Linear Advance:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M900 K", planner.extruder_advance_k); SERIAL_ECHOPAIR_P(port, " M900 K", planner.extruder_advance_k);
SERIAL_ECHOLNPAIR(" R", planner.advance_ed_ratio); SERIAL_ECHOLNPAIR_P(port, " R", planner.advance_ed_ratio);
#endif #endif
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM
CONFIG_ECHO_START; CONFIG_ECHO_START;
if (!forReplay) { if (!forReplay) {
SERIAL_ECHOLNPGM("Stepper motor currents:"); SERIAL_ECHOLNPGM_P(port, "Stepper motor currents:");
CONFIG_ECHO_START; CONFIG_ECHO_START;
} }
SERIAL_ECHOPAIR(" M907 X", stepper.motor_current_setting[0]); SERIAL_ECHOPAIR_P(port, " M907 X", stepper.motor_current_setting[0]);
SERIAL_ECHOPAIR(" Z", stepper.motor_current_setting[1]); SERIAL_ECHOPAIR_P(port, " Z", stepper.motor_current_setting[1]);
SERIAL_ECHOPAIR(" E", stepper.motor_current_setting[2]); SERIAL_ECHOPAIR_P(port, " E", stepper.motor_current_setting[2]);
SERIAL_EOL(); SERIAL_EOL_P(port);
#endif #endif
/** /**
@ -2325,30 +2375,30 @@ void MarlinSettings::reset() {
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM("Filament load/unload lengths:"); SERIAL_ECHOLNPGM_P(port, "Filament load/unload lengths:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
#if EXTRUDERS == 1 #if EXTRUDERS == 1
SERIAL_ECHOPAIR(" M603 L", LINEAR_UNIT(filament_change_load_length[0])); SERIAL_ECHOPAIR_P(port, " M603 L", LINEAR_UNIT(filament_change_load_length[0]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[0])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0]));
#else #else
SERIAL_ECHOPAIR(" M603 T0 L", LINEAR_UNIT(filament_change_load_length[0])); SERIAL_ECHOPAIR_P(port, " M603 T0 L", LINEAR_UNIT(filament_change_load_length[0]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[0])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0]));
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M603 T1 L", LINEAR_UNIT(filament_change_load_length[1])); SERIAL_ECHOPAIR_P(port, " M603 T1 L", LINEAR_UNIT(filament_change_load_length[1]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[1])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[1]));
#if EXTRUDERS > 2 #if EXTRUDERS > 2
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M603 T2 L", LINEAR_UNIT(filament_change_load_length[2])); SERIAL_ECHOPAIR_P(port, " M603 T2 L", LINEAR_UNIT(filament_change_load_length[2]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[2])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[2]));
#if EXTRUDERS > 3 #if EXTRUDERS > 3
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M603 T3 L", LINEAR_UNIT(filament_change_load_length[3])); SERIAL_ECHOPAIR_P(port, " M603 T3 L", LINEAR_UNIT(filament_change_load_length[3]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[3])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[3]));
#if EXTRUDERS > 4 #if EXTRUDERS > 4
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR(" M603 T4 L", LINEAR_UNIT(filament_change_load_length[4])); SERIAL_ECHOPAIR_P(port, " M603 T4 L", LINEAR_UNIT(filament_change_load_length[4]));
SERIAL_ECHOLNPAIR(" U", LINEAR_UNIT(filament_change_unload_length[4])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[4]));
#endif // EXTRUDERS > 4 #endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3 #endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2 #endif // EXTRUDERS > 2

@ -25,14 +25,24 @@
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfig.h"
#define ADD_PORT_ARG ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1
class MarlinSettings { class MarlinSettings {
public: public:
MarlinSettings() { } MarlinSettings() { }
static uint16_t datasize(); static uint16_t datasize();
static void reset(); static void reset(
static bool save(); // Return 'true' if data was saved #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() { FORCE_INLINE static bool init_eeprom() {
bool success = true; bool success = true;
@ -47,8 +57,16 @@ class MarlinSettings {
} }
#if ENABLED(EEPROM_SETTINGS) #if ENABLED(EEPROM_SETTINGS)
static bool load(); // Return 'true' if data was loaded ok static bool load(
static bool validate(); // Return 'true' if EEPROM data is ok #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 #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled // That can store is enabled
@ -67,7 +85,11 @@ class MarlinSettings {
#endif #endif
#if DISABLED(DISABLE_M503) #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 #else
FORCE_INLINE FORCE_INLINE
static void report(const bool forReplay=false) { UNUSED(forReplay); } static void report(const bool forReplay=false) { UNUSED(forReplay); }
@ -87,8 +109,16 @@ class MarlinSettings {
#endif #endif
static bool _load(); static bool _load(
static bool size_error(const uint16_t size); #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 #endif
}; };

@ -337,8 +337,8 @@ class Stepper {
} }
if (timer < 100) { // (20kHz - this should never happen) if (timer < 100) { // (20kHz - this should never happen)
timer = 100; timer = 100;
MYSERIAL.print(MSG_STEPPER_TOO_HIGH); SERIAL_ECHOPGM(MSG_STEPPER_TOO_HIGH);
MYSERIAL.println(step_rate); SERIAL_ECHOLN(step_rate);
} }
#endif #endif

@ -2121,18 +2121,21 @@ void Temperature::isr() {
#include "../gcode/gcode.h" #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) #if ENABLED(SHOW_TEMP_ADC_VALUES)
const float r, , const float r
#endif #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 #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1
UNUSED(e); UNUSED(e);
#endif #endif
SERIAL_PROTOCOLCHAR(' '); SERIAL_PROTOCOLCHAR_P(port, ' ');
SERIAL_PROTOCOLCHAR( SERIAL_PROTOCOLCHAR_P(port,
#if HAS_TEMP_BED && HAS_TEMP_HOTEND #if HAS_TEMP_BED && HAS_TEMP_HOTEND
e == -1 ? 'B' : 'T' e == -1 ? 'B' : 'T'
#elif HAS_TEMP_HOTEND #elif HAS_TEMP_HOTEND
@ -2142,23 +2145,30 @@ void Temperature::isr() {
#endif #endif
); );
#if HOTENDS > 1 #if HOTENDS > 1
if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); if (e >= 0) SERIAL_PROTOCOLCHAR_P(port, '0' + e);
#endif #endif
SERIAL_PROTOCOLCHAR(':'); SERIAL_PROTOCOLCHAR_P(port, ':');
SERIAL_PROTOCOL(c); SERIAL_PROTOCOL_P(port, c);
SERIAL_PROTOCOLPAIR(" /" , t); SERIAL_PROTOCOLPAIR_P(port, " /" , t);
#if ENABLED(SHOW_TEMP_ADC_VALUES) #if ENABLED(SHOW_TEMP_ADC_VALUES)
SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); SERIAL_PROTOCOLPAIR_P(port, " (", r / OVERSAMPLENR);
SERIAL_PROTOCOLCHAR(')'); SERIAL_PROTOCOLCHAR_P(port, ')');
#endif #endif
} }
void Temperature::print_heaterstates() { void Temperature::print_heaterstates(
#if NUM_SERIAL > 1
const int8_t port
#endif
) {
#if HAS_TEMP_HOTEND #if HAS_TEMP_HOTEND
print_heater_state(degHotend(gcode.target_extruder), degTargetHotend(gcode.target_extruder) print_heater_state(degHotend(gcode.target_extruder), degTargetHotend(gcode.target_extruder)
#if ENABLED(SHOW_TEMP_ADC_VALUES) #if ENABLED(SHOW_TEMP_ADC_VALUES)
, rawHotendTemp(gcode.target_extruder) , rawHotendTemp(gcode.target_extruder)
#endif #endif
#if NUM_SERIAL > 1
, port
#endif
); );
#endif #endif
#if HAS_TEMP_BED #if HAS_TEMP_BED
@ -2166,6 +2176,9 @@ void Temperature::isr() {
#if ENABLED(SHOW_TEMP_ADC_VALUES) #if ENABLED(SHOW_TEMP_ADC_VALUES)
, rawBedTemp() , rawBedTemp()
#endif #endif
#if NUM_SERIAL > 1
, port
#endif
, -1 // BED , -1 // BED
); );
#endif #endif
@ -2174,20 +2187,23 @@ void Temperature::isr() {
#if ENABLED(SHOW_TEMP_ADC_VALUES) #if ENABLED(SHOW_TEMP_ADC_VALUES)
, rawHotendTemp(e) , rawHotendTemp(e)
#endif #endif
#if NUM_SERIAL > 1
, port
#endif
, e , e
); );
#endif #endif
SERIAL_PROTOCOLPGM(" @:"); SERIAL_PROTOCOLPGM_P(port, " @:");
SERIAL_PROTOCOL(getHeaterPower(gcode.target_extruder)); SERIAL_PROTOCOL_P(port, getHeaterPower(gcode.target_extruder));
#if HAS_TEMP_BED #if HAS_TEMP_BED
SERIAL_PROTOCOLPGM(" B@:"); SERIAL_PROTOCOLPGM_P(port, " B@:");
SERIAL_PROTOCOL(getHeaterPower(-1)); SERIAL_PROTOCOL_P(port, getHeaterPower(-1));
#endif #endif
#if HOTENDS > 1 #if HOTENDS > 1
HOTEND_LOOP() { HOTEND_LOOP() {
SERIAL_PROTOCOLPAIR(" @", e); SERIAL_PROTOCOLPAIR_P(port, " @", e);
SERIAL_PROTOCOLCHAR(':'); SERIAL_PROTOCOLCHAR_P(port, ':');
SERIAL_PROTOCOL(getHeaterPower(e)); SERIAL_PROTOCOL_P(port, getHeaterPower(e));
} }
#endif #endif
} }

@ -547,7 +547,11 @@ class Temperature {
#endif // HEATER_IDLE_HANDLER #endif // HEATER_IDLE_HANDLER
#if HAS_TEMP_HOTEND || HAS_TEMP_BED #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) #if ENABLED(AUTO_REPORT_TEMPERATURES)
static uint8_t auto_report_temp_interval; static uint8_t auto_report_temp_interval;
static millis_t next_temp_report_ms; static millis_t next_temp_report_ms;

@ -339,38 +339,38 @@ int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) {
&& DIR_IS_FILE_OR_SUBDIR(&dir)) break; && DIR_IS_FILE_OR_SUBDIR(&dir)) break;
} }
// indent for dir level // 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 // print name
for (uint8_t i = 0; i < 11; i++) { for (uint8_t i = 0; i < 11; i++) {
if (dir.name[i] == ' ')continue; if (dir.name[i] == ' ')continue;
if (i == 8) { if (i == 8) {
MYSERIAL.write('.'); SERIAL_CHAR('.');
w++; w++;
} }
MYSERIAL.write(dir.name[i]); SERIAL_CHAR(dir.name[i]);
w++; w++;
} }
if (DIR_IS_SUBDIR(&dir)) { if (DIR_IS_SUBDIR(&dir)) {
MYSERIAL.write('/'); SERIAL_CHAR('/');
w++; w++;
} }
if (flags & (LS_DATE | LS_SIZE)) { if (flags & (LS_DATE | LS_SIZE)) {
while (w++ < 14) MYSERIAL.write(' '); while (w++ < 14) SERIAL_CHAR(' ');
} }
// print modify date/time if requested // print modify date/time if requested
if (flags & LS_DATE) { if (flags & LS_DATE) {
MYSERIAL.write(' '); SERIAL_CHAR(' ');
printFatDate(dir.lastWriteDate); printFatDate(dir.lastWriteDate);
MYSERIAL.write(' '); SERIAL_CHAR(' ');
printFatTime(dir.lastWriteTime); printFatTime(dir.lastWriteTime);
} }
// print size if requested // print size if requested
if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) { if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) {
MYSERIAL.write(' '); SERIAL_CHAR(' ');
MYSERIAL.print(dir.fileSize); SERIAL_ECHO(dir.fileSize);
} }
MYSERIAL.println(); SERIAL_EOL();
return DIR_IS_FILE(&dir) ? 1 : 2; return DIR_IS_FILE(&dir) ? 1 : 2;
} }
@ -902,11 +902,10 @@ int SdBaseFile::peek() {
return c; return c;
} }
// print uint8_t with width 2 // print uint8_t with width 2
static void print2u(uint8_t v) { static void print2u(const uint8_t v) {
if (v < 10) MYSERIAL.write('0'); if (v < 10) SERIAL_CHAR('0');
MYSERIAL.print(v, DEC); 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. * \param[in] fatDate The date field from a directory entry.
*/ */
void SdBaseFile::printFatDate(uint16_t fatDate) { void SdBaseFile::printFatDate(uint16_t fatDate) {
MYSERIAL.print(FAT_YEAR(fatDate)); SERIAL_ECHO(FAT_YEAR(fatDate));
MYSERIAL.write('-'); SERIAL_CHAR('-');
print2u(FAT_MONTH(fatDate)); print2u(FAT_MONTH(fatDate));
MYSERIAL.write('-'); SERIAL_CHAR('-');
print2u(FAT_DAY(fatDate)); print2u(FAT_DAY(fatDate));
} }
@ -945,9 +944,9 @@ void SdBaseFile::printFatDate(uint16_t fatDate) {
*/ */
void SdBaseFile::printFatTime(uint16_t fatTime) { void SdBaseFile::printFatTime(uint16_t fatTime) {
print2u(FAT_HOUR(fatTime)); print2u(FAT_HOUR(fatTime));
MYSERIAL.write(':'); SERIAL_CHAR(':');
print2u(FAT_MINUTE(fatTime)); print2u(FAT_MINUTE(fatTime));
MYSERIAL.write(':'); SERIAL_CHAR(':');
print2u(FAT_SECOND(fatTime)); print2u(FAT_SECOND(fatTime));
} }
@ -959,7 +958,7 @@ void SdBaseFile::printFatTime(uint16_t fatTime) {
bool SdBaseFile::printName() { bool SdBaseFile::printName() {
char name[FILENAME_LENGTH]; char name[FILENAME_LENGTH];
if (!getFilename(name)) return false; if (!getFilename(name)) return false;
MYSERIAL.print(name); SERIAL_ECHO(name);
return true; return true;
} }

@ -38,54 +38,22 @@
* \return The number of free bytes. * \return The number of free bytes.
*/ */
#ifdef __arm__ #ifdef __arm__
extern "C" char* sbrk(int incr);
int SdFatUtil::FreeRam() {
char top;
return &top - reinterpret_cast<char*>(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
/** extern "C" char* sbrk(int incr);
* %Print a string in flash memory. int SdFatUtil::FreeRam() {
* char top;
* \param[in] pr Print object for output. return &top - reinterpret_cast<char*>(sbrk(0));
* \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);
}
/** #else
* %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(); }
/** extern char* __brkval;
* %Print a string in flash memory to Serial. extern char __bss_end;
* int SdFatUtil::FreeRam() {
* \param[in] str Pointer to string stored in flash memory. char top;
*/ return __brkval ? &top - __brkval : &top - &__bss_end;
void SdFatUtil::SerialPrint_P(PGM_P str) { print_P(str); } }
/** #endif
* %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 // SDSUPPORT #endif // SDSUPPORT

@ -35,17 +35,9 @@
* \file * \file
* \brief Useful utility functions. * \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 { namespace SdFatUtil {
int FreeRam(); 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 using namespace SdFatUtil; // NOLINT

@ -85,7 +85,11 @@ char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters
uint16_t nrFile_index; 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; dir_t p;
uint8_t cnt = 0; uint8_t cnt = 0;
@ -118,12 +122,16 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
SdFile dir; SdFile dir;
if (!dir.open(parent, lfilename, O_READ)) { if (!dir.open(parent, lfilename, O_READ)) {
if (lsAction == LS_SerialPrint) { if (lsAction == LS_SerialPrint) {
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR);
SERIAL_ECHOLN(lfilename); 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 // close() is done automatically by destructor of SdFile
} }
else { else {
@ -145,10 +153,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
case LS_SerialPrint: case LS_SerialPrint:
createFilename(filename, p); createFilename(filename, p);
SERIAL_PROTOCOL(prepend); SERIAL_PROTOCOL_P(port, prepend);
SERIAL_PROTOCOL(filename); SERIAL_PROTOCOL_P(port, filename);
SERIAL_PROTOCOLCHAR(' '); SERIAL_PROTOCOLCHAR_P(port, ' ');
SERIAL_PROTOCOLLN(p.fileSize); SERIAL_PROTOCOLLN_P(port, p.fileSize);
break; break;
case LS_GetFilename: case LS_GetFilename:
@ -165,10 +173,18 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
} // while readDir } // while readDir
} }
void CardReader::ls() { void CardReader::ls(
#if NUM_SERIAL > 1
const int8_t port
#endif
) {
lsAction = LS_SerialPrint; lsAction = LS_SerialPrint;
root.rewind(); root.rewind();
lsDive("", root); lsDive("", root
#if NUM_SERIAL > 1
, NULL, port
#endif
);
} }
#if ENABLED(LONG_FILENAME_HOST_SUPPORT) #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 * 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; lsAction = LS_GetFilename;
int i, pathLen = strlen(path); 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 // Zero out slashes to make segments
for (i = 0; i < pathLen; i++) if (path[i] == '/') path[i] = '\0'; for (i = 0; i < pathLen; i++) if (path[i] == '/') path[i] = '\0';
@ -199,28 +219,32 @@ void CardReader::ls() {
// Go to the next segment // Go to the next segment
while (path[++i]) { } 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 // Find the item, setting the long filename
diveDir.rewind(); diveDir.rewind();
lsDive("", diveDir, segment); lsDive("", diveDir, segment
#if NUM_SERIAL > 1
, port
#endif
);
// Print /LongNamePart to serial output // Print /LongNamePart to serial output
SERIAL_PROTOCOLCHAR('/'); SERIAL_PROTOCOLCHAR_P(port, '/');
SERIAL_PROTOCOL(longFilename[0] ? longFilename : "???"); SERIAL_PROTOCOL_P(port, longFilename[0] ? longFilename : "???");
// If the filename was printed then that's it // If the filename was printed then that's it
if (!filenameIsDir) break; 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 // Open the sub-item as the new dive parent
SdFile dir; SdFile dir;
if (!dir.open(diveDir, segment, O_READ)) { if (!dir.open(diveDir, segment, O_READ)) {
SERIAL_EOL(); SERIAL_EOL_P(port);
SERIAL_ECHO_START(); SERIAL_ECHO_START_P(port);
SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); SERIAL_ECHOPGM_P(port, MSG_SD_CANT_OPEN_SUBDIR);
SERIAL_ECHO(segment); SERIAL_ECHO_P(port, segment);
break; break;
} }
@ -229,7 +253,7 @@ void CardReader::ls() {
} // while i<pathLen } // while i<pathLen
SERIAL_EOL(); SERIAL_EOL_P(port);
} }
#endif // LONG_FILENAME_HOST_SUPPORT #endif // LONG_FILENAME_HOST_SUPPORT
@ -500,15 +524,19 @@ void CardReader::removeFile(const char * const name) {
} }
} }
void CardReader::getStatus() { void CardReader::getStatus(
#if NUM_SERIAL > 1
const int8_t port/*= -1*/
#endif
) {
if (cardOK) { if (cardOK) {
SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); SERIAL_PROTOCOLPGM_P(port, MSG_SD_PRINTING_BYTE);
SERIAL_PROTOCOL(sdpos); SERIAL_PROTOCOL_P(port, sdpos);
SERIAL_PROTOCOLCHAR('/'); SERIAL_PROTOCOLCHAR_P(port, '/');
SERIAL_PROTOCOLLN(filesize); SERIAL_PROTOCOLLN_P(port, filesize);
} }
else else
SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); SERIAL_PROTOCOLLNPGM_P(port, MSG_SD_NOT_PRINTING);
} }
void CardReader::write_command(char *buf) { void CardReader::write_command(char *buf) {

@ -49,11 +49,19 @@ public:
void openAndPrintFile(const char *name); void openAndPrintFile(const char *name);
void startFileprint(); void startFileprint();
void stopSDPrint(); void stopSDPrint();
void getStatus(); void getStatus(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
void printingHasFinished(); void printingHasFinished();
#if ENABLED(LONG_FILENAME_HOST_SUPPORT) #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 #endif
void getfilename(uint16_t nr, const char* const match=NULL); void getfilename(uint16_t nr, const char* const match=NULL);
@ -61,7 +69,11 @@ public:
void getAbsFilename(char *t); void getAbsFilename(char *t);
void ls(); void ls(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
void chdir(const char *relpath); void chdir(const char *relpath);
int8_t updir(); int8_t updir();
void setroot(); void setroot();
@ -162,7 +174,11 @@ private:
LsAction lsAction; //stored for recursion. 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. 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; 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) #if ENABLED(SDCARD_SORT_ALPHA)
void flush_presort(); void flush_presort();

Loading…
Cancel
Save