Propagated premature step end bug fix from the edge branch. Updated printFloat() function.

- Will not be uploading a hex build of this, unless asked.
This commit is contained in:
Sonny Jeon 2012-01-15 19:05:06 -07:00
parent 12bae58994
commit 66d3155f2f
2 changed files with 41 additions and 25 deletions

35
print.c
View File

@ -3,6 +3,7 @@
Part of Grbl Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Sungeun K. Jeon
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -28,20 +29,21 @@
#ifndef DECIMAL_PLACES #ifndef DECIMAL_PLACES
#define DECIMAL_PLACES 3 #define DECIMAL_PLACES 3
#define DECIMAL_MULTIPLIER 10*10*10
#endif #endif
void printString(const char *s) void printString(const char *s)
{ {
while (*s) while (*s)
serial_write(*s++); serial_write(*s++);
} }
// Print a string stored in PGM-memory // Print a string stored in PGM-memory
void printPgmString(const char *s) void printPgmString(const char *s)
{ {
char c; char c;
while ((c = pgm_read_byte_near(s++))) while ((c = pgm_read_byte_near(s++)))
serial_write(c); serial_write(c);
} }
void printIntegerInBase(unsigned long n, unsigned long base) void printIntegerInBase(unsigned long n, unsigned long base)
@ -78,18 +80,25 @@ void printInteger(long n)
// A very simple // A very simple
void printFloat(double n) void printFloat(double n)
{ {
double integer_part, fractional_part; if (n < 0) {
uint8_t decimal_part; serial_write('-');
fractional_part = modf(n, &integer_part); n = -n;
printInteger(integer_part); }
n += 0.5/DECIMAL_MULTIPLIER; // Add rounding factor
long integer_part;
integer_part = (int)n;
printIntegerInBase(integer_part,10);
serial_write('.'); serial_write('.');
fractional_part *= 10;
n -= integer_part;
int decimals = DECIMAL_PLACES; int decimals = DECIMAL_PLACES;
uint8_t decimal_part;
while(decimals-- > 0) { while(decimals-- > 0) {
decimal_part = floor(fractional_part); n *= 10;
decimal_part = (int) n;
serial_write('0'+decimal_part); serial_write('0'+decimal_part);
fractional_part -= decimal_part; n -= decimal_part;
fractional_part *= 10;
} }
} }

View File

@ -133,21 +133,25 @@ static uint8_t iterate_trapezoid_cycle_counter()
// config_step_timer. It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. // config_step_timer. It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
// It is supported by The Stepper Port Reset Interrupt which it uses to reset the stepper port after each pulse. // It is supported by The Stepper Port Reset Interrupt which it uses to reset the stepper port after each pulse.
// The bresenham line tracer algorithm controls all three stepper outputs simultaneously with these two interrupts. // The bresenham line tracer algorithm controls all three stepper outputs simultaneously with these two interrupts.
// NOTE: ISR_NOBLOCK allows SIG_OVERFLOW2 to trigger on-time regardless of time in this handler. This is ISR(TIMER1_COMPA_vect)
// the compiler optimizable equivalent of the old SIGNAL() and sei() method.
ISR(TIMER1_COMPA_vect,ISR_NOBLOCK)
{ {
if (busy) { return; } // The busy-flag is used to avoid reentering this interrupt if (busy) { return; } // The busy-flag is used to avoid reentering this interrupt
busy = true;
// Set the direction pins a couple of nanoseconds before we step the steppers // Set the direction pins a couple of nanoseconds before we step the steppers
STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (out_bits & DIRECTION_MASK); STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (out_bits & DIRECTION_MASK);
// Then pulse the stepping pins // Then pulse the stepping pins
STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | out_bits; STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | out_bits;
// Reset step pulse reset timer so that The Stepper Port Reset Interrupt can reset the signal after // Enable step pulse reset timer so that The Stepper Port Reset Interrupt can reset the signal after
// exactly settings.pulse_microseconds microseconds. // exactly settings.pulse_microseconds microseconds, independent of the main Timer1 prescaler.
TCNT2 = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); TCNT2 = -(((settings.pulse_microseconds-2)*TICKS_PER_MICROSECOND) >> 3); // Reload timer counter
TCCR2B = (1<<CS21); // Begin timer2. Full speed, 1/8 prescaler
busy = true;
// Re-enable interrupts to allow ISR_TIMER2_OVERFLOW to trigger on-time and allow serial communications
// regardless of time in this handler. The following code prepares the stepper driver for the next
// step interrupt compare and will always finish before returning to the main program.
sei();
// If there is no current block, attempt to pop one from the buffer // If there is no current block, attempt to pop one from the buffer
if (current_block == NULL) { if (current_block == NULL) {
// Anything in the buffer? If so, initialize next motion. // Anything in the buffer? If so, initialize next motion.
@ -250,12 +254,15 @@ ISR(TIMER1_COMPA_vect,ISR_NOBLOCK)
busy=false; busy=false;
} }
// This interrupt is set up by SIG_OUTPUT_COMPARE1A when it sets the motor port bits. It resets // This interrupt is set up by ISR_TIMER1_COMPAREA when it sets the motor port bits. It resets
// the motor port after a short period (settings.pulse_microseconds) completing one step cycle. // the motor port after a short period (settings.pulse_microseconds) completing one step cycle.
// TODO: It is possible for the serial interrupts to delay this interrupt by a few microseconds, if
// they execute right before this interrupt. Not a big deal, but could use some TLC at some point.
ISR(TIMER2_OVF_vect) ISR(TIMER2_OVF_vect)
{ {
// Reset stepping pins (leave the direction pins) // Reset stepping pins (leave the direction pins)
STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | (settings.invert_mask & STEP_MASK); STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | (settings.invert_mask & STEP_MASK);
TCCR2B = 0; // Disable Timer2 to prevent re-entering this interrupt when it's not needed.
} }
// Initialize and start the stepper motor subsystem // Initialize and start the stepper motor subsystem
@ -277,9 +284,9 @@ void st_init()
TCCR1A &= ~(3<<COM1B0); TCCR1A &= ~(3<<COM1B0);
// Configure Timer 2 // Configure Timer 2
TCCR2A = 0; // Normal operation TCCR2A = 0; // Normal operation
TCCR2B = (1<<CS21); // Full speed, 1/8 prescaler TCCR2B = 0; // Disable timer until needed.
TIMSK2 |= (1<<TOIE2); TIMSK2 |= (1<<TOIE2); // Enable Timer2 interrupt flag
set_step_events_per_minute(MINIMUM_STEPS_PER_MINUTE); set_step_events_per_minute(MINIMUM_STEPS_PER_MINUTE);
trapezoid_tick_cycle_counter = 0; trapezoid_tick_cycle_counter = 0;