time to save, motors working nicely, XON/XOFF flow control implemented for *simple* dumping of gcode
This commit is contained in:
parent
1bde999e0e
commit
980f39a2c3
|
|
@ -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 *~
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
70
mendel/dda.c
70
mendel/dda.c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue