misc tidying, added watchdog stuff, moved things around a bit

This commit is contained in:
Michael Moon 2010-02-10 12:56:26 +11:00
parent 65c237cff6
commit 7326e17560
7 changed files with 80 additions and 40 deletions

View File

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

View File

@ -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(&current_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

View File

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

View File

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

View File

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

27
mendel/watchdog.c Normal file
View File

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

12
mendel/watchdog.h Normal file
View File

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