tons of small fixes, improvements etc. Clocked DDA at 25000mm/min (over 400mm/s!)
This commit is contained in:
parent
54a793b3a1
commit
7b79d2ea32
|
|
@ -36,7 +36,7 @@ CC = $(ARCH)gcc
|
|||
OBJDUMP = $(ARCH)objdump
|
||||
OBJCOPY = $(ARCH)objcopy
|
||||
|
||||
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=0
|
||||
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=0
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void clock_setup() {
|
|||
}
|
||||
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
WRITE(SCK, 1);
|
||||
// global clock
|
||||
#ifdef GLOBAL_CLOCK
|
||||
clock++;
|
||||
|
|
@ -53,6 +54,7 @@ ISR(TIMER2_COMPA_vect) {
|
|||
clock_counter_1s = 0;
|
||||
}
|
||||
}
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
||||
#ifdef GLOBAL_CLOCK
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ extern volatile uint8_t clock_flag;
|
|||
|
||||
or:
|
||||
ifclock(CLOCK_FLAG_1S)
|
||||
disable_steppers();
|
||||
power_off();
|
||||
*/
|
||||
|
||||
#define ifclock(F) for (;clock_flag & (F);clock_flag &= ~(F))
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ void dda_create(DDA *dda, TARGET *target) {
|
|||
else {
|
||||
// get steppers ready to go
|
||||
steptimeout = 0;
|
||||
enable_steppers();
|
||||
power_on();
|
||||
|
||||
if (DEBUG) {
|
||||
serwrite_uint32(dda->total_steps); serial_writechar(',');
|
||||
|
|
@ -229,7 +229,7 @@ void dda_start(DDA *dda) {
|
|||
|
||||
// ensure steppers are ready to go
|
||||
steptimeout = 0;
|
||||
enable_steppers();
|
||||
power_on();
|
||||
|
||||
// set direction outputs
|
||||
x_direction(dda->x_direction);
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ uint8_t mb_tail = 0;
|
|||
DDA movebuffer[MOVEBUFFER_SIZE];
|
||||
|
||||
uint8_t queue_full() {
|
||||
// if (mb_tail == 0)
|
||||
// return mb_head == (MOVEBUFFER_SIZE - 1);
|
||||
// else
|
||||
// return mb_head == (mb_tail - 1);
|
||||
return (((mb_tail - mb_head - 1) & (MOVEBUFFER_SIZE - 1)) == 0)?255:0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,8 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
xoff();
|
||||
#endif
|
||||
// wait for all moves to complete
|
||||
for (;queue_empty() == 0;);
|
||||
for (;queue_empty() == 0;)
|
||||
wd_reset();
|
||||
// delay
|
||||
delay_ms(gcmd->P);
|
||||
#ifdef XONXOFF
|
||||
|
|
@ -448,9 +449,6 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
void clock_250ms(void);
|
||||
clock_250ms();
|
||||
}
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
}
|
||||
do {
|
||||
// backup feedrate, move E very quickly then restore feedrate
|
||||
|
|
@ -479,7 +477,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
temp_set(gcmd->S);
|
||||
if (gcmd->S) {
|
||||
enable_heater();
|
||||
enable_steppers();
|
||||
power_on();
|
||||
}
|
||||
else {
|
||||
disable_heater();
|
||||
|
|
@ -488,24 +486,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
|
||||
// M105- get temperature
|
||||
case 105:
|
||||
// do .. while block here to provide local scope for temp
|
||||
do {
|
||||
uint16_t t = temp_get();
|
||||
serial_writestr_P(PSTR("T: "));
|
||||
serwrite_uint16(t >> 2);
|
||||
serial_writechar('.');
|
||||
if (t & 3) {
|
||||
if ((t & 3) == 1)
|
||||
serial_writechar('2');
|
||||
else if ((t & 3) == 3)
|
||||
serial_writechar('7');
|
||||
serial_writechar('5');
|
||||
}
|
||||
else {
|
||||
serial_writechar('0');
|
||||
}
|
||||
serial_writechar('\n');
|
||||
} while (0);
|
||||
temp_print();
|
||||
break;
|
||||
|
||||
// M106- fan on
|
||||
|
|
@ -539,6 +520,35 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
i_limit = gcmd->S;
|
||||
break;
|
||||
|
||||
// DEBUG: return current position
|
||||
case 250:
|
||||
serial_writestr_P(PSTR("\n{X:"));
|
||||
serwrite_int32(current_position.X);
|
||||
serial_writestr_P(PSTR(",Y:"));
|
||||
serwrite_int32(current_position.Y);
|
||||
serial_writestr_P(PSTR(",Z:"));
|
||||
serwrite_int32(current_position.Z);
|
||||
serial_writestr_P(PSTR(",E:"));
|
||||
serwrite_int32(current_position.E);
|
||||
serial_writestr_P(PSTR(",F:"));
|
||||
serwrite_int32(current_position.F);
|
||||
serial_writestr_P(PSTR("}\n"));
|
||||
break;
|
||||
|
||||
// DEBUG: read arbitrary memory location
|
||||
case 253:
|
||||
serwrite_hex8(*(volatile uint8_t *)(gcmd->S));
|
||||
break;
|
||||
// DEBUG: write arbitrary memory locatiom
|
||||
case 254:
|
||||
serwrite_hex8(gcmd->S);
|
||||
serial_writechar(':');
|
||||
serwrite_hex8(*(volatile uint8_t *)(gcmd->S));
|
||||
serial_writestr_P(PSTR("->"));
|
||||
serwrite_hex8(gcmd->P);
|
||||
serial_writechar('\n');
|
||||
(*(volatile uint8_t *)(gcmd->S)) = gcmd->P;
|
||||
break;
|
||||
// unknown mcode: spit an error
|
||||
default:
|
||||
serial_writestr_P(PSTR("E: Bad M-code "));
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
inline void io_init(void) {
|
||||
void io_init(void) {
|
||||
// disable modules we don't use
|
||||
PRR = MASK(PRTWI) | MASK(PRTIM2) | MASK(PRADC);
|
||||
PRR = MASK(PRTWI) | MASK(PRADC);
|
||||
ACSR = MASK(ACD);
|
||||
|
||||
// setup I/O pins
|
||||
|
|
@ -58,7 +58,7 @@ inline void io_init(void) {
|
|||
#endif
|
||||
|
||||
#ifdef STEPPER_ENABLE_PIN
|
||||
disable_steppers();
|
||||
power_off();
|
||||
#endif
|
||||
|
||||
// setup SPI
|
||||
|
|
@ -68,7 +68,7 @@ inline void io_init(void) {
|
|||
WRITE(SS, 1); SET_OUTPUT(SS);
|
||||
}
|
||||
|
||||
inline void init(void) {
|
||||
void init(void) {
|
||||
|
||||
// set up watchdog
|
||||
wd_init();
|
||||
|
|
@ -85,27 +85,28 @@ inline void init(void) {
|
|||
// set up clock
|
||||
clock_setup();
|
||||
|
||||
// set up variables
|
||||
current_position.F = FEEDRATE_SLOW_Z;
|
||||
memcpy(&startpoint, ¤t_position, sizeof(TARGET));
|
||||
memcpy(&(next_target.target), ¤t_position, sizeof(TARGET));
|
||||
// set up feedrate
|
||||
current_position.F = startpoint.F = next_target.target.F = FEEDRATE_SLOW_Z;
|
||||
|
||||
// enable interrupts
|
||||
sei();
|
||||
|
||||
// say hi to host
|
||||
serial_writestr_P(PSTR("Start\n"));
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
|
||||
// say hi to host
|
||||
serial_writestr_P(PSTR("Start\nOK\n"));
|
||||
}
|
||||
|
||||
void clock_250ms(void) {
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
|
||||
temp_tick();
|
||||
|
||||
if (steptimeout > (30 * 4)) {
|
||||
if (temp_get_target() == 0)
|
||||
disable_steppers();
|
||||
power_off();
|
||||
}
|
||||
else
|
||||
steptimeout++;
|
||||
|
|
@ -170,8 +171,5 @@ int main (void)
|
|||
ifclock(CLOCK_FLAG_250MS) {
|
||||
clock_250ms();
|
||||
}
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,14 +137,14 @@
|
|||
|
||||
#ifdef STEPPER_ENABLE_PIN
|
||||
// for connection to stepper driver ENABLE pins (negative asserted)
|
||||
// #define enable_steppers() WRITE(STEPPER_ENABLE_PIN, 0)
|
||||
// #define disable_steppers() WRITE(STEPPER_ENABLE_PIN, 1)
|
||||
// #define power_on() WRITE(STEPPER_ENABLE_PIN, 0)
|
||||
// #define power_off() WRITE(STEPPER_ENABLE_PIN, 1)
|
||||
// for connection to ATX PSU PWR_ON signal
|
||||
#define enable_steppers() do { WRITE(STEPPER_ENABLE_PIN, 0); SET_OUTPUT(STEPPER_ENABLE_PIN); } while (0)
|
||||
#define disable_steppers() SET_INPUT(STEPPER_ENABLE_PIN)
|
||||
#define power_on() do { WRITE(STEPPER_ENABLE_PIN, 0); SET_OUTPUT(STEPPER_ENABLE_PIN); } while (0)
|
||||
#define power_off() SET_INPUT(STEPPER_ENABLE_PIN)
|
||||
#else
|
||||
#define enable_steppers() if (0) {}
|
||||
#define disable_steppers() if (0) {}
|
||||
#define power_on() if (0) {}
|
||||
#define power_off() if (0) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -76,12 +76,15 @@ void serial_init()
|
|||
|
||||
ISR(USART_RX_vect)
|
||||
{
|
||||
WRITE(SCK, 1);
|
||||
if (buf_canwrite(rx))
|
||||
buf_push(rx, UDR0);
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
||||
ISR(USART_UDRE_vect)
|
||||
{
|
||||
WRITE(SCK, 1);
|
||||
#if XONXOFF
|
||||
if (flowflags & FLOWFLAG_SEND_XOFF) {
|
||||
UDR0 = ASCII_XOFF;
|
||||
|
|
@ -97,6 +100,7 @@ ISR(USART_UDRE_vect)
|
|||
buf_pop(tx, UDR0);
|
||||
else
|
||||
UCSR0B &= ~MASK(UDRIE0);
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ void temp_print() {
|
|||
serial_writestr_P(PSTR("no thermocouple!"));
|
||||
}
|
||||
else {
|
||||
serwrite_uint16(temp_get() >> 2);
|
||||
serwrite_uint16(current_temp >> 2);
|
||||
serial_writechar('.');
|
||||
if (current_temp) {
|
||||
if (current_temp & 3) {
|
||||
if ((current_temp & 3) == 3)
|
||||
serial_writechar('7');
|
||||
else if ((current_temp & 3) == 1)
|
||||
|
|
@ -127,6 +127,19 @@ void temp_print() {
|
|||
serial_writechar('0');
|
||||
}
|
||||
// serial_writestr_P(PSTR("°C"));
|
||||
serial_writechar('/');
|
||||
serwrite_uint16(target_temp >> 2);
|
||||
serial_writechar('.');
|
||||
if (target_temp & 3) {
|
||||
if ((target_temp & 3) == 3)
|
||||
serial_writechar('7');
|
||||
else if ((target_temp & 3) == 1)
|
||||
serial_writechar('2');
|
||||
serial_writechar('5');
|
||||
}
|
||||
else {
|
||||
serial_writechar('0');
|
||||
}
|
||||
}
|
||||
serial_writechar('\n');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
#include "pinout.h"
|
||||
#include "dda_queue.h"
|
||||
#include "dda.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
ISR(TIMER1_COMPA_vect) {
|
||||
WRITE(SCK, 1);
|
||||
// do our next step
|
||||
// NOTE: dda_step makes this interrupt interruptible after steps have been sent but before new speed is calculated.
|
||||
if (movebuffer[mb_tail].live)
|
||||
|
|
@ -26,9 +28,10 @@ ISR(TIMER1_COMPA_vect) {
|
|||
// return from interrupt in a way that prevents this interrupt nesting with itself at high step rates
|
||||
cli();
|
||||
// check queue, if empty we don't need to interrupt again until re-enabled in dda_create
|
||||
if (!queue_empty())
|
||||
if (queue_empty() == 0)
|
||||
enableTimerInterrupt();
|
||||
#endif
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
||||
void setupTimerInterrupt()
|
||||
|
|
@ -129,20 +132,28 @@ void setTimer(uint32_t delay)
|
|||
setTimerResolution(getTimerResolution(delay));
|
||||
}
|
||||
|
||||
// delay( microseconds )
|
||||
void delay(uint32_t delay) {
|
||||
wd_reset();
|
||||
while (delay > 65535) {
|
||||
delayMicrosecondsInterruptible(65534);
|
||||
delay -= 65535;
|
||||
wd_reset();
|
||||
}
|
||||
delayMicrosecondsInterruptible(delay & 0xFFFF);
|
||||
wd_reset();
|
||||
}
|
||||
|
||||
// delay_ms( milliseconds )
|
||||
void delay_ms(uint32_t delay) {
|
||||
wd_reset();
|
||||
while (delay > 65) {
|
||||
delayMicrosecondsInterruptible(64999);
|
||||
delay -= 65;
|
||||
wd_reset();
|
||||
}
|
||||
delayMicrosecondsInterruptible(delay * 1000);
|
||||
wd_reset();
|
||||
}
|
||||
|
||||
void delayMicrosecondsInterruptible(uint16_t us)
|
||||
|
|
|
|||
|
|
@ -4,17 +4,36 @@
|
|||
#include <avr/interrupt.h>
|
||||
|
||||
#include "arduino.h"
|
||||
#include "serial.h"
|
||||
|
||||
volatile uint8_t wd_flag = 0;
|
||||
|
||||
// uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
|
||||
// void get_mcusr(void) \
|
||||
// __attribute__((naked)) \
|
||||
// __attribute__((section(".init3")));
|
||||
// void get_mcusr(void) {
|
||||
// mcusr_mirror = MCUSR;
|
||||
// MCUSR = 0;
|
||||
// wdt_disable();
|
||||
// }
|
||||
|
||||
ISR(WDT_vect) {
|
||||
// watchdog has tripped- no main loop activity for 0.25s, probably a bad thing
|
||||
WRITE(SCK, 1);
|
||||
// watchdog has tripped- no main loop activity for 0.5s, probably a bad thing
|
||||
// if watchdog fires again, we will reset
|
||||
// perhaps we should do something more intelligent in this interrupt?
|
||||
wd_flag |= 1;
|
||||
WRITE(SCK, 0);
|
||||
}
|
||||
|
||||
void wd_init() {
|
||||
// check if we were reset by the watchdog
|
||||
// if (mcusr_mirror & MASK(WDRF))
|
||||
// serial_writestr_P(PSTR("Watchdog Reset!\n"));
|
||||
|
||||
// 0.25s timeout, interrupt and system reset
|
||||
wdt_enable(WDTO_250MS);
|
||||
wdt_enable(WDTO_500MS);
|
||||
WDTCSR |= MASK(WDIE);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue