Browse Source

Multi-host support

pull/1/head
Thomas Moore 7 years ago
committed by Scott Lahteine
parent
commit
f7efac57b7
  1. 9
      Marlin/Configuration.h
  2. 3
      Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp
  3. 18
      Marlin/src/HAL/HAL_AVR/HAL_AVR.h
  4. 4
      Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h
  5. 4
      Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h
  6. 16
      Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp
  7. 15
      Marlin/src/HAL/HAL_DUE/HAL_Due.h
  8. 12
      Marlin/src/HAL/HAL_LPC1768/HAL.cpp
  9. 37
      Marlin/src/HAL/HAL_LPC1768/HAL.h
  10. 2
      Marlin/src/HAL/HAL_LPC1768/arduino.cpp
  11. 15
      Marlin/src/HAL/HAL_LPC1768/main.cpp
  12. 155
      Marlin/src/HAL/HAL_LPC1768/serial.h
  13. 35
      Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h
  14. 12
      Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h
  15. 19
      Marlin/src/Marlin.cpp
  16. 40
      Marlin/src/core/serial.cpp
  17. 178
      Marlin/src/core/serial.h
  18. 9
      Marlin/src/feature/bedlevel/abl/abl.cpp
  19. 31
      Marlin/src/feature/bedlevel/ubl/ubl.cpp
  20. 12
      Marlin/src/feature/bedlevel/ubl/ubl.h
  21. 4
      Marlin/src/feature/tmc_util.cpp
  22. 28
      Marlin/src/gcode/eeprom/M500-M504.cpp
  23. 40
      Marlin/src/gcode/feature/trinamic/M122.cpp
  24. 13
      Marlin/src/gcode/host/M115.cpp
  25. 15
      Marlin/src/gcode/parser.cpp
  26. 272
      Marlin/src/gcode/queue.cpp
  27. 7
      Marlin/src/gcode/queue.h
  28. 32
      Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp
  29. 11
      Marlin/src/gcode/stats/M31.cpp
  30. 22
      Marlin/src/gcode/temperature/M105.cpp
  31. 6
      Marlin/src/inc/Conditionals_LCD.h
  32. 536
      Marlin/src/module/configuration_store.cpp
  33. 44
      Marlin/src/module/configuration_store.h
  34. 4
      Marlin/src/module/stepper.h
  35. 54
      Marlin/src/module/temperature.cpp
  36. 6
      Marlin/src/module/temperature.h
  37. 39
      Marlin/src/sd/SdBaseFile.cpp
  38. 58
      Marlin/src/sd/SdFatUtil.cpp
  39. 8
      Marlin/src/sd/SdFatUtil.h
  40. 86
      Marlin/src/sd/cardreader.cpp
  41. 24
      Marlin/src/sd/cardreader.h

9
Marlin/Configuration.h

@ -102,6 +102,15 @@
*/
#define SERIAL_PORT 0
/**
* Select a secondary serial port on the board to use for communication with the host.
* This allows the connection of wireless adapters (for instance) to non-default port pins.
* Serial port -1 is the USB emulated serial port, if avaialble.
*
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
#define SERIAL_PORT_2 -1
/**
* This setting determines the communication speed of the printer.
*

3
Marlin/src/HAL/HAL_AVR/HAL_AVR.cpp

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

18
Marlin/src/HAL/HAL_AVR/HAL_AVR.h

@ -47,6 +47,12 @@
#include "watchdog_AVR.h"
#include "math_AVR.h"
#ifdef USBCON
#include "HardwareSerial.h"
#else
#include "MarlinSerial.h"
#endif
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
@ -79,6 +85,18 @@ typedef int8_t pin_t;
//extern uint8_t MCUSR;
#define NUM_SERIAL 1
#ifdef USBCON
#if ENABLED(BLUETOOTH)
#define MYSERIAL0 bluetoothSerial
#else
#define MYSERIAL0 Serial
#endif
#else
#define MYSERIAL0 customizedSerial
#endif
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------

4
Marlin/src/HAL/HAL_AVR/HAL_pinsDebug_AVR.h

@ -483,9 +483,9 @@ inline void report_pin_state_extended(pin_t pin, bool ignore, bool extended = fa
for (uint8_t y = 0; y < 28; y++) { // always print pin name
temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0)
MYSERIAL.write(temp_char);
SERIAL_CHAR(temp_char);
else {
for (uint8_t i = 0; i < 28 - y; i++) MYSERIAL.write(' ');
for (uint8_t i = 0; i < 28 - y; i++) SERIAL_CHAR(' ');
break;
}
}

4
Marlin/src/HAL/HAL_AVR/pinsDebug_AVR_8_bit.h

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

16
Marlin/src/HAL/HAL_DUE/EepromEmulation_Due.cpp

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

15
Marlin/src/HAL/HAL_DUE/HAL_Due.h

@ -40,8 +40,15 @@
//
// Defines
//
#if SERIAL_PORT >= -1 && SERIAL_PORT <= 4
#define MYSERIAL customizedSerial
#define NUM_SERIAL 1
//#undef SERIAL_PORT
//#define SERIAL_PORT -1
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#else
#define MYSERIAL0 customizedSerial
#endif
// We need the previous define before the include, or compilation bombs...
@ -147,6 +154,10 @@ uint16_t HAL_getAdcFreerun(uint8_t chan, bool wait_for_conversion = false);
void HAL_enable_AdcFreerun(void);
//void HAL_disable_AdcFreerun(uint8_t chan);
/**
* Pin Map
*/
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)

