Browse Source

Cmdqueue code in separate files, debug codes for read/write eeprom and ram, PWM amplitude for Y axis stealtchop mode increased to 210.

Robert Pelnar 6 years ago
parent
commit
9105de073c

+ 192 - 0
Firmware/Dcodes.cpp

@@ -0,0 +1,192 @@
+#include "Dcodes.h"
+#include "Marlin.h"
+#include "cmdqueue.h"
+
+inline void serial_print_hex_nibble(uint8_t val)
+{
+	MYSERIAL.write((val > 9)?(val - 10 + 'a'):(val + '0'));
+}
+
+void serial_print_hex_byte(uint8_t val)
+{
+	serial_print_hex_nibble(val >> 4);
+	serial_print_hex_nibble(val & 15);
+}
+
+void serial_print_hex_word(uint16_t val)
+{
+	serial_print_hex_byte(val >> 8);
+	serial_print_hex_byte(val & 255);
+}
+
+int parse_hex(char* hex, uint8_t* data, int count)
+{
+	int parsed = 0;
+	while (*hex)
+	{
+		if (count && (parsed >= count)) break;
+		char c = *(hex++);
+		if (c == ' ') continue;
+		if (c == '\n') break;
+		uint8_t val = 0x00;
+		if ((c >= '0') && (c <= '9')) val |= ((c - '0') << 4);
+		else if ((c >= 'a') && (c <= 'f')) val |= ((c - 'a' + 10) << 4);
+		else return -parsed;
+		c = *(hex++);
+		if ((c >= '0') && (c <= '9')) val |= (c - '0');
+		else if ((c >= 'a') && (c <= 'f')) val |= (c - 'a' + 10);
+		else return -parsed;
+		data[parsed] = val;
+		parsed++;
+	}
+	return parsed;
+}
+
+void dcode_0()
+{
+	if (*(strchr_pointer + 1) == 0) return;
+	MYSERIAL.println("D0 - Reset");
+	if (code_seen('B')) //bootloader
+		asm volatile("jmp 0x1e000");
+	else //reset
+		asm volatile("jmp 0x00000");
+/*
+	cli(); //disable interrupts
+	wdt_reset(); //reset watchdog
+	WDTCSR = (1<<WDCE) | (1<<WDE); //enable watchdog
+	WDTCSR = (1<<WDE) | (1<<WDP0); //30ms prescaler
+	while(1); //wait for reset
+*/
+}
+
+void dcode_1()
+{
+	MYSERIAL.println("D1 - Clear EEPROM");
+	cli();
+	for (int i = 0; i < 4096; i++)
+		eeprom_write_byte((unsigned char*)i, (unsigned char)0);
+	sei();
+}
+
+void dcode_2()
+{
+	MYSERIAL.println("D2 - Read/Write RAM");
+	uint16_t address = 0x0000; //default 0x0000
+	uint16_t count = 0x2000; //default 0x2000 (entire ram)
+	if (code_seen('A')) // Address (0x0000-0x1fff)
+		address = (strchr_pointer[1] == 'x')?strtol(strchr_pointer + 2, 0, 16):(int)code_value();
+	if (code_seen('C')) // Count (0x0001-0x2000)
+		count = (int)code_value();
+	address &= 0x1fff;
+	if (count > 0x2000) count = 0x2000;
+	if ((address + count) > 0x2000) count = 0x2000 - address;
+	if (code_seen('X')) // Data
+	{
+		uint8_t data[16];
+		count = parse_hex(strchr_pointer + 1, data, 16);
+		if (count > 0)
+		{
+			for (int i = 0; i < count; i++)
+				*((uint8_t*)(address + i)) =  data[i];
+			MYSERIAL.print(count, DEC);
+			MYSERIAL.println(" bytes written to RAM at addres ");
+			serial_print_hex_word(address);
+			MYSERIAL.write('\n');
+		}
+		else
+			count = 0;
+	}
+	while (count)
+	{
+		serial_print_hex_word(address);
+		MYSERIAL.write(' ');
+		uint8_t countperline = 16;
+		while (count && countperline)
+		{
+			uint8_t data = *((uint8_t*)address++);
+			MYSERIAL.write(' ');
+			serial_print_hex_byte(data);
+			countperline--;
+			count--;
+		}
+		MYSERIAL.write('\n');
+	}
+}
+void dcode_3()
+{
+	MYSERIAL.println("D3 - Read/Write EEPROM");
+	uint16_t address = 0x0000; //default 0x0000
+	uint16_t count = 0x2000; //default 0x2000 (entire eeprom)
+	if (code_seen('A')) // Address (0x0000-0x1fff)
+		address = (strchr_pointer[1] == 'x')?strtol(strchr_pointer + 2, 0, 16):(int)code_value();
+	if (code_seen('C')) // Count (0x0001-0x2000)
+		count = (int)code_value();
+	address &= 0x1fff;
+	if (count > 0x2000) count = 0x2000;
+	if ((address + count) > 0x2000) count = 0x2000 - address;
+	if (code_seen('X')) // Data
+	{
+		uint8_t data[16];
+		count = parse_hex(strchr_pointer + 1, data, 16);
+		if (count > 0)
+		{
+			for (int i = 0; i < count; i++)
+				eeprom_write_byte((uint8_t*)(address + i), data[i]);
+			MYSERIAL.print(count, DEC);
+			MYSERIAL.println(" bytes written to EEPROM at addres ");
+			serial_print_hex_word(address);
+			MYSERIAL.write('\n');
+		}
+		else
+			count = 0;
+	}
+	while (count)
+	{
+		serial_print_hex_word(address);
+		MYSERIAL.write(' ');
+		uint8_t countperline = 16;
+		while (count && countperline)
+		{
+			uint8_t data = eeprom_read_byte((uint8_t*)address++);
+			MYSERIAL.write(' ');
+			serial_print_hex_byte(data);
+			countperline--;
+			count--;
+		}
+		MYSERIAL.write('\n');
+	}
+}
+
+void dcode_4()
+{
+	MYSERIAL.println("D4 - Read/Write PIN");
+	if (code_seen('P')) // Pin (0-255)
+	{
+		int pin = (int)code_value();
+		if ((pin >= 0) && (pin <= 255))
+		{
+			if (code_seen('F')) // Function in/out (0/1)
+			{
+				int fnc = (int)code_value();
+				if (fnc == 0) pinMode(pin, INPUT);
+				else if (fnc == 1) pinMode(pin, OUTPUT);
+			}
+			if (code_seen('V')) // Value (0/1)
+			{
+				int val = (int)code_value();
+				if (val == 0) digitalWrite(pin, LOW);
+				else if (val == 1) digitalWrite(pin, HIGH);
+			}
+			else
+			{
+				int val = (digitalRead(pin) != LOW)?1:0;
+				MYSERIAL.print("PIN");
+				MYSERIAL.print(pin);
+				MYSERIAL.print("=");
+				MYSERIAL.println(val);
+			}
+		}
+	}
+}
+
+

+ 11 - 0
Firmware/Dcodes.h

@@ -0,0 +1,11 @@
+#ifndef DCODES_H
+#define DCODES_H
+
+extern void dcode_0();
+extern void dcode_1();
+extern void dcode_2();
+extern void dcode_3();
+extern void dcode_4();
+
+
+#endif //DCODES_H

+ 26 - 687
Firmware/Marlin_main.cpp

@@ -57,6 +57,9 @@
 
 #include <avr/wdt.h>
 
+#include "Dcodes.h"
+
+
 #ifdef SWSPI
 #include "swspi.h"
 #endif //SWSPI
@@ -96,6 +99,8 @@
 
 #include "ultralcd.h"
 
+#include "cmdqueue.h"
+
 // Macros for bit masks
 #define BIT(b) (1<<(b))
 #define TEST(n,b) (((n)&BIT(b))!=0)
@@ -240,8 +245,6 @@
 CardReader card;
 #endif
 
