diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 54e74ba0a..c682aa4b9 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -334,7 +334,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st //The ASCII buffer for receiving from the serial: #define MAX_CMD_SIZE 96 -#define BUFSIZE 4 +#define BUFSIZE 12 // Firmware based and LCD controlled retract diff --git a/Firmware/Configuration_prusa.h b/Firmware/Configuration_prusa.h index 9ed148983..16f90b6e9 100644 --- a/Firmware/Configuration_prusa.h +++ b/Firmware/Configuration_prusa.h @@ -21,7 +21,7 @@ GENERAL SETTINGS // Prusa Single extruder multiple material suport //#define SNMM #define MK3 -#define EINSY_HIGH_SAMPLE_RATE +// #define EINSY_HIGH_SAMPLE_RATE #define ENABLE_LEVELING_FADE_HEIGHT diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index a8dd4eab6..da7bbd32c 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -116,70 +116,29 @@ void ramming(); void manage_inactivity(bool ignore_stepper_queue=false); #if defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 - #define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) - #define disable_x() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } -#else + #define enable_x_() WRITE(X_ENABLE_PIN, X_ENABLE_ON) + #define disable_x_() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } #define enable_x() ; #define disable_x() ; #endif #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 - #ifdef Y_DUAL_STEPPER_DRIVERS - #define enable_y() { WRITE(Y_ENABLE_PIN, Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, Y_ENABLE_ON); } - #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } - #else - #define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) - #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } - #endif -#else + #define enable_y_() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) + #define disable_y_() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } #define enable_y() ; #define disable_y() ; #endif #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 - #if defined(Z_AXIS_ALWAYS_ON) - #ifdef Z_DUAL_STEPPER_DRIVERS - #define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); } - #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } - #else - #define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) - #define disable_z() ; - #endif - #else - #ifdef Z_DUAL_STEPPER_DRIVERS - #define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); } - #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } - #else - #define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) - #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } - #endif - #endif -#else + #define enable_z_() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) + #define disable_z_() ; #define enable_z() ; #define disable_z() ; #endif - - - -//#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 -//#ifdef Z_DUAL_STEPPER_DRIVERS -//#define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); } -//#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } -//#else -//#define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) -//#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } -//#endif -//#else -//#define enable_z() ; -//#define disable_z() ; -//#endif - - #if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1) - #define enable_e0() WRITE(E0_ENABLE_PIN, E_ENABLE_ON) - #define disable_e0() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON) -#else + #define enable_e0_() WRITE(E0_ENABLE_PIN, E_ENABLE_ON) + #define disable_e0_() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON) #define enable_e0() /* nothing */ #define disable_e0() /* nothing */ #endif diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index aa7b2f462..6d5f071bc 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -991,6 +991,10 @@ void factory_reset(char level, bool quiet) // are initialized by the main() routine provided by the Arduino framework. void setup() { + LOGIC_ANALYZER_CH2_ENABLE; + LOGIC_ANALYZER_CH7_ENABLE; + LOGIC_ANALYZER_SERIAL_TX_ENABLE; + WRITE(X_TMC2130_CS, HIGH); WRITE(Y_TMC2130_CS, HIGH); WRITE(Z_TMC2130_CS, HIGH); @@ -1080,6 +1084,11 @@ void setup() tmc2130_mode = TMC2130_MODE_NORMAL; tmc2130_init(); + enable_x_(); + enable_y_(); + enable_z_(); + enable_e0_(); + setup_photpin(); servo_init(); // Reset the machine correction matrix. @@ -1315,6 +1324,69 @@ int serial_read_stream() { } } +void push_raw_gcode_to_planner_queue() +{ + //SERIAL_ECHOPGM("Processing a raw GCODE command, len "); + //SERIAL_ECHO((int)(*(unsigned char*)(cmdbuffer+bufindr+1))); + //SERIAL_ECHOLNPGM(""); + //SERIAL_ECHOPGM("Processing a raw GCODE command, block_t: "); + //SERIAL_ECHO((int)sizeof(block_t)); + //SERIAL_ECHOLNPGM(""); + for (;;) { + // Calculate the buffer head after we push this byte + int next_buffer_head = block_buffer_head; + if (++ next_buffer_head == BLOCK_BUFFER_SIZE) + next_buffer_head = 0; + // If the buffer is full: good! That means we are well ahead of the robot. + if (block_buffer_tail == next_buffer_head) + break; + //WRITE(BEEPER, HIGH); + WRITE_NC(LOGIC_ANALYZER_CH2, true); + // Mark the block as raw. + block_buffer[block_buffer_head].busy = 2; + block_buffer[block_buffer_head].fan_speed = fanSpeed; + uint8_t len = *(unsigned char*)(CMDBUFFER_CURRENT_STRING + 1); + block_buffer[block_buffer_head].raw_length = len; + memcpy(block_buffer[block_buffer_head].raw_data, (void*)(CMDBUFFER_CURRENT_STRING + 2), len); + //WRITE(BEEPER, LOW); + WRITE_NC(LOGIC_ANALYZER_CH2, false); + cmdqueue_pop_front(); + // Enable motors. + enable_x(); + enable_y(); + enable_e0(); +#if 0 + //SERIAL_ECHOPGM("Raw line enqueued, length: "); + //SERIAL_ECHO((int)((uint8_t*)(block_buffer + block_buffer_head))[1]); + //SERIAL_ECHOPGM(", type "); + //SERIAL_ECHO((int)(block_buffer[block_buffer_head]).busy); + //SERIAL_ECHOLNPGM(""); + for (int i = 0; i < len; i += 2) { + SERIAL_ECHOPGM("Event "); + SERIAL_ECHO(i / 2); + SERIAL_ECHOPGM(", axes "); + uint8_t axes = ((uint8_t*)(block_buffer + block_buffer_head))[2 + i]; + for (int j = 0; j < 8; ++ j, axes >>= 1) + SERIAL_ECHO((axes & 1) ? '1' : '0'); + SERIAL_ECHOPGM(", time "); + SERIAL_ECHO((int)((uint8_t*)(block_buffer + block_buffer_head))[3 + i]); + SERIAL_ECHOLNPGM(""); + } +#endif + // Move the buffer head. From now the block may be picked up by the stepper interrupt controller. + block_buffer_head = next_buffer_head; + if (buflen == 0 || *(unsigned char*)(CMDBUFFER_CURRENT_STRING) != 128) + break; + } +} + +void get_command_push_raw_gcode_to_planner_queue() +{ + get_command(); + if(buflen && *(unsigned char*)(CMDBUFFER_CURRENT_STRING) == 128) + push_raw_gcode_to_planner_queue(); +} + // The loop() function is called in an endless loop by the Arduino framework from the default main() routine. // Before loop(), the setup() function is called by the main() routine. void loop() @@ -1344,8 +1416,10 @@ void loop() #ifdef SDSUPPORT card.checkautostart(false); #endif - if(buflen) - { + if(buflen) { + if (*(unsigned char*)(CMDBUFFER_CURRENT_STRING) == 128) { + push_raw_gcode_to_planner_queue(); + } else { #ifdef SDSUPPORT if(card.saving) { @@ -1370,6 +1444,7 @@ void loop() if (! cmdbuffer_front_already_processed) cmdqueue_pop_front(); cmdbuffer_front_already_processed = false; + } } } //check heater every n milliseconds @@ -1381,9 +1456,12 @@ void loop() void get_command() { + WRITE_NC(LOGIC_ANALYZER_CH7, true); // Test and reserve space for the new command string. - if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1)) + if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1)) { + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; + } bool rx_buffer_full = false; //flag that serial rx buffer is full @@ -1409,6 +1487,7 @@ void get_command() { if(!serial_count) { //if empty line comment_mode = false; //for new command + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } cmdbuffer[bufindw+serial_count+1] = 0; //terminate string @@ -1429,6 +1508,7 @@ void get_command() //Serial.println(gcode_N); FlushSerialRequestResend(); serial_count = 0; + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } @@ -1444,6 +1524,7 @@ void get_command() SERIAL_ERRORLN(gcode_LastN); FlushSerialRequestResend(); serial_count = 0; + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } // If no errors, remove the checksum and continue parsing. @@ -1456,6 +1537,7 @@ void get_command() SERIAL_ERRORLN(gcode_LastN); FlushSerialRequestResend(); serial_count = 0; + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } @@ -1471,6 +1553,7 @@ void get_command() SERIAL_ERRORRPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM); SERIAL_ERRORLN(gcode_LastN); serial_count = 0; + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } } // end of '*' command @@ -1513,8 +1596,10 @@ void get_command() 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)) + if (MYSERIAL.available() == 0 || ! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1)) { + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; + } } // end of "end of line" processing else { // Not an "end of line" symbol. Store the new character into a buffer. @@ -1537,6 +1622,7 @@ void get_command() SERIAL_ECHOPGM("TIMEOUT:"); //memset(cmdbuffer, 0 , sizeof(cmdbuffer)); + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } } @@ -1552,6 +1638,7 @@ void get_command() 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. + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; } @@ -1565,6 +1652,42 @@ void get_command() // 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(); + if (n == 128) { + // SERIAL_ECHOLNPGM("Raw gcode"); + // Special character: a raw movement line. + uint8_t len = card.get(); + //SERIAL_ECHOPGM("Len"); + //SERIAL_ECHO((int)len); + //SERIAL_ECHOLNPGM(""); + unsigned char *ptr = (unsigned char*)(cmdbuffer + bufindw); + *ptr ++ = CMDBUFFER_CURRENT_TYPE_SDCARD; + *ptr ++ = 128; + *ptr ++ = len; + n = card.read((void*)ptr, len); + ptr += len; + if (n != len) + SERIAL_ECHOLNPGM("Wrong number of bytes received"); + bufindw += len + 2 + 2; // command indicator, command, length, data, zero + if (bufindw == sizeof(cmdbuffer)) + bufindw = 0; + comment_mode = false; //for new command + serial_count = 0; //clear buffer + *ptr = 0; + ++ buflen; + // Read the end of line indicator. + n = card.get(); + if (n != '\n') + SERIAL_ECHOLNPGM("EOL NOT received"); + //else + // SERIAL_ECHOLNPGM("EOL received"); + // The following line will reserve buffer space if available. + if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1)) { + WRITE_NC(LOGIC_ANALYZER_CH7, false); + return; + } + // Read other lines. + continue; + } char serial_char = (char)n; if(serial_char == '\n' || serial_char == '\r' || @@ -1602,6 +1725,7 @@ void get_command() if(!serial_count) { comment_mode = false; //for new command + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; //if empty line } cmdbuffer[bufindw+serial_count+1] = 0; //terminate string @@ -1613,8 +1737,10 @@ void get_command() 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)) + if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1)) { + WRITE_NC(LOGIC_ANALYZER_CH7, false); return; + } } else { @@ -1622,8 +1748,8 @@ void get_command() if(!comment_mode) cmdbuffer[bufindw+1+serial_count++] = serial_char; } } - #endif //SDSUPPORT + WRITE_NC(LOGIC_ANALYZER_CH7, false); } diff --git a/Firmware/Sd2Card.cpp b/Firmware/Sd2Card.cpp index 76f767485..5a027b78b 100644 --- a/Firmware/Sd2Card.cpp +++ b/Firmware/Sd2Card.cpp @@ -88,7 +88,7 @@ static inline __attribute__((always_inline)) static uint8_t spiRec() { uint8_t data = 0; // no interrupts during byte receive - about 8 us - cli(); +// cli(); // output pin high - like sending 0XFF fastDigitalWrite(SPI_MOSI_PIN, HIGH); @@ -106,7 +106,7 @@ static uint8_t spiRec() { fastDigitalWrite(SPI_SCK_PIN, LOW); } // enable interrupts - sei(); +// sei(); return data; } //------------------------------------------------------------------------------ @@ -120,7 +120,7 @@ static void spiRead(uint8_t* buf, uint16_t nbyte) { /** Soft SPI send byte */ static void spiSend(uint8_t data) { // no interrupts during byte send - about 8 us - cli(); +// cli(); for (uint8_t i = 0; i < 8; i++) { fastDigitalWrite(SPI_SCK_PIN, LOW); @@ -138,7 +138,7 @@ static void spiSend(uint8_t data) { fastDigitalWrite(SPI_SCK_PIN, LOW); // enable interrupts - sei(); +// sei(); } //------------------------------------------------------------------------------ /** Soft SPI send block */ diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 3e87b3315..8d36925bf 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -44,6 +44,7 @@ public: FORCE_INLINE bool isFileOpen() { return file.isOpen(); } FORCE_INLINE bool eof() { return sdpos>=filesize ;}; FORCE_INLINE int16_t get() { sdpos = file.curPosition();return (int16_t)file.read();}; + FORCE_INLINE int16_t read(void* buf, uint16_t nbyte) { sdpos = file.curPosition(); return (int16_t)file.read(buf, nbyte);}; FORCE_INLINE void setIndex(long index) {sdpos = index;file.seekSet(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; diff --git a/Firmware/fastio.h b/Firmware/fastio.h index c20a6b70a..8a60cec9f 100644 --- a/Firmware/fastio.h +++ b/Firmware/fastio.h @@ -66,6 +66,7 @@ #define READ(IO) _READ(IO) /// Write to a pin wrapper #define WRITE(IO, v) _WRITE(IO, v) +#define WRITE_NC(IO, v) _WRITE_NC(IO, v) /// toggle a pin wrapper #define TOGGLE(IO) _TOGGLE(IO) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 966fd1d56..3c0c3fff8 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -480,10 +480,17 @@ void check_axes_activity() while(block_index != block_buffer_head) { block = &block_buffer[block_index]; - if(block->steps_x != 0) x_active++; - if(block->steps_y != 0) y_active++; - if(block->steps_z != 0) z_active++; - if(block->steps_e != 0) e_active++; + if (block->busy == 2) { + ++ x_active; + ++ y_active; + ++ z_active; + ++ e_active; + } else { + if(block->steps_x != 0) x_active++; + if(block->steps_y != 0) y_active++; + if(block->steps_z != 0) z_active++; + if(block->steps_e != 0) e_active++; + } block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1); } } @@ -978,7 +985,7 @@ Having the real displacement of the head, we can calculate the total movement le // Acceleration of the segment, in mm/sec^2 block->acceleration = block->acceleration_st / steps_per_mm; -#if 1 +#if 0 // Oversample diagonal movements by a power of 2 up to 8x // to achieve more accurate diagonal movements. uint8_t bresenham_oversample = 1; diff --git a/Firmware/planner.h b/Firmware/planner.h index 30194952d..7a18ba7b7 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -44,50 +44,62 @@ enum BlockFlag { // This struct is used when buffering the setup for each linear movement "nominal" values are as specified in // the source g-code and may never actually be reached if acceleration management is active. -typedef struct { - // Fields used by the bresenham algorithm for tracing the line - // steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line(). - long steps_x, steps_y, steps_z, steps_e; // Step count along each axis - unsigned long step_event_count; // The number of step events required to complete this block - long acceleration_rate; // The acceleration rate used for acceleration calculation - unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) - unsigned char active_extruder; // Selects the active extruder - // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. - long accelerate_until; // The index of the step event on which to stop acceleration - long decelerate_after; // The index of the step event on which to start decelerating +typedef union { + struct { + // Busy flag: Currently processed. + // Misused for the raw movement algorithm. + volatile char busy; - // Fields used by the motion planner to manage acceleration -// float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis - // The nominal speed for this block in mm/sec. - // This speed may or may not be reached due to the jerk and acceleration limits. - float nominal_speed; - // Entry speed at previous-current junction in mm/sec, respecting the acceleration and jerk limits. - // The entry speed limit of the current block equals the exit speed of the preceding block. - float entry_speed; - // Maximum allowable junction entry speed in mm/sec. This value is also a maximum exit speed of the previous block. - float max_entry_speed; - // The total travel of this block in mm - float millimeters; - // acceleration mm/sec^2 - float acceleration; + // Fields used by the bresenham algorithm for tracing the line + // steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line(). + long steps_x, steps_y, steps_z, steps_e; // Step count along each axis + unsigned long step_event_count; // The number of step events required to complete this block + long acceleration_rate; // The acceleration rate used for acceleration calculation + unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) + unsigned char active_extruder; // Selects the active extruder + // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. + long accelerate_until; // The index of the step event on which to stop acceleration + long decelerate_after; // The index of the step event on which to start decelerating - // Bit flags defined by the BlockFlag enum. - bool flag; + // Fields used by the motion planner to manage acceleration + // float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis + // The nominal speed for this block in mm/sec. + // This speed may or may not be reached due to the jerk and acceleration limits. + float nominal_speed; + // Entry speed at previous-current junction in mm/sec, respecting the acceleration and jerk limits. + // The entry speed limit of the current block equals the exit speed of the preceding block. + float entry_speed; + // Maximum allowable junction entry speed in mm/sec. This value is also a maximum exit speed of the previous block. + float max_entry_speed; + // The total travel of this block in mm + float millimeters; + // acceleration mm/sec^2 + float acceleration; - // Settings for the trapezoid generator (runs inside an interrupt handler). - // Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts. - //FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway! - unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec - unsigned long initial_rate; // The jerk-adjusted step rate at start of block - unsigned long final_rate; // The minimal rate at exit - unsigned long acceleration_st; // acceleration steps/sec^2 - //FIXME does it have to be unsigned long? Probably uint8_t would be just fine. - unsigned long fan_speed; - volatile char busy; + // Bit flags defined by the BlockFlag enum. + bool flag; + + // Settings for the trapezoid generator (runs inside an interrupt handler). + // Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts. + //FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway! + unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec + unsigned long initial_rate; // The jerk-adjusted step rate at start of block + unsigned long final_rate; // The minimal rate at exit + unsigned long acceleration_st; // acceleration steps/sec^2 - // Pre-calculated division for the calculate_trapezoid_for_block() routine to run faster. - float speed_factor; + // Pre-calculated division for the calculate_trapezoid_for_block() routine to run faster. + float speed_factor; + }; + + struct { + unsigned char raw_flag; + unsigned char raw_length; + unsigned char raw_data[80]; + //FIXME does it have to be unsigned long? Probably uint8_t would be just fine. + unsigned int fan_speed; + }; + } block_t; #ifdef ENABLE_AUTO_BED_LEVELING @@ -166,7 +178,8 @@ FORCE_INLINE block_t *plan_get_current_block() return(NULL); } block_t *block = &block_buffer[block_buffer_tail]; - block->busy = true; + if (! block->busy) + block->busy = true; return(block); } diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index b92f54ee1..9c568ba26 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -331,22 +331,30 @@ ISR(TIMER1_COMPA_vect) // Anything in the buffer? current_block = plan_get_current_block(); if (current_block != NULL) { - // The busy flag is set by the plan_get_current_block() call. - // current_block->busy = true; - trapezoid_generator_reset(); - counter_x = -(current_block->step_event_count >> 1); - counter_y = counter_x; - counter_z = counter_x; - counter_e = counter_x; - step_events_completed = 0; + if (current_block->busy == 2) { + // This is a raw block. + counter_x = ((unsigned char*)current_block)[1]; + // Stored in bytes, converted to number of steps. + counter_x >>= 1; + counter_y = 2; + } else { + // The busy flag is set by the plan_get_current_block() call. + // current_block->busy = true; + trapezoid_generator_reset(); + counter_x = -(current_block->step_event_count >> 1); + counter_y = counter_x; + counter_z = counter_x; + counter_e = counter_x; + step_events_completed = 0; - #ifdef Z_LATE_ENABLE - if(current_block->steps_z > 0) { - enable_z(); - OCR1A = 2000; //1ms wait - return; - } - #endif + #ifdef Z_LATE_ENABLE + if(current_block->steps_z > 0) { + enable_z(); + OCR1A = 2000; //1ms wait + return; + } + #endif + } } else { OCR1A=2000; // 1kHz. @@ -354,6 +362,49 @@ ISR(TIMER1_COMPA_vect) } if (current_block != NULL) { + if (current_block->busy == 2) { + // This is a raw block. + out_bits = ((unsigned char*)current_block)[counter_y ++]; + LOGIC_ANALYZER_SERIAL_TX_WRITE_NC((int)(out_bits) + 0x100); + WRITE(X_DIR_PIN, (out_bits & (0x10< interrupt out_bits = current_block->direction_bits; diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 754262192..0ac156d7f 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -812,9 +812,7 @@ static void updateTemperaturesFromRawValues() //Reset the watchdog after we know we have a temperature measurement. watchdog_reset(); - CRITICAL_SECTION_START; temp_meas_ready = false; - CRITICAL_SECTION_END; } @@ -1403,6 +1401,12 @@ int read_max6675() // Timer 0 is shared with millies ISR(TIMER0_COMPB_vect) { + static bool inside = false; + if (inside) + return; + inside = true; + sei(); + //these variables are only accesible from the ISR, but static, so they don't lose their value static unsigned char temp_count = 0; static unsigned long raw_temp_0_value = 0; @@ -1955,6 +1959,8 @@ ISR(TIMER0_COMPB_vect) } } #endif //BABYSTEPPING + + inside = false; } #ifdef PIDTEMP diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a933d4bc1..5c1fcffc3 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -378,21 +378,25 @@ static void lcd_status_screen() if (ReInitLCD == 30) { + #if 0 lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) currentMenu == lcd_status_screen #endif ); + #endif ReInitLCD = 0 ; } else { if ((ReInitLCD % 10) == 0) { //lcd_implementation_nodisplay(); + #if 0 lcd_implementation_init_noclear( // to maybe revive the LCD if static electricity killed it. #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) currentMenu == lcd_status_screen #endif ); + #endif } diff --git a/Firmware/ultralcd_implementation_hitachi_HD44780.h b/Firmware/ultralcd_implementation_hitachi_HD44780.h index 8b1ed3de6..3478a4643 100644 --- a/Firmware/ultralcd_implementation_hitachi_HD44780.h +++ b/Firmware/ultralcd_implementation_hitachi_HD44780.h @@ -652,6 +652,7 @@ void lcd_implementation_print_at(uint8_t x, uint8_t y, const char *str) lcd.print(str); } +extern void get_command_push_raw_gcode_to_planner_queue(); /* 20x4 |01234567890123456789| @@ -692,6 +693,8 @@ static void lcd_implementation_status_screen() lcd.print(' '); #endif + get_command_push_raw_gcode_to_planner_queue(); + //Print the Bedtemperature lcd.setCursor(0, 1); tHotend=int(degBed() + 0.5); @@ -728,6 +731,8 @@ static void lcd_implementation_status_screen() planner_queue_min_reset(); } #endif + + get_command_push_raw_gcode_to_planner_queue(); //Print SD status lcd.setCursor(0, 2); @@ -786,7 +791,7 @@ static void lcd_implementation_status_screen() #endif } - + get_command_push_raw_gcode_to_planner_queue(); //Print time elapsed lcd.setCursor(LCD_WIDTH - 8 -1, 2); @@ -810,6 +815,8 @@ static void lcd_implementation_status_screen() // If heating in progress, set flag if (heating_status != 0) { custom_message = true; } + get_command_push_raw_gcode_to_planner_queue(); + // If printing from SD, show what we are printing if ((IS_SD_PRINTING) && !custom_message) { @@ -988,7 +995,9 @@ static void lcd_implementation_status_screen() lcd.print(lcd_status_message); } } - + + get_command_push_raw_gcode_to_planner_queue(); + // Fill the rest of line to have nice and clean output for(int fillspace = 0; fillspace<20;fillspace++) {