12
Marlin/src/HAL/HAL_LPC1768/HAL.cpp

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

37
Marlin/src/HAL/HAL_LPC1768/HAL.h

@ -69,19 +69,44 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_2 DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP
#define ST7920_DELAY_3 DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP;DELAY_5_NOP
//Serial override
extern HalSerial usb_serial;
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
#endif
#if SERIAL_PORT == -1
#define MYSERIAL usb_serial
#define MYSERIAL0 usb_serial
#elif SERIAL_PORT == 0
#define MYSERIAL Serial
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 1
#define MYSERIAL Serial1
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2
#define MYSERIAL Serial2
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3
#define MYSERIAL Serial3
#define MYSERIAL0 Serial3
#endif
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3"
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
#endif
#define NUM_SERIAL 2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 usb_serial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#endif
#else
#define NUM_SERIAL 1
#endif
#define CRITICAL_SECTION_START uint32_t primask = __get_PRIMASK(); __disable_irq();

2
Marlin/src/HAL/HAL_LPC1768/arduino.cpp

@ -139,7 +139,7 @@ void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255
if (LPC1768_PWM_attach_pin(pin, 1, LPC_PWM1->MR0, 0xFF))
LPC1768_PWM_write(pin, map(value, 0, 255, 1, LPC_PWM1->MR0)); // map 1-254 onto PWM range
else { // out of PWM channels
if (!out_of_PWM_slots) MYSERIAL.printf(".\nWARNING - OUT OF PWM CHANNELS\n.\n"); //only warn once
if (!out_of_PWM_slots) SERIAL_ECHOPGM(".\nWARNING - OUT OF PWM CHANNELS\n.\n"); //only warn once
out_of_PWM_slots = true;
digitalWrite(pin, value); // treat as a digital pin if out of channels
}

15
Marlin/src/HAL/HAL_LPC1768/main.cpp

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

155
Marlin/src/HAL/HAL_LPC1768/serial.h

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

35
Marlin/src/HAL/HAL_STM32F1/HAL_Stm32f1.h

@ -65,16 +65,41 @@
// Defines
// --------------------------------------------------------------------------
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
#endif
#if SERIAL_PORT == -1
#define MYSERIAL SerialUSB
#define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 0
#define MYSERIAL Serial
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 1
#define MYSERIAL Serial1
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2
#define MYSERIAL Serial2
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3
#define MYSERIAL Serial3
#define MYSERIAL0 Serial3
#endif
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3"
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
#endif
#define NUM_SERIAL 2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#endif
#else
#define NUM_SERIAL 1
#endif
/**

12
Marlin/src/HAL/HAL_TEENSY35_36/HAL_Teensy.h

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

19
Marlin/src/Marlin.cpp

@ -669,9 +669,22 @@ void setup() {
disableStepperDrivers();
#endif
MYSERIAL.begin(BAUDRATE);
uint32_t serial_connect_timeout = millis() + 1000;
while(!MYSERIAL && PENDING(millis(), serial_connect_timeout));
#if NUM_SERIAL > 0
MYSERIAL0.begin(BAUDRATE);
#if NUM_SERIAL > 1
MYSERIAL1.begin(BAUDRATE);
#endif
#endif
#if NUM_SERIAL > 0
uint32_t serial_connect_timeout = millis() + 1000UL;
while(!MYSERIAL0 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#if NUM_SERIAL > 1
serial_connect_timeout = millis() + 1000UL;
while(!MYSERIAL1 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
#endif
SERIAL_PROTOCOLLNPGM("start");
SERIAL_ECHO_START();

40
Marlin/src/core/serial.cpp

@ -27,25 +27,37 @@ uint8_t marlin_debug_flags = DEBUG_NONE;
const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:";
#if NUM_SERIAL > 1
void serialprintPGM_P(const int8_t p, const char * str) {
while (char ch = pgm_read_byte(str++)) SERIAL_CHAR_P(p, ch);
}
void serial_echopair_PGM_P(const int8_t p, const char* s_P, const char *v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, char v) { serialprintPGM_P(p, s_P); SERIAL_CHAR_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, int v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, long v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, float v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, double v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned int v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned long v) { serialprintPGM_P(p, s_P); SERIAL_ECHO_P(p, v); }
void serial_spaces_P(const int8_t p, uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR_P(p, ' '); }
#endif
void serialprintPGM(const char * str) {
#ifdef TARGET_LPC1768
MYSERIAL.print(str);
#else
while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch);
#endif
while (char ch = pgm_read_byte(str++)) SERIAL_CHAR(ch);
}
void serial_echopair_P(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); }
void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); }
void serial_echopair_PGM(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) MYSERIAL.write(' '); }
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); }
#if ENABLED(DEBUG_LEVELING_FEATURE)

178
Marlin/src/core/serial.h

@ -75,9 +75,7 @@ enum DebugFlags {
#include "../HAL/HAL_AVR/MarlinSerial.h"
#define MYSERIAL customizedSerial
#endif
#endif
#ifdef ARDUINO_ARCH_SAM
#elif defined(ARDUINO_ARCH_SAM)
// To pull the Serial port definitions and overrides
#include "../HAL/HAL_DUE/MarlinSerial_Due.h"
#endif
@ -88,17 +86,152 @@ extern uint8_t marlin_debug_flags;
extern const char echomagic[] PROGMEM;
extern const char errormagic[] PROGMEM;
#define SERIAL_CHAR(x) ((void)MYSERIAL.write(x))
#if TX_BUFFER_SIZE < 1
#define SERIAL_FLUSHTX_P(p)
#define SERIAL_FLUSHTX()
#endif
#if NUM_SERIAL > 1
#define SERIAL_CHAR_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.write(x) : MYSERIAL1.write(x)) : SERIAL_CHAR(x))
#define SERIAL_PROTOCOL_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x) : MYSERIAL1.print(x)) : SERIAL_PROTOCOL(x))
#define SERIAL_PROTOCOL_F_P(p,x,y) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x,y) : MYSERIAL1.print(x,y)) : SERIAL_PROTOCOL_F(x,y))
#define SERIAL_PROTOCOLLN_P(p,x) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.println(x) : MYSERIAL1.println(x)) : SERIAL_PROTOCOLLN(x))
#define SERIAL_PRINT_P(p,x,b) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.print(x,b) : MYSERIAL1.print(x,b)) : SERIAL_PRINT(x,b))
#define SERIAL_PRINTLN_P(p,x,b) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.println(x,b) : MYSERIAL1.println(x,b)) : SERIAL_PRINTLN(x,b))
#define SERIAL_PRINTF_P(p,args...) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.printf(args) : MYSERIAL1.printf(args)) : SERIAL_PRINTF(args))
#define SERIAL_CHAR(x) (MYSERIAL0.write(x), MYSERIAL1.write(x))
#define SERIAL_PROTOCOL(x) (MYSERIAL0.print(x), MYSERIAL1.print(x))
#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL0.print(x,y), MYSERIAL1.print(x,y))
#define SERIAL_PROTOCOLLN(x) (MYSERIAL0.println(x), MYSERIAL1.println(x))
#define SERIAL_PRINT(x,b) (MYSERIAL0.print(x,b), MYSERIAL1.print(x,b))
#define SERIAL_PRINTLN(x,b) (MYSERIAL0.println(x,b), MYSERIAL1.println(x,b))
#define SERIAL_PRINTF(args...) (MYSERIAL0.printf(args), MYSERIAL1.printf(args))
#define SERIAL_FLUSH_P(p) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.flush() : MYSERIAL1.flush()) : SERIAL_FLUSH())
#define SERIAL_FLUSH() (MYSERIAL0.flush(), MYSERIAL1.flush())
#if TX_BUFFER_SIZE > 0
#define SERIAL_FLUSHTX_P(p) (WITHIN(p, 0, NUM_SERIAL-1) ? (p == 0 ? MYSERIAL0.flushTX() : MYSERIAL1.flushTX()) : SERIAL_FLUSHTX())
#define SERIAL_FLUSHTX() (MYSERIAL0.flushTX(), MYSERIAL1.flushTX())
#endif
#define SERIAL_EOL_P(p) SERIAL_CHAR_P(p,'\n')
#define SERIAL_PROTOCOLCHAR_P(p,x) SERIAL_CHAR_P(p,x)
#define SERIAL_PROTOCOLPGM_P(p,x) (serialprintPGM_P(p,PSTR(x)))
#define SERIAL_PROTOCOLLNPGM_P(p,x) (serialprintPGM_P(p,PSTR(x "\n")))
#define SERIAL_PROTOCOLPAIR_P(p, pre, value) (serial_echopair_PGM_P(p,PSTR(pre),(value)))
#define SERIAL_PROTOCOLLNPAIR_P(p, pre, value) do { SERIAL_PROTOCOLPAIR_P(p, pre, value); SERIAL_EOL_P(p); } while(0)
#define SERIAL_ECHO_START_P(p) (serialprintPGM_P(p,echomagic))
#define SERIAL_ECHO_P(p,x) SERIAL_PROTOCOL_P(p,x)
#define SERIAL_ECHOPGM_P(p,x) SERIAL_PROTOCOLPGM_P(p,x)
#define SERIAL_ECHOLN_P(p,x) SERIAL_PROTOCOLLN_P(p,x)
#define SERIAL_ECHOLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM_P(p,x)
#define SERIAL_ECHOPAIR_P(p,pre,value) SERIAL_PROTOCOLPAIR_P(p, pre, value)
#define SERIAL_ECHOLNPAIR_P(p,pre, value) SERIAL_PROTOCOLLNPAIR_P(p, pre, value)
#define SERIAL_ECHO_F_P(p,x,y) SERIAL_PROTOCOL_F_P(p,x,y)
#define SERIAL_ERROR_START_P(p) (serialprintPGM_P(p,errormagic))
#define SERIAL_ERROR_P(p,x) SERIAL_PROTOCOL_P(p,x)
#define SERIAL_ERRORPGM_P(p,x) SERIAL_PROTOCOLPGM_P(p,x)
#define SERIAL_ERRORLN_P(p,x) SERIAL_PROTOCOLLN_P(p,x)
#define SERIAL_ERRORLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM_P(p,x)
// These macros compensate for float imprecision
#define SERIAL_PROTOCOLPAIR_F_P(p, pre, value) SERIAL_PROTOCOLPAIR_P(p, pre, FIXFLOAT(value))
#define SERIAL_PROTOCOLLNPAIR_F_P(p, pre, value) SERIAL_PROTOCOLLNPAIR_P(p, pre, FIXFLOAT(value))
#define SERIAL_ECHOPAIR_F_P(p,pre,value) SERIAL_ECHOPAIR_P(p, pre, FIXFLOAT(value))
#define SERIAL_ECHOLNPAIR_F_P(p,pre, value) SERIAL_ECHOLNPAIR_P(p, pre, FIXFLOAT(value))
void serial_echopair_PGM_P(const int8_t p, const char* s_P, const char *v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, char v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, int v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, long v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, float v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, double v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned int v);
void serial_echopair_PGM_P(const int8_t p, const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, uint8_t v) { serial_echopair_PGM_P(p, s_P, (int)v); }
FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, bool v) { serial_echopair_PGM_P(p, s_P, (int)v); }
FORCE_INLINE void serial_echopair_PGM_P(const int8_t p, const char* s_P, void *v) { serial_echopair_PGM_P(p, s_P, (unsigned long)v); }
void serial_spaces_P(const int8_t p, uint8_t count);
#define SERIAL_ECHO_SP_P(p,C) serial_spaces_P(p,C)
#define SERIAL_ERROR_SP_P(p,C) serial_spaces_P(p,C)
#define SERIAL_PROTOCOL_SP_P(p,C) serial_spaces_P(p,C)
void serialprintPGM_P(const int8_t p, const char* str);
#else
#define SERIAL_CHAR_P(p,x) SERIAL_CHAR(x)
#define SERIAL_PROTOCOL_P(p,x) SERIAL_PROTOCOL(x)
#define SERIAL_PROTOCOL_F_P(p,x,y) SERIAL_PROTOCOL_F(x,y)
#define SERIAL_PROTOCOLLN_P(p,x) SERIAL_PROTOCOLLN(x)
#define SERIAL_PRINT_P(p,x,b) SERIAL_PRINT(x,b)
#define SERIAL_PRINTLN_P(p,x,b) SERIAL_PRINTLN(x,b)
#define SERIAL_PRINTF_P(p,args...) SERIAL_PRINTF(args)
#define SERIAL_CHAR(x) MYSERIAL0.write(x)
#define SERIAL_PROTOCOL(x) MYSERIAL0.print(x)
#define SERIAL_PROTOCOL_F(x,y) MYSERIAL0.print(x,y)
#define SERIAL_PROTOCOLLN(x) MYSERIAL0.println(x)
#define SERIAL_PRINT(x,b) MYSERIAL0.print(x,b)
#define SERIAL_PRINTLN(x,b) MYSERIAL0.println(x,b)
#define SERIAL_PRINTF(args...) MYSERIAL0.printf(args)
#define SERIAL_FLUSH_P(p) SERIAL_FLUSH()
#define SERIAL_FLUSH() MYSERIAL0.flush()
#if TX_BUFFER_SIZE > 0
#define SERIAL_FLUSHTX_P(p) SERIAL_FLUSHTX()
#define SERIAL_FLUSHTX() MYSERIAL0.flushTX()
#endif
#define SERIAL_EOL_P(p) SERIAL_EOL()
#define SERIAL_PROTOCOLCHAR_P(p,x) SERIAL_PROTOCOLCHAR(x)
#define SERIAL_PROTOCOLPGM_P(p,x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_PROTOCOLLNPGM_P(p,x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_PROTOCOLPAIR_P(p, pre, value) SERIAL_PROTOCOLPAIR(pre, value)
#define SERIAL_PROTOCOLLNPAIR_P(p, pre, value) SERIAL_PROTOCOLLNPAIR(pre, value)
#define SERIAL_ECHO_START_P(p) SERIAL_ECHO_START()
#define SERIAL_ECHO_P(p,x) SERIAL_ECHO(x)
#define SERIAL_ECHOPGM_P(p,x) SERIAL_ECHOPGM(x)
#define SERIAL_ECHOLN_P(p,x) SERIAL_ECHOLN(x)
#define SERIAL_ECHOLNPGM_P(p,x) SERIAL_ECHOLNPGM(x)
#define SERIAL_ECHOPAIR_P(p,pre,value) SERIAL_ECHOPAIR(pre, value)
#define SERIAL_ECHOLNPAIR_P(p,pre, value) SERIAL_ECHOLNPAIR(pre, value)
#define SERIAL_ECHO_F_P(p,x,y) SERIAL_ECHO_F(x,y)
#define SERIAL_ERROR_START_P(p) SERIAL_ERROR_START()
#define SERIAL_ERROR_P(p,x) SERIAL_ERROR(x)
#define SERIAL_ERRORPGM_P(p,x) SERIAL_ERRORPGM(x)
#define SERIAL_ERRORLN_P(p,x) SERIAL_ERRORLN(x)
#define SERIAL_ERRORLNPGM_P(p,x) SERIAL_ERRORLNPGM(x)
// These macros compensate for float imprecision
#define SERIAL_PROTOCOLPAIR_F_P(p, pre, value) SERIAL_PROTOCOLPAIR_F(pre, value)
#define SERIAL_PROTOCOLLNPAIR_F_P(p, pre, value) SERIAL_PROTOCOLLNPAIR_F(pre, value)
#define SERIAL_ECHOPAIR_F_P(p,pre,value) SERIAL_ECHOPAIR_F(pre, value)
#define SERIAL_ECHOLNPAIR_F_P(p,pre, value) SERIAL_ECHOLNPAIR_F(pre, value)
#define serial_echopair_PGM_P(p,s_P,v) serial_echopair_PGM(s_P, v)
#define serial_spaces_P(p,c) serial_spaces(c)
#define SERIAL_ECHO_SP_P(p,C) SERIAL_ECHO_SP(C)
#define SERIAL_ERROR_SP_P(p,C) SERIAL_ERROR_SP(C)
#define SERIAL_PROTOCOL_SP_P(p,C) SERIAL_PROTOCOL_SP(C)
#define serialprintPGM_P(p,s) serialprintPGM(s)
#endif
#define SERIAL_EOL() SERIAL_CHAR('\n')
#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x)
#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL(); }while(0)
#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n")))
#define SERIAL_PROTOCOLPAIR(pre, value) (serial_echopair_P(PSTR(pre),(value)))
#define SERIAL_PROTOCOLLNPAIR(pre, value) do{ SERIAL_PROTOCOLPAIR(pre, value); SERIAL_EOL(); }while(0)
#define SERIAL_PROTOCOLPAIR(pre, value) (serial_echopair_PGM(PSTR(pre), value))
#define SERIAL_PROTOCOLLNPAIR(pre, value) do { SERIAL_PROTOCOLPAIR(pre, value); SERIAL_EOL(); } while(0)
#define SERIAL_ECHO_START() (serialprintPGM(echomagic))
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
@ -107,7 +240,7 @@ extern const char errormagic[] PROGMEM;
#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHOPAIR(pre,value) SERIAL_PROTOCOLPAIR(pre, value)
#define SERIAL_ECHOLNPAIR(pre, value) SERIAL_PROTOCOLLNPAIR(pre, value)
#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x,y)
#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x, y)
#define SERIAL_ERROR_START() (serialprintPGM(errormagic))
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
@ -121,17 +254,17 @@ extern const char errormagic[] PROGMEM;
#define SERIAL_ECHOPAIR_F(pre,value) SERIAL_ECHOPAIR(pre, FIXFLOAT(value))
#define SERIAL_ECHOLNPAIR_F(pre, value) SERIAL_ECHOLNPAIR(pre, FIXFLOAT(value))
void serial_echopair_P(const char* s_P, const char *v);
void serial_echopair_P(const char* s_P, char v);
void serial_echopair_P(const char* s_P, int v);
void serial_echopair_P(const char* s_P, long v);
void serial_echopair_P(const char* s_P, float v);
void serial_echopair_P(const char* s_P, double v);
void serial_echopair_P(const char* s_P, unsigned int v);
void serial_echopair_P(const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); }
void serial_echopair_PGM(const char* s_P, const char *v);
void serial_echopair_PGM(const char* s_P, char v);
void serial_echopair_PGM(const char* s_P, int v);
void serial_echopair_PGM(const char* s_P, long v);
void serial_echopair_PGM(const char* s_P, float v);
void serial_echopair_PGM(const char* s_P, double v);
void serial_echopair_PGM(const char* s_P, unsigned int v);
void serial_echopair_PGM(const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_PGM(const char* s_P, uint8_t v) { serial_echopair_PGM(s_P, (int)v); }
FORCE_INLINE void serial_echopair_PGM(const char* s_P, bool v) { serial_echopair_PGM(s_P, (int)v); }
FORCE_INLINE void serial_echopair_PGM(const char* s_P, void *v) { serial_echopair_PGM(s_P, (unsigned long)v); }
void serial_spaces(uint8_t count);
#define SERIAL_ECHO_SP(C) serial_spaces(C)
@ -149,8 +282,7 @@ void serialprintPGM(const char* str);
#if HAS_ABL
void print_xyz(const char* prefix, const char* suffix, const vector_3 &xyz);
#endif
#define DEBUG_POS(SUFFIX,VAR) do { \
print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); }while(0)
#define DEBUG_POS(SUFFIX,VAR) do { print_xyz(PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n"), VAR); } while(0)
#endif
#endif // __SERIAL_H__

9
Marlin/src/feature/bedlevel/abl/abl.cpp

@ -64,9 +64,12 @@ static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t
c1 = z_values[x1][y1], c2 = z_values[x2][y2];
// Treat far unprobed points as zero, near as equal to far
if (isnan(a2)) a2 = 0.0; if (isnan(a1)) a1 = a2;
if (isnan(b2)) b2 = 0.0; if (isnan(b1)) b1 = b2;
if (isnan(c2)) c2 = 0.0; if (isnan(c1)) c1 = c2;
if (isnan(a2)) a2 = 0.0;
if (isnan(a1)) a1 = a2;
if (isnan(b2)) b2 = 0.0;
if (isnan(b1)) b1 = b2;
if (isnan(c2)) c2 = 0.0;
if (isnan(c1)) c1 = c2;
const float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2;

31
Marlin/src/feature/bedlevel/ubl/ubl.cpp

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

12
Marlin/src/feature/bedlevel/ubl/ubl.h

@ -104,8 +104,16 @@ class unified_bed_leveling {
public:
static void echo_name();
static void report_state();
static void echo_name(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
static void report_state(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
static void save_ubl_active_state_and_disable();
static void restore_ubl_active_state_and_leave();
static void display_map(const int);

4
Marlin/src/feature/tmc_util.cpp

@ -146,12 +146,12 @@ char extended_axis_codes[11][3] = { "X", "X2", "Y", "Y2", "Z", "Z2", "E0", "E1",
const uint32_t pwm_scale = get_pwm_scale(st);
SERIAL_ECHO(axisID);
SERIAL_ECHOPAIR(":", pwm_scale);
SERIAL_ECHO(" |0b"); MYSERIAL.print(get_status_response(st), BIN);
SERIAL_ECHO(" |0b"); SERIAL_PRINT(get_status_response(st), BIN);
SERIAL_ECHO("| ");
if (data.is_error) SERIAL_ECHO('E');
else if (data.is_ot) SERIAL_ECHO('O');
else if (data.is_otpw) SERIAL_ECHO('W');
else if (otpw_cnt>0) MYSERIAL.print(otpw_cnt, DEC);
else if (otpw_cnt>0) SERIAL_PRINT(otpw_cnt, DEC);
else if (st.flag_otpw) SERIAL_ECHO('F');
SERIAL_ECHO("\t");
}

28
Marlin/src/gcode/eeprom/M500-M504.cpp

@ -24,25 +24,41 @@
#include "../../module/configuration_store.h"
#include "../../inc/MarlinConfig.h"
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
/**
* M500: Store settings in EEPROM
*/
void GcodeSuite::M500() {
(void)settings.save();
(void)settings.save(
#if ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1
command_queue_port[cmd_queue_index_r]
#endif
);
}
/**
* M501: Read settings from EEPROM
*/
void GcodeSuite::M501() {
(void)settings.load();
(void)settings.load(
#if ENABLED(EEPROM_SETTINGS) && ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1
command_queue_port[cmd_queue_index_r]
#endif
);
}
/**
* M502: Revert to default settings
*/
void GcodeSuite::M502() {
(void)settings.reset();
(void)settings.reset(
#if ENABLED(EEPROM_CHITCHAT) && NUM_SERIAL > 1
command_queue_port[cmd_queue_index_r]
#endif
);
}
#if DISABLED(DISABLE_M503)
@ -51,7 +67,11 @@ void GcodeSuite::M502() {
* M503: print settings currently in memory
*/
void GcodeSuite::M503() {
(void)settings.report(parser.seen('S') && !parser.value_bool());
(void)settings.report(parser.seen('S') && !parser.value_bool()
#if NUM_SERIAL > 1
, command_queue_port[cmd_queue_index_r]
#endif
);
}
#endif // !DISABLE_M503

40
Marlin/src/gcode/feature/trinamic/M122.cpp

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

13
Marlin/src/gcode/host/M115.cpp

@ -23,6 +23,10 @@
#include "../gcode.h"
#include "../../inc/MarlinConfig.h"
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
#if ENABLED(EXTENDED_CAPABILITIES_REPORT)
static void cap_line(const char * const name, bool ena=false) {
SERIAL_PROTOCOLPGM("Cap:");
@ -36,7 +40,14 @@
* M115: Capabilities string
*/
void GcodeSuite::M115() {
SERIAL_PROTOCOLLNPGM(MSG_M115_REPORT);
#if NUM_SERIAL > 1
const int8_t port = command_queue_port[cmd_queue_index_r];
#define CAPLINE(STR,...) cap_line(PSTR(STR), port, __VA_ARGS__)
#else
#define CAPLINE(STR,...) cap_line(PSTR(STR), __VA_ARGS__)
#endif
SERIAL_PROTOCOLLNPGM_P(port, MSG_M115_REPORT);
#if ENABLED(EXTENDED_CAPABILITIES_REPORT)

15
Marlin/src/gcode/parser.cpp

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

272
Marlin/src/gcode/queue.cpp

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

7
Marlin/src/gcode/queue.h

@ -51,6 +51,13 @@ extern uint8_t commands_in_queue, // Count of commands in the queue
extern char command_queue[BUFSIZE][MAX_CMD_SIZE];
/*
* The port that the command was received on
*/
#if NUM_SERIAL > 1
extern int16_t command_queue_port[BUFSIZE];
#endif
/**
* Initialization of queue for setup()
*/

32
Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp

@ -34,13 +34,25 @@
#include "../queue.h"
#endif
#if NUM_SERIAL > 1
#include "../../gcode/queue.h"
#endif
/**
* M20: List SD card to serial output
*/
void GcodeSuite::M20() {
SERIAL_PROTOCOLLNPGM(MSG_BEGIN_FILE_LIST);
card.ls();
SERIAL_PROTOCOLLNPGM(MSG_END_FILE_LIST);
#if NUM_SERIAL > 1
const int16_t port = command_queue_port[cmd_queue_index_r];
#endif
SERIAL_PROTOCOLLNPGM_P(port, MSG_BEGIN_FILE_LIST);
card.ls(
#if NUM_SERIAL > 1
port
#endif
);
SERIAL_PROTOCOLLNPGM_P(port, MSG_END_FILE_LIST);
}
/**
@ -97,7 +109,13 @@ void GcodeSuite::M26() {
/**
* M27: Get SD Card status
*/
void GcodeSuite::M27() { card.getStatus(); }
void GcodeSuite::M27() {
card.getStatus(
#if NUM_SERIAL > 1
command_queue_port[cmd_queue_index_r]
#endif
);
}
/**
* M28: Start SD Write
@ -164,7 +182,11 @@ void GcodeSuite::M32() {
* /Miscellaneous/Armchair/Armchair.gcode
*/
void GcodeSuite::M33() {
card.printLongPath(parser.string_arg);
card.printLongPath(parser.string_arg
#if NUM_SERIAL > 1
, command_queue_port[cmd_queue_index_r]
#endif
);
}
#endif // LONG_FILENAME_HOST_SUPPORT

11
Marlin/src/gcode/stats/M31.cpp

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

22
Marlin/src/gcode/temperature/M105.cpp

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

6
Marlin/src/inc/Conditionals_LCD.h

@ -494,10 +494,4 @@
#define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER))
#define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED))
// For Re-ARM boards, always use the USB Emulated Serial Port unless RE_ARM_FORCE_SERIAL_PORT is defined
#if !defined(RE_ARM_FORCE_SERIAL_PORT) && (MB(RAMPS_14_RE_ARM_EFB) || MB(RAMPS_14_RE_ARM_EEB) || MB(RAMPS_14_RE_ARM_EFF) || MB(RAMPS_14_RE_ARM_EEF) || MB(RAMPS_14_RE_ARM_SF))
#undef SERIAL_PORT
#define SERIAL_PORT -1
#endif
#endif // CONDITIONALS_LCD_H

536
Marlin/src/module/configuration_store.cpp

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

44
Marlin/src/module/configuration_store.h

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

4
Marlin/src/module/stepper.h

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

54
Marlin/src/module/temperature.cpp

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

6
Marlin/src/module/temperature.h

@ -547,7 +547,11 @@ class Temperature {
#endif // HEATER_IDLE_HANDLER
#if HAS_TEMP_HOTEND || HAS_TEMP_BED
static void print_heaterstates();
static void print_heaterstates(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
#if ENABLED(AUTO_REPORT_TEMPERATURES)
static uint8_t auto_report_temp_interval;
static millis_t next_temp_report_ms;

39
Marlin/src/sd/SdBaseFile.cpp

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

58
Marlin/src/sd/SdFatUtil.cpp

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

8
Marlin/src/sd/SdFatUtil.h

@ -35,17 +35,9 @@
* \file
* \brief Useful utility functions.
*/
/** Store and print a string in flash memory.*/
#define PgmPrint(x) SerialPrint_P(PSTR(x))
/** Store and print a string in flash memory followed by a CR/LF.*/
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
namespace SdFatUtil {
int FreeRam();
void print_P(PGM_P str);
void println_P(PGM_P str);
void SerialPrint_P(PGM_P str);
void SerialPrintln_P(PGM_P str);
}
using namespace SdFatUtil; // NOLINT

86
Marlin/src/sd/cardreader.cpp

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

24
Marlin/src/sd/cardreader.h

@ -49,11 +49,19 @@ public:
void openAndPrintFile(const char *name);
void startFileprint();
void stopSDPrint();
void getStatus();
void getStatus(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
void printingHasFinished();
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
void printLongPath(char *path);
void printLongPath(char *path
#if NUM_SERIAL > 1
, const int8_t port = -1
#endif
);
#endif
void getfilename(uint16_t nr, const char* const match=NULL);
@ -61,7 +69,11 @@ public:
void getAbsFilename(char *t);
void ls();
void ls(
#if NUM_SERIAL > 1
const int8_t port = -1
#endif
);
void chdir(const char *relpath);
int8_t updir();
void setroot();
@ -162,7 +174,11 @@ private:
LsAction lsAction; //stored for recursion.
uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
char* diveDirName;
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL
#if NUM_SERIAL > 1
, const int8_t port = -1
#endif
);
#if ENABLED(SDCARD_SORT_ALPHA)
void flush_presort();

Loading…
Cancel
Save