-unsigned long TimeSent = millis();
-unsigned long TimeNow = millis();
 unsigned long PingTime = millis();
 union Data
 {
@@ -417,58 +420,11 @@ static float delta[3] = {0.0, 0.0, 0.0};
 static float offset[3] = {0.0, 0.0, 0.0};
 static bool home_all_axis = true;
 static float feedrate = 1500.0, next_feedrate, saved_feedrate;
-static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
 
 // Determines Absolute or Relative Coordinates.
 // Also there is bool axis_relative_modes[] per axis flag.
 static bool relative_mode = false;  
 
-// String circular buffer. Commands may be pushed to the buffer from both sides:
-// Chained commands will be pushed to the front, interactive (from LCD menu) 
-// and printing commands (from serial line or from SD card) are pushed to the tail.
-// First character of each entry indicates the type of the entry: 
-#define CMDBUFFER_CURRENT_TYPE_UNKNOWN  0
-// Command in cmdbuffer was sent over USB.
-#define CMDBUFFER_CURRENT_TYPE_USB      1
-// Command in cmdbuffer was read from SDCARD.
-#define CMDBUFFER_CURRENT_TYPE_SDCARD   2
-// Command in cmdbuffer was generated by the UI.
-#define CMDBUFFER_CURRENT_TYPE_UI       3
-// Command in cmdbuffer was generated by another G-code.
-#define CMDBUFFER_CURRENT_TYPE_CHAINED  4
-
-// How much space to reserve for the chained commands
-// of type CMDBUFFER_CURRENT_TYPE_CHAINED,
-// which are pushed to the front of the queue?
-// Maximum 5 commands of max length 20 + null terminator.
-#define CMDBUFFER_RESERVE_FRONT       (5*21)
-// Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT.
-static char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];
-// Head of the circular buffer, where to read.
-static int bufindr = 0;
-// Tail of the buffer, where to write.
-static int bufindw = 0;
-// Number of lines in cmdbuffer.
-static int buflen = 0;
-// Flag for processing the current command inside the main Arduino loop().
-// If a new command was pushed to the front of a command buffer while
-// processing another command, this replaces the command on the top.
-// Therefore don't remove the command from the queue in the loop() function.
-static bool cmdbuffer_front_already_processed = false;
-
-// Type of a command, which is to be executed right now.
-#define CMDBUFFER_CURRENT_TYPE   (cmdbuffer[bufindr])
-// String of a command, which is to be executed right now.
-#define CMDBUFFER_CURRENT_STRING (cmdbuffer+bufindr+CMDHDRSIZE)
-
-// Enable debugging of the command buffer.
-// Debugging information will be sent to serial line.
-//#define CMDBUFFER_DEBUG
-
-static int serial_count = 0;  //index of character read from serial line
-static boolean comment_mode = false;
-static char *strchr_pointer; // just a pointer to find chars in the command string like X, Y, Z, E, etc
-
 const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42
 
 //static float tt = 0;
@@ -537,315 +493,6 @@ void serial_echopair_P(const char *s_P, unsigned long v)
   }
 #endif //!SDSUPPORT
 
-// Pop the currently processed command from the queue.
-// It is expected, that there is at least one command in the queue.
-bool cmdqueue_pop_front()
-{
-    if (buflen > 0) {
-#ifdef CMDBUFFER_DEBUG
-        SERIAL_ECHOPGM("Dequeing ");
-        SERIAL_ECHO(cmdbuffer+bufindr+CMDHDRSIZE);
-        SERIAL_ECHOLNPGM("");
-        SERIAL_ECHOPGM("Old indices: buflen ");
-        SERIAL_ECHO(buflen);
-        SERIAL_ECHOPGM(", bufindr ");
-        SERIAL_ECHO(bufindr);
-        SERIAL_ECHOPGM(", bufindw ");
-        SERIAL_ECHO(bufindw);
-        SERIAL_ECHOPGM(", serial_count ");
-        SERIAL_ECHO(serial_count);
-        SERIAL_ECHOPGM(", bufsize ");
-        SERIAL_ECHO(sizeof(cmdbuffer));
-        SERIAL_ECHOLNPGM("");
-#endif /* CMDBUFFER_DEBUG */
-        if (-- buflen == 0) {
-            // Empty buffer.
-            if (serial_count == 0)
-                // No serial communication is pending. Reset both pointers to zero.
-                bufindw = 0;
-            bufindr = bufindw;
-        } else {
-            // There is at least one ready line in the buffer.
-            // First skip the current command ID and iterate up to the end of the string.
-//            for (++ bufindr; cmdbuffer[bufindr] != 0; ++ bufindr) ;
-            for (bufindr += CMDHDRSIZE; cmdbuffer[bufindr] != 0; ++ bufindr) ;
-            // Second, skip the end of string null character and iterate until a nonzero command ID is found.
-            for (++ bufindr; bufindr < sizeof(cmdbuffer) && cmdbuffer[bufindr] == 0; ++ bufindr) ;
-            // If the end of the buffer was empty,
-            if (bufindr == sizeof(cmdbuffer)) {
-                // skip to the start and find the nonzero command.
-                for (bufindr = 0; cmdbuffer[bufindr] == 0; ++ bufindr) ;
-            }
-#ifdef CMDBUFFER_DEBUG
-            SERIAL_ECHOPGM("New indices: buflen ");
-            SERIAL_ECHO(buflen);
-            SERIAL_ECHOPGM(", bufindr ");
-            SERIAL_ECHO(bufindr);
-            SERIAL_ECHOPGM(", bufindw ");
-            SERIAL_ECHO(bufindw);
-            SERIAL_ECHOPGM(", serial_count ");
-            SERIAL_ECHO(serial_count);
-            SERIAL_ECHOPGM(" new command on the top: ");
-            SERIAL_ECHO(cmdbuffer+bufindr+CMDHDRSIZE);
-            SERIAL_ECHOLNPGM("");
-#endif /* CMDBUFFER_DEBUG */
-        }
-        return true;
-    }
-    return false;
-}
-
-void cmdqueue_reset()
-{
-    while (cmdqueue_pop_front()) ;
-}
-
-// How long a string could be pushed to the front of the command queue?
-// If yes, adjust bufindr to the new position, where the new command could be enqued.
-// len_asked does not contain the zero terminator size.
-bool cmdqueue_could_enqueue_front(int len_asked)
-{
-    // MAX_CMD_SIZE has to accommodate the zero terminator.
-    if (len_asked >= MAX_CMD_SIZE)
-        return false;
-    // Remove the currently processed command from the queue.
-    if (! cmdbuffer_front_already_processed) {
-        cmdqueue_pop_front();
-        cmdbuffer_front_already_processed = true;
-    }
-	if (bufindr == bufindw && buflen > 0)
-		// Full buffer.
-        return false;
-    // Adjust the end of the write buffer based on whether a partial line is in the receive buffer.
-    int endw = (serial_count > 0) ? (bufindw + MAX_CMD_SIZE + 1) : bufindw;
-    if (bufindw < bufindr) {
-        int bufindr_new = bufindr - len_asked - (1 + CMDHDRSIZE);
-        // Simple case. There is a contiguous space between the write buffer and the read buffer.
-        if (endw <= bufindr_new) {
-            bufindr = bufindr_new;
-            return true;
-        }
-    } else {
-        // Otherwise the free space is split between the start and end.
-        if (len_asked + (1 + CMDHDRSIZE) <= bufindr) {
-            // Could fit at the start.
-            bufindr -= len_asked + (1 + CMDHDRSIZE);
-            return true;
-        }
-        int bufindr_new = sizeof(cmdbuffer) - len_asked - (1 + CMDHDRSIZE);
-        if (endw <= bufindr_new) {
-            memset(cmdbuffer, 0, bufindr);
-            bufindr = bufindr_new;
-            return true;
-        }
-    }
-    return false;
-}
-
-// Could one enqueue a command of lenthg len_asked into the buffer,
-// while leaving CMDBUFFER_RESERVE_FRONT at the start?
-// If yes, adjust bufindw to the new position, where the new command could be enqued.
-// len_asked does not contain the zero terminator size.
-bool cmdqueue_could_enqueue_back(int len_asked)
-{
-    // MAX_CMD_SIZE has to accommodate the zero terminator.
-    if (len_asked >= MAX_CMD_SIZE)
-        return false;
-
-	if (bufindr == bufindw && buflen > 0)
-		// Full buffer.
-		return false;
-
-    if (serial_count > 0) {
-        // If there is some data stored starting at bufindw, len_asked is certainly smaller than
-        // the allocated data buffer. Try to reserve a new buffer and to move the already received
-        // serial data.
-        // How much memory to reserve for the commands pushed to the front?
-        // End of the queue, when pushing to the end.
-        int endw = bufindw + len_asked + (1 + CMDHDRSIZE);
-        if (bufindw < bufindr)
-            // Simple case. There is a contiguous space between the write buffer and the read buffer.
-            return endw + CMDBUFFER_RESERVE_FRONT <= bufindr;
-        // Otherwise the free space is split between the start and end.
-        if (// Could one fit to the end, including the reserve?
-            endw + CMDBUFFER_RESERVE_FRONT <= sizeof(cmdbuffer) ||
-            // Could one fit to the end, and the reserve to the start?
-            (endw <= sizeof(cmdbuffer) && CMDBUFFER_RESERVE_FRONT <= bufindr))
-            return true;
-        // Could one fit both to the start?
-        if (len_asked + (1 + CMDHDRSIZE) + CMDBUFFER_RESERVE_FRONT <= bufindr) {
-            // Mark the rest of the buffer as used.
-            memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
-            // and point to the start.
-            bufindw = 0;
-            return true;
-        }
-    } else {
-        // How much memory to reserve for the commands pushed to the front?
-        // End of the queue, when pushing to the end.
-        int endw = bufindw + len_asked + (1 + CMDHDRSIZE);
-        if (bufindw < bufindr)
-            // Simple case. There is a contiguous space between the write buffer and the read buffer.
-            return endw + CMDBUFFER_RESERVE_FRONT <= bufindr;
-        // Otherwise the free space is split between the start and end.
-        if (// Could one fit to the end, including the reserve?
-            endw + CMDBUFFER_RESERVE_FRONT <= sizeof(cmdbuffer) ||
-            // Could one fit to the end, and the reserve to the start?
-            (endw <= sizeof(cmdbuffer) && CMDBUFFER_RESERVE_FRONT <= bufindr))
-            return true;
-        // Could one fit both to the start?
-        if (len_asked + (1 + CMDHDRSIZE) + CMDBUFFER_RESERVE_FRONT <= bufindr) {
-            // Mark the rest of the buffer as used.
-            memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
-            // and point to the start.
-            bufindw = 0;
-            return true;
-        }
-    }
-    return false;
-}
-
-#ifdef CMDBUFFER_DEBUG
-static void cmdqueue_dump_to_serial_single_line(int nr, const char *p)
-{
-    SERIAL_ECHOPGM("Entry nr: ");
-    SERIAL_ECHO(nr);
-    SERIAL_ECHOPGM(", type: ");
-    SERIAL_ECHO(int(*p));
-    SERIAL_ECHOPGM(", cmd: ");
-    SERIAL_ECHO(p+1);  
-    SERIAL_ECHOLNPGM("");
-}
-
-static void cmdqueue_dump_to_serial()
-{
-    if (buflen == 0) {
-        SERIAL_ECHOLNPGM("The command buffer is empty.");
-    } else {
-        SERIAL_ECHOPGM("Content of the buffer: entries ");
-        SERIAL_ECHO(buflen);
-        SERIAL_ECHOPGM(", indr ");
-        SERIAL_ECHO(bufindr);
-        SERIAL_ECHOPGM(", indw ");
-        SERIAL_ECHO(bufindw);
-        SERIAL_ECHOLNPGM("");
-        int nr = 0;
-        if (bufindr < bufindw) {
-            for (const char *p = cmdbuffer + bufindr; p < cmdbuffer + bufindw; ++ nr) {
-                cmdqueue_dump_to_serial_single_line(nr, p);
-                // Skip the command.
-                for (++p; *p != 0; ++ p);
-                // Skip the gaps.
-                for (++p; p < cmdbuffer + bufindw && *p == 0; ++ p);
-            }
-        } else {
-            for (const char *p = cmdbuffer + bufindr; p < cmdbuffer + sizeof(cmdbuffer); ++ nr) {
-                cmdqueue_dump_to_serial_single_line(nr, p);
-                // Skip the command.
-                for (++p; *p != 0; ++ p);
-                // Skip the gaps.
-                for (++p; p < cmdbuffer + sizeof(cmdbuffer) && *p == 0; ++ p);
-            }
-            for (const char *p = cmdbuffer; p < cmdbuffer + bufindw; ++ nr) {
-                cmdqueue_dump_to_serial_single_line(nr, p);
-                // Skip the command.
-                for (++p; *p != 0; ++ p);
-                // Skip the gaps.
-                for (++p; p < cmdbuffer + bufindw && *p == 0; ++ p);
-            }
-        }
-        SERIAL_ECHOLNPGM("End of the buffer.");
-    }
-}
-#endif /* CMDBUFFER_DEBUG */
-
-//adds an command to the main command buffer
-//thats really done in a non-safe way.
-//needs overworking someday
-// Currently the maximum length of a command piped through this function is around 20 characters
-void enquecommand(const char *cmd, bool from_progmem)
-{
-    int len = from_progmem ? strlen_P(cmd) : strlen(cmd);
-    // Does cmd fit the queue while leaving sufficient space at the front for the chained commands?
-    // If it fits, it may move bufindw, so it points to a contiguous buffer, which fits cmd.
-    if (cmdqueue_could_enqueue_back(len)) {
-        // This is dangerous if a mixing of serial and this happens
-        // This may easily be tested: If serial_count > 0, we have a problem.
-        cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_UI;
-        if (from_progmem)
-            strcpy_P(cmdbuffer + bufindw + CMDHDRSIZE, cmd);
-        else
-            strcpy(cmdbuffer + bufindw + CMDHDRSIZE, cmd);
-        SERIAL_ECHO_START;
-        SERIAL_ECHORPGM(MSG_Enqueing);
-        SERIAL_ECHO(cmdbuffer + bufindw + CMDHDRSIZE);
-        SERIAL_ECHOLNPGM("\"");
-        bufindw += len + (CMDHDRSIZE + 1);
-        if (bufindw == sizeof(cmdbuffer))
-            bufindw = 0;
-        ++ buflen;
-#ifdef CMDBUFFER_DEBUG
-        cmdqueue_dump_to_serial();
-#endif /* CMDBUFFER_DEBUG */
-    } else {
-        SERIAL_ERROR_START;
-        SERIAL_ECHORPGM(MSG_Enqueing);
-        if (from_progmem)
-            SERIAL_PROTOCOLRPGM(cmd);
-        else
-            SERIAL_ECHO(cmd);
-        SERIAL_ECHOLNPGM("\" failed: Buffer full!");
-#ifdef CMDBUFFER_DEBUG
-        cmdqueue_dump_to_serial();
-#endif /* CMDBUFFER_DEBUG */
-    }
-}
-
-void enquecommand_front(const char *cmd, bool from_progmem)
-{
-    int len = from_progmem ? strlen_P(cmd) : strlen(cmd);
-    // Does cmd fit the queue? This call shall move bufindr, so the command may be copied.
-    if (cmdqueue_could_enqueue_front(len)) {
-        cmdbuffer[bufindr] = CMDBUFFER_CURRENT_TYPE_UI;
-        if (from_progmem)
-            strcpy_P(cmdbuffer + bufindr + CMDHDRSIZE, cmd);
-        else
-            strcpy(cmdbuffer + bufindr + CMDHDRSIZE, cmd);
-        ++ buflen;
-        SERIAL_ECHO_START;
-        SERIAL_ECHOPGM("Enqueing to the front: \"");
-        SERIAL_ECHO(cmdbuffer + bufindr + CMDHDRSIZE);
-        SERIAL_ECHOLNPGM("\"");
-#ifdef CMDBUFFER_DEBUG
-        cmdqueue_dump_to_serial();
-#endif /* CMDBUFFER_DEBUG */
-    } else {
-        SERIAL_ERROR_START;
-        SERIAL_ECHOPGM("Enqueing to the front: \"");
-        if (from_progmem)
-            SERIAL_PROTOCOLRPGM(cmd);
-        else
-            SERIAL_ECHO(cmd);
-        SERIAL_ECHOLNPGM("\" failed: Buffer full!");
-#ifdef CMDBUFFER_DEBUG
-        cmdqueue_dump_to_serial();
-#endif /* CMDBUFFER_DEBUG */
-    }
-}
-
-// Mark the command at the top of the command queue as new.
-// Therefore it will not be removed from the queue.
-void repeatcommand_front()
-{
-    cmdbuffer_front_already_processed = true;
-} 
-
-bool is_buffer_empty()
-{
-	if (buflen == 0) return true;
-	else return false;
-}
-
 void setup_killpin()
 {
   #if defined(KILL_PIN) && KILL_PIN > -1
@@ -1520,287 +1167,6 @@ void loop()
 #endif //TMC2130
 }
 
