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 <math.h>
#include <avr/interrupt.h>
#include "dda_maths.h"
#include <stdint.h>
#include "config.h"
#include "timer.h"
#include "serial.h"
#include "dda_queue.h"
#include "debug.h"
#include "sersendf.h"
#include "pinio.h"
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 | |
void | dda_init (void) |
Inititalise DDA movement structures. | |
void | dda_new_startpoint (void) |
Distribute a new startpoint to DDA's internal structures without any movement. | |
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. | |
void | update_current_position () |
update global current_position struct |
Digital differential analyser - this is where we figure out which steppers need to move, and when they need to move.
CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue.
*dda | pointer to a dda_queue entry to overwrite | |
*target | the 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
void dda_new_startpoint | ( | void | ) |
Distribute a new startpoint to DDA's internal structures without any movement.
This is needed for example after homing or a G92. The new location must be in startpoint already.
Referenced by home_x_negative(), home_y_negative(), home_z_negative(), and process_gcode_command().
void dda_start | ( | DDA * | dda | ) |
Start a prepared DDA.
*dda | pointer 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
Called both inside and outside of interrupts.
Referenced by next_move().
void dda_step | ( | DDA * | dda | ) |
STEP.
*dda | the current move |
This is called from our timer interrupt every time a step needs to occur. Keep it as simple as possible! 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.
< Stop due to endstop trigger
< Which axes haven't finished homing
Referenced by queue_step().