Reintroduced machine cycle state
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Sat, 27 Aug 2016 21:18:30 +0000 (14:18 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Sat, 27 Aug 2016 21:18:30 +0000 (14:18 -0700)
src/estop.c
src/homing.c
src/machine.c
src/machine.h
src/plan/calibrate.c
src/plan/exec.c
src/plan/jog.c
src/probing.c
src/status.h
src/varcb.c
src/vars.def

index 96a416bc5dc9b600b615e2b431f4b0363a2fdaeb..e9edd660c9da00471e57261f7bc2851bbd758d2a 100644 (file)
@@ -73,7 +73,7 @@ void estop_init() {
 
   switch_set_callback(SW_ESTOP, _switch_callback);
 
-  if (estop.triggered) mach_set_state(STATE_ESTOP);
+  if (estop.triggered) mach_set_state(STATE_ESTOPPED);
 
   // Fault signal
   if (estop.triggered) OUTSET_PIN(FAULT_PIN); // High
@@ -95,7 +95,7 @@ void estop_trigger(estop_reason_t reason) {
   mach_spindle_estop();
 
   // Set machine state
-  mach_set_state(STATE_ESTOP);
+  mach_set_state(STATE_ESTOPPED);
 
   // Set axes not homed
   mach_set_not_homed();
index 70222c0e600f5f16fe71ea415f6adef3a11be564..c1d517d282ee6c03746fbdf7e6faf6d78519b12c 100644 (file)
@@ -177,6 +177,7 @@ static void _homing_finalize_exit() {
   mach.gm.feed_rate = hm.saved_feed_rate;
   mach_set_motion_mode(MOTION_MODE_CANCEL_MOTION_MODE);
   mach_cycle_end();
+  mach_set_cycle(CYCLE_MACHINING);
 }
 
 
@@ -342,7 +343,7 @@ static void _homing_axis_start(int8_t axis) {
 
 
 bool mach_is_homing() {
-  return mach_get_state() == STATE_HOMING;
+  return mach_get_cycle() == CYCLE_HOMING;
 }
 
 
@@ -371,7 +372,7 @@ void mach_homing_cycle_start() {
 
   hm.axis = -1;                            // set to retrieve initial axis
   hm.func = _homing_axis_start;            // bind initial processing function
-  mach_set_state(STATE_HOMING);
+  mach_set_cycle(CYCLE_HOMING);
   mach.homing_state = HOMING_NOT_HOMED;
 }
 
@@ -384,6 +385,6 @@ void mach_homing_cycle_start_no_set() {
 
 /// Main loop callback for running the homing cycle
 void mach_homing_callback() {
-  if (mach_get_state() != STATE_HOMING || mach_get_runtime_busy()) return;
+  if (mach_get_cycle() != CYCLE_HOMING || mach_get_runtime_busy()) return;
   hm.func(hm.axis); // execute the current homing move
 }
index b637ab900c98a255c1c8bd9f78556747e0e0f0df..8b583b928efe80abbd67e862ebc9350401e665e0 100644 (file)
@@ -183,6 +183,7 @@ machine_t mach = {
   },
 
   ._state = STATE_IDLE,
+  ._cycle = CYCLE_MACHINING,
 
   // State
   .gm = {.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE},
@@ -203,14 +204,29 @@ static void _exec_absolute_origin(float *value, float *flag);
 uint32_t mach_get_line() {return mach.gm.line;}
 
 
-bool mach_is_running() {
-  switch (mach_get_state()) {
-  case STATE_RUNNING:
-  case STATE_HOMING:
-  case STATE_PROBING:
-    return true;
-  default: return false;
+PGM_P mach_get_state_pgmstr(machState_t state) {
+  switch (state) {
+  case STATE_IDLE:     return PSTR("idle");
+  case STATE_ESTOPPED: return PSTR("estopped");
+  case STATE_RUNNING:  return PSTR("running");
+  case STATE_STOPPING: return PSTR("stopping");
+  case STATE_HOLDING:  return PSTR("holding");
   }
+
+  return PSTR("invalid");
+}
+
+
+PGM_P mach_get_cycle_pgmstr(machCycle_t cycle) {
+  switch (cycle) {
+  case CYCLE_MACHINING:   return PSTR("machining");
+  case CYCLE_HOMING:      return PSTR("homing");
+  case CYCLE_PROBING:     return PSTR("probing");
+  case CYCLE_CALIBRATING: return PSTR("calibrating");
+  case CYCLE_JOGGING:     return PSTR("jogging");
+  }
+
+  return PSTR("invalid");
 }
 
 
@@ -231,12 +247,35 @@ float mach_get_feed_rate() {return mach.gm.feed_rate;}
 
 void mach_set_state(machState_t state) {
   if (mach._state == state) return; // No change
-  if (mach._state == STATE_ESTOP) return; // Can't leave EStop state
+  if (mach._state == STATE_ESTOPPED) return; // Can't leave EStop state
   mach._state = state;
   report_request();
 }
 
 
+void mach_set_cycle(machCycle_t cycle) {
+  if (mach._cycle == cycle) return; // No change
+
+  if (mach._state != STATE_IDLE) {
+    STATUS_ERROR(STAT_INTERNAL_ERROR, "Cannot transition to %S while %S",
+                 mach_get_cycle_pgmstr(cycle),
+                 mach_get_state_pgmstr(mach._state));
+    return;
+  }
+
+  if (mach._cycle != CYCLE_MACHINING && cycle != CYCLE_MACHINING) {
+    STATUS_ERROR(STAT_INTERNAL_ERROR,
+                 "Cannot transition to cycle %S while in %S",
+                 mach_get_cycle_pgmstr(cycle),
+                 mach_get_cycle_pgmstr(mach._cycle));
+    return;
+  }
+
+  mach._cycle = cycle;
+  report_request();
+}
+
+
 void mach_set_motion_mode(machMotionMode_t motion_mode) {
   mach.gm.motion_mode = motion_mode;
 }
@@ -1126,7 +1165,7 @@ void mach_feedhold_callback() {
   if (mach.feedhold_requested) {
     mach.feedhold_requested = false;
 
-    if (mach_is_running()) {
+    if (mach_get_state() == STATE_RUNNING) {
       mach_set_state(STATE_STOPPING);
       mach.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution
     }
@@ -1228,7 +1267,6 @@ stat_t mach_queue_flush() {
 
 /// Do a cycle start right now
 void mach_cycle_start() {
-  // don't (re)start homing, probe or other canned cycles
   if (mach_get_state() == STATE_IDLE) mach_set_state(STATE_RUNNING);
 }
 
index a9b2502741453c76d41b9955030eb7f0a5f1f27b..f9c2a0fd94567861f83130224d8ef7a460f0ea0f 100644 (file)
@@ -32,6 +32,8 @@
 #include "config.h"
 #include "status.h"
 
+#include <avr/pgmspace.h>
+
 #include <stdint.h>
 #include <stdbool.h>
 
 
 typedef enum {
   STATE_IDLE,
-  STATE_ESTOP,
+  STATE_ESTOPPED,
   STATE_RUNNING,
-  STATE_HOMING,
-  STATE_PROBING,
   STATE_STOPPING,
   STATE_HOLDING,
 } machState_t;
 
 
+typedef enum {
+  CYCLE_MACHINING,
+  CYCLE_HOMING,
+  CYCLE_PROBING,
+  CYCLE_CALIBRATING,
+  CYCLE_JOGGING,
+} machCycle_t;
+
+
 typedef enum {          // feedhold_state machine
   FEEDHOLD_OFF,         // no feedhold in effect
   FEEDHOLD_SYNC,        // start hold - sync to latest aline segment
@@ -348,6 +357,7 @@ typedef struct { // struct to manage mach globals and cycles
   AxisConfig_t a[AXES];
 
   machState_t _state;
+  machCycle_t _cycle;
   machFeedholdState_t hold_state;      // hold: feedhold sub-state machine
   machHomingState_t homing_state;      // home: homing cycle sub-state machine
   bool homed[AXES];                    // individual axis homing flags
@@ -373,7 +383,7 @@ extern machine_t mach;                 // machine controller singleton
 // Model state getters and setters
 uint32_t mach_get_line();
 inline machState_t mach_get_state() {return mach._state;}
-bool mach_is_running();
+inline machCycle_t mach_get_cycle() {return mach._cycle;}
 machFeedholdState_t mach_get_hold_state();
 machHomingState_t mach_get_homing_state();
 machMotionMode_t mach_get_motion_mode();
@@ -389,6 +399,9 @@ bool mach_get_runtime_busy();
 float mach_get_feed_rate();
 
 void mach_set_state(machState_t state);
+void mach_set_cycle(machCycle_t cycle);
+PGM_P mach_get_state_pgmstr(machState_t state);
+PGM_P mach_get_cycle_pgmstr(machCycle_t cycle);
 void mach_set_motion_mode(machMotionMode_t motion_mode);
 void mach_set_spindle_mode(machSpindleMode_t spindle_mode);
 void mach_set_spindle_speed_parameter(float speed);
index b1833c8c1ac6a339faea960cb0e88c4d7ff3d87e..289e8ba77a675d346bc61c5762bb168cf1e08a76 100644 (file)
@@ -59,7 +59,6 @@ enum {
 
 
 typedef struct {
-  bool busy;
   bool stall_valid;
   bool stalled;
   bool reverse;
@@ -112,7 +111,7 @@ static stat_t _exec_calibrate(mpBuf_t *bf) {
 
           tmc2660_set_stallguard_threshold(cal.motor, 63);
           mp_free_run_buffer(); // Release buffer
-          cal.busy = false;
+          mach_set_cycle(CYCLE_MACHINING);
           return STAT_OK;
 
         } else {
@@ -145,7 +144,7 @@ static stat_t _exec_calibrate(mpBuf_t *bf) {
 }
 
 
-bool calibrate_busy() {return cal.busy;}
+bool calibrate_busy() {return mach_get_cycle() == CYCLE_CALIBRATING;}
 
 
 void calibrate_set_stallguard(int motor, uint16_t sg) {
@@ -164,7 +163,8 @@ void calibrate_set_stallguard(int motor, uint16_t sg) {
 
 
 uint8_t command_calibrate(int argc, char *argv[]) {
-  if (cal.busy) return 0;
+  if (mach_get_cycle() != CYCLE_MACHINING || mach_get_state() != STATE_IDLE)
+    return 0;
 
   mpBuf_t *bf = mp_get_write_buffer();
   if (!bf) {
@@ -174,7 +174,7 @@ uint8_t command_calibrate(int argc, char *argv[]) {
 
   // Start
   memset(&cal, 0, sizeof(cal));
-  cal.busy = true;
+  mach_set_cycle(CYCLE_CALIBRATING);
   cal.motor = 1;
 
   bf->bf_func = _exec_calibrate; // register callback
index 4460580d56120b2609854ca3fc7e996b7ddaa84b..e87bb5dfe8cf38532b7b72e570d2ddc11425e9c1 100644 (file)
@@ -796,20 +796,15 @@ stat_t mp_exec_aline(mpBuf_t *bf) {
 }
 
 
-/// Dequeues buffer, executes move continuations and manages run buffers.
+/// Dequeues buffer, executes move callback and enters RUNNING state
 stat_t mp_exec_move() {
-  mpBuf_t *bf = mp_get_run_buffer();
-
-  if (!bf) return STAT_NOOP; // nothing's running
   if (estop_triggered()) return STAT_MACHINE_ALARMED;
 
-  // Manage state transitions
-  // Cycle auto-start for lines only
-  if (bf->move_type == MOVE_TYPE_ALINE && mach_get_state() == STATE_IDLE)
-    mach_set_state(STATE_RUNNING);
+  mpBuf_t *bf = mp_get_run_buffer();
+  if (!bf) return STAT_NOOP; // nothing running
+  if (!bf->bf_func) return CM_ALARM(STAT_INTERNAL_ERROR);
 
-  if (!bf->bf_func)
-    return CM_ALARM(STAT_INTERNAL_ERROR); // never supposed to get here
+  if (mach_get_state() == STATE_IDLE) mach_set_state(STATE_RUNNING);
 
-  return bf->bf_func(bf); // run the move callback on the planner buffer
+  return bf->bf_func(bf); // move callback
 }
index 265402f706e81cb444905b07275d4a8c2ce55d6b..ca978843e7fb8fa849c0986f20954affe157904e 100644 (file)
@@ -43,7 +43,6 @@
 
 
 typedef struct {
-  bool running;
   bool writing;
   float next_velocity[AXES];
   float target_velocity[AXES];
@@ -96,7 +95,7 @@ static stat_t _exec_jog(mpBuf_t *bf) {
     // Release buffer
     mp_free_run_buffer();
 
-    jr.running = false;
+    mach_set_cycle(CYCLE_MACHINING);
 
     return STAT_NOOP;
   }
@@ -113,10 +112,14 @@ static stat_t _exec_jog(mpBuf_t *bf) {
 }
 
 
-bool mp_jog_busy() {return jr.running;}
+bool mp_jog_busy() {return mach_get_cycle() == CYCLE_JOGGING;}
 
 
 uint8_t command_jog(int argc, char *argv[]) {
+  if (!mp_jog_busy() &&
+      (mach_get_state() != STATE_IDLE || mach_get_cycle() != CYCLE_MACHINING))
+    return STAT_NOOP;
+
   float velocity[AXES];
 
   for (int axis = 0; axis < AXES; axis++)
@@ -124,14 +127,14 @@ uint8_t command_jog(int argc, char *argv[]) {
     else velocity[axis] = 0;
 
   // Reset
-  if (!jr.running) memset(&jr, 0, sizeof(jr));
+  if (mp_jog_busy()) memset(&jr, 0, sizeof(jr));
 
   jr.writing = true;
   for (int axis = 0; axis < AXES; axis++)
     jr.next_velocity[axis] = velocity[axis];
   jr.writing = false;
 
-  if (!jr.running) {
+  if (!mp_jog_busy()) {
     // Should always be at least one free buffer
     mpBuf_t *bf = mp_get_write_buffer();
     if (!bf) {
@@ -140,7 +143,7 @@ uint8_t command_jog(int argc, char *argv[]) {
     }
 
     // Start
-    jr.running = true;
+    mach_set_cycle(CYCLE_JOGGING);
     bf->bf_func = _exec_jog; // register callback
     mp_commit_write_buffer(-1, MOVE_TYPE_COMMAND);
   }
index a7dd584c96ce0fa6e1e72964ca8d64e8d0936062..e79ee523d53d8c0c376edfecd75a6100edbeb624 100644 (file)
@@ -89,6 +89,7 @@ static void _probe_restore_settings() {
   // update the model with actual position
   mach_set_motion_mode(MOTION_MODE_CANCEL_MOTION_MODE);
   mach_cycle_end();
+  mach_set_cycle(CYCLE_MACHINING);
 }
 
 
@@ -140,7 +141,7 @@ static void _probing_init() {
   // it is an error for the limit or homing switches to fire, or for some other
   // configuration error.
   mach.probe_state = PROBE_FAILED;
-  mach_set_state(STATE_PROBING);
+  mach_set_cycle(CYCLE_PROBING);
 
   // initialize the axes - save the jerk settings & switch to the jerk_homing
   // settings
@@ -175,7 +176,7 @@ static void _probing_init() {
 
 
 bool mach_is_probing() {
-  return mach_get_state() == STATE_PROBING || mach.probe_state == PROBE_WAITING;
+  return mach_get_cycle() == CYCLE_PROBING || mach.probe_state == PROBE_WAITING;
 }
 
 
index e2e7df9f4f0c2caa34bbdc8a02c0fb696472911d..24f222b152ed99addb733b2e046f0fe78186f61b 100644 (file)
@@ -77,5 +77,5 @@ void status_help();
 #define STATUS_WARNING(MSG, ...)                                \
   STATUS_MESSAGE(STAT_LEVEL_WARNING, STAT_OK, MSG, ##__VA_ARGS__)
 
-#define STATUS_ERROR(MSG, CODE, ...)                        \
+#define STATUS_ERROR(CODE, MSG, ...)                            \
   STATUS_MESSAGE(STAT_LEVEL_ERROR, CODE, MSG, ##__VA_ARGS__)
index 4a559b641df533ad781600bc2de47874557617f1..488d0916860a6816cd6de669067dede833f6e70a 100644 (file)
 \******************************************************************************/
 
 #include "usart.h"
+#include "machine.h"
 #include "plan/planner.h"
 #include "plan/buffer.h"
 
-#include <avr/pgmspace.h>
-
 
 float get_position(int index) {return mp_get_runtime_absolute_position(index);}
 float get_velocity() {return mp_get_runtime_velocity();}
@@ -39,18 +38,5 @@ bool get_echo() {return usart_is_set(USART_ECHO);}
 void set_echo(bool value) {return usart_set(USART_ECHO, value);}
 uint16_t get_queue() {return mp_get_planner_buffer_room();}
 int32_t get_line() {return mr.ms.line;}
-
-
-PGM_P get_state() {
-  switch (mach_get_state()) {
-  case STATE_IDLE:     return PSTR("idle");
-  case STATE_ESTOP:    return PSTR("estop");
-  case STATE_RUNNING:  return PSTR("running");
-  case STATE_HOMING:   return PSTR("homing");
-  case STATE_PROBING:  return PSTR("probing");
-  case STATE_STOPPING: return PSTR("stopping");
-  case STATE_HOLDING:  return PSTR("holding");
-  }
-
-  return PSTR("invalid");
-}
+PGM_P get_state() {return mach_get_state_pgmstr(mach_get_state());}
+PGM_P get_cycle() {return mach_get_cycle_pgmstr(mach_get_cycle());}
index cd9b0e2461814ba32fa12b7deea3d240c411d47d..e65bf1499aa4a7091ab923895d9e14e3e6b016c9 100644 (file)
@@ -100,3 +100,4 @@ VAR(estop_reason,   "er", pstring,  0,      0, 0, "Emergency stop reason")
 VAR(line,           "ln", int32_t,  0,      0, 0, "Last GCode line executed")
 VAR(queue,          "q",  uint16_t, 0,      0, 0, "Space in planner queue")
 VAR(state,          "s",  pstring,  0,      0, 0, "Machine state")
+VAR(cycle,          "c",  pstring,  0,      0, 0, "Current machine cycle")