Merge branch 'master' of github.com:triffid/FiveD_on_Arduino

This commit is contained in:
Michael Moon 2010-09-26 11:30:55 +10:00
commit bbf74cc660
5 changed files with 56 additions and 31 deletions

33
dda.c
View File

@ -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
}

49
gcode.c
View File

@ -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;

View File

@ -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.

View File

@ -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"));
}

View File

@ -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