tons of small fixes, improvements etc. Clocked DDA at 25000mm/min (over 400mm/s!)

This commit is contained in:
Michael Moon 2010-02-11 15:34:06 +11:00
parent 54a793b3a1
commit 7b79d2ea32
12 changed files with 110 additions and 57 deletions

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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);

View File

@ -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;
}

View File

@ -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 "));

View File

@ -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, &current_position, sizeof(TARGET));
memcpy(&(next_target.target), &current_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();
}
}

View File

@ -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
/*

View File

@ -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);
}
/*

View File

@ -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');
}

View File

@ -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)

View File

@ -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);
}