Defines | Functions | Variables

dda.c File Reference

Digital differential analyser - this is where we figure out which steppers need to move, and when they need to move. More...

#include "dda.h"
#include <string.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "timer.h"
#include "serial.h"
#include "sermsg.h"
#include "dda_queue.h"
#include "debug.h"
#include "sersendf.h"
#include "pinio.h"
#include "config.h"

Defines

#define UM_PER_STEP_X   1000L / ((uint32_t) STEPS_PER_MM_X)
 micrometers per step X
#define UM_PER_STEP_Y   1000L / ((uint32_t) STEPS_PER_MM_Y)
 micrometers per step Y
#define UM_PER_STEP_Z   1000L / ((uint32_t) STEPS_PER_MM_Z)
 micrometers per step Z
#define UM_PER_STEP_E   1000L / ((uint32_t) STEPS_PER_MM_E)
 micrometers per step E

Functions

TARGET startpoint __attribute__ ((__section__(".bss")))
 this is where we store all the data for the current command before we work out what to do with it
uint32_t approx_distance (uint32_t dx, uint32_t dy)
 linear approximation 2d distance formula
uint32_t approx_distance_3 (uint32_t dx, uint32_t dy, uint32_t dz)
 linear approximation 3d distance formula
uint16_t int_sqrt (uint32_t a)
 integer square root algorithm
const uint8_t msbloc (uint32_t v)
 crude logarithm algorithm
void dda_create (DDA *dda, TARGET *target)
 CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue.
void dda_start (DDA *dda)
 Start a prepared DDA.
void dda_step (DDA *dda)
 STEP.

Variables

uint8_t steptimeout = 0
 step timeout

Detailed Description

Digital differential analyser - this is where we figure out which steppers need to move, and when they need to move.


Function Documentation

uint32_t approx_distance ( uint32_t  dx,
uint32_t  dy 
)

linear approximation 2d distance formula

Parameters:
dxdistance in X plane
dydistance in Y plane
Returns:
3-part linear approximation of $\sqrt{\Delta x^2 + \Delta y^2}$

see http://www.flipcode.com/archives/Fast_Approximate_Distance_Functions.shtml

Referenced by dda_create().

uint32_t approx_distance_3 ( uint32_t  dx,
uint32_t  dy,
uint32_t  dz 
)

linear approximation 3d distance formula

Parameters:
dxdistance in X plane
dydistance in Y plane
dzdistance in Z plane
Returns:
3-part linear approximation of $\sqrt{\Delta x^2 + \Delta y^2 + \Delta z^2}$

see http://www.oroboro.com/rafael/docserv.php/index/programming/article/distance

Referenced by dda_create().

void dda_create ( DDA dda,
TARGET target 
)

CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue.

Parameters:
*ddapointer to a dda_queue entry to overwrite
*targetthe target position of this move

startpoint the beginning position of this move

This function does a /lot/ of math. It works out directions for each axis, distance travelled, the time between the first and second step

It also pre-fills any data that the selected accleration algorithm needs, and can be pre-computed for the whole move.

This algorithm is probably the main limiting factor to print speed in terms of firmware limitations

Referenced by enqueue().

void dda_start ( DDA dda )

Start a prepared DDA.

Parameters:
*ddapointer to entry in dda_queue to start

This function actually begins the move described by the passed DDA entry.

We set direction and enable outputs, and set the timer for the first step from the precalculated value.

We also mark this DDA as running, so other parts of the firmware know that something is happening

Referenced by next_move().

void dda_step ( DDA dda )

STEP.

Parameters:
*ddathe current move

This is called from our timer interrupt every time a step needs to occur. We first work out which axes need to step, and generate step pulses for them Then we re-enable global interrupts so serial data reception and other important things can occur while we do some math. Next, we work out how long until our next step using the selected acceleration algorithm and set the timer. Then we decide if this was the last step for this move, and if so mark this dda as dead so next timer interrupt we can start a new one. Finally we de-assert any asserted step pins.

Todo:
take into account the time that interrupt takes to run

Referenced by queue_step().

uint16_t int_sqrt ( uint32_t  a )

integer square root algorithm

Parameters:
afind square root of this number
Returns:
sqrt(a - 1) < returnvalue <= sqrt(a)

see http://www.embedded-systems.com/98/9802fe2.htm

const uint8_t msbloc ( uint32_t  v )

crude logarithm algorithm

Parameters:
vvalue to find $log_2$ of
Returns:
floor(log(v) / log(2))

Referenced by dda_create().


Variable Documentation

uint8_t steptimeout = 0

step timeout

steptimeout is set to zero when we step, and increases over time so we can turn the motors off when they've been idle for a while

Referenced by clock_250ms(), dda_create(), dda_start(), dda_step(), and process_gcode_command().

 All Data Structures Files Functions Variables Defines