Experimental feature: Binary G-code
This commit is contained in:
parent
1661902e2f
commit
6ef4dd5e88
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<<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
|
||||
out_bits = current_block->direction_bits;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -729,6 +732,8 @@ static void lcd_implementation_status_screen()
|
|||
}
|
||||
#endif
|
||||
|
||||
get_command_push_raw_gcode_to_planner_queue();
|
||||
|
||||
//Print SD status
|
||||
lcd.setCursor(0, 2);
|
||||
if (is_usb_printing)
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -989,6 +996,8 @@ static void lcd_implementation_status_screen()
|
|||
}
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue