From bc67608462e1dd24c6fb5e36c0110e4360d40074 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Sun, 20 Mar 2016 21:05:56 -0700 Subject: [PATCH] Even more switch cleanup --- src/command.def | 1 + src/config.h | 12 ++++++ src/controller.c | 2 +- src/cycle_homing.c | 14 +++---- src/cycle_probing.c | 21 +++++----- src/stepper.c | 20 ++++------ src/switch.c | 75 +++++++++++++++++++++++++----------- src/switch.h | 93 ++++++++------------------------------------- 8 files changed, 107 insertions(+), 131 deletions(-) diff --git a/src/command.def b/src/command.def index fc5e06d..d7dd746 100644 --- a/src/command.def +++ b/src/command.def @@ -28,3 +28,4 @@ CMD(help, command_help, 0, 1, "Print this help screen") CMD(reboot, command_reboot, 0, 0, "Reboot the controller") CMD(jog, command_jog, 1, 4, "Jog") +CMD(mreset, command_mreset, 1, 1, "Reset motor") diff --git a/src/config.h b/src/config.h index b8bd23a..248c2b5 100644 --- a/src/config.h +++ b/src/config.h @@ -94,6 +94,18 @@ #define C_SWITCH_MODE_MIN SW_MODE_HOMING #define C_SWITCH_MODE_MAX SW_MODE_DISABLED +// Switch ISRs +#define X_SWITCH_ISR_vect PORTA_INT0_vect +#define Y_SWITCH_ISR_vect PORTD_INT0_vect +#define Z_SWITCH_ISR_vect PORTE_INT0_vect +#define A_SWITCH_ISR_vect PORTF_INT0_vect + +#define SWITCH_INTLVL PORT_INT0LVL_MED_gc + +// Timer for debouncing switches +#define SW_LOCKOUT_TICKS 25 // 25=250ms. RTC ticks are ~10ms each +#define SW_DEGLITCH_TICKS 3 // 3=30ms + // Machine settings #define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing diff --git a/src/controller.c b/src/controller.c index c150860..f53b907 100644 --- a/src/controller.c +++ b/src/controller.c @@ -90,7 +90,7 @@ static stat_t _sync_to_planner() { /// Shut down system if limit switch fired static stat_t _limit_switch_handler() { if (cm_get_machine_state() == MACHINE_ALARM) return STAT_NOOP; - if (!get_limit_switch_thrown()) return STAT_NOOP; + if (!switch_get_limit_thrown()) return STAT_NOOP; return cm_hard_alarm(STAT_LIMIT_SWITCH_HIT); } diff --git a/src/cycle_homing.c b/src/cycle_homing.c index 7ae2659..1298902 100644 --- a/src/cycle_homing.c +++ b/src/cycle_homing.c @@ -231,8 +231,8 @@ static stat_t _homing_axis_start(int8_t axis) { return _homing_error_exit(axis, STAT_HOMING_ERROR_TRAVEL_MIN_MAX_IDENTICAL); // determine the switch setup and that config is OK - hm.min_mode = get_switch_mode(MIN_SWITCH(axis)); - hm.max_mode = get_switch_mode(MAX_SWITCH(axis)); + hm.min_mode = switch_get_mode(MIN_SWITCH(axis)); + hm.max_mode = switch_get_mode(MAX_SWITCH(axis)); // one or the other must be homing if (!((hm.min_mode & SW_HOMING_BIT) ^ (hm.max_mode & SW_HOMING_BIT))) @@ -263,12 +263,12 @@ static stat_t _homing_axis_start(int8_t axis) { } // if homing is disabled for the axis then skip to the next axis - uint8_t sw_mode = get_switch_mode(hm.homing_switch); + uint8_t sw_mode = switch_get_mode(hm.homing_switch); if (sw_mode != SW_MODE_HOMING && sw_mode != SW_MODE_HOMING_LIMIT) return _set_homing_func(_homing_axis_start); // disable the limit switch parameter if there is no limit switch - if (get_switch_mode(hm.limit_switch) == SW_MODE_DISABLED) + if (switch_get_mode(hm.limit_switch) == SW_MODE_DISABLED) hm.limit_switch = -1; hm.saved_jerk = cm_get_axis_jerk(axis); // save the max jerk value @@ -282,10 +282,10 @@ static stat_t _homing_axis_clear(int8_t axis) { // Handle an initial switch closure by backing off the closed switch // NOTE: Relies on independent switches per axis (not shared) - if (sw.switches[hm.homing_switch].state == SW_CLOSED) + if (switch_get_closed(hm.homing_switch)) _homing_axis_move(axis, hm.latch_backoff, hm.search_velocity); - else if (sw.switches[hm.limit_switch].state == SW_CLOSED) + else if (switch_get_closed(hm.limit_switch)) _homing_axis_move(axis, -hm.latch_backoff, hm.search_velocity); return _set_homing_func(_homing_axis_search); @@ -306,7 +306,7 @@ static stat_t _homing_axis_search(int8_t axis) { static stat_t _homing_axis_latch(int8_t axis) { // verify assumption that we arrived here because of homing switch closure // rather than user-initiated feedhold or other disruption - if (sw.switches[hm.homing_switch].state != SW_CLOSED) + if (!switch_get_closed(hm.homing_switch)) return _set_homing_func(_homing_abort); _homing_axis_move(axis, hm.latch_backoff, hm.latch_velocity); diff --git a/src/cycle_probing.c b/src/cycle_probing.c index cf41111..6da3a99 100644 --- a/src/cycle_probing.c +++ b/src/cycle_probing.c @@ -172,13 +172,13 @@ static uint8_t _probing_init() { // Can't because switch mode is global and our probe is NO, not NC. pb.probe_switch = SW_MIN_Z; // FIXME: hardcoded... - pb.saved_switch_mode = sw.switches[pb.probe_switch].mode; + pb.saved_switch_mode = switch_get_mode(pb.probe_switch); - sw.switches[pb.probe_switch].mode = SW_MODE_HOMING; + switch_set_mode(pb.probe_switch, SW_MODE_HOMING); // save the switch type for recovery later. - pb.saved_switch_type = sw.switches[pb.probe_switch].type; + pb.saved_switch_type = switch_get_type(pb.probe_switch); // contact probes are NO switches... usually - sw.switches[pb.probe_switch].type = SW_TYPE_NORMALLY_OPEN; + switch_set_type(pb.probe_switch, SW_TYPE_NORMALLY_OPEN); // re-init to pick up new switch settings switch_init(); @@ -197,18 +197,17 @@ static uint8_t _probing_init() { static stat_t _probing_start() { // initial probe state, don't probe if we're already contacted! - int8_t probe = sw.switches[pb.probe_switch].state; + bool closed = switch_get_closed(pb.probe_switch); - if (probe == SW_OPEN) - ritorno(cm_straight_feed(pb.target, pb.flags)); + if (!closed) ritorno(cm_straight_feed(pb.target, pb.flags)); return _set_pb_func(_probing_finish); } static stat_t _probing_finish() { - int8_t probe = sw.switches[pb.probe_switch].state; - cm.probe_state = probe == SW_CLOSED ? PROBE_SUCCEEDED : PROBE_FAILED; + bool closed = switch_get_closed(pb.probe_switch); + cm.probe_state = closed ? PROBE_SUCCEEDED : PROBE_FAILED; for (uint8_t axis = 0; axis < AXES; axis++) { // if we got here because of a feed hold keep the model position correct @@ -226,8 +225,8 @@ static void _probe_restore_settings() { // we should be stopped now, but in case of switch closure mp_flush_planner(); - sw.switches[pb.probe_switch].type = pb.saved_switch_type; - sw.switches[pb.probe_switch].mode = pb.saved_switch_mode; + switch_set_type(pb.probe_switch, pb.saved_switch_type); + switch_set_mode(pb.probe_switch, pb.saved_switch_mode); switch_init(); // re-init to pick up changes // restore axis jerk diff --git a/src/stepper.c b/src/stepper.c index 9513c06..faad639 100644 --- a/src/stepper.c +++ b/src/stepper.c @@ -65,15 +65,6 @@ static void _request_load_move(); static void _update_steps_per_unit(int motor); -/* Initialize stepper motor subsystem - * - * Notes: - * - This init requires sys_init() to be run beforehand - * - microsteps are setup during config_init() - * - motor polarity is setup during config_init() - * - high level interrupts must be enabled in main() once all inits are - * complete - */ void stepper_init() { /// clear all values, pointers and status memset(&st_run, 0, sizeof(st_run)); @@ -81,8 +72,8 @@ void stepper_init() { // Setup ports for (int motor = 0; motor < MOTORS; motor++) { - hw.st_port[motor]->DIR = MOTOR_PORT_DIR_gm; hw.st_port[motor]->OUTSET = MOTOR_ENABLE_BIT_bm; // disable motor + hw.st_port[motor]->DIR = MOTOR_PORT_DIR_gm; // pin directions } // Setup step timer @@ -153,9 +144,9 @@ void stepper_init() { uint8_t st_runtime_isbusy() {return st_run.busy;} -/// returns true if motor is enabled (motor is actually active low) +/// returns true if motor is enabled static bool _motor_is_enabled(uint8_t motor) { - return !(hw.st_port[motor]->OUT & MOTOR_ENABLE_BIT_bm); + return st_run.mot[motor].flags & MOTOR_FLAG_ENABLED_bm; } /// returns true if motor is in an error state @@ -597,3 +588,8 @@ void set_power_mode(int index, uint16_t value) { if (value < MOTOR_POWER_MODE_MAX_VALUE) st_cfg.mot[index].power_mode = value; } + + +void command_mreset(int motor) { + if (motor < MOTORS) st_run.mot[motor].flags &= 0; +} diff --git a/src/switch.c b/src/switch.c index d158de7..ef1fc97 100644 --- a/src/switch.c +++ b/src/switch.c @@ -44,6 +44,13 @@ * The normally closed switch modes (NC) trigger an interrupt on the * rising edge and lockout subsequent interrupts for the defined * lockout period. + * + * These functions interact with each other to process switch closures + * and firing. Each switch has a counter which is initially set to + * negative SW_DEGLITCH_TICKS. When a switch closure is DETECTED the + * count increments for each RTC tick. When the count reaches zero + * the switch is tripped and action occurs. The counter continues to + * increment positive until the lockout is exceeded. */ #include "switch.h" @@ -57,6 +64,30 @@ #include +typedef enum { // state machine for managing debouncing and lockout + SW_IDLE, + SW_DEGLITCHING, + SW_LOCKOUT +} swDebounce_t; + +typedef struct { + bool last; + bool state; + swType_t type; + swMode_t mode; + swDebounce_t debounce; // debounce state + int8_t count; // deglitching and lockout counter +} switch_t; + +/* Switch control structures + * Note 1: The term "thrown" is used because switches could be normally-open + * or normally-closed. "Thrown" means activated or hit. + */ +typedef struct { + bool limit_thrown; + switch_t switches[SWITCHES]; +} swSingleton_t; + swSingleton_t sw; @@ -75,14 +106,6 @@ static bool _read_switch(uint8_t sw_num) { } -/* These functions interact with each other to process switch closures - * and firing. Each switch has a counter which is initially set to - * negative SW_DEGLITCH_TICKS. When a switch closure is DETECTED the - * count increments for each RTC tick. When the count reaches zero - * the switch is tripped and action occurs. The counter continues to - * increment positive until the lockout is exceeded. - */ - static void _switch_isr() { for (int i = 0; i < SWITCHES; i++) { switch_t *s = &sw.switches[i]; @@ -105,19 +128,14 @@ static void _switch_isr() { // Switch interrupt handler vectors -ISR(X_ISR_vect) {_switch_isr();} -ISR(Y_ISR_vect) {_switch_isr();} -ISR(Z_ISR_vect) {_switch_isr();} -ISR(A_ISR_vect) {_switch_isr();} +ISR(X_SWITCH_ISR_vect) {_switch_isr();} +ISR(Y_SWITCH_ISR_vect) {_switch_isr();} +ISR(Z_SWITCH_ISR_vect) {_switch_isr();} +ISR(A_SWITCH_ISR_vect) {_switch_isr();} -/* Initialize homing/limit switches - * - * This function assumes sys_init() and st_init() have been run previously to - * bind the ports and set bit IO directions, repsectively. - */ void switch_init() { - for (int i = 0; i < NUM_SWITCH_PAIRS; i++) { + for (int i = 0; i < SWITCHES / 2; i++) { // setup input bits and interrupts (previously set to inputs by st_init()) if (sw.switches[MIN_SWITCH(i)].mode != SW_MODE_DISABLED) { hw.sw_port[i]->DIRCLR = SW_MIN_BIT_bm; // set min input - see 13.14.14 @@ -193,11 +211,24 @@ void switch_rtc_callback() { } -/// return switch mode setting -swMode_t get_switch_mode(uint8_t sw_num) {return sw.switches[sw_num].mode;} +bool switch_get_closed(uint8_t n) {return sw.switches[n].state;} +swType_t switch_get_type(uint8_t n) {return sw.switches[n].type;} + + +void switch_set_type(uint8_t n, swType_t type) { + sw.switches[n].type = type; +} + + +swMode_t switch_get_mode(uint8_t n) {return sw.switches[n].mode;} + + +void switch_set_mode(uint8_t n, swMode_t mode) { + sw.switches[n].mode = mode; +} + -/// return true if a limit was tripped -bool get_limit_switch_thrown() {return sw.limit_thrown;} +bool switch_get_limit_thrown() {return sw.limit_thrown;} uint8_t get_switch_type(int index) { diff --git a/src/switch.h b/src/switch.h index 5a668a4..e5bedbb 100644 --- a/src/switch.h +++ b/src/switch.h @@ -26,21 +26,6 @@ \******************************************************************************/ -/* Switch processing functions - * - * Switch processing turns pin transitions into reliable switch states. - * There are 2 main operations: - * - * - read pin get raw data from a pin - * - read switch return processed switch closures - * - * Read pin may be a polled operation or an interrupt on pin - * change. If interrupts are used they must be provided for both - * leading and trailing edge transitions. - * - * Read switch contains the results of read pin and manages edges and - * debouncing. - */ #pragma once @@ -49,11 +34,11 @@ #include #include -// timer for debouncing switches -#define SW_LOCKOUT_TICKS 25 // 25=250ms. RTC ticks are ~10ms each -#define SW_DEGLITCH_TICKS 3 // 3=30ms +// macros for finding the index into the switch table give the axis number +#define MIN_SWITCH(axis) (axis * 2) +#define MAX_SWITCH(axis) (axis * 2 + 1) -// switch modes +/// switch modes typedef enum { SW_MODE_DISABLED, SW_HOMING_BIT, @@ -69,68 +54,20 @@ typedef enum { SW_TYPE_NORMALLY_CLOSED } swType_t; +/// indices into switch arrays typedef enum { - SW_OPEN, - SW_CLOSED -} swState_t; - -// macros for finding the index into the switch table give the axis number -#define MIN_SWITCH(axis) (axis * 2) -#define MAX_SWITCH(axis) (axis * 2 + 1) - -typedef enum { // state machine for managing debouncing and lockout - SW_IDLE, - SW_DEGLITCHING, - SW_LOCKOUT -} swDebounce_t; - -typedef enum { // indexes into switch arrays - SW_MIN_X, - SW_MAX_X, - SW_MIN_Y, - SW_MAX_Y, - SW_MIN_Z, - SW_MAX_Z, - SW_MIN_A, - SW_MAX_A + SW_MIN_X, SW_MAX_X, + SW_MIN_Y, SW_MAX_Y, + SW_MIN_Z, SW_MAX_Z, + SW_MIN_A, SW_MAX_A } swNums_t; -#define SW_OFFSET SW_MAX_X // offset between MIN and MAX switches -#define NUM_SWITCH_PAIRS (SWITCHES / 2) - -/// Interrupt levels and vectors - The vectors are hard-wired to xmega ports -/// If you change axis port assignments you need to change these, too. -#define SWITCH_INTLVL PORT_INT0LVL_MED_gc - -// port assignments for vectors -#define X_ISR_vect PORTA_INT0_vect -#define Y_ISR_vect PORTD_INT0_vect -#define Z_ISR_vect PORTE_INT0_vect -#define A_ISR_vect PORTF_INT0_vect - -typedef struct { - bool last; - bool state; - swType_t type; - swMode_t mode; - swDebounce_t debounce; // debounce state - int8_t count; // deglitching and lockout counter -} switch_t; - -/* Switch control structures - * Note 1: The term "thrown" is used because switches could be normally-open - * or normally-closed. "Thrown" means activated or hit. - */ -typedef struct { - bool limit_thrown; - switch_t switches[SWITCHES]; -} swSingleton_t; - -extern swSingleton_t sw; void switch_init(); -swMode_t get_switch_mode(uint8_t sw_num); - void switch_rtc_callback(); -bool get_limit_switch_thrown(); -void reset_switches(); +bool switch_get_closed(uint8_t n); +swType_t switch_get_type(uint8_t n); +void switch_set_type(uint8_t n, swType_t type); +swMode_t switch_get_mode(uint8_t n); +void switch_set_mode(uint8_t n, swMode_t mode); +bool switch_get_limit_thrown(); -- 2.27.0