Multi-host support
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							dabb75034c
						
					
				
				
					commit
					f7efac57b7
				
			| @@ -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. | ||||
|  * | ||||
|   | ||||
| @@ -33,8 +33,7 @@ | ||||
| // Includes | ||||
| // -------------------------------------------------------------------------- | ||||
|  | ||||
| #include "../HAL.h" | ||||
| #include "../../core/macros.h" | ||||
| #include "../../inc/MarlinConfig.h" | ||||
|  | ||||
| // -------------------------------------------------------------------------- | ||||
| // Externals | ||||
|   | ||||
| @@ -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 | ||||
| // -------------------------------------------------------------------------- | ||||
|   | ||||
| @@ -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; | ||||
|         } | ||||
|       } | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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 | ||||
|     } | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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_ | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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__ | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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 ? ']' : ' '); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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"); | ||||
|     } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|           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; | ||||
|           } | ||||
|  | ||||
|           gcode_LastN = gcode_N; | ||||
|         } | ||||
|  | ||||
|         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; | ||||
|         // 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; | ||||
|         #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 | ||||
|         } | ||||
|         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; | ||||
|     } | ||||
|  | ||||
|         ); | ||||
|       } | ||||
|       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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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() | ||||
|  */ | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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 HAS_TEMP_HOTEND || HAS_TEMP_BED | ||||
|     SERIAL_PROTOCOLPGM(MSG_OK); | ||||
|     thermalManager.print_heaterstates(); | ||||
|   #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED | ||||
|     SERIAL_ERROR_START(); | ||||
|     SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); | ||||
|   #if NUM_SERIAL > 1 | ||||
|     const int16_t port = command_queue_port[cmd_queue_index_r]; | ||||
|   #endif | ||||
|  | ||||
|   SERIAL_EOL(); | ||||
|   #if HAS_TEMP_HOTEND || HAS_TEMP_BED | ||||
|     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_P(port); | ||||
|     SERIAL_ERRORLNPGM_P(port, MSG_ERR_NO_THERMISTORS); | ||||
|   #endif | ||||
|  | ||||
|   SERIAL_EOL_P(port); | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user