It's alive! (cue evil cackle). still has some bugs, eg small movements with large delta F cause weirdness, queueing lots of moves end-to-end causes some to not execute but appear as complete in the queue
This commit is contained in:
parent
d302329eee
commit
4fc004c6c2
|
|
@ -32,7 +32,7 @@ F_CPU = 16000000L
|
|||
##############################################################################
|
||||
|
||||
ARCH = avr-
|
||||
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=0
|
||||
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=1
|
||||
# OPTIMIZE = -O0
|
||||
CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps
|
||||
LDFLAGS = -Wl,--as-needed -Wl,--gc-sections
|
||||
|
|
@ -54,9 +54,10 @@ all: $(PROGRAM).hex $(PROGRAM).lst size
|
|||
|
||||
program: $(PROGRAM).hex
|
||||
stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT)
|
||||
@sleep 0.2
|
||||
@stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT)
|
||||
$(AVRDUDE) -cstk500v1 -b$(PROGBAUD) -p$(MCU_TARGET) -P$(PROGPORT) -C/etc/avrdude.conf -U flash:w:$^
|
||||
stty -hup -echo < $(PROGPORT)
|
||||
stty 57600 raw ignbrk -hup -echo < $(PROGPORT)
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~
|
||||
|
|
|
|||
|
|
@ -26,6 +26,34 @@
|
|||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||
|
||||
/*
|
||||
ports and functions
|
||||
*/
|
||||
|
||||
// UART
|
||||
#define RXD DIO0
|
||||
#define TXD DIO1
|
||||
|
||||
// SPI
|
||||
#define SCK DIO13
|
||||
#define MISO DIO12
|
||||
#define MOSI DIO11
|
||||
#define SS DIO10
|
||||
|
||||
// TWI (I2C)
|
||||
#define SCL AIO5
|
||||
#define SDA AIO4
|
||||
|
||||
// timers and PWM
|
||||
#define OC0A DIO6
|
||||
#define OC0B DIO5
|
||||
#define OC1A DIO9
|
||||
#define OC1B DIO10
|
||||
#define OC2A DIO11
|
||||
#define OC2B DIO3
|
||||
|
||||
#define ICP1 DIO8
|
||||
|
||||
/*
|
||||
pins
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <avr/interrupt.h>
|
||||
|
||||
#include "arduino.h"
|
||||
#include "pinout.h"
|
||||
|
||||
// global clock
|
||||
#ifdef GLOBAL_CLOCK
|
||||
|
|
@ -38,6 +39,7 @@ void clock_setup() {
|
|||
}
|
||||
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
// WRITE(SCK, 0);
|
||||
// global clock
|
||||
#ifdef GLOBAL_CLOCK
|
||||
clock++;
|
||||
|
|
@ -47,6 +49,7 @@ ISR(TIMER2_COMPA_vect) {
|
|||
clock_flag_250ms = 255;
|
||||
clock_counter_250ms = 0;
|
||||
}
|
||||
// WRITE(SCK, 1);
|
||||
}
|
||||
|
||||
#ifdef GLOBAL_CLOCK
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ uint32_t clock_read(void);
|
|||
|
||||
extern volatile uint8_t clock_flag_250ms;
|
||||
|
||||
#define CLOCK_FLAG_250MS_TEMPCHECK 1
|
||||
#define CLOCK_FLAG_250MS_REPORT 2
|
||||
#define CLOCK_FLAG_250MS_TEMPCHECK 1
|
||||
#define CLOCK_FLAG_250MS_REPORT 2
|
||||
#define CLOCL_FLAG_250MS_STEPTIMEOUT 4
|
||||
|
||||
#endif /* _CLOCK_H */
|
||||
|
|
|
|||
46
mendel/dda.c
46
mendel/dda.c
|
|
@ -18,6 +18,12 @@
|
|||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
step timeout
|
||||
*/
|
||||
|
||||
uint8_t steptimeout = 0;
|
||||
|
||||
/*
|
||||
move queue
|
||||
*/
|
||||
|
|
@ -201,6 +207,7 @@ void dda_create(TARGET *target, DDA *dda) {
|
|||
dda->f_delta = dda->total_steps;
|
||||
}
|
||||
else {
|
||||
// if we boost the number of steps here, many will only be F-steps which take no time- maybe we should calculate move_distance first?
|
||||
dda->f_scale = 1;
|
||||
dda->total_steps = dda->f_delta;
|
||||
}
|
||||
|
|
@ -253,6 +260,10 @@ void dda_create(TARGET *target, DDA *dda) {
|
|||
// not running yet, we fire up in dda_start()
|
||||
dda->live = 0;
|
||||
|
||||
// get steppers ready to go
|
||||
steptimeout = 0;
|
||||
enable_steppers();
|
||||
|
||||
// fire up
|
||||
enableTimerInterrupt();
|
||||
}
|
||||
|
|
@ -269,16 +280,18 @@ void dda_start(DDA *dda) {
|
|||
return;
|
||||
}
|
||||
|
||||
// set direction outputs
|
||||
x_direction(dda->x_direction);
|
||||
y_direction(dda->y_direction);
|
||||
z_direction(dda->z_direction);
|
||||
e_direction(dda->e_direction);
|
||||
|
||||
// ensure steppers are ready to go
|
||||
steptimeout = 0;
|
||||
enable_steppers();
|
||||
|
||||
dda->firstep = 1;
|
||||
|
||||
dda->live = 1;
|
||||
// set timeout for first step
|
||||
setTimer(dda->move_duration / current_position.F);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -321,9 +334,10 @@ void dda_step(DDA *dda) {
|
|||
#define REAL_MOVE 32
|
||||
#define F_REAL_STEP 64
|
||||
|
||||
WRITE(SCK, 1);
|
||||
|
||||
do {
|
||||
WRITE(SCK, 0);
|
||||
|
||||
step_option = 0;
|
||||
// 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;
|
||||
|
|
@ -417,7 +431,7 @@ void dda_step(DDA *dda) {
|
|||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
if (0 && DEBUG) {
|
||||
serial_writechar('[');
|
||||
serwrite_hex8(step_option);
|
||||
serial_writechar(':');
|
||||
|
|
@ -430,20 +444,28 @@ void dda_step(DDA *dda) {
|
|||
serwrite_uint32(dda->move_duration);
|
||||
serial_writechar(']');
|
||||
}
|
||||
|
||||
WRITE(SCK, 1);
|
||||
|
||||
} 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();
|
||||
|
||||
// we have stepped in speed and now need to recalculate our delay
|
||||
if (((step_option & REAL_MOVE) && (step_option & F_REAL_STEP)) || (dda->firstep)) {
|
||||
setTimer(dda->move_duration / current_position.F);
|
||||
dda->firstep = 0;
|
||||
if (step_option & REAL_MOVE) {
|
||||
// we stepped, reset timeout
|
||||
steptimeout = 0;
|
||||
|
||||
// we have stepped in speed and now need to recalculate our delay
|
||||
// WARNING: this is a divide in interrupt context! (which unfortunately seems unavoidable)
|
||||
// we simply don't have the memory to precalculate this for each step,
|
||||
// can't use a simplified process because the denominator changes rather than the numerator so the curve is non-linear
|
||||
// and don't have a process framework to force it to be done outside interrupt context within a usable period of time
|
||||
if (step_option & F_REAL_STEP)
|
||||
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))?1:0;
|
||||
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ extern DDA movebuffer[MOVEBUFFER_SIZE];
|
|||
extern TARGET startpoint;
|
||||
extern TARGET current_position;
|
||||
|
||||
extern uint8_t steptimeout;
|
||||
|
||||
uint8_t queue_full(void);
|
||||
uint8_t queue_empty(void);
|
||||
void enqueue(TARGET *t);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator)
|
|||
if (df->sign)
|
||||
r = -r;
|
||||
|
||||
// exponent- try to keep divides to a minimum at expense of slightly more code
|
||||
// exponent- try to keep divides to a minimum for common (small) values at expense of slightly more code
|
||||
while (e >= 5) {
|
||||
r /= 100000;
|
||||
e -= 5;
|
||||
|
|
@ -126,8 +126,8 @@ void scan_char(uint8_t c) {
|
|||
serwrite_uint32(next_target.target.E);
|
||||
break;
|
||||
case 'F':
|
||||
// just save an integer value for F, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it
|
||||
next_target.target.F = read_digit.mantissa;
|
||||
// just use raw integer, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it
|
||||
next_target.target.F = decfloat_to_int(&read_digit, 1, 1);
|
||||
serwrite_uint32(next_target.target.F);
|
||||
break;
|
||||
case 'S':
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
#include "dda.h"
|
||||
|
||||
typedef struct {
|
||||
uint16_t sign :1;
|
||||
uint16_t mantissa :11;
|
||||
uint16_t exponent :4;
|
||||
uint32_t sign :1;
|
||||
uint32_t mantissa :24;
|
||||
uint32_t exponent :7;
|
||||
} decfloat;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
axis calculations, adjust as necessary
|
||||
*/
|
||||
|
||||
#define X_STEPS_PER_REV 1600.0
|
||||
#define X_STEPS_PER_REV 3200.0
|
||||
#define Y_STEPS_PER_REV X_STEPS_PER_REV
|
||||
// we need more speed than precision on Z, turn off microstepping
|
||||
#define Z_STEPS_PER_REV 200.0
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
// #define XY_COG_CIRCUMFERENCE (XY_COG_RADIUS * PI * 2)
|
||||
#define Z_GEAR_RATIO 1.0
|
||||
|
||||
#define EXTRUDER_STEPS_PER_REV 3200.0
|
||||
#define EXTRUDER_STEPS_PER_REV E_STEPS_PER_REV
|
||||
#define EXTRUDER_SHAFT_RADIUS 5.0
|
||||
#define EXTRUDER_INLET_DIAMETER 3.0
|
||||
#define EXTRUDER_NOZZLE_DIAMETER 0.8
|
||||
|
|
@ -40,10 +40,10 @@
|
|||
// does this refer to filament or extrudate? extrudate depends on layer thickness.. hm
|
||||
#define STEPS_PER_MM_E ((uint32_t) ((EXTRUDER_STEPS_PER_REV / (EXTRUDER_SHAFT_RADIUS * PI * EXTRUDER_INLET_DIAMETER / EXTRUDER_NOZZLE_DIAMETER)) + 0.5))
|
||||
|
||||
#define FEEDRATE_FAST_XY 2400
|
||||
#define FEEDRATE_SLOW_XY 120
|
||||
#define FEEDRATE_FAST_Z 240
|
||||
#define FEEDRATE_SLOW_Z 12
|
||||
#define FEEDRATE_FAST_XY 6000
|
||||
#define FEEDRATE_SLOW_XY 300
|
||||
#define FEEDRATE_FAST_Z 6000
|
||||
#define FEEDRATE_SLOW_Z 300
|
||||
|
||||
#define E_STARTSTOP_STEPS 20
|
||||
#define FEEDRATE_FAST_E 1200
|
||||
|
|
|
|||
|
|
@ -19,14 +19,7 @@
|
|||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
int main (void)
|
||||
{
|
||||
uint8_t report;
|
||||
|
||||
// set up serial
|
||||
serial_init();
|
||||
|
||||
// set up inputs and outputs
|
||||
inline void io_init(void) {
|
||||
WRITE(X_STEP_PIN, 0); SET_OUTPUT(X_STEP_PIN);
|
||||
WRITE(X_DIR_PIN, 0); SET_OUTPUT(X_DIR_PIN);
|
||||
WRITE(X_MIN_PIN, 1); SET_INPUT(X_MIN_PIN);
|
||||
|
|
@ -42,15 +35,29 @@ int main (void)
|
|||
WRITE(E_STEP_PIN, 0); SET_OUTPUT(E_STEP_PIN);
|
||||
WRITE(E_DIR_PIN, 0); SET_OUTPUT(E_DIR_PIN);
|
||||
|
||||
WRITE(HEATER_PIN, 0); SET_OUTPUT(HEATER_PIN);
|
||||
|
||||
#ifdef FAN_PIN
|
||||
WRITE(FAN_PIN, 0); SET_OUTPUT(FAN_PIN);
|
||||
#ifdef HEATER_PIN
|
||||
disable_heater(); SET_OUTPUT(HEATER_PIN);
|
||||
#endif
|
||||
|
||||
WRITE(SCK, 0); SET_OUTPUT(SCK);
|
||||
WRITE(MISO, 1); SET_INPUT(MISO);
|
||||
WRITE(SS, 0); SET_OUTPUT(SS);
|
||||
#ifdef FAN_PIN
|
||||
disable_fan(); SET_OUTPUT(FAN_PIN);
|
||||
#endif
|
||||
|
||||
#ifdef STEPPER_ENABLE_PIN
|
||||
disable_steppers(); SET_OUTPUT(STEPPER_ENABLE_PIN);
|
||||
#endif
|
||||
|
||||
WRITE(SCK, 1); SET_OUTPUT(SCK);
|
||||
WRITE(MISO, 1); SET_INPUT(MISO);
|
||||
WRITE(SS, 0); SET_OUTPUT(SS);
|
||||
}
|
||||
|
||||
inline void init(void) {
|
||||
// set up serial
|
||||
serial_init();
|
||||
|
||||
// set up inputs and outputs
|
||||
io_init();
|
||||
|
||||
// set up timers
|
||||
setupTimerInterrupt();
|
||||
|
|
@ -66,6 +73,13 @@ int main (void)
|
|||
|
||||
// start queue
|
||||
//enableTimerInterrupt();
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
uint8_t report;
|
||||
|
||||
init();
|
||||
|
||||
// main loop
|
||||
for (;;)
|
||||
|
|
@ -81,6 +95,17 @@ int main (void)
|
|||
temp_tick();
|
||||
}
|
||||
|
||||
if (clock_flag_250ms & CLOCK_FLAG_250MS_STEPTIMEOUT) {
|
||||
clock_flag_250ms &= ~CLOCK_FLAG_250MS_STEPTIMEOUT;
|
||||
|
||||
if (steptimeout > 25) {
|
||||
disable_steppers();
|
||||
}
|
||||
else {
|
||||
steptimeout++;
|
||||
}
|
||||
}
|
||||
|
||||
if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) {
|
||||
clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT;
|
||||
report++;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,14 @@
|
|||
we NEED these for communication
|
||||
*/
|
||||
|
||||
// RXD DIO0
|
||||
// TXD DIO1
|
||||
#define RESERVED_RXD DIO0
|
||||
#define RESERVED_TXD DIO1
|
||||
|
||||
/*
|
||||
user defined pins
|
||||
adjust to suit your electronics,
|
||||
or adjust your electronics to suit this
|
||||
*/
|
||||
|
||||
#define X_STEP_PIN AIO0
|
||||
#define X_DIR_PIN AIO1
|
||||
|
|
@ -30,7 +36,10 @@
|
|||
#define E_STEP_PIN DIO7
|
||||
#define E_DIR_PIN DIO8
|
||||
|
||||
#define STEPPER_ENABLE_PIN DIO9
|
||||
|
||||
// list of PWM-able pins and corresponding timers
|
||||
// timer1 is reserved for step timing
|
||||
// OC0A DIO6
|
||||
// OC0B DIO5
|
||||
// OC1A DIO9
|
||||
|
|
@ -41,12 +50,7 @@
|
|||
#define HEATER_PIN DIO6
|
||||
#define HEATER_PIN_PWM OC0A
|
||||
|
||||
#define FAN_PIN DIO5
|
||||
|
||||
#define SCK DIO13
|
||||
#define MISO DIO12
|
||||
#define MOSI DIO11
|
||||
#define SS DIO10
|
||||
// #define FAN_PIN DIO5
|
||||
|
||||
/*
|
||||
X Stepper
|
||||
|
|
@ -105,13 +109,25 @@
|
|||
#define enable_heater() WRITE(HEATER_PIN, 1)
|
||||
#define disable_heater() WRITE(HEATER_PIN, 0)
|
||||
|
||||
/*
|
||||
fan
|
||||
*/
|
||||
|
||||
#ifdef FAN_PIN
|
||||
#define enable_fan() WRITE(FAN_PIN, 1)
|
||||
#define disable_fan() WRITE(FAN_PIN, 0)
|
||||
#else
|
||||
#define enable_fan() if (0) {}
|
||||
#define disable_fan() if (0) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Stepper Enable (ATX PSU pwr_good signal?)
|
||||
*/
|
||||
|
||||
#ifdef STEPPER_ENABLE_PIN
|
||||
#define enable_steppers() WRITE(STEPPER_ENABLE_PIN, 1)
|
||||
#define disable_steppers() WRITE(STEPPER_ENABLE_PIN, 0)
|
||||
#define enable_steppers() WRITE(STEPPER_ENABLE_PIN, 0)
|
||||
#define disable_steppers() WRITE(STEPPER_ENABLE_PIN, 1)
|
||||
#else
|
||||
#define enable_steppers() if (0) {}
|
||||
#define disable_steppers() if (0) {}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ uint16_t temp_read() {
|
|||
|
||||
WRITE(SS, 0);
|
||||
|
||||
SPCR = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,16 +9,19 @@ ISR(TIMER1_COMPA_vect) {
|
|||
if(movebuffer[mb_tail].live) {
|
||||
// this interrupt can be interruptible
|
||||
// TODO: remove when not debugging
|
||||
disableTimerInterrupt();
|
||||
sei();
|
||||
// disableTimerInterrupt();
|
||||
// sei();
|
||||
|
||||
// WRITE(SCK, 0);
|
||||
dda_step(&(movebuffer[mb_tail]));
|
||||
// WRITE(SCK, 1);
|
||||
|
||||
cli();
|
||||
enableTimerInterrupt();
|
||||
// cli();
|
||||
// enableTimerInterrupt();
|
||||
}
|
||||
else
|
||||
else {
|
||||
next_move();
|
||||
}
|
||||
}
|
||||
|
||||
void setupTimerInterrupt()
|
||||
|
|
|
|||
Loading…
Reference in New Issue