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
|
||||
@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 *~
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
70
mendel/dda.c
70
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue