time to save, motors working nicely, XON/XOFF flow control implemented for *simple* dumping of gcode

This commit is contained in:
Michael Moon 2010-02-01 18:13:26 +11:00
parent 1bde999e0e
commit 980f39a2c3
7 changed files with 106 additions and 55 deletions

View File

@ -57,7 +57,7 @@ program: $(PROGRAM).hex
@sleep 0.2 @sleep 0.2
@stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT) @stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT)
$(AVRDUDE) -cstk500v1 -b$(PROGBAUD) -p$(MCU_TARGET) -P$(PROGPORT) -C/etc/avrdude.conf -U flash:w:$^ $(AVRDUDE) -cstk500v1 -b$(PROGBAUD) -p$(MCU_TARGET) -P$(PROGPORT) -C/etc/avrdude.conf -U flash:w:$^
stty 57600 raw ignbrk -hup -echo < $(PROGPORT) stty 57600 raw ignbrk -hup -echo ixon < $(PROGPORT)
clean: clean:
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~ rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~

View File

@ -15,4 +15,18 @@ extern volatile uint8_t clock_flag_250ms;
#define CLOCK_FLAG_250MS_REPORT 2 #define CLOCK_FLAG_250MS_REPORT 2
#define CLOCK_FLAG_250MS_STEPTIMEOUT 4 #define CLOCK_FLAG_250MS_STEPTIMEOUT 4
/*
ifclock() {}
so we can do stuff like:
ifclock(CLOCK_FLAG_250MS_REPORT) {
report();
}
or:
ifclock(CLOCK_FLAG_250MS_STEPTIMEOUT)
disable_steppers();
*/
#define ifclock(F) for (;clock_flag_250ms & (F);clock_flag_250ms &= ~(F))
#endif /* _CLOCK_H */ #endif /* _CLOCK_H */

View File

@ -58,7 +58,13 @@ void enqueue(TARGET *t) {
h++; h++;
if (h == MOVEBUFFER_SIZE) if (h == MOVEBUFFER_SIZE)
h = 0; h = 0;
dda_create(t, &movebuffer[h]); dda_create(t, &movebuffer[h]);
// if queue only has one space left, stop transmition
if (((h + 2) & (MOVEBUFFER_SIZE - 1)) == mb_tail)
xoff();
mb_head = h; mb_head = h;
// fire up in case we're not running yet // fire up in case we're not running yet
@ -80,6 +86,20 @@ void next_move() {
dda_start(&movebuffer[t]); dda_start(&movebuffer[t]);
mb_tail = t; mb_tail = t;
} }
// restart transmission
xon();
}
void print_queue() {
serial_writechar('Q');
serwrite_uint8(mb_tail);
serial_writechar('/');
serwrite_uint8(mb_head);
if (queue_full())
serial_writechar('F');
if (queue_empty())
serial_writechar('E');
serial_writechar('\n');
} }
/* /*
@ -149,19 +169,6 @@ uint32_t abs32(int32_t v) {
return (uint32_t) (v); return (uint32_t) (v);
} }
void print_queue() {
serial_writechar('Q');
serwrite_uint8(mb_tail);
serial_writechar('/');
serwrite_uint8(mb_head);
if (queue_full())
serial_writechar('F');
if (queue_empty())
serial_writechar('E');
serial_writechar('\n');
}
/* /*
CREATE CREATE
*/ */
@ -207,6 +214,9 @@ void dda_create(TARGET *target, DDA *dda) {
dda->nullmove = 1; dda->nullmove = 1;
} }
else { else {
// get steppers ready to go
steptimeout = 0;
enable_steppers();
if (DEBUG) { if (DEBUG) {
serwrite_uint32(dda->total_steps); serial_writechar(','); serwrite_uint32(dda->total_steps); serial_writechar(',');
@ -269,10 +279,6 @@ void dda_create(TARGET *target, DDA *dda) {
// next dda starts where we finish // next dda starts where we finish
memcpy(&startpoint, target, sizeof(TARGET)); memcpy(&startpoint, target, sizeof(TARGET));
// get steppers ready to go
steptimeout = 0;
enable_steppers();
} }
/* /*
@ -354,10 +360,11 @@ void dda_step(DDA *dda) {
WRITE(SCK, 0); WRITE(SCK, 0);
step_option = 0;
do { do {
// WRITE(SCK, 0); // WRITE(SCK, 0);
step_option = 0; step_option &= ~(X_CAN_STEP | Y_CAN_STEP | Z_CAN_STEP | E_CAN_STEP | F_CAN_STEP);
// step_option |= can_step(x_min(), x_max(), current_position.X, dda->endpoint.X, dda->x_direction) & X_CAN_STEP; // 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(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; // step_option |= can_step(z_min(), z_max(), current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP;
@ -433,17 +440,12 @@ void dda_step(DDA *dda) {
dda->f_counter += dda->total_steps; dda->f_counter += dda->total_steps;
// if (dda->f_scale == 0)
// dda->f_scale = 1;
if (dda->f_direction) { if (dda->f_direction) {
// current_position.F += dda->f_scale;
current_position.F += 1; current_position.F += 1;
if (current_position.F > dda->endpoint.F) if (current_position.F > dda->endpoint.F)
current_position.F = dda->endpoint.F; current_position.F = dda->endpoint.F;
} }
else { else {
// current_position.F -= dda->f_scale;
current_position.F -= 1; current_position.F -= 1;
if (current_position.F < dda->endpoint.F) if (current_position.F < dda->endpoint.F)
current_position.F = dda->endpoint.F; current_position.F = dda->endpoint.F;
@ -457,8 +459,6 @@ void dda_step(DDA *dda) {
serial_writechar('['); serial_writechar('[');
serwrite_hex8(step_option); serwrite_hex8(step_option);
serial_writechar(':'); serial_writechar(':');
// serwrite_uint16(dda->f_scale);
// serial_writechar(',');
serwrite_int32(current_position.F); serwrite_int32(current_position.F);
serial_writechar('/'); serial_writechar('/');
serwrite_int32(dda->endpoint.F); serwrite_int32(dda->endpoint.F);
@ -488,16 +488,16 @@ void dda_step(DDA *dda) {
setTimer(dda->move_duration / current_position.F); setTimer(dda->move_duration / current_position.F);
// if we could step, we're still running // 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; dda->live = (step_option != 0)?1:0;
if ( // if (
(current_position.X == dda->endpoint.X) && // (current_position.X == dda->endpoint.X) &&
(current_position.Y == dda->endpoint.Y) && // (current_position.Y == dda->endpoint.Y) &&
(current_position.Z == dda->endpoint.Z) && // (current_position.Z == dda->endpoint.Z) &&
(current_position.E == dda->endpoint.E) && // (current_position.E == dda->endpoint.E) &&
(current_position.F == dda->endpoint.F) // (current_position.F == dda->endpoint.F)
) { // ) {
dda->live = 0; // dda->live = 0;
} // }
WRITE(SCK, 1); WRITE(SCK, 1);
} }

View File

@ -35,16 +35,21 @@ inline void io_init(void) {
WRITE(E_STEP_PIN, 0); SET_OUTPUT(E_STEP_PIN); WRITE(E_STEP_PIN, 0); SET_OUTPUT(E_STEP_PIN);
WRITE(E_DIR_PIN, 0); SET_OUTPUT(E_DIR_PIN); WRITE(E_DIR_PIN, 0); SET_OUTPUT(E_DIR_PIN);
// setup PWM timer: phase-correct PWM, no prescaler, no outputs enabled yet
TCCR0A = MASK(WGM00);
TCCR0B = MASK(CS00);
TIMSK0 = 0;
#ifdef HEATER_PIN #ifdef HEATER_PIN
disable_heater(); disable_heater();
#endif #endif
#ifdef FAN_PIN #ifdef FAN_PIN
disable_fan(); disable_fan();
#endif #endif
#ifdef STEPPER_ENABLE_PIN #ifdef STEPPER_ENABLE_PIN
disable_steppers(); disable_steppers();
#endif #endif
WRITE(SCK, 1); SET_OUTPUT(SCK); WRITE(SCK, 1); SET_OUTPUT(SCK);
@ -84,7 +89,7 @@ inline void init(void) {
int main (void) int main (void)
{ {
uint8_t report; uint8_t report = 0;
init(); init();
@ -93,28 +98,21 @@ int main (void)
{ {
if (serial_rxchars()) { if (serial_rxchars()) {
uint8_t c = serial_popchar(); uint8_t c = serial_popchar();
// TOGGLE(SCK);
scan_char(c); scan_char(c);
} }
if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) { ifclock(CLOCK_FLAG_250MS_TEMPCHECK) {
clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK;
temp_tick(); temp_tick();
} }
if (clock_flag_250ms & CLOCK_FLAG_250MS_STEPTIMEOUT) { ifclock(CLOCK_FLAG_250MS_STEPTIMEOUT) {
clock_flag_250ms &= ~CLOCK_FLAG_250MS_STEPTIMEOUT; if (steptimeout > (30 * 4))
if (steptimeout > 25) {
disable_steppers(); disable_steppers();
} else
else {
steptimeout++; steptimeout++;
}
} }
if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) { ifclock(CLOCK_FLAG_250MS_REPORT) {
clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT;
report++; report++;
if (report == 4) { if (report == 4) {
report = 0; report = 0;

View File

@ -51,6 +51,7 @@
#define HEATER_PIN_PWM OC0A #define HEATER_PIN_PWM OC0A
// #define FAN_PIN DIO5 // #define FAN_PIN DIO5
// #define FAN_PIN_PWM OC0B
/* /*
X Stepper X Stepper
@ -106,8 +107,13 @@
Heater Heater
*/ */
#define enable_heater() WRITE(HEATER_PIN, 1) #ifdef HEATER_PIN_PWM
#define disable_heater() do { WRITE(HEATER_PIN, 0); SET_OUTPUT(HEATER_PIN); } while (0) #define enable_heater() WRITE(HEATER_PIN, 1)
#define disable_heater() do { WRITE(HEATER_PIN, 0); } while (0)
#else
#define enable_heater() do { TCCR0A = (TCCR0A & MASK(COM0A0)) | MASK(COM0A1); SET_OUTPUT(HEATER_PIN); } while (0)
#define disable_heater() do { WRITE(HEATER_PIN, 0); HEATER_PIN_PWM = 0; TCCR0A &= ~(MASK(COM0A0) | MASK(COM0A1)); SET_OUTPUT(HEATER_PIN); } while (0)
#endif
/* /*
fan fan

View File

@ -6,9 +6,18 @@
#define BUFSIZE 64 + sizeof(ringbuffer) #define BUFSIZE 64 + sizeof(ringbuffer)
#define BAUD 57600 #define BAUD 57600
#define ASCII_XOFF 19
#define ASCII_XON 17
volatile uint8_t _rx_buffer[BUFSIZE]; volatile uint8_t _rx_buffer[BUFSIZE];
volatile uint8_t _tx_buffer[BUFSIZE]; volatile uint8_t _tx_buffer[BUFSIZE];
volatile uint8_t flowflags = 0;
#define FLOWFLAG_SEND_XOFF 1
#define FLOWFLAG_SEND_XON 2
#define FLOWFLAG_SENT_XOFF 4
#define FLOWFLAG_SENT_XON 8
#define rx_buffer ((ringbuffer *) _rx_buffer) #define rx_buffer ((ringbuffer *) _rx_buffer)
#define tx_buffer ((ringbuffer *) _tx_buffer) #define tx_buffer ((ringbuffer *) _tx_buffer)
@ -33,7 +42,15 @@ ISR(USART_RX_vect)
ISR(USART_UDRE_vect) ISR(USART_UDRE_vect)
{ {
if (ringbuffer_canread(tx_buffer)) if (flowflags & FLOWFLAG_SEND_XOFF) {
UDR0 = ASCII_XOFF;
flowflags = (flowflags & ~FLOWFLAG_SEND_XOFF) | FLOWFLAG_SENT_XOFF;
}
else if (flowflags & FLOWFLAG_SEND_XON) {
UDR0 = ASCII_XON;
flowflags = (flowflags & ~FLOWFLAG_SEND_XON) | FLOWFLAG_SENT_XON;
}
else if (ringbuffer_canread(tx_buffer))
UDR0 = ringbuffer_readchar(tx_buffer); UDR0 = ringbuffer_readchar(tx_buffer);
else else
UCSR0B &= ~(1 << UDRIE0); UCSR0B &= ~(1 << UDRIE0);
@ -103,3 +120,16 @@ void serial_writestr_P(PGM_P data)
for (uint8_t r; (r = pgm_read_byte(&data[i])); i++) for (uint8_t r; (r = pgm_read_byte(&data[i])); i++)
serial_writechar(r); serial_writechar(r);
} }
void xoff() {
flowflags = FLOWFLAG_SEND_XOFF;
// enable TX interrupt so we can send this character
UCSR0B |= (1 << UDRIE0);
}
void xon() {
if (flowflags & FLOWFLAG_SENT_XOFF)
flowflags = FLOWFLAG_SEND_XON;
// enable TX interrupt so we can send this character
UCSR0B |= (1 << UDRIE0);
}

View File

@ -21,4 +21,7 @@ void serial_writeblock_P(PGM_P data, int datalen);
void serial_writestr_P(PGM_P data); void serial_writestr_P(PGM_P data);
void xoff(void);
void xon(void);
#endif /* _SERIAL_H */ #endif /* _SERIAL_H */