misc tidying, added watchdog stuff, moved things around a bit
This commit is contained in:
parent
65c237cff6
commit
7326e17560
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
PROGRAM = mendel
|
||||
|
||||
SOURCES = $(PROGRAM).c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c dda_queue.c
|
||||
SOURCES = $(PROGRAM).c serial.c dda.c gcode.c timer.c clock.c temp.c sermsg.c dda_queue.c watchdog.c
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
|
|
|
|||
40
mendel/dda.c
40
mendel/dda.c
|
|
@ -272,6 +272,7 @@ uint8_t can_step(uint8_t min, uint8_t max, int32_t current, int32_t target, uint
|
|||
*/
|
||||
|
||||
void dda_step(DDA *dda) {
|
||||
// called from interrupt context! keep it as simple as possible
|
||||
uint8_t step_option = 0;
|
||||
#define X_CAN_STEP 1
|
||||
#define Y_CAN_STEP 2
|
||||
|
|
@ -284,12 +285,11 @@ void dda_step(DDA *dda) {
|
|||
if (DEBUG)
|
||||
serial_writechar('!');
|
||||
|
||||
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;
|
||||
step_option |= can_step(0 , 0 , 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(0 , 0 , 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(0 , 0 , current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP;
|
||||
step_option |= can_step(0 , 0 , current_position.E, dda->endpoint.E, dda->e_direction) & E_CAN_STEP;
|
||||
step_option |= can_step(0 , 0 , current_position.F, dda->endpoint.F, dda->f_direction) & F_CAN_STEP;
|
||||
|
|
@ -354,9 +354,17 @@ void dda_step(DDA *dda) {
|
|||
}
|
||||
}
|
||||
|
||||
#if STEP_INTERRUPT_INTERRUPTIBLE
|
||||
// since we have sent steps to all the motors that will be stepping and the rest of this function isn't so time critical,
|
||||
// this interrupt can now be interruptible
|
||||
disableTimerInterrupt();
|
||||
sei();
|
||||
#endif
|
||||
|
||||
if (step_option & F_CAN_STEP) {
|
||||
dda->f_counter -= dda->f_delta;
|
||||
// since we don't allow total_steps to be defined by F, we may need to step multiple times if f_delta is greater than total_steps
|
||||
// loops in interrupt context are a bad idea, but this is the best way to do this that I've come up with so far
|
||||
while (dda->f_counter < 0) {
|
||||
|
||||
dda->f_counter += dda->total_steps;
|
||||
|
|
@ -376,25 +384,6 @@ void dda_step(DDA *dda) {
|
|||
}
|
||||
}
|
||||
|
||||
#if STEP_INTERRUPT_INTERRUPTIBLE
|
||||
// this interrupt can now be interruptible
|
||||
disableTimerInterrupt();
|
||||
sei();
|
||||
#endif
|
||||
|
||||
// this generates too much debug output for all but the slowest step rates
|
||||
if (0 && DEBUG) {
|
||||
serial_writechar('[');
|
||||
serwrite_hex8(step_option);
|
||||
serial_writechar(':');
|
||||
serwrite_int32(current_position.F);
|
||||
serial_writechar('/');
|
||||
serwrite_int32(dda->endpoint.F);
|
||||
serial_writechar('#');
|
||||
serwrite_uint32(dda->move_duration);
|
||||
serial_writechar(']');
|
||||
}
|
||||
|
||||
if (step_option & REAL_MOVE)
|
||||
// we stepped, reset timeout
|
||||
steptimeout = 0;
|
||||
|
|
@ -409,13 +398,8 @@ void dda_step(DDA *dda) {
|
|||
|
||||
// if we could do anything at all, we're still running
|
||||
// otherwise, must have finished
|
||||
else if (step_option == 0) {
|
||||
else if (step_option == 0)
|
||||
dda->live = 0;
|
||||
#ifdef STUPIDLY_HIDE_BUGS
|
||||
// this magically makes bugs disappear after each move, probably a bad idea
|
||||
memcpy(¤t_position, &(dda->endpoint), sizeof(TARGET));
|
||||
#endif
|
||||
}
|
||||
|
||||
// turn off step outputs, hopefully they've been on long enough by now to register with the drivers
|
||||
// if not, too bad. or insert a (very!) small delay here, or fire up a spare timer or something
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "dda_queue.h"
|
||||
#include "dda.h"
|
||||
#include "clock.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
uint8_t option_bitfield;
|
||||
#define OPTION_COMMENT 128
|
||||
|
|
@ -267,7 +268,7 @@ void scan_char(uint8_t c) {
|
|||
// if (DEBUG)
|
||||
serial_writechar(c);
|
||||
// process
|
||||
// if (next_target.seen_G || next_target.seen_M) {
|
||||
if (next_target.seen_G || next_target.seen_M) {
|
||||
process_gcode_command(&next_target);
|
||||
|
||||
// reset 'seen comment'
|
||||
|
|
@ -281,7 +282,7 @@ void scan_char(uint8_t c) {
|
|||
read_digit.exponent = 0;
|
||||
|
||||
serial_writestr_P(PSTR("OK\n"));
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -434,6 +435,9 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
|||
void clock_250ms(void);
|
||||
clock_250ms();
|
||||
}
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
}
|
||||
SpecialMoveE(E_STARTSTOP_STEPS, FEEDRATE_FAST_E);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -15,12 +15,18 @@
|
|||
#include "clock.h"
|
||||
#include "temp.h"
|
||||
#include "sermsg.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
|
||||
inline void io_init(void) {
|
||||
// disable modules we don't use
|
||||
PRR = MASK(PRTWI) | MASK(PRTIM2) | MASK(PRADC);
|
||||
ACSR = MASK(ACD);
|
||||
|
||||
// setup I/O pins
|
||||
WRITE(X_STEP_PIN, 0); SET_OUTPUT(X_STEP_PIN);
|
||||
WRITE(X_DIR_PIN, 0); SET_OUTPUT(X_DIR_PIN);
|
||||
WRITE(X_MIN_PIN, 1); SET_INPUT(X_MIN_PIN);
|
||||
|
|
@ -62,8 +68,11 @@ inline void io_init(void) {
|
|||
WRITE(SS, 1); SET_OUTPUT(SS);
|
||||
}
|
||||
|
||||
inline void init(void);
|
||||
inline void init() {
|
||||
inline void init(void) {
|
||||
|
||||
// set up watchdog
|
||||
wd_init();
|
||||
|
||||
// set up serial
|
||||
serial_init();
|
||||
|
||||
|
|
@ -86,10 +95,12 @@ inline void init() {
|
|||
|
||||
// say hi to host
|
||||
serial_writestr_P(PSTR("Start\n"));
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
}
|
||||
|
||||
void clock_250ms(void);
|
||||
void clock_250ms() {
|
||||
void clock_250ms(void) {
|
||||
temp_tick();
|
||||
|
||||
if (steptimeout > (30 * 4)) {
|
||||
|
|
@ -159,5 +170,8 @@ int main (void)
|
|||
ifclock(CLOCK_FLAG_250MS) {
|
||||
clock_250ms();
|
||||
}
|
||||
|
||||
// reset watchdog
|
||||
wd_reset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,9 +93,8 @@ ISR(USART_UDRE_vect)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
if (buf_canread(tx)) {
|
||||
if (buf_canread(tx))
|
||||
buf_pop(tx, UDR0);
|
||||
}
|
||||
else
|
||||
UCSR0B &= ~MASK(UDRIE0);
|
||||
}
|
||||
|
|
@ -112,6 +111,7 @@ uint8_t serial_rxchars()
|
|||
uint8_t serial_popchar()
|
||||
{
|
||||
uint8_t c = 0;
|
||||
// it's imperative that we check, because if the buffer is empty and we pop, we'll go through the whole buffer again
|
||||
if (buf_canread(rx))
|
||||
buf_pop(rx, c);
|
||||
return c;
|
||||
|
|
@ -130,16 +130,15 @@ void serial_writechar(uint8_t data)
|
|||
{
|
||||
// check if interrupts are enabled
|
||||
if (SREG & MASK(SREG_I)) {
|
||||
// if they are, we should be ok to block
|
||||
// if they are, we should be ok to block since the tx buffer is emptied from an interrupt
|
||||
for (;buf_canwrite(tx) == 0;);
|
||||
buf_push(tx, data);
|
||||
}
|
||||
else {
|
||||
// interrupts are disabled- maybe we're in one?
|
||||
// anyway, instead of blocking, only write if we have room
|
||||
if (buf_canwrite(tx)) {
|
||||
if (buf_canwrite(tx))
|
||||
buf_push(tx, data);
|
||||
}
|
||||
}
|
||||
// enable TX interrupt so we can send this character
|
||||
UCSR0B |= MASK(UDRIE0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
#include "watchdog.h"
|
||||
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "arduino.h"
|
||||
|
||||
volatile uint8_t wd_flag = 0;
|
||||
|
||||
ISR(WDT_vect) {
|
||||
// watchdog has tripped- no main loop activity for 0.25s, probably a bad thing
|
||||
wd_flag |= 1;
|
||||
}
|
||||
|
||||
void wd_init() {
|
||||
// 0.25s timeout, interrupt and system reset
|
||||
wdt_enable(WDTO_250MS);
|
||||
WDTCSR |= MASK(WDIE);
|
||||
}
|
||||
|
||||
void wd_reset() {
|
||||
wdt_reset();
|
||||
if (wd_flag) {
|
||||
WDTCSR |= MASK(WDIE);
|
||||
wd_flag &= ~1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _WATCHDOG_H
|
||||
#define _WATCHDOG_H
|
||||
|
||||
// initialize
|
||||
void wd_init(void);
|
||||
|
||||
// reset timeout- must be called periodically or we reboot
|
||||
void wd_reset(void);
|
||||
|
||||
// notable lack of disable function
|
||||
|
||||
#endif /* _WATCHDOG_H */
|
||||
Loading…
Reference in New Issue