Experimental feature: Binary G-code

This commit is contained in:
bubnikv 2018-06-19 09:46:25 +02:00
parent 1661902e2f
commit 6ef4dd5e88
13 changed files with 302 additions and 125 deletions

View File

@ -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: //The ASCII buffer for receiving from the serial:
#define MAX_CMD_SIZE 96 #define MAX_CMD_SIZE 96
#define BUFSIZE 4 #define BUFSIZE 12
// Firmware based and LCD controlled retract // Firmware based and LCD controlled retract

View File

@ -21,7 +21,7 @@ GENERAL SETTINGS
// Prusa Single extruder multiple material suport // Prusa Single extruder multiple material suport
//#define SNMM //#define SNMM
#define MK3 #define MK3
#define EINSY_HIGH_SAMPLE_RATE // #define EINSY_HIGH_SAMPLE_RATE
#define ENABLE_LEVELING_FADE_HEIGHT #define ENABLE_LEVELING_FADE_HEIGHT

View File

@ -116,70 +116,29 @@ void ramming();
void manage_inactivity(bool ignore_stepper_queue=false); void manage_inactivity(bool ignore_stepper_queue=false);
#if defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 #if defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1
#define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) #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 disable_x_() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
#else
#define enable_x() ; #define enable_x() ;
#define disable_x() ; #define disable_x() ;
#endif #endif
#if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
#ifdef Y_DUAL_STEPPER_DRIVERS #define enable_y_() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
#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); axis_known_position[Y_AXIS] = false; }
#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() ; #define enable_y() ;
#define disable_y() ; #define disable_y() ;
#endif #endif
#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
#if defined(Z_AXIS_ALWAYS_ON) #define enable_z_() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
#ifdef Z_DUAL_STEPPER_DRIVERS #define disable_z_() ;
#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() ; #define enable_z() ;
#define disable_z() ; #define disable_z() ;
#endif #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) #if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1)
#define enable_e0() WRITE(E0_ENABLE_PIN, E_ENABLE_ON) #define enable_e0_() WRITE(E0_ENABLE_PIN, E_ENABLE_ON)
#define disable_e0() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON) #define disable_e0_() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON)
#else
#define enable_e0() /* nothing */ #define enable_e0() /* nothing */
#define disable_e0() /* nothing */ #define disable_e0() /* nothing */
#endif #endif

View File