-void get_command()
-{
-    // Test and reserve space for the new command string.
-	if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1)) 
-		return;
-	
-	bool rx_buffer_full = false; //flag that serial rx buffer is full
-
-  while (MYSERIAL.available() > 0) {
-	  if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
-		  SERIAL_ECHOLNPGM("Full RX Buffer");   //if buffer was full, there is danger that reading of last gcode will not be completed
-		  rx_buffer_full = true;				//sets flag that buffer was full	
-	  }
-    char serial_char = MYSERIAL.read();
-	if (selectedSerialPort == 1)
-	{
-		selectedSerialPort = 0; 
-		MYSERIAL.write(serial_char); 
-		selectedSerialPort = 1; 
-	} 
-      TimeSent = millis();
-      TimeNow = millis();
-
-    if (serial_char < 0)
-        // Ignore extended ASCII characters. These characters have no meaning in the G-code apart from the file names
-        // and Marlin does not support such file names anyway.
-        // Serial characters with a highest bit set to 1 are generated when the USB cable is unplugged, leading
-        // to a hang-up of the print process from an SD card.
-        continue;
-    if(serial_char == '\n' ||
-       serial_char == '\r' ||
-       (serial_char == ':' && comment_mode == false) ||
-       serial_count >= (MAX_CMD_SIZE - 1) )
-    {
-      if(!serial_count) { //if empty line
-        comment_mode = false; //for new command
-        return;
-      }
-      cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
-      if(!comment_mode){
-        comment_mode = false; //for new command
-        if ((strchr_pointer = strstr(cmdbuffer+bufindw+CMDHDRSIZE, "PRUSA")) == NULL && (strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'N')) != NULL) {
-            if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'N')) != NULL)
-            {
-            // Line number met. When sending a G-code over a serial line, each line may be stamped with its index,
-            // and Marlin tests, whether the successive lines are stamped with an increasing line number ID.
-            gcode_N = (strtol(strchr_pointer+1, NULL, 10));
-            if(gcode_N != gcode_LastN+1 && (strstr_P(cmdbuffer+bufindw+CMDHDRSIZE, PSTR("M110")) == NULL) ) {
-                // M110 - set current line number.
-                // Line numbers not sent in succession.
-                SERIAL_ERROR_START;
-                SERIAL_ERRORRPGM(MSG_ERR_LINE_NO);
-                SERIAL_ERRORLN(gcode_LastN);
-                //Serial.println(gcode_N);
-                FlushSerialRequestResend();
-                serial_count = 0;
-                return;
-            }
-
-            if((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*')) != NULL)
-            {
-                byte checksum = 0;
-                char *p = cmdbuffer+bufindw+CMDHDRSIZE;
-                while (p != strchr_pointer)
-                    checksum = checksum^(*p++);
-                if (int(strtol(strchr_pointer+1, NULL, 10)) != int(checksum)) {
-                SERIAL_ERROR_START;
-                SERIAL_ERRORRPGM(MSG_ERR_CHECKSUM_MISMATCH);
-                SERIAL_ERRORLN(gcode_LastN);
-                FlushSerialRequestResend();
-                serial_count = 0;
-                return;
-                }
-                // If no errors, remove the checksum and continue parsing.
-                *strchr_pointer = 0;
-            }
-            else
-            {
-                SERIAL_ERROR_START;
-                SERIAL_ERRORRPGM(MSG_ERR_NO_CHECKSUM);
-                SERIAL_ERRORLN(gcode_LastN);
-                FlushSerialRequestResend();
-                serial_count = 0;
-                return;
-            }
-
-            gcode_LastN = gcode_N;
-            //if no errors, continue parsing
-            } // end of 'N' command
-        }
-        else  // if we don't receive 'N' but still see '*'
-        {
-          if((strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*') != NULL))
-          {
-            SERIAL_ERROR_START;
-            SERIAL_ERRORRPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
-            SERIAL_ERRORLN(gcode_LastN);
-            serial_count = 0;
-            return;
-          }
-        } // end of '*' command
-        if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'G')) != NULL) {
-      		  if (! IS_SD_PRINTING) {
-        			  usb_printing_counter = 10;
-        			  is_usb_printing = true;
-      		  }
-            if (Stopped == true) {
-                int gcode = strtol(strchr_pointer+1, NULL, 10);
-                if (gcode >= 0 && gcode <= 3) {
-                    SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
-                    LCD_MESSAGERPGM(MSG_STOPPED);
-                }
-            }
-        } // end of 'G' command
-
-        //If command was e-stop process now
-        if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
-          kill("", 2);
-        
-        // Store the current line into buffer, move to the next line.
-        cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_USB;
-#ifdef CMDBUFFER_DEBUG
-        SERIAL_ECHO_START;
-        SERIAL_ECHOPGM("Storing a command line to buffer: ");
-        SERIAL_ECHO(cmdbuffer+bufindw+CMDHDRSIZE);
-        SERIAL_ECHOLNPGM("");
-#endif /* CMDBUFFER_DEBUG */
-        bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
-        if (bufindw == sizeof(cmdbuffer))
-            bufindw = 0;
-        ++ buflen;
-#ifdef CMDBUFFER_DEBUG
-        SERIAL_ECHOPGM("Number of commands in the buffer: ");
-        SERIAL_ECHO(buflen);
-        SERIAL_ECHOLNPGM("");
-#endif /* CMDBUFFER_DEBUG */
-      } // end of 'not comment mode'
-      serial_count = 0; //clear buffer
-      // Don't call cmdqueue_could_enqueue_back if there are no characters waiting
-      // in the queue, as this function will reserve the memory.
-      if (MYSERIAL.available() == 0 || ! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
-          return;
-    } // end of "end of line" processing
-    else {
-      // Not an "end of line" symbol. Store the new character into a buffer.
-      if(serial_char == ';') comment_mode = true;
-      if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
-    }
-  } // end of serial line processing loop
-
-    if(farm_mode){
-        TimeNow = millis();
-        if ( ((TimeNow - TimeSent) > 800) && (serial_count > 0) ) {
-            cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0;
-            
-            bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
-            if (bufindw == sizeof(cmdbuffer))
-                bufindw = 0;
-            ++ buflen;
-            
-            serial_count = 0;
-            
-            SERIAL_ECHOPGM("TIMEOUT:");
-            //memset(cmdbuffer, 0 , sizeof(cmdbuffer));
-            return;
-        }
-    }
-
-	//add comment
-	if (rx_buffer_full == true && serial_count > 0) {   //if rx buffer was full and string was not properly terminated
-		rx_buffer_full = false;
-		bufindw = bufindw - serial_count;				//adjust tail of the buffer to prepare buffer for writing new command
-		serial_count = 0;
-	}
-
-  #ifdef SDSUPPORT
-  if(!card.sdprinting || serial_count!=0){
-    // If there is a half filled buffer from serial line, wait until return before
-    // continuing with the serial line.
-     return;
-  }
-
-  //'#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible
-  // if it occurs, stop_buffering is triggered and the buffer is ran dry.
-  // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
-
-  static bool stop_buffering=false;
-  if(buflen==0) stop_buffering=false;
-  unsigned char sd_count = 0;
-  // Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer.
-  while( !card.eof() && !stop_buffering) {
-    int16_t n=card.get();
-	sd_count++;
-    char serial_char = (char)n;
-    if(serial_char == '\n' ||
-       serial_char == '\r' ||
-       (serial_char == '#' && comment_mode == false) ||
-       (serial_char == ':' && comment_mode == false) ||
-       serial_count >= (MAX_CMD_SIZE - 1)||n==-1)
-    {
-      if(card.eof()){
-        SERIAL_PROTOCOLLNRPGM(MSG_FILE_PRINTED);
-        stoptime=millis();
-        char time[30];
-        unsigned long t=(stoptime-starttime-pause_time)/1000;
-		pause_time = 0;
-        int hours, minutes;
-        minutes=(t/60)%60;
-        hours=t/60/60;
-		save_statistics(total_filament_used, t);
-		sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
-        SERIAL_ECHO_START;
-        SERIAL_ECHOLN(time);
-        lcd_setstatus(time);
-        card.printingHasFinished();
-        card.checkautostart(true);
-
-		if (farm_mode)
-		{
-			prusa_statistics(6);
-			lcd_commands_type = LCD_COMMAND_FARM_MODE_CONFIRM;
-		}
-
-      }
-      if(serial_char=='#')
-        stop_buffering=true;
-
-      if(!serial_count)
-      {
-        comment_mode = false; //for new command
-        return; //if empty line
-      }
-      cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
-      cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD;
-      cmdbuffer[bufindw+1] = sd_count;
-/*	  SERIAL_ECHOPGM("SD cmd(");
-	  MYSERIAL.print(sd_count, DEC);
-	  SERIAL_ECHOPGM(") ");
-	  SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE);*/
-//	  SERIAL_ECHOPGM("cmdbuffer:");
-//	  MYSERIAL.print(cmdbuffer);
-      ++ buflen;
-//	  SERIAL_ECHOPGM("buflen:");
-//	  MYSERIAL.print(buflen);
-      bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
-      if (bufindw == sizeof(cmdbuffer))
-          bufindw = 0;
-      comment_mode = false; //for new command
-      serial_count = 0; //clear buffer
-      // The following line will reserve buffer space if available.
-      if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
-          return;
-    }
-    else
-    {
-      if(serial_char == ';') comment_mode = true;
-      if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
-    }
-  }
-
-  #endif //SDSUPPORT
-}
-
-
-// Return True if a character was found
-static inline bool    code_seen(char code) { return (strchr_pointer = strchr(CMDBUFFER_CURRENT_STRING, code)) != NULL; }
-static inline bool    code_seen(const char *code) { return (strchr_pointer = strstr(CMDBUFFER_CURRENT_STRING, code)) != NULL; }
-static inline float   code_value()      { return strtod(strchr_pointer+1, NULL);}
-static inline long    code_value_long()    { return strtol(strchr_pointer+1, NULL, 10); }
-static inline int16_t code_value_short()   { return int16_t(strtol(strchr_pointer+1, NULL, 10)); };
-static inline uint8_t code_value_uint8()   { return uint8_t(strtol(strchr_pointer+1, NULL, 10)); };
-
-static inline float code_value_float() {
-    char* e = strchr(strchr_pointer, 'E');
-    if (!e) return strtod(strchr_pointer + 1, NULL);
-    *e = 0;
-    float ret = strtod(strchr_pointer + 1, NULL);
-    *e = 'E';
-    return ret;
-}
-
 #define DEFINE_PGM_READ_ANY(type, reader)       \
     static inline type pgm_read_any(const type *p)  \
     { return pgm_read_##reader##_near(p); }
@@ -6207,57 +5573,30 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
     switch((int)code_value())
     {
 	case 0: // D0 - Reset
-		if (*(strchr_pointer + 1) == 0) break;
-		MYSERIAL.println("D0 - Reset");
-		asm volatile("jmp 0x00000");
-		break;
-/*		MYSERIAL.println("D0 - Reset");
-		cli(); //disable interrupts
-		wdt_reset(); //reset watchdog
-		WDTCSR = (1<<WDCE) | (1<<WDE); //enable watchdog
-		WDTCSR = (1<<WDE) | (1<<WDP0); //30ms prescaler
-		while(1); //wait for reset*/
+		dcode_0(); break;
 	case 1: // D1 - Clear EEPROM
+		dcode_1(); break;
+	case 2: // D2 - Read/Write RAM
+		dcode_2(); break;
+	case 3: // D3 - Read/Write EEPROM
+		dcode_3(); break;
+	case 4: // D4 - Read/Write PIN
+		dcode_4(); break;
+/*	case 4:
 		{
-			MYSERIAL.println("D1 - Clear EEPROM");
-			cli();
-			for (int i = 0; i < 4096; i++)
-				eeprom_write_byte((unsigned char*)i, (unsigned char)0);
-			sei();
-		}
-		break;
-	case 2: // D2 - Read/Write PIN
-		{
-			if (code_seen('P')) // Pin (0-255)
+			MYSERIAL.println("D4 - Test");
+			uint8_t data[16];
+			int cnt = parse_hex(strchr_pointer + 2, data, 16);
+			MYSERIAL.println(cnt, DEC);
+			for (int i = 0; i < cnt; i++)
 			{
-				int pin = (int)code_value();
-				if ((pin >= 0) && (pin <= 255))
-				{
-					if (code_seen('F')) // Function in/out (0/1)
-					{
-						int fnc = (int)code_value();
-						if (fnc == 0) pinMode(pin, INPUT);
-						else if (fnc == 1) pinMode(pin, OUTPUT);
-					}
-					if (code_seen('V')) // Value (0/1)
-					{
-						int val = (int)code_value();
-						if (val == 0) digitalWrite(pin, LOW);
-						else if (val == 1) digitalWrite(pin, HIGH);
-					}
-					else
-					{
-						int val = (digitalRead(pin) != LOW)?1:0;
-						MYSERIAL.print("PIN");
-						MYSERIAL.print(pin);
-						MYSERIAL.print("=");
-						MYSERIAL.println(val);
-					}
-				}
+				serial_print_hex_byte(data[i]);
+				MYSERIAL.write(' ');
 			}
+			MYSERIAL.write('\n');
 		}
 		break;
-	case 3:
+/*	case 3:
 		if (code_seen('L')) // lcd pwm (0-255)
 		{
 			lcdSoftPwm = (int)code_value();
@@ -6272,14 +5611,14 @@ case 404:  //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp
 		fsensor_enable();
 #endif*/
 		break;
-	case 4:
+//	case 4:
 //			lcdBlinkDelay = 10;
 /*		MYSERIAL.print("fsensor_disable()");
 #ifdef PAT9125
 		fsensor_disable();
 #endif            
 		break;*/
-		break;
+//		break;
 	case 5:
 		{
 /*			MYSERIAL.print("tmc2130_rd_MSCNT(0)=");
@@ -7352,7 +6691,7 @@ void serialecho_temperatures() {
 
 
 void uvlo_() {
-		//SERIAL_ECHOLNPGM("UVLO");	
+		//SERIAL_ECHOLNPGM("UVLO");
 		save_print_to_eeprom();
 		float current_position_bckp[2];
 		int feedrate_bckp = feedrate;

+ 603 - 0
Firmware/cmdqueue.cpp

@@ -0,0 +1,603 @@
+#include "cmdqueue.h"
+#include "cardreader.h"
+#include "ultralcd.h"
+
+extern bool Stopped;
+
+// Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT.
+char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];
+// Head of the circular buffer, where to read.
+int bufindr = 0;
+// Tail of the buffer, where to write.
+int bufindw = 0;
+// Number of lines in cmdbuffer.
+int buflen = 0;
+// Flag for processing the current command inside the main Arduino loop().
+// If a new command was pushed to the front of a command buffer while
+// processing another command, this replaces the command on the top.
+// Therefore don't remove the command from the queue in the loop() function.
+bool cmdbuffer_front_already_processed = false;
+
+int serial_count = 0;  //index of character read from serial line
+boolean comment_mode = false;
+char *strchr_pointer; // just a pointer to find chars in the command string like X, Y, Z, E, etc
+
+unsigned long TimeSent = millis();
+unsigned long TimeNow = millis();
+
+long gcode_N = 0;
+long gcode_LastN = 0;
+long Stopped_gcode_LastN = 0;
+
+
+// Pop the currently processed command from the queue.
+// It is expected, that there is at least one command in the queue.
+bool cmdqueue_pop_front()
+{
+    if (buflen > 0) {
+#ifdef CMDBUFFER_DEBUG
+        SERIAL_ECHOPGM("Dequeing ");
+        SERIAL_ECHO(cmdbuffer+bufindr+CMDHDRSIZE);
+        SERIAL_ECHOLNPGM("");
+        SERIAL_ECHOPGM("Old indices: buflen ");
+        SERIAL_ECHO(buflen);
+        SERIAL_ECHOPGM(", bufindr ");
+        SERIAL_ECHO(bufindr);
+        SERIAL_ECHOPGM(", bufindw ");
+        SERIAL_ECHO(bufindw);
+        SERIAL_ECHOPGM(", serial_count ");
+        SERIAL_ECHO(serial_count);
+        SERIAL_ECHOPGM(", bufsize ");
+        SERIAL_ECHO(sizeof(cmdbuffer));
+        SERIAL_ECHOLNPGM("");
+#endif /* CMDBUFFER_DEBUG */
+        if (-- buflen == 0) {
+            // Empty buffer.
+            if (serial_count == 0)
+                // No serial communication is pending. Reset both pointers to zero.
+                bufindw = 0;
+            bufindr = bufindw;
+        } else {
+            // There is at least one ready line in the buffer.
+            // First skip the current command ID and iterate up to the end of the string.
+//            for (++ bufindr; cmdbuffer[bufindr] != 0; ++ bufindr) ;
+            for (bufindr += CMDHDRSIZE; cmdbuffer[bufindr] != 0; ++ bufindr) ;
+            // Second, skip the end of string null character and iterate until a nonzero command ID is found.
+            for (++ bufindr; bufindr < sizeof(cmdbuffer) && cmdbuffer[bufindr] == 0; ++ bufindr) ;
+            // If the end of the buffer was empty,
+            if (bufindr == sizeof(cmdbuffer)) {
+                // skip to the start and find the nonzero command.
+                for (bufindr = 0; cmdbuffer[bufindr] == 0; ++ bufindr) ;
+            }
+#ifdef CMDBUFFER_DEBUG
+            SERIAL_ECHOPGM("New indices: buflen ");
+            SERIAL_ECHO(buflen);
+            SERIAL_ECHOPGM(", bufindr ");
+            SERIAL_ECHO(bufindr);
+            SERIAL_ECHOPGM(", bufindw ");
+            SERIAL_ECHO(bufindw);
+            SERIAL_ECHOPGM(", serial_count ");
+            SERIAL_ECHO(serial_count);
+            SERIAL_ECHOPGM(" new command on the top: ");
+            SERIAL_ECHO(cmdbuffer+bufindr+CMDHDRSIZE);
+            SERIAL_ECHOLNPGM("");
+#endif /* CMDBUFFER_DEBUG */
+        }
+        return true;
+    }
+    return false;
+}
+
+void cmdqueue_reset()
+{
+    while (cmdqueue_pop_front()) ;
+}
+
+// How long a string could be pushed to the front of the command queue?
+// If yes, adjust bufindr to the new position, where the new command could be enqued.
+// len_asked does not contain the zero terminator size.
+bool cmdqueue_could_enqueue_front(int len_asked)
+{
+    // MAX_CMD_SIZE has to accommodate the zero terminator.
+    if (len_asked >= MAX_CMD_SIZE)
+        return false;
+    // Remove the currently processed command from the queue.
+    if (! cmdbuffer_front_already_processed) {
+        cmdqueue_pop_front();
+        cmdbuffer_front_already_processed = true;
+    }
+	if (bufindr == bufindw && buflen > 0)
+		// Full buffer.
+        return false;
+    // Adjust the end of the write buffer based on whether a partial line is in the receive buffer.
+    int endw = (serial_count > 0) ? (bufindw + MAX_CMD_SIZE + 1) : bufindw;
+    if (bufindw < bufindr) {
+        int bufindr_new = bufindr - len_asked - (1 + CMDHDRSIZE);
+        // Simple case. There is a contiguous space between the write buffer and the read buffer.
+        if (endw <= bufindr_new) {
+            bufindr = bufindr_new;
+            return true;
+        }
+    } else {
+        // Otherwise the free space is split between the start and end.
+        if (len_asked + (1 + CMDHDRSIZE) <= bufindr) {
+            // Could fit at the start.
+            bufindr -= len_asked + (1 + CMDHDRSIZE);
+            return true;
+        }
+        int bufindr_new = sizeof(cmdbuffer) - len_asked - (1 + CMDHDRSIZE);
+        if (endw <= bufindr_new) {
+            memset(cmdbuffer, 0, bufindr);
+            bufindr = bufindr_new;
+            return true;
+        }
+    }
+    return false;
+}
+
+// Could one enqueue a command of lenthg len_asked into the buffer,
+// while leaving CMDBUFFER_RESERVE_FRONT at the start?
+// If yes, adjust bufindw to the new position, where the new command could be enqued.
+// len_asked does not contain the zero terminator size.
+bool cmdqueue_could_enqueue_back(int len_asked)
+{
+    // MAX_CMD_SIZE has to accommodate the zero terminator.
+    if (len_asked >= MAX_CMD_SIZE)
+        return false;
+
+	if (bufindr == bufindw && buflen > 0)
+		// Full buffer.
+		return false;
+
+    if (serial_count > 0) {
+        // If there is some data stored starting at bufindw, len_asked is certainly smaller than
+        // the allocated data buffer. Try to reserve a new buffer and to move the already received
+        // serial data.
+        // How much memory to reserve for the commands pushed to the front?
+        // End of the queue, when pushing to the end.
+        int endw = bufindw + len_asked + (1 + CMDHDRSIZE);
+        if (bufindw < bufindr)
+            // Simple case. There is a contiguous space between the write buffer and the read buffer.
+            return endw + CMDBUFFER_RESERVE_FRONT <= bufindr;
+        // Otherwise the free space is split between the start and end.
+        if (// Could one fit to the end, including the reserve?
+            endw + CMDBUFFER_RESERVE_FRONT <= sizeof(cmdbuffer) ||
+            // Could one fit to the end, and the reserve to the start?
+            (endw <= sizeof(cmdbuffer) && CMDBUFFER_RESERVE_FRONT <= bufindr))
+            return true;
+        // Could one fit both to the start?
+        if (len_asked + (1 + CMDHDRSIZE) + CMDBUFFER_RESERVE_FRONT <= bufindr) {
+            // Mark the rest of the buffer as used.
+            memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
+            // and point to the start.
+            bufindw = 0;
+            return true;
+        }
+    } else {
+        // How much memory to reserve for the commands pushed to the front?
+        // End of the queue, when pushing to the end.
+        int endw = bufindw + len_asked + (1 + CMDHDRSIZE);
+        if (bufindw < bufindr)
+            // Simple case. There is a contiguous space between the write buffer and the read buffer.
+            return endw + CMDBUFFER_RESERVE_FRONT <= bufindr;
+        // Otherwise the free space is split between the start and end.
+        if (// Could one fit to the end, including the reserve?
+            endw + CMDBUFFER_RESERVE_FRONT <= sizeof(cmdbuffer) ||
+            // Could one fit to the end, and the reserve to the start?
+            (endw <= sizeof(cmdbuffer) && CMDBUFFER_RESERVE_FRONT <= bufindr))
+            return true;
+        // Could one fit both to the start?
+        if (len_asked + (1 + CMDHDRSIZE) + CMDBUFFER_RESERVE_FRONT <= bufindr) {
+            // Mark the rest of the buffer as used.
+            memset(cmdbuffer+bufindw, 0, sizeof(cmdbuffer)-bufindw);
+            // and point to the start.
+            bufindw = 0;
+            return true;
+        }
+    }
+    return false;
+}
+
+#ifdef CMDBUFFER_DEBUG
+void cmdqueue_dump_to_serial_single_line(int nr, const char *p)
+{
+    SERIAL_ECHOPGM("Entry nr: ");
+    SERIAL_ECHO(nr);
+    SERIAL_ECHOPGM(", type: ");
+    SERIAL_ECHO(int(*p));
+    SERIAL_ECHOPGM(", cmd: ");
+    SERIAL_ECHO(p+1);  
+    SERIAL_ECHOLNPGM("");
+}
+
+void cmdqueue_dump_to_serial()
+{
+    if (buflen == 0) {
+        SERIAL_ECHOLNPGM("The command buffer is empty.");
+    } else {
+        SERIAL_ECHOPGM("Content of the buffer: entries ");
+        SERIAL_ECHO(buflen);
+        SERIAL_ECHOPGM(", indr ");
+        SERIAL_ECHO(bufindr);
+        SERIAL_ECHOPGM(", indw ");
+        SERIAL_ECHO(bufindw);
+        SERIAL_ECHOLNPGM("");
+        int nr = 0;
+        if (bufindr < bufindw) {
+            for (const char *p = cmdbuffer + bufindr; p < cmdbuffer + bufindw; ++ nr) {
+                cmdqueue_dump_to_serial_single_line(nr, p);
+                // Skip the command.
+                for (++p; *p != 0; ++ p);
+                // Skip the gaps.
+                for (++p; p < cmdbuffer + bufindw && *p == 0; ++ p);
+            }
+        } else {
+            for (const char *p = cmdbuffer + bufindr; p < cmdbuffer + sizeof(cmdbuffer); ++ nr) {
+                cmdqueue_dump_to_serial_single_line(nr, p);
+                // Skip the command.
+                for (++p; *p != 0; ++ p);
+                // Skip the gaps.
+                for (++p; p < cmdbuffer + sizeof(cmdbuffer) && *p == 0; ++ p);
+            }
+            for (const char *p = cmdbuffer; p < cmdbuffer + bufindw; ++ nr) {
+                cmdqueue_dump_to_serial_single_line(nr, p);
+                // Skip the command.
+                for (++p; *p != 0; ++ p);
+                // Skip the gaps.
+                for (++p; p < cmdbuffer + bufindw && *p == 0; ++ p);
+            }
+        }
+        SERIAL_ECHOLNPGM("End of the buffer.");
+    }
+}
+#endif /* CMDBUFFER_DEBUG */
+
+//adds an command to the main command buffer
+//thats really done in a non-safe way.
+//needs overworking someday
+// Currently the maximum length of a command piped through this function is around 20 characters
+void enquecommand(const char *cmd, bool from_progmem)
+{
+    int len = from_progmem ? strlen_P(cmd) : strlen(cmd);
+    // Does cmd fit the queue while leaving sufficient space at the front for the chained commands?
+    // If it fits, it may move bufindw, so it points to a contiguous buffer, which fits cmd.
+    if (cmdqueue_could_enqueue_back(len)) {
+        // This is dangerous if a mixing of serial and this happens
+        // This may easily be tested: If serial_count > 0, we have a problem.
+        cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_UI;
+        if (from_progmem)
+            strcpy_P(cmdbuffer + bufindw + CMDHDRSIZE, cmd);
+        else
+            strcpy(cmdbuffer + bufindw + CMDHDRSIZE, cmd);
+        SERIAL_ECHO_START;
+        SERIAL_ECHORPGM(MSG_Enqueing);
+        SERIAL_ECHO(cmdbuffer + bufindw + CMDHDRSIZE);
+        SERIAL_ECHOLNPGM("\"");
+        bufindw += len + (CMDHDRSIZE + 1);
+        if (bufindw == sizeof(cmdbuffer))
+            bufindw = 0;
+        ++ buflen;
+#ifdef CMDBUFFER_DEBUG
+        cmdqueue_dump_to_serial();
+#endif /* CMDBUFFER_DEBUG */
+    } else {
+        SERIAL_ERROR_START;
+        SERIAL_ECHORPGM(MSG_Enqueing);
+        if (from_progmem)
+            SERIAL_PROTOCOLRPGM(cmd);
+        else
+            SERIAL_ECHO(cmd);
+        SERIAL_ECHOLNPGM("\" failed: Buffer full!");
+#ifdef CMDBUFFER_DEBUG
+        cmdqueue_dump_to_serial();
+#endif /* CMDBUFFER_DEBUG */
+    }
+}
+
+void enquecommand_front(const char *cmd, bool from_progmem)
+{
+    int len = from_progmem ? strlen_P(cmd) : strlen(cmd);
+    // Does cmd fit the queue? This call shall move bufindr, so the command may be copied.
+    if (cmdqueue_could_enqueue_front(len)) {
+        cmdbuffer[bufindr] = CMDBUFFER_CURRENT_TYPE_UI;
+        if (from_progmem)
+            strcpy_P(cmdbuffer + bufindr + CMDHDRSIZE, cmd);
+        else
+            strcpy(cmdbuffer + bufindr + CMDHDRSIZE, cmd);
+        ++ buflen;
+        SERIAL_ECHO_START;
+        SERIAL_ECHOPGM("Enqueing to the front: \"");
+        SERIAL_ECHO(cmdbuffer + bufindr + CMDHDRSIZE);
+        SERIAL_ECHOLNPGM("\"");
+#ifdef CMDBUFFER_DEBUG
+        cmdqueue_dump_to_serial();
+#endif /* CMDBUFFER_DEBUG */
+    } else {
+        SERIAL_ERROR_START;
+        SERIAL_ECHOPGM("Enqueing to the front: \"");
+        if (from_progmem)
+            SERIAL_PROTOCOLRPGM(cmd);
+        else
+            SERIAL_ECHO(cmd);
+        SERIAL_ECHOLNPGM("\" failed: Buffer full!");
+#ifdef CMDBUFFER_DEBUG
+        cmdqueue_dump_to_serial();
+#endif /* CMDBUFFER_DEBUG */
+    }
+}
+
+// Mark the command at the top of the command queue as new.
+// Therefore it will not be removed from the queue.
+void repeatcommand_front()
+{
+    cmdbuffer_front_already_processed = true;
+} 
+
+bool is_buffer_empty()
+{
+	if (buflen == 0) return true;
+	else return false;
+}
+
+void get_command()
+{
+    // Test and reserve space for the new command string.
+	if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1)) 
+		return;
+	
+	bool rx_buffer_full = false; //flag that serial rx buffer is full
+
+  while (MYSERIAL.available() > 0) {
+	  if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size
+		  SERIAL_ECHOLNPGM("Full RX Buffer");   //if buffer was full, there is danger that reading of last gcode will not be completed
+		  rx_buffer_full = true;				//sets flag that buffer was full	
+	  }
+    char serial_char = MYSERIAL.read();
+	if (selectedSerialPort == 1)
+	{
+		selectedSerialPort = 0; 
+		MYSERIAL.write(serial_char); 
+		selectedSerialPort = 1; 
+	} 
+      TimeSent = millis();
+      TimeNow = millis();
+
+    if (serial_char < 0)
+        // Ignore extended ASCII characters. These characters have no meaning in the G-code apart from the file names
+        // and Marlin does not support such file names anyway.
+        // Serial characters with a highest bit set to 1 are generated when the USB cable is unplugged, leading
+        // to a hang-up of the print process from an SD card.
+        continue;
+    if(serial_char == '\n' ||
+       serial_char == '\r' ||
+       (serial_char == ':' && comment_mode == false) ||
+       serial_count >= (MAX_CMD_SIZE - 1) )
+    {
+      if(!serial_count) { //if empty line
+        comment_mode = false; //for new command
+        return;
+      }
+      cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
+      if(!comment_mode){
+        comment_mode = false; //for new command
+        if ((strchr_pointer = strstr(cmdbuffer+bufindw+CMDHDRSIZE, "PRUSA")) == NULL && (strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'N')) != NULL) {
+            if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'N')) != NULL)
+            {
+            // Line number met. When sending a G-code over a serial line, each line may be stamped with its index,
+            // and Marlin tests, whether the successive lines are stamped with an increasing line number ID.
+            gcode_N = (strtol(strchr_pointer+1, NULL, 10));
+            if(gcode_N != gcode_LastN+1 && (strstr_P(cmdbuffer+bufindw+CMDHDRSIZE, PSTR("M110")) == NULL) ) {
+                // M110 - set current line number.
+                // Line numbers not sent in succession.
+                SERIAL_ERROR_START;
+                SERIAL_ERRORRPGM(MSG_ERR_LINE_NO);
+                SERIAL_ERRORLN(gcode_LastN);
+                //Serial.println(gcode_N);
+                FlushSerialRequestResend();
+                serial_count = 0;
+                return;
+            }
+
+            if((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*')) != NULL)
+            {
+                byte checksum = 0;
+                char *p = cmdbuffer+bufindw+CMDHDRSIZE;
+                while (p != strchr_pointer)
+                    checksum = checksum^(*p++);
+                if (int(strtol(strchr_pointer+1, NULL, 10)) != int(checksum)) {
+                SERIAL_ERROR_START;
+                SERIAL_ERRORRPGM(MSG_ERR_CHECKSUM_MISMATCH);
+                SERIAL_ERRORLN(gcode_LastN);
+                FlushSerialRequestResend();
+                serial_count = 0;
+                return;
+                }
+                // If no errors, remove the checksum and continue parsing.
+                *strchr_pointer = 0;
+            }
+            else
+            {
+                SERIAL_ERROR_START;
+                SERIAL_ERRORRPGM(MSG_ERR_NO_CHECKSUM);
+                SERIAL_ERRORLN(gcode_LastN);
+                FlushSerialRequestResend();
+                serial_count = 0;
+                return;
+            }
+
+            gcode_LastN = gcode_N;
+            //if no errors, continue parsing
+            } // end of 'N' command
+        }
+        else  // if we don't receive 'N' but still see '*'
+        {
+          if((strchr(cmdbuffer+bufindw+CMDHDRSIZE, '*') != NULL))
+          {
+            SERIAL_ERROR_START;
+            SERIAL_ERRORRPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
+            SERIAL_ERRORLN(gcode_LastN);
+            serial_count = 0;
+            return;
+          }
+        } // end of '*' command
+        if ((strchr_pointer = strchr(cmdbuffer+bufindw+CMDHDRSIZE, 'G')) != NULL) {
+      		  if (! IS_SD_PRINTING) {
+        			  usb_printing_counter = 10;
+        			  is_usb_printing = true;
+      		  }
+            if (Stopped == true) {
+                int gcode = strtol(strchr_pointer+1, NULL, 10);
+                if (gcode >= 0 && gcode <= 3) {
+                    SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
+                    LCD_MESSAGERPGM(MSG_STOPPED);
+                }
+            }
+        } // end of 'G' command
+
+        //If command was e-stop process now
+        if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
+          kill("", 2);
+        
+        // Store the current line into buffer, move to the next line.
+        cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_USB;
+#ifdef CMDBUFFER_DEBUG
+        SERIAL_ECHO_START;
+        SERIAL_ECHOPGM("Storing a command line to buffer: ");
+        SERIAL_ECHO(cmdbuffer+bufindw+CMDHDRSIZE);
+        SERIAL_ECHOLNPGM("");
+#endif /* CMDBUFFER_DEBUG */
+        bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
+        if (bufindw == sizeof(cmdbuffer))
+            bufindw = 0;
+        ++ buflen;
+#ifdef CMDBUFFER_DEBUG
+        SERIAL_ECHOPGM("Number of commands in the buffer: ");
+        SERIAL_ECHO(buflen);
+        SERIAL_ECHOLNPGM("");
+#endif /* CMDBUFFER_DEBUG */
+      } // end of 'not comment mode'
+      serial_count = 0; //clear buffer
+      // Don't call cmdqueue_could_enqueue_back if there are no characters waiting
+      // in the queue, as this function will reserve the memory.
+      if (MYSERIAL.available() == 0 || ! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
+          return;
+    } // end of "end of line" processing
+    else {
+      // Not an "end of line" symbol. Store the new character into a buffer.
+      if(serial_char == ';') comment_mode = true;
+      if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
+    }
+  } // end of serial line processing loop
+
+    if(farm_mode){
+        TimeNow = millis();
+        if ( ((TimeNow - TimeSent) > 800) && (serial_count > 0) ) {
+            cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0;
+            
+            bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
+            if (bufindw == sizeof(cmdbuffer))
+                bufindw = 0;
+            ++ buflen;
+            
+            serial_count = 0;
+            
+            SERIAL_ECHOPGM("TIMEOUT:");
+            //memset(cmdbuffer, 0 , sizeof(cmdbuffer));
+            return;
+        }
+    }
+
+	//add comment
+	if (rx_buffer_full == true && serial_count > 0) {   //if rx buffer was full and string was not properly terminated
+		rx_buffer_full = false;
+		bufindw = bufindw - serial_count;				//adjust tail of the buffer to prepare buffer for writing new command
+		serial_count = 0;
+	}
+
+  #ifdef SDSUPPORT
+  if(!card.sdprinting || serial_count!=0){
+    // If there is a half filled buffer from serial line, wait until return before
+    // continuing with the serial line.
+     return;
+  }
+
+  //'#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible
+  // if it occurs, stop_buffering is triggered and the buffer is ran dry.
+  // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
+
+  static bool stop_buffering=false;
+  if(buflen==0) stop_buffering=false;
+  unsigned char sd_count = 0;
+  // Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer.
+  while( !card.eof() && !stop_buffering) {
+    int16_t n=card.get();
+	sd_count++;
+    char serial_char = (char)n;
+    if(serial_char == '\n' ||
+       serial_char == '\r' ||
+       (serial_char == '#' && comment_mode == false) ||
+       (serial_char == ':' && comment_mode == false) ||
+       serial_count >= (MAX_CMD_SIZE - 1)||n==-1)
+    {
+      if(card.eof()){
+        SERIAL_PROTOCOLLNRPGM(MSG_FILE_PRINTED);
+        stoptime=millis();
+        char time[30];
+        unsigned long t=(stoptime-starttime-pause_time)/1000;
+		pause_time = 0;
+        int hours, minutes;
+        minutes=(t/60)%60;
+        hours=t/60/60;
+		save_statistics(total_filament_used, t);
+		sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
+        SERIAL_ECHO_START;
+        SERIAL_ECHOLN(time);
+        lcd_setstatus(time);
+        card.printingHasFinished();
+        card.checkautostart(true);
+
+		if (farm_mode)
+		{
+			prusa_statistics(6);
+			lcd_commands_type = LCD_COMMAND_FARM_MODE_CONFIRM;
+		}
+
+      }
+      if(serial_char=='#')
+        stop_buffering=true;
+
+      if(!serial_count)
+      {
+        comment_mode = false; //for new command
+        return; //if empty line
+      }
+      cmdbuffer[bufindw+serial_count+CMDHDRSIZE] = 0; //terminate string
+      cmdbuffer[bufindw] = CMDBUFFER_CURRENT_TYPE_SDCARD;
+      cmdbuffer[bufindw+1] = sd_count;
+/*	  SERIAL_ECHOPGM("SD cmd(");
+	  MYSERIAL.print(sd_count, DEC);
+	  SERIAL_ECHOPGM(") ");
+	  SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE);*/
+//	  SERIAL_ECHOPGM("cmdbuffer:");
+//	  MYSERIAL.print(cmdbuffer);
+      ++ buflen;
+//	  SERIAL_ECHOPGM("buflen:");
+//	  MYSERIAL.print(buflen);
+      bufindw += strlen(cmdbuffer+bufindw+CMDHDRSIZE) + (1 + CMDHDRSIZE);
+      if (bufindw == sizeof(cmdbuffer))
+          bufindw = 0;
+      comment_mode = false; //for new command
+      serial_count = 0; //clear buffer
+      // The following line will reserve buffer space if available.
+      if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1))
+          return;
+    }
+    else
+    {
+      if(serial_char == ';') comment_mode = true;
+      if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
+    }
+  }
+
+  #endif //SDSUPPORT
+}

+ 85 - 0
Firmware/cmdqueue.h

@@ -0,0 +1,85 @@
+#ifndef CMDQUEUE_H
+#define CMDQUEUE_H
+
+#include "Marlin.h"
+#include "language_all.h"
+
+
+// String circular buffer. Commands may be pushed to the buffer from both sides:
+// Chained commands will be pushed to the front, interactive (from LCD menu) 
+// and printing commands (from serial line or from SD card) are pushed to the tail.
+// First character of each entry indicates the type of the entry: 
+#define CMDBUFFER_CURRENT_TYPE_UNKNOWN  0
+// Command in cmdbuffer was sent over USB.
+#define CMDBUFFER_CURRENT_TYPE_USB      1
+// Command in cmdbuffer was read from SDCARD.
+#define CMDBUFFER_CURRENT_TYPE_SDCARD   2
+// Command in cmdbuffer was generated by the UI.
+#define CMDBUFFER_CURRENT_TYPE_UI       3
+// Command in cmdbuffer was generated by another G-code.
+#define CMDBUFFER_CURRENT_TYPE_CHAINED  4
+
+// How much space to reserve for the chained commands
+// of type CMDBUFFER_CURRENT_TYPE_CHAINED,
+// which are pushed to the front of the queue?
+// Maximum 5 commands of max length 20 + null terminator.
+#define CMDBUFFER_RESERVE_FRONT       (5*21)
+
+extern char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];
+extern int bufindr;
+extern int bufindw;
+extern int buflen;
+extern bool cmdbuffer_front_already_processed;
+
+// Type of a command, which is to be executed right now.
+#define CMDBUFFER_CURRENT_TYPE   (cmdbuffer[bufindr])
+// String of a command, which is to be executed right now.
+#define CMDBUFFER_CURRENT_STRING (cmdbuffer+bufindr+CMDHDRSIZE)
+
+// Enable debugging of the command buffer.
+// Debugging information will be sent to serial line.
+//#define CMDBUFFER_DEBUG
+
+extern int serial_count;
+extern boolean comment_mode;
+extern char *strchr_pointer;
+
+extern unsigned long TimeSent;
+extern unsigned long TimeNow;
+
+extern long gcode_N;
+extern long gcode_LastN;
+extern long Stopped_gcode_LastN;
+
+extern bool cmdqueue_pop_front();
+extern void cmdqueue_reset();
+extern bool cmdqueue_could_enqueue_front(int len_asked);
+extern bool cmdqueue_could_enqueue_back(int len_asked);
+extern void cmdqueue_dump_to_serial_single_line(int nr, const char *p);
+extern void cmdqueue_dump_to_serial();
+extern void enquecommand(const char *cmd, bool from_progmem);
+extern void enquecommand_front(const char *cmd, bool from_progmem);
+extern void repeatcommand_front();
+extern bool is_buffer_empty();
+extern void get_command();
+
+// Return True if a character was found
+static inline bool    code_seen(char code) { return (strchr_pointer = strchr(CMDBUFFER_CURRENT_STRING, code)) != NULL; }
+static inline bool    code_seen(const char *code) { return (strchr_pointer = strstr(CMDBUFFER_CURRENT_STRING, code)) != NULL; }
+static inline float   code_value()      { return strtod(strchr_pointer+1, NULL);}
+static inline long    code_value_long()    { return strtol(strchr_pointer+1, NULL, 10); }
+static inline int16_t code_value_short()   { return int16_t(strtol(strchr_pointer+1, NULL, 10)); };
+static inline uint8_t code_value_uint8()   { return uint8_t(strtol(strchr_pointer+1, NULL, 10)); };
+
+static inline float code_value_float()
+{
+    char* e = strchr(strchr_pointer, 'E');
+    if (!e) return strtod(strchr_pointer + 1, NULL);
+    *e = 0;
+    float ret = strtod(strchr_pointer + 1, NULL);
+    *e = 'E';
+    return ret;
+}
+
+
+#endif //CMDQUEUE_H

