From 980f39a2c374959d749ed498e010ae51eef8da43 Mon Sep 17 00:00:00 2001 From: Michael Moon Date: Mon, 1 Feb 2010 18:13:26 +1100 Subject: [PATCH] time to save, motors working nicely, XON/XOFF flow control implemented for *simple* dumping of gcode --- mendel/Makefile | 2 +- mendel/clock.h | 14 ++++++++++ mendel/dda.c | 70 ++++++++++++++++++++++++------------------------- mendel/mendel.c | 30 ++++++++++----------- mendel/pinout.h | 10 +++++-- mendel/serial.c | 32 +++++++++++++++++++++- mendel/serial.h | 3 +++ 7 files changed, 106 insertions(+), 55 deletions(-) diff --git a/mendel/Makefile b/mendel/Makefile index 30c8a0a..fc4c870 100644 --- a/mendel/Makefile +++ b/mendel/Makefile @@ -57,7 +57,7 @@ program: $(PROGRAM).hex @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 57600 raw ignbrk -hup -echo < $(PROGPORT) + stty 57600 raw ignbrk -hup -echo ixon < $(PROGPORT) clean: rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~ diff --git a/mendel/clock.h b/mendel/clock.h index d9ef610..9f12804 100644 --- a/mendel/clock.h +++ b/mendel/clock.h @@ -15,4 +15,18 @@ extern volatile uint8_t clock_flag_250ms; #define CLOCK_FLAG_250MS_REPORT 2 #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 */ diff --git a/mendel/dda.c b/mendel/dda.c index cb5788a..434b7e0 100644 --- a/mendel/dda.c +++ b/mendel/dda.c @@ -58,7 +58,13 @@ void enqueue(TARGET *t) { h++; if (h == MOVEBUFFER_SIZE) h = 0; + 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; // fire up in case we're not running yet @@ -80,6 +86,20 @@ void next_move() { dda_start(&movebuffer[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); } - -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 */ @@ -207,6 +214,9 @@ void dda_create(TARGET *target, DDA *dda) { dda->nullmove = 1; } else { + // get steppers ready to go + steptimeout = 0; + enable_steppers(); if (DEBUG) { serwrite_uint32(dda->total_steps); serial_writechar(','); @@ -269,10 +279,6 @@ void dda_create(TARGET *target, DDA *dda) { // next dda starts where we finish 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); + step_option = 0; do { // 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(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; @@ -433,17 +440,12 @@ void dda_step(DDA *dda) { dda->f_counter += dda->total_steps; -// if (dda->f_scale == 0) -// dda->f_scale = 1; - if (dda->f_direction) { -// current_position.F += dda->f_scale; current_position.F += 1; if (current_position.F > dda->endpoint.F) current_position.F = dda->endpoint.F; } else { -// current_position.F -= dda->f_scale; current_position.F -= 1; if (current_position.F < dda->endpoint.F) current_position.F = dda->endpoint.F; @@ -457,8 +459,6 @@ void dda_step(DDA *dda) { serial_writechar('['); serwrite_hex8(step_option); serial_writechar(':'); -// serwrite_uint16(dda->f_scale); -// serial_writechar(','); serwrite_int32(current_position.F); serial_writechar('/'); serwrite_int32(dda->endpoint.F); @@ -488,16 +488,16 @@ void dda_step(DDA *dda) { 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; - if ( - (current_position.X == dda->endpoint.X) && - (current_position.Y == dda->endpoint.Y) && - (current_position.Z == dda->endpoint.Z) && - (current_position.E == dda->endpoint.E) && - (current_position.F == dda->endpoint.F) - ) { - dda->live = 0; - } + dda->live = (step_option != 0)?1:0; +// if ( +// (current_position.X == dda->endpoint.X) && +// (current_position.Y == dda->endpoint.Y) && +// (current_position.Z == dda->endpoint.Z) && +// (current_position.E == dda->endpoint.E) && +// (current_position.F == dda->endpoint.F) +// ) { +// dda->live = 0; +// } WRITE(SCK, 1); } diff --git a/mendel/mendel.c b/mendel/mendel.c index cfde75f..283c85d 100644 --- a/mendel/mendel.c +++ b/mendel/mendel.c @@ -35,16 +35,21 @@ inline void io_init(void) { WRITE(E_STEP_PIN, 0); SET_OUTPUT(E_STEP_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 - disable_heater(); + disable_heater(); #endif #ifdef FAN_PIN - disable_fan(); + disable_fan(); #endif #ifdef STEPPER_ENABLE_PIN - disable_steppers(); + disable_steppers(); #endif WRITE(SCK, 1); SET_OUTPUT(SCK); @@ -84,7 +89,7 @@ inline void init(void) { int main (void) { - uint8_t report; + uint8_t report = 0; init(); @@ -93,28 +98,21 @@ int main (void) { if (serial_rxchars()) { uint8_t c = serial_popchar(); -// TOGGLE(SCK); scan_char(c); } - if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) { - clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK; + ifclock(CLOCK_FLAG_250MS_TEMPCHECK) { temp_tick(); } - if (clock_flag_250ms & CLOCK_FLAG_250MS_STEPTIMEOUT) { - clock_flag_250ms &= ~CLOCK_FLAG_250MS_STEPTIMEOUT; - - if (steptimeout > 25) { + ifclock(CLOCK_FLAG_250MS_STEPTIMEOUT) { + if (steptimeout > (30 * 4)) disable_steppers(); - } - else { + else steptimeout++; - } } - if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) { - clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT; + ifclock(CLOCK_FLAG_250MS_REPORT) { report++; if (report == 4) { report = 0; diff --git a/mendel/pinout.h b/mendel/pinout.h index 0deee2b..246a71d 100644 --- a/mendel/pinout.h +++ b/mendel/pinout.h @@ -51,6 +51,7 @@ #define HEATER_PIN_PWM OC0A // #define FAN_PIN DIO5 +// #define FAN_PIN_PWM OC0B /* X Stepper @@ -106,8 +107,13 @@ Heater */ -#define enable_heater() WRITE(HEATER_PIN, 1) -#define disable_heater() do { WRITE(HEATER_PIN, 0); SET_OUTPUT(HEATER_PIN); } while (0) +#ifdef HEATER_PIN_PWM + #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 diff --git a/mendel/serial.c b/mendel/serial.c index 35e9f1d..d895e82 100644 --- a/mendel/serial.c +++ b/mendel/serial.c @@ -6,9 +6,18 @@ #define BUFSIZE 64 + sizeof(ringbuffer) #define BAUD 57600 +#define ASCII_XOFF 19 +#define ASCII_XON 17 + volatile uint8_t _rx_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 tx_buffer ((ringbuffer *) _tx_buffer) @@ -33,7 +42,15 @@ ISR(USART_RX_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); else 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++) 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); +} diff --git a/mendel/serial.h b/mendel/serial.h index 80c416d..19597f7 100644 --- a/mendel/serial.h +++ b/mendel/serial.h @@ -21,4 +21,7 @@ void serial_writeblock_P(PGM_P data, int datalen); void serial_writestr_P(PGM_P data); +void xoff(void); +void xon(void); + #endif /* _SERIAL_H */