diff --git a/dda.c b/dda.c index 24b465b..5b7ef8c 100644 --- a/dda.c +++ b/dda.c @@ -106,7 +106,7 @@ const uint8_t msbloc (uint32_t v) { */ void dda_create(DDA *dda, TARGET *target) { - uint32_t distance; + uint32_t distance, c_limit, c_limit_calc; // initialise DDA to a known state dda->allflags = 0; @@ -199,16 +199,37 @@ void dda_create(DDA *dda, TARGET *target) { // distance * 2400 .. * F_CPU / 40000 so we can move a distance of up to 1800mm without overflowing uint32_t move_duration = ((distance * 2400) / dda->total_steps) * (F_CPU / 40000); + // similarly, find out how fast we can run our axes. + // do this for each axis individually, as the combined speed of two or more axes can be higher than the capabilities of a single one. + c_limit = 0; + c_limit_calc = ((dda->x_delta * UM_PER_STEP_X * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_X) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->y_delta * UM_PER_STEP_Y * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_Y) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->z_delta * UM_PER_STEP_Z * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_Z) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + c_limit_calc = ((dda->e_delta * UM_PER_STEP_E * 2400) / dda->total_steps * (F_CPU / 40000) / MAXIMUM_FEEDRATE_E) << 8; + if (c_limit_calc > c_limit) + c_limit = c_limit_calc; + #ifdef ACCELERATION_REPRAP // c is initial step time in IOclk ticks dda->c = (move_duration / startpoint.F) << 8; + if (dda->c < c_limit) + dda->c = c_limit; + dda->end_c = (move_duration / target->F) << 8; + if (dda->end_c < c_limit) + dda->end_c = c_limit; if (debug_flags & DEBUG_DDA) { serial_writestr_P(PSTR(",md:")); serwrite_uint32(move_duration); serial_writestr_P(PSTR(",c:")); serwrite_uint32(dda->c >> 8); } - if (startpoint.F != target->F) { + if (dda->c != dda->end_c) { uint32_t stF = startpoint.F / 4; uint32_t enF = target->F / 4; // now some constant acceleration stuff, courtesy of http://www.embedded.com/columns/technicalinsights/56800129?printable=true @@ -219,7 +240,6 @@ void dda_create(DDA *dda, TARGET *target) { uint8_t msb_ssq = msbloc(ssq); uint8_t msb_tot = msbloc(dda->total_steps); - dda->end_c = (move_duration / target->F) << 8; // the raw equation WILL overflow at high step rates, but 64 bit math routines take waay too much space // at 65536 mm/min (1092mm/s), ssq/esq overflows, and dsq is also close to overflowing if esq/ssq is small // but if ssq-esq is small, ssq/dsq is only a few bits @@ -252,15 +272,20 @@ void dda_create(DDA *dda, TARGET *target) { else dda->accel = 0; #elif defined ACCELERATION_RAMPING - dda->ramp_steps = dda->total_steps / 2; + // add the last bit of dda->total_steps to always round up + dda->ramp_steps = dda->total_steps / 2 + (dda->total_steps & 1); dda->step_no = 0; // c is initial step time in IOclk ticks dda->c = ACCELERATION_STEEPNESS << 8; dda->c_min = (move_duration / target->F) << 8; + if (dda->c_min < c_limit) + dda->c_min = c_limit; dda->n = 1; dda->ramp_state = RAMP_UP; #else dda->c = (move_duration / target->F) << 8; + if (dda->c < c_limit) + dda->c = c_limit; #endif } diff --git a/gcode.c b/gcode.c index 7e3b4ea..23cefee 100644 --- a/gcode.c +++ b/gcode.c @@ -271,6 +271,14 @@ void scan_char(uint8_t c) { if (read_digit.exponent == 0) read_digit.exponent = 1; break; + #ifdef DEBUG + case ' ': + case '\t': + case 10: + case 13: + // ignore + break; + #endif default: // can't do ranges in switch..case, so process actual digits here @@ -280,7 +288,14 @@ void scan_char(uint8_t c) { if (read_digit.exponent) read_digit.exponent++; } - // everything else is ignored + #ifdef DEBUG + else { + // invalid + serial_writechar('?'); + serial_writechar(c); + serial_writechar('?'); + } + #endif } } else if ( next_target.seen_parens_comment == 1 && c == ')') next_target.seen_parens_comment = 0; // recognize stuff after a (comment) @@ -311,15 +326,8 @@ void scan_char(uint8_t c) { #endif ) { // process - if (next_target.seen_G || next_target.seen_M) { - process_gcode_command(&next_target); - - serial_writestr_P(PSTR("ok\n")); - } - else { - // write "OK" for invalid/unknown commands as well - serial_writestr_P(PSTR("ok huh?\n")); - } + process_gcode_command(&next_target); + serial_writestr_P(PSTR("ok\n")); // expect next line number if (next_target.seen_N == 1) @@ -341,13 +349,16 @@ void scan_char(uint8_t c) { // reset variables next_target.seen_X = next_target.seen_Y = next_target.seen_Z = \ - next_target.seen_E = next_target.seen_F = next_target.seen_G = \ - next_target.seen_S = next_target.seen_P = next_target.seen_N = \ - next_target.seen_M = next_target.seen_checksum = \ - next_target.seen_semi_comment = next_target.seen_parens_comment = \ - next_target.checksum_read = next_target.checksum_calculated = 0; + next_target.seen_E = next_target.seen_F = next_target.seen_S = \ + next_target.seen_P = next_target.seen_N = next_target.seen_M = \ + next_target.seen_checksum = next_target.seen_semi_comment = \ + next_target.seen_parens_comment = next_target.checksum_read = \ + next_target.checksum_calculated = 0; last_field = 0; read_digit.sign = read_digit.mantissa = read_digit.exponent = 0; + // assume a G1 by default + next_target.seen_G = 1; + next_target.G = 1; } } @@ -393,14 +404,6 @@ void process_gcode_command(GCODE_COMMAND *gcmd) { // G1 - synchronised motion case 1: - // check speeds here - if (gcmd->seen_Z) { - if (gcmd->target.F > MAXIMUM_FEEDRATE_Z) - gcmd->target.F = MAXIMUM_FEEDRATE_Z; - } - else if (gcmd->target.F > MAXIMUM_FEEDRATE_X) - gcmd->target.F = MAXIMUM_FEEDRATE_X; - enqueue(&gcmd->target); break; diff --git a/machine.h b/machine.h index 1bcec16..720406c 100644 --- a/machine.h +++ b/machine.h @@ -41,9 +41,7 @@ Each movement starts at the speed of the previous command and accelerates or decelerates linearly to reach target speed at the end of the movement. Can also be set in Makefile */ -#ifndef ACCELERATION_RAMPING #define ACCELERATION_REPRAP -#endif /* acceleration and deceleration ramping. diff --git a/mendel.c b/mendel.c index 600074a..0ccf7f9 100644 --- a/mendel.c +++ b/mendel.c @@ -108,7 +108,7 @@ void init(void) { wd_reset(); // say hi to host - serial_writestr_P(PSTR("Start\nOK\n")); + serial_writestr_P(PSTR("Start\nok\n")); } diff --git a/timer.c b/timer.c index 6cafbcf..b04be2a 100644 --- a/timer.c +++ b/timer.c @@ -104,7 +104,6 @@ void setTimer(uint32_t delay) // the result is the timer counts up to the appropriate time and then fires an interrupt. setTimerResolution(0); // stop timer - TCNT1 = 0; // reset timer GTCCR = MASK(PSRSYNC); // reset prescaler - affects timer 0 too but since it's doing PWM, it's not using the prescaler setTimerCeiling(getTimerCeiling(delay)); // set timeout