+ 4 - 4
Firmware/tmc2130.cpp

@@ -28,13 +28,13 @@ uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
 uint8_t tmc2130_axis_stalled[3] = {0, 0, 0};
 
 //pwm_ampl
-uint8_t tmc2130_pwm_ampl[2] = {TMC2130_PWM_AMPL_XY, TMC2130_PWM_AMPL_XY};
+uint8_t tmc2130_pwm_ampl[2] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y};
 //pwm_grad
-uint8_t tmc2130_pwm_grad[2] = {TMC2130_PWM_GRAD_XY, TMC2130_PWM_GRAD_XY};
+uint8_t tmc2130_pwm_grad[2] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y};
 //pwm_auto
-uint8_t tmc2130_pwm_auto[2] = {TMC2130_PWM_AUTO_XY, TMC2130_PWM_AUTO_XY};
+uint8_t tmc2130_pwm_auto[2] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y};
 //pwm_freq
-uint8_t tmc2130_pwm_freq[2] = {TMC2130_PWM_FREQ_XY, TMC2130_PWM_FREQ_XY};
+uint8_t tmc2130_pwm_freq[2] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y};
 
 
 uint8_t tmc2131_axis_sg_thr[3] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z};

+ 9 - 4
Firmware/variants/1_75mm_MK3-EINY03-E3Dv6full.h