@ -991,6 +991,10 @@ void factory_reset(char level, bool quiet)
// are initialized by the main() routine provided by the Arduino framework. // are initialized by the main() routine provided by the Arduino framework.
void setup() void setup()
{ {
LOGIC_ANALYZER_CH2_ENABLE;
LOGIC_ANALYZER_CH7_ENABLE;
LOGIC_ANALYZER_SERIAL_TX_ENABLE;
WRITE(X_TMC2130_CS, HIGH); WRITE(X_TMC2130_CS, HIGH);
WRITE(Y_TMC2130_CS, HIGH); WRITE(Y_TMC2130_CS, HIGH);
WRITE(Z_TMC2130_CS, HIGH); WRITE(Z_TMC2130_CS, HIGH);
@ -1080,6 +1084,11 @@ void setup()
tmc2130_mode = TMC2130_MODE_NORMAL; tmc2130_mode = TMC2130_MODE_NORMAL;
tmc2130_init(); tmc2130_init();
enable_x_();
enable_y_();
enable_z_();
enable_e0_();
setup_photpin(); setup_photpin();
servo_init(); servo_init();
// Reset the machine correction matrix. // 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. // 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. // Before loop(), the setup() function is called by the main() routine.
void loop() void loop()
@ -1344,8 +1416,10 @@ void loop()
#ifdef SDSUPPORT #ifdef SDSUPPORT
card.checkautostart(false); card.checkautostart(false);
#endif #endif
if(buflen) if(buflen) {
{ if (*(unsigned char*)(CMDBUFFER_CURRENT_STRING) == 128) {
push_raw_gcode_to_planner_queue();
} else {
#ifdef SDSUPPORT #ifdef SDSUPPORT
if(card.saving) if(card.saving)
{ {
@ -1370,6 +1444,7 @@ void loop()
if (! cmdbuffer_front_already_processed) if (! cmdbuffer_front_already_processed)
cmdqueue_pop_front(); cmdqueue_pop_front();
cmdbuffer_front_already_processed = false; cmdbuffer_front_already_processed = false;
}
} }
} }
//check heater every n milliseconds //check heater every n milliseconds
@ -1381,9 +1456,12 @@ void loop()
void get_command() void get_command()
{ {
WRITE_NC(LOGIC_ANALYZER_CH7, true);
// Test and reserve space for the new command string. // 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; return;
}
bool rx_buffer_full = false; //flag that serial rx buffer is full 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 if(!serial_count) { //if empty line
comment_mode = false; //for new command comment_mode = false; //for new command
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
cmdbuffer[bufindw+serial_count+1] = 0; //terminate string cmdbuffer[bufindw+serial_count+1] = 0; //terminate string
@ -1429,6 +1508,7 @@ void get_command()
//Serial.println(gcode_N); //Serial.println(gcode_N);
FlushSerialRequestResend(); FlushSerialRequestResend();
serial_count = 0; serial_count = 0;
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
@ -1444,6 +1524,7 @@ void get_command()
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN(gcode_LastN);
FlushSerialRequestResend(); FlushSerialRequestResend();
serial_count = 0; serial_count = 0;
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
// If no errors, remove the checksum and continue parsing. // If no errors, remove the checksum and continue parsing.
@ -1456,6 +1537,7 @@ void get_command()
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN(gcode_LastN);
FlushSerialRequestResend(); FlushSerialRequestResend();
serial_count = 0; serial_count = 0;
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
@ -1471,6 +1553,7 @@ void get_command()
SERIAL_ERRORRPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM); SERIAL_ERRORRPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN(gcode_LastN);
serial_count = 0; serial_count = 0;
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
} // end of '*' command } // end of '*' command
@ -1513,8 +1596,10 @@ void get_command()
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
// Don't call cmdqueue_could_enqueue_back if there are no characters waiting // Don't call cmdqueue_could_enqueue_back if there are no characters waiting
// in the queue, as this function will reserve the memory. // 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; return;
}
} // end of "end of line" processing } // end of "end of line" processing
else { else {
// Not an "end of line" symbol. Store the new character into a buffer. // Not an "end of line" symbol. Store the new character into a buffer.
@ -1537,6 +1622,7 @@ void get_command()
SERIAL_ECHOPGM("TIMEOUT:"); SERIAL_ECHOPGM("TIMEOUT:");
//memset(cmdbuffer, 0 , sizeof(cmdbuffer)); //memset(cmdbuffer, 0 , sizeof(cmdbuffer));
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
} }
@ -1552,6 +1638,7 @@ void get_command()
if(!card.sdprinting || serial_count!=0){ if(!card.sdprinting || serial_count!=0){
// If there is a half filled buffer from serial line, wait until return before // If there is a half filled buffer from serial line, wait until return before
// continuing with the serial line. // continuing with the serial line.
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; return;
} }
@ -1565,6 +1652,42 @@ void get_command()
// Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer. // Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer.
while( !card.eof() && !stop_buffering) { while( !card.eof() && !stop_buffering) {
int16_t n=card.get(); 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; char serial_char = (char)n;
if(serial_char == '\n' || if(serial_char == '\n' ||
serial_char == '\r' || serial_char == '\r' ||
@ -1602,6 +1725,7 @@ void get_command()
if(!serial_count) if(!serial_count)
{ {
comment_mode = false; //for new command comment_mode = false; //for new command
WRITE_NC(LOGIC_ANALYZER_CH7, false);
return; //if empty line return; //if empty line
} }
cmdbuffer[bufindw+serial_count+1] = 0; //terminate string cmdbuffer[bufindw+serial_count+1] = 0; //terminate string
@ -1613,8 +1737,10 @@ void get_command()
comment_mode = false; //for new command comment_mode = false; //for new command
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
// The following line will reserve buffer space if available. // 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; return;
}
} }
else else
{ {
@ -1622,8 +1748,8 @@ void get_command()
if(!comment_mode) cmdbuffer[bufindw+1+serial_count++] = serial_char; if(!comment_mode) cmdbuffer[bufindw+1+serial_count++] = serial_char;
} }
} }
#endif //SDSUPPORT #endif //SDSUPPORT
WRITE_NC(LOGIC_ANALYZER_CH7, false);
} }

View File

@ -88,7 +88,7 @@ static inline __attribute__((always_inline))
static uint8_t spiRec() { static uint8_t spiRec() {
uint8_t data = 0; uint8_t data = 0;
// no interrupts during byte receive - about 8 us // no interrupts during byte receive - about 8 us
cli(); // cli();
// output pin high - like sending 0XFF // output pin high - like sending 0XFF
fastDigitalWrite(SPI_MOSI_PIN, HIGH); fastDigitalWrite(SPI_MOSI_PIN, HIGH);
@ -106,7 +106,7 @@ static uint8_t spiRec() {
fastDigitalWrite(SPI_SCK_PIN, LOW); fastDigitalWrite(SPI_SCK_PIN, LOW);
} }
// enable interrupts // enable interrupts
sei(); // sei();
return data; return data;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -120,7 +120,7 @@ static void spiRead(uint8_t* buf, uint16_t nbyte) {
/** Soft SPI send byte */ /** Soft SPI send byte */
static void spiSend(uint8_t data) { static void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us // no interrupts during byte send - about 8 us
cli(); // cli();
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, LOW); fastDigitalWrite(SPI_SCK_PIN, LOW);
@ -138,7 +138,7 @@ static void spiSend(uint8_t data) {
fastDigitalWrite(SPI_SCK_PIN, LOW); fastDigitalWrite(SPI_SCK_PIN, LOW);
// enable interrupts // enable interrupts
sei(); // sei();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Soft SPI send block */ /** Soft SPI send block */

View File

@ -44,6 +44,7 @@ public:
FORCE_INLINE bool isFileOpen() { return file.isOpen(); } FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
FORCE_INLINE bool eof() { return sdpos>=filesize ;}; FORCE_INLINE bool eof() { return sdpos>=filesize ;};
FORCE_INLINE int16_t get() { sdpos = file.curPosition();return (int16_t)file.read();}; 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 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 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;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;};

View File

@ -66,6 +66,7 @@
#define READ(IO) _READ(IO) #define READ(IO) _READ(IO)
/// Write to a pin wrapper /// Write to a pin wrapper
#define WRITE(IO, v) _WRITE(IO, v) #define WRITE(IO, v) _WRITE(IO, v)
#define WRITE_NC(IO, v) _WRITE_NC(IO, v)
/// toggle a pin wrapper /// toggle a pin wrapper
#define TOGGLE(IO) _TOGGLE(IO) #define TOGGLE(IO) _TOGGLE(IO)

View File

@ -480,10 +480,17 @@ void check_axes_activity()
while(block_index != block_buffer_head) while(block_index != block_buffer_head)
{ {
block = &block_buffer[block_index]; block = &block_buffer[block_index];
if(block->steps_x != 0) x_active++; if (block->busy == 2) {
if(block->steps_y != 0) y_active++; ++ x_active;
if(block->steps_z != 0) z_active++; ++ y_active;
if(block->steps_e != 0) e_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); 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 // Acceleration of the segment, in mm/sec^2
block->acceleration = block->acceleration_st / steps_per_mm; block->acceleration = block->acceleration_st / steps_per_mm;
#if 1 #if 0
// Oversample diagonal movements by a power of 2 up to 8x // Oversample diagonal movements by a power of 2 up to 8x
// to achieve more accurate diagonal movements. // to achieve more accurate diagonal movements.
uint8_t bresenham_oversample = 1; uint8_t bresenham_oversample = 1;

View File

@ -44,50 +44,62 @@ enum BlockFlag {
// This struct is used when buffering the setup for each linear movement "nominal" values are as specified in // 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. // the source g-code and may never actually be reached if acceleration management is active.
typedef struct { typedef union {
// Fields used by the bresenham algorithm for tracing the line struct {
// steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line(). // Busy flag: Currently processed.
long steps_x, steps_y, steps_z, steps_e; // Step count along each axis // Misused for the raw movement algorithm.
unsigned long step_event_count; // The number of step events required to complete this block volatile char busy;
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
// Fields used by the motion planner to manage acceleration // Fields used by the bresenham algorithm for tracing the line
// float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis // steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line().
// The nominal speed for this block in mm/sec. long steps_x, steps_y, steps_z, steps_e; // Step count along each axis
// This speed may or may not be reached due to the jerk and acceleration limits. unsigned long step_event_count; // The number of step events required to complete this block
float nominal_speed; long acceleration_rate; // The acceleration rate used for acceleration calculation
// Entry speed at previous-current junction in mm/sec, respecting the acceleration and jerk limits. unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
// The entry speed limit of the current block equals the exit speed of the preceding block. unsigned char active_extruder; // Selects the active extruder
float entry_speed; // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller.
// Maximum allowable junction entry speed in mm/sec. This value is also a maximum exit speed of the previous block. long accelerate_until; // The index of the step event on which to stop acceleration
float max_entry_speed; long decelerate_after; // The index of the step event on which to start decelerating
// The total travel of this block in mm
float millimeters;
// acceleration mm/sec^2
float acceleration;
// Bit flags defined by the BlockFlag enum. // Fields used by the motion planner to manage acceleration
bool flag; // 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). // Bit flags defined by the BlockFlag enum.
// Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts. bool flag;
//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 // Settings for the trapezoid generator (runs inside an interrupt handler).
unsigned long initial_rate; // The jerk-adjusted step rate at start of block // Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts.
unsigned long final_rate; // The minimal rate at exit //FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway!
unsigned long acceleration_st; // acceleration steps/sec^2 unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec
//FIXME does it have to be unsigned long? Probably uint8_t would be just fine. unsigned long initial_rate; // The jerk-adjusted step rate at start of block
unsigned long fan_speed; unsigned long final_rate; // The minimal rate at exit
volatile char busy; unsigned long acceleration_st; // acceleration steps/sec^2
// Pre-calculated division for the calculate_trapezoid_for_block() routine to run faster. // Pre-calculated division for the calculate_trapezoid_for_block() routine to run faster.
float speed_factor; 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; } block_t;
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
@ -166,7 +178,8 @@ FORCE_INLINE block_t *plan_get_current_block()
return(NULL); return(NULL);
} }
block_t *block = &block_buffer[block_buffer_tail]; block_t *block = &block_buffer[block_buffer_tail];
block->busy = true; if (! block->busy)
block->busy = true;
return(block); return(block);
} }

View File

@ -331,22 +331,30 @@ ISR(TIMER1_COMPA_vect)
// Anything in the buffer? // Anything in the buffer?
current_block = plan_get_current_block(); current_block = plan_get_current_block();
if (current_block != NULL) { if (current_block != NULL) {
// The busy flag is set by the plan_get_current_block() call. if (current_block->busy == 2) {
// current_block->busy = true; // This is a raw block.
trapezoid_generator_reset(); counter_x = ((unsigned char*)current_block)[1];
counter_x = -(current_block->step_event_count >> 1); // Stored in bytes, converted to number of steps.
counter_y = counter_x; counter_x >>= 1;
counter_z = counter_x; counter_y = 2;
counter_e = counter_x; } else {
step_events_completed = 0; // 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 #ifdef Z_LATE_ENABLE
if(current_block->steps_z > 0) { if(current_block->steps_z > 0) {
enable_z(); enable_z();
OCR1A = 2000; //1ms wait OCR1A = 2000; //1ms wait
return; return;
} }
#endif #endif
}
} }
else { else {
OCR1A=2000; // 1kHz. OCR1A=2000; // 1kHz.
@ -354,6 +362,49 @@ ISR(TIMER1_COMPA_vect)
} }
if (current_block != NULL) { 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<<X_AXIS)) ? INVERT_X_DIR : !INVERT_X_DIR);
WRITE(Y_DIR_PIN, (out_bits & (0x10<<Y_AXIS)) ? INVERT_Y_DIR : !INVERT_Y_DIR);
WRITE(Z_DIR_PIN, (out_bits & (0x10<<Z_AXIS)) ? INVERT_Z_DIR : !INVERT_Z_DIR);
WRITE(E0_DIR_PIN, (out_bits & (0x10<<E_AXIS)) ? INVERT_E0_DIR : !INVERT_E0_DIR);
// uint16_t old_time = TCNT1;
if (out_bits & (1<<X_AXIS))
WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN);
if (out_bits & (1<<Y_AXIS))
WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN);
if (out_bits & (1<<Z_AXIS))
WRITE(Z_STEP_PIN, !INVERT_Z_STEP_PIN);
if (out_bits & (1<<E_AXIS))
WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN);
if (out_bits & (1<<X_AXIS))
WRITE(X_STEP_PIN, INVERT_X_STEP_PIN);
if (out_bits & (1<<Y_AXIS))
WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN);
if (out_bits & (1<<Z_AXIS))
WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN);
if (out_bits & (1<<E_AXIS))
WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN);
// Plan the next tick.
out_bits = ((unsigned char*)current_block)[counter_y ++];
LOGIC_ANALYZER_SERIAL_TX_WRITE_NC((int)(out_bits));
OCR1A = out_bits;
if (-- counter_x == 0) {
current_block = NULL;
plan_discard_current_block();
LOGIC_ANALYZER_SERIAL_TX_WRITE_NC(0x1ff);
}
// Don't run the ISR faster than possible
// Is there a 8us time left before the next interrupt triggers?
if (OCR1A < TCNT1 + 8) {
// Fix the next interrupt to be executed after 8us from now.
OCR1A = TCNT1 + 8;
}
return;
}
// Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt // Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
out_bits = current_block->direction_bits; out_bits = current_block->direction_bits;

View File

@ -812,9 +812,7 @@ static void updateTemperaturesFromRawValues()
//Reset the watchdog after we know we have a temperature measurement. //Reset the watchdog after we know we have a temperature measurement.
watchdog_reset(); watchdog_reset();
CRITICAL_SECTION_START;
temp_meas_ready = false; temp_meas_ready = false;
CRITICAL_SECTION_END;
} }
@ -1403,6 +1401,12 @@ int read_max6675()
// Timer 0 is shared with millies // Timer 0 is shared with millies
ISR(TIMER0_COMPB_vect) 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 //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 char temp_count = 0;
static unsigned long raw_temp_0_value = 0; static unsigned long raw_temp_0_value = 0;
@ -1955,6 +1959,8 @@ ISR(TIMER0_COMPB_vect)
} }
} }
#endif //BABYSTEPPING #endif //BABYSTEPPING
inside = false;
} }
#ifdef PIDTEMP #ifdef PIDTEMP

View File

@ -378,21 +378,25 @@ static void lcd_status_screen()
if (ReInitLCD == 30) { if (ReInitLCD == 30) {
#if 0
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
currentMenu == lcd_status_screen currentMenu == lcd_status_screen
#endif #endif
); );
#endif
ReInitLCD = 0 ; ReInitLCD = 0 ;
} else { } else {
if ((ReInitLCD % 10) == 0) { if ((ReInitLCD % 10) == 0) {
//lcd_implementation_nodisplay(); //lcd_implementation_nodisplay();
#if 0
lcd_implementation_init_noclear( // to maybe revive the LCD if static electricity killed it. lcd_implementation_init_noclear( // to maybe revive the LCD if static electricity killed it.
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
currentMenu == lcd_status_screen currentMenu == lcd_status_screen
#endif #endif
); );
#endif
} }

View File

@ -652,6 +652,7 @@ void lcd_implementation_print_at(uint8_t x, uint8_t y, const char *str)
lcd.print(str); lcd.print(str);
} }
extern void get_command_push_raw_gcode_to_planner_queue();
/* /*
20x4 |01234567890123456789| 20x4 |01234567890123456789|
@ -692,6 +693,8 @@ static void lcd_implementation_status_screen()
lcd.print(' '); lcd.print(' ');
#endif #endif
get_command_push_raw_gcode_to_planner_queue();
//Print the Bedtemperature //Print the Bedtemperature
lcd.setCursor(0, 1); lcd.setCursor(0, 1);
tHotend=int(degBed() + 0.5); tHotend=int(degBed() + 0.5);
@ -728,6 +731,8 @@ static void lcd_implementation_status_screen()
planner_queue_min_reset(); planner_queue_min_reset();
} }
#endif #endif
get_command_push_raw_gcode_to_planner_queue();
//Print SD status //Print SD status
lcd.setCursor(0, 2); lcd.setCursor(0, 2);
@ -786,7 +791,7 @@ static void lcd_implementation_status_screen()
#endif #endif
} }
get_command_push_raw_gcode_to_planner_queue();
//Print time elapsed //Print time elapsed
lcd.setCursor(LCD_WIDTH - 8 -1, 2); 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 in progress, set flag
if (heating_status != 0) { custom_message = true; } 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 printing from SD, show what we are printing
if ((IS_SD_PRINTING) && !custom_message) if ((IS_SD_PRINTING) && !custom_message)
{ {
@ -988,7 +995,9 @@ static void lcd_implementation_status_screen()
lcd.print(lcd_status_message); lcd.print(lcd_status_message);
} }
} }
get_command_push_raw_gcode_to_planner_queue();
// Fill the rest of line to have nice and clean output // Fill the rest of line to have nice and clean output
for(int fillspace = 0; fillspace<20;fillspace++) for(int fillspace = 0; fillspace<20;fillspace++)
{ {