diff --git a/mendel/dda.c b/mendel/dda.c index df9c053..e4c3aa8 100644 --- a/mendel/dda.c +++ b/mendel/dda.c @@ -12,6 +12,10 @@ extern struct { volatile int32_t F; } current_position; +/* + move queue +*/ + uint8_t mb_head = 0; uint8_t mb_tail = 0; DDA movebuffer[MOVEBUFFER_SIZE]; @@ -23,10 +27,6 @@ uint8_t queue_full() { return mb_head == (mb_tail - 1); } -inline uint8_t queue_empty() { - return (mb_tail == mb_head) && !movebuffer[tail].live; -} - void enqueue(TARGET *t) { while (queue_full()) delay(WAITING_DELAY); @@ -55,6 +55,10 @@ void next_move() { } } +/* + utility functions +*/ + // courtesy of http://www.oroboro.com/rafael/docserv.php/index/programming/article/distance uint32_t approx_distance( int32_t dx, int32_t dy ) { @@ -127,7 +131,7 @@ void dda_create(TARGET *target, DDA *dda) { static TARGET startpoint = { 0, 0, 0, 0, 0 }; // we start at the previous endpoint - memcpy(&dda->currentpoint, &startpoint, sizeof(TARGET)); +// memcpy(&dda->currentpoint, &startpoint, sizeof(TARGET)); // we end at the passed command's endpoint memcpy(&dda->endpoint, target, sizeof(TARGET)); @@ -166,14 +170,6 @@ void dda_create(TARGET *target, DDA *dda) { if (dda->total_steps == 0) dda->nullmove = 1; - // MM = sqrt(X^2 + Y^2) - // STEPS = max(X * STEPS_PER_MM_X, Y * STEPS_PER_MM_Y) - // DURATION = MM / MM_PER_MIN * 60 SEC_PER_MIN * 1000000 US_PER_SEC - // US/STEP = DURATION / STEPS - // intF = sqrt(X^2 + Y^2) / max(X * STEPS_PER_MM_X, Y * STEPS_PER_MM_Y) - -// dda->endpoint.F = distance / total_steps; - if (dda->f_delta > dda->total_steps) { dda->f_scale = dda->f_delta / dda->total_steps; if (dda->f_scale > 3) { @@ -196,12 +192,14 @@ void dda_create(TARGET *target, DDA *dda) { // pre-calculate move speed in millimeter microseconds per step minute for less math in interrupt context // mm (distance) * 60000000 us/min / step (total_steps) = mm.us per step.min - // mm.us per step.min / mm/min (F) = us per step + // so in the interrupt we must simply calculate + // mm.us per step.min / mm per min (F) = us per step dda->move_duration = dda->distance * 60000000 / dda->total_steps; // next dda starts where we finish memcpy(&startpoint, &dda->endpoint, sizeof(TARGET)); + // make sure we're not running dda->live = 0; } @@ -220,6 +218,7 @@ void dda_start(DDA *dda) { e_direction(dda->e_direction); enable_steppers(); + dda->live = 1; } @@ -257,8 +256,8 @@ void dda_step(DDA *dda) { step_option |= can_step(x_min(), x_max(), current_position.X, dda->endpoint.X, dda->x_direction) & X_CAN_STEP; step_option |= can_step(y_min(), y_max(), current_position.Y, dda->endpoint.Y, dda->y_direction) & Y_CAN_STEP; step_option |= can_step(z_min(), z_max(), current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP; - step_option |= can_step(-1 , -1 , current_position.E, dda->endpoint.E, dda->e_direction) & E_CAN_STEP; - step_option |= can_step(-1 , -1 , current_position.F, dda->endpoint.F, dda->f_direction) & F_CAN_STEP; + step_option |= can_step(0 , 0 , current_position.E, dda->endpoint.E, dda->e_direction) & E_CAN_STEP; + step_option |= can_step(0 , 0 , current_position.F, dda->endpoint.F, dda->f_direction) & F_CAN_STEP; if (step_option & X_CAN_STEP) { dda->x_counter -= dda->x_delta; @@ -339,11 +338,13 @@ void dda_step(DDA *dda) { } while ( ((step_option & REAL_MOVE ) == 0) && ((step_option & F_CAN_STEP) != 0) ); + // turn off step outputs, hopefully they've been on long enough by now to register with the drivers unstep(); - if (step_option & REAL_MOVE) { + // we have stepped and now need to wait + if (step_option & REAL_MOVE) setTimer(dda->move_duration / current_position.F); - } + // if we could step, we're still running dda->live = (step_option & (X_CAN_STEP | Y_CAN_STEP | Z_CAN_STEP | E_CAN_STEP | F_CAN_STEP)); } diff --git a/mendel/dda.h b/mendel/dda.h index f1a6d8e..0c3b742 100644 --- a/mendel/dda.h +++ b/mendel/dda.h @@ -9,7 +9,7 @@ #include "machine.h" typedef struct { - TARGET currentpoint; +// TARGET currentpoint; TARGET endpoint; uint8_t x_direction :1; @@ -43,9 +43,15 @@ extern uint8_t mb_head; extern uint8_t mb_tail; extern DDA movebuffer[MOVEBUFFER_SIZE]; -uint32_t approx_distance( int32_t dx, int32_t dy ); +uint8_t queue_full(void); +inline uint8_t queue_empty(void) { return (mb_tail == mb_head) && !movebuffer[mb_tail].live; } +void enqueue(TARGET *t); +void next_move(void); -void dda_create(GCODE_COMMAND *cmd, DDA *dda); +uint32_t approx_distance( int32_t dx, int32_t dy ); +uint32_t approx_distance_3( int32_t dx, int32_t dy, int32_t dz ); + +void dda_create(TARGET *target, DDA *dda); void dda_start(DDA *dda); void dda_step(DDA *dda); diff --git a/mendel/pinout.h b/mendel/pinout.h index a2226de..8b69263 100644 --- a/mendel/pinout.h +++ b/mendel/pinout.h @@ -13,11 +13,6 @@ #define SET_INPUT(IO) (DDR_ ## IO |= MASK(PIN_ ## IO)) #define SET_OUTPUT(IO) (DDR_ ## IO &= ~MASK(PIN ## IO)) -// void x_step(void); -// void y_step(void); -// void z_step(void); -// void e_step(void); - #define _x_step(st) WRITE(AIO0, st) #define x_step() _x_step(1); #define x_direction(dir) WRITE(AIO1, dir) diff --git a/mendel/timer.c b/mendel/timer.c index ea43835..6e2a913 100644 --- a/mendel/timer.c +++ b/mendel/timer.c @@ -133,6 +133,14 @@ void setTimer(uint32_t delay) setTimerResolution(getTimerResolution(delay)); } +void delay(uint32_t delay) { + while (delay > 65535) { + delayMicrosecondsInterruptible(delay); + delay -= 65535; + } + delayMicrosecondsInterruptible(delay & 0xFFFF); +} + // from reprap project 5D firmware void delayMicrosecondsInterruptible(uint16_t us) { diff --git a/mendel/timer.h b/mendel/timer.h index ee73127..abe4960 100644 --- a/mendel/timer.h +++ b/mendel/timer.h @@ -9,6 +9,7 @@ #define MS * (F_CPU / 1000) #define DEFAULT_TICK (100 US) +#define WAITING_DELAY (10 MS) void setupTimerInterrupt(void); uint8_t getTimerResolution(const uint32_t delay); @@ -17,6 +18,7 @@ uint16_t getTimerCeiling(const uint32_t delay); void setTimer(uint32_t delay); +void delay(uint32_t delay); void delayMicrosecondsInterruptible(unsigned int us); inline void enableTimerInterrupt(void)