@@ -109,10 +109,15 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define TMC2130_INTPOL_Z    1         // extrapolate 256 for Z axis
 #define TMC2130_INTPOL_E    1         // extrapolate 256 for E axis
 
-#define TMC2130_PWM_GRAD_XY 4         // PWMCONF
-#define TMC2130_PWM_AMPL_XY 200       // PWMCONF
-#define TMC2130_PWM_AUTO_XY 1         // PWMCONF
-#define TMC2130_PWM_FREQ_XY 2         // PWMCONF
+#define TMC2130_PWM_GRAD_X  4         // PWMCONF
+#define TMC2130_PWM_AMPL_X  200       // PWMCONF
+#define TMC2130_PWM_AUTO_X  1         // PWMCONF
+#define TMC2130_PWM_FREQ_X  2         // PWMCONF
+
+#define TMC2130_PWM_GRAD_Y  4         // PWMCONF
+#define TMC2130_PWM_AMPL_Y  210       // PWMCONF
+#define TMC2130_PWM_AUTO_Y  1         // PWMCONF
+#define TMC2130_PWM_FREQ_Y  2         // PWMCONF
 
 /* //not used
 #define TMC2130_PWM_GRAD_Z  4         // PWMCONF

+ 9 - 4
Firmware/variants/1_75mm_MK3-EINY04-E3Dv6full.h

@@ -109,10 +109,15 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 #define TMC2130_INTPOL_Z    1         // extrapolate 256 for Z axis
 #define TMC2130_INTPOL_E    1         // extrapolate 256 for E axis
 
-#define TMC2130_PWM_GRAD_XY 4         // PWMCONF
-#define TMC2130_PWM_AMPL_XY 200       // PWMCONF
-#define TMC2130_PWM_AUTO_XY 1         // PWMCONF
-#define TMC2130_PWM_FREQ_XY 2         // PWMCONF
+#define TMC2130_PWM_GRAD_X  4         // PWMCONF
+#define TMC2130_PWM_AMPL_X  200       // PWMCONF
+#define TMC2130_PWM_AUTO_X  1         // PWMCONF
+#define TMC2130_PWM_FREQ_X  2         // PWMCONF
+
+#define TMC2130_PWM_GRAD_Y  4         // PWMCONF
+#define TMC2130_PWM_AMPL_Y  210       // PWMCONF
+#define TMC2130_PWM_AUTO_Y  1         // PWMCONF
+#define TMC2130_PWM_FREQ_Y  2         // PWMCONF
 
 /* //not used
 #define TMC2130_PWM_GRAD_Z  4         // PWMCONF