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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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