Even more switch cleanup
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 21 Mar 2016 04:05:56 +0000 (21:05 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 21 Mar 2016 04:05:56 +0000 (21:05 -0700)
src/command.def
src/config.h
src/controller.c
src/cycle_homing.c
src/cycle_probing.c
src/stepper.c
src/switch.c
src/switch.h

index fc5e06d241de75358aa5721280d0eea1578ff7af..d7dd746cb28c943ab156795ee3271e8cc3b35341 100644 (file)
@@ -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")
index b8bd23aa9e2f307039614780427a8931d850dfa1..248c2b53586c214fb94c9fdddc4607f34de3a357 100644 (file)
 #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
index c1508607f005ebca2047e85fd842bd9605f3ae71..f53b9072f985664687d89fb9b7f529480e272e42 100644 (file)
@@ -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);
 }
index 7ae26591da402b3d6d28ff2eb9c60fb6e8a8f026..12989024fcea48e61ad82e81c550b73760855240 100644 (file)
@@ -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);
index cf41111115f3ff443f8b1aa96b6877927223f3c5..6da3a99260e1a3f929823a4c838d0db5a3b6b381 100644 (file)
@@ -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
index 9513c06098994fc3d8ab32840906dac6d87ea6be..faad639655cb303cc81f675041880c2d1ad4a7e7 100644 (file)
@@ -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;
+}
index d158de77e579ee0c181ce2d891a6bb382bd7ec2b..ef1fc978f905137b5e0d3c453ad4d8cbbdbca854 100644 (file)
  * 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"
 #include <stdbool.h>
 
 
+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) {
index 5a668a41ccedc6c49c1ae0df70290168fae6e64b..e5bedbb18dec9b161506f2fa2be2ca97548ab7a3 100644 (file)
 
 \******************************************************************************/
 
-/* 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
 
 
 #include <stdint.h>
 #include <stdbool.h>
 
-// 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();