Work on spindle vars, Added hold reason, hold on tool change, hold on pallet change...
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 12 Sep 2016 06:17:55 +0000 (23:17 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 12 Sep 2016 06:17:55 +0000 (23:17 -0700)
src/command.c
src/huanyang.c
src/machine.c
src/plan/exec.c
src/plan/state.c
src/plan/state.h
src/pwm_spindle.c
src/varcb.c
src/vars.def

index dc947281ae047d37d5b0aba450bc85d0092fe728..6f7e483fe894cc886fecf1658f041aed551027e7 100644 (file)
@@ -71,17 +71,17 @@ static unsigned _parse_axis(uint8_t axis) {
 
 static void command_i2c_cb(i2c_cmd_t cmd, uint8_t *data, uint8_t length) {
   switch (cmd) {
-  case I2C_NULL:                                      break;
-  case I2C_ESTOP:          estop_trigger(ESTOP_USER); break;
-  case I2C_CLEAR:          estop_clear();             break;
-  case I2C_PAUSE:          mp_request_hold();         break;
-  case I2C_OPTIONAL_PAUSE:                            break; // TODO
-  case I2C_RUN:            mp_request_start();        break;
-  case I2C_STEP:                                      break; // TODO
-  case I2C_FLUSH:          mp_request_flush();        break;
-  case I2C_REPORT:         report_request_full();     break;
-  case I2C_HOME:                                      break; // TODO
-  case I2C_REBOOT:         _reboot();                 break;
+  case I2C_NULL:                                        break;
+  case I2C_ESTOP:          estop_trigger(ESTOP_USER);   break;
+  case I2C_CLEAR:          estop_clear();               break;
+  case I2C_PAUSE:          mp_request_hold();           break;
+  case I2C_OPTIONAL_PAUSE: mp_request_optional_pause(); break;
+  case I2C_RUN:            mp_request_start();          break;
+  case I2C_STEP:                                        break; // TODO
+  case I2C_FLUSH:          mp_request_flush();          break;
+  case I2C_REPORT:         report_request_full();       break;
+  case I2C_HOME:                                        break; // TODO
+  case I2C_REBOOT:         _reboot();                   break;
   case I2C_ZERO:
     if (length == 0) mach_zero_all();
     else if (length == 1) mach_zero_axis(_parse_axis(*data));
index 639b8075cd7f41afcc8d1f4d56e7022312645282..1b2a48ddaafeb1f7b98f7d0209b0eb203529ba0a 100644 (file)
@@ -534,74 +534,18 @@ bool huanyang_stopping() {
 }
 
 
-uint8_t get_huanyang_id(int index) {
-  return ha.id;
-}
-
-void set_huanyang_id(int index, uint8_t value) {
-  ha.id = value;
-}
-
-
-bool get_huanyang_debug(int index) {
-  return ha.debug;
-}
-
-void set_huanyang_debug(int index, uint8_t value) {
-  ha.debug = value;
-}
-
-
-bool get_huanyang_connected(int index) {
-  return ha.connected;
-}
-
-
-float get_huanyang_freq(int index) {
-  return ha.actual_freq;
-}
-
-
-float get_huanyang_current(int index) {
-  return ha.actual_current;
-}
-
-
-uint16_t get_huanyang_rpm(int index) {
-  return ha.actual_rpm;
-}
-
-
-uint16_t get_huanyang_dcv(int index) {
-  return ha.dc_voltage;
-}
-
-
-uint16_t get_huanyang_acv(int index) {
-  return ha.ac_voltage;
-}
-
-
-uint16_t get_huanyang_temp(int index) {
-  return ha.temperature;
-}
-
-
-float get_huanyang_max_freq(int index) {
-  return ha.max_freq;
-}
-
-
-float get_huanyang_min_freq(int index) {
-  return ha.min_freq;
-}
-
-
-uint16_t get_huanyang_rated_rpm(int index) {
-  return ha.rated_rpm;
-}
-
-
-float get_huanyang_status(int index) {
-  return ha.status;
-}
+uint8_t get_huanyang_id(int index) {return ha.id;}
+void set_huanyang_id(int index, uint8_t value) {ha.id = value;}
+bool get_huanyang_debug(int index) {return ha.debug;}
+void set_huanyang_debug(int index, uint8_t value) {ha.debug = value;}
+bool get_huanyang_connected(int index) {return ha.connected;}
+float get_huanyang_freq(int index) {return ha.actual_freq;}
+float get_huanyang_current(int index) {return ha.actual_current;}
+uint16_t get_huanyang_rpm(int index) {return ha.actual_rpm;}
+uint16_t get_huanyang_dcv(int index) {return ha.dc_voltage;}
+uint16_t get_huanyang_acv(int index) {return ha.ac_voltage;}
+uint16_t get_huanyang_temp(int index) {return ha.temperature;}
+float get_huanyang_max_freq(int index) {return ha.max_freq;}
+float get_huanyang_min_freq(int index) {return ha.min_freq;}
+uint16_t get_huanyang_rated_rpm(int index) {return ha.rated_rpm;}
+float get_huanyang_status(int index) {return ha.status;}
index c4f064c5bea17962262a7ef661e72de6a72aa962..246be383fb9236372a2118c38262228818fcf512 100644 (file)
@@ -770,15 +770,17 @@ void mach_select_tool(uint8_t tool) {mach.gm.tool = tool;}
 
 static stat_t _exec_change_tool(mp_buffer_t *bf) {
   mp_runtime_set_tool(bf->value);
+  mp_set_hold_reason(HOLD_REASON_TOOL_CHANGE);
+  mp_state_holding();
   return STAT_NOOP; // No move queued
 }
 
 
-/// M6 This might become a complete tool change cycle
+/// M6
 void mach_change_tool(bool x) {
   mp_buffer_t *bf = mp_queue_get_tail();
   bf->value = mach.gm.tool;
-  mp_queue_push_nonstop(_exec_change_tool, mach_get_line());
+  mp_queue_push(_exec_change_tool, mach_get_line());
 }
 
 
@@ -870,6 +872,7 @@ void mach_message(const char *message) {
 static stat_t _exec_program_stop(mp_buffer_t *bf) {
   // Machine should be stopped at this point.  Go into hold so that a start is
   // needed before executing further instructions.
+  mp_set_hold_reason(HOLD_REASON_PROGRAM_PAUSE);
   mp_state_holding();
   return STAT_NOOP; // No move queued
 }
@@ -881,17 +884,29 @@ void mach_program_stop() {
 }
 
 
+static stat_t _exec_optional_program_stop(mp_buffer_t *bf) {
+  mp_state_optional_pause(); // Pause here if it was requested by the user
+  return STAT_NOOP; // No move queued
+}
+
+
 /// M1
 void mach_optional_program_stop() {
-  // TODO Check for user stop signal
-  mach_program_stop();
+  mp_queue_push(_exec_optional_program_stop, mach_get_line());
+}
+
+
+static stat_t _exec_pallet_change_stop(mp_buffer_t *bf) {
+  // Emit pallet change signal
+  mp_set_hold_reason(HOLD_REASON_PALLET_CHANGE);
+  mp_state_holding();
+  return STAT_NOOP; // No move queued
 }
 
 
 /// M60
 void mach_pallet_change_stop() {
-  // TODO Emit pallet change signal
-  mach_program_stop();
+  mp_queue_push(_exec_pallet_change_stop, mach_get_line());
 }
 
 
index c16c08e7206021b0eb91fd8a93d042d38dee6384..5e6370416b74e256cf7a3d5c86f84577049d9ee2 100644 (file)
@@ -521,11 +521,13 @@ stat_t mp_exec_aline(mp_buffer_t *bf) {
 
 /// Dequeues buffer and executes move callback
 stat_t mp_exec_move() {
-  if (mp_get_state() == STATE_ESTOPPED || mp_get_state() == STATE_HOLDING)
-    return STAT_NOOP;
-
   mp_buffer_t *bf = mp_queue_get_head();
-  if (!bf) return STAT_NOOP; // Nothing running
+  if (mp_get_state() == STATE_ESTOPPED || mp_get_state() == STATE_HOLDING ||
+      !bf) {
+    mp_runtime_set_velocity(0);
+    mp_runtime_set_busy(false);
+    return STAT_NOOP; // Nothing running
+  }
 
   if (bf->run_state == MOVE_NEW) {
     // On restart wait a bit to give planner queue a chance to fill
@@ -546,13 +548,10 @@ stat_t mp_exec_move() {
   if (status == STAT_EAGAIN || status == STAT_OK) mp_runtime_set_busy(true);
 
   if (status != STAT_EAGAIN) {
-    bool idle = false;
-
     // Enter HOLDING state
     if (mp_get_state() == STATE_STOPPING &&
         fp_ZERO(mp_runtime_get_velocity())) {
       mp_state_holding();
-      idle = true;
     }
 
     // Handle buffer run state
@@ -566,19 +565,10 @@ stat_t mp_exec_move() {
       mp_queue_pop(); // Release buffer
 
       // Enter READY state
-      if (mp_queue_is_empty()) {
-        mp_state_idle();
-        idle = true;
-      }
+      if (mp_queue_is_empty()) mp_state_idle();
 
       mp_set_cycle(CYCLE_MACHINING); // Default cycle
     }
-
-    // Queue idle
-    if (idle) {
-      mp_runtime_set_velocity(0);
-      mp_runtime_set_busy(false);
-    }
   }
 
   switch (status) {
index 66fafc6c0d470e8b31826115c29652618a5fd2a8..97e74197d3bd6d56210eab118d6c2d8d089fd962 100644 (file)
 typedef struct {
   mp_state_t state;
   mp_cycle_t cycle;
+  mp_hold_reason_t hold_reason;
 
   bool hold_requested;
   bool flush_requested;
   bool start_requested;
   bool resume_requested;
+  bool optional_pause_requested;
 } planner_state_t;
 
 
@@ -56,10 +58,6 @@ static planner_state_t ps = {
 };
 
 
-mp_state_t mp_get_state() {return ps.state;}
-mp_cycle_t mp_get_cycle() {return ps.cycle;}
-
-
 PGM_P mp_get_state_pgmstr(mp_state_t state) {
   switch (state) {
   case STATE_READY:     return PSTR("READY");
@@ -69,7 +67,7 @@ PGM_P mp_get_state_pgmstr(mp_state_t state) {
   case STATE_HOLDING:   return PSTR("HOLDING");
   }
 
-  return PSTR("invalid");
+  return PSTR("INVALID");
 }
 
 
@@ -82,10 +80,27 @@ PGM_P mp_get_cycle_pgmstr(mp_cycle_t cycle) {
   case CYCLE_JOGGING:     return PSTR("JOGGING");
   }
 
-  return PSTR("invalid");
+  return PSTR("INVALID");
+}
+
+
+PGM_P mp_get_hold_reason_pgmstr(mp_hold_reason_t reason) {
+  switch (reason) {
+  case HOLD_REASON_USER_PAUSE:    return PSTR("USER");
+  case HOLD_REASON_PROGRAM_PAUSE: return PSTR("PROGRAM");
+  case HOLD_REASON_PROGRAM_END:   return PSTR("END");
+  case HOLD_REASON_PALLET_CHANGE: return PSTR("PALLET");
+  case HOLD_REASON_TOOL_CHANGE:   return PSTR("TOOL");
+  }
+
+  return PSTR("INVALID");
 }
 
 
+mp_state_t mp_get_state() {return ps.state;}
+mp_cycle_t mp_get_cycle() {return ps.cycle;}
+
+
 static void _set_state(mp_state_t state) {
   if (ps.state == state) return; // No change
   if (ps.state == STATE_ESTOPPED) return; // Can't leave EStop state
@@ -117,6 +132,16 @@ void mp_set_cycle(mp_cycle_t cycle) {
 }
 
 
+mp_hold_reason_t mp_get_hold_reason() {return ps.hold_reason;}
+
+
+void mp_set_hold_reason(mp_hold_reason_t reason) {
+  if (ps.hold_reason == reason) return; // No change
+  ps.hold_reason = reason;
+  report_request();
+}
+
+
 bool mp_is_flushing() {return ps.flush_requested && !ps.resume_requested;}
 bool mp_is_resuming() {return ps.resume_requested;}
 
@@ -127,6 +152,14 @@ bool mp_is_quiescent() {
 }
 
 
+void mp_state_optional_pause() {
+  if (ps.optional_pause_requested) {
+    mp_set_hold_reason(HOLD_REASON_USER_PAUSE);
+    mp_state_holding();
+  }
+}
+
+
 void mp_state_holding() {_set_state(STATE_HOLDING);}
 
 
@@ -147,6 +180,7 @@ void mp_request_hold() {ps.hold_requested = true;}
 void mp_request_start() {ps.start_requested = true;}
 void mp_request_flush() {ps.flush_requested = true;}
 void mp_request_resume() {if (ps.flush_requested) ps.resume_requested = true;}
+void mp_request_optional_pause() {ps.optional_pause_requested = true;}
 
 
 /*** Feedholds, queue flushes and starts are all related.  Request functions
@@ -173,6 +207,7 @@ void mp_request_resume() {if (ps.flush_requested) ps.resume_requested = true;}
 void mp_state_callback() {
   if (ps.hold_requested || ps.flush_requested) {
     ps.hold_requested = false;
+    mp_set_hold_reason(HOLD_REASON_USER_PAUSE);
 
     if (mp_get_state() == STATE_RUNNING) _set_state(STATE_STOPPING);
   }
@@ -202,6 +237,7 @@ void mp_state_callback() {
   if (ps.start_requested && !ps.flush_requested &&
       mp_get_state() != STATE_STOPPING) {
     ps.start_requested = false;
+    ps.optional_pause_requested = false;
 
     if (mp_get_state() == STATE_HOLDING) {
       // Check if any moves are buffered
index 5708f1c5db67f80c3a4bd0f0649ac7bff45fb312..bc129d484e1f25848bd7a3991fdb73683f88620f 100644 (file)
@@ -52,18 +52,32 @@ typedef enum {
 } mp_cycle_t;
 
 
-mp_state_t mp_get_state();
-mp_cycle_t mp_get_cycle();
+typedef enum {
+  HOLD_REASON_USER_PAUSE,
+  HOLD_REASON_PROGRAM_PAUSE,
+  HOLD_REASON_PROGRAM_END,
+  HOLD_REASON_PALLET_CHANGE,
+  HOLD_REASON_TOOL_CHANGE,
+} mp_hold_reason_t;
 
-void mp_set_cycle(mp_cycle_t cycle);
 
 PGM_P mp_get_state_pgmstr(mp_state_t state);
 PGM_P mp_get_cycle_pgmstr(mp_cycle_t cycle);
+PGM_P mp_get_hold_reason_pgmstr(mp_hold_reason_t reason);
+
+mp_state_t mp_get_state();
+
+mp_cycle_t mp_get_cycle();
+void mp_set_cycle(mp_cycle_t cycle);
+
+mp_hold_reason_t mp_get_hold_reason();
+void mp_set_hold_reason(mp_hold_reason_t reason);
 
 bool mp_is_flushing();
 bool mp_is_resuming();
 bool mp_is_quiescent();
 
+void mp_state_optional_pause();
 void mp_state_holding();
 void mp_state_running();
 void mp_state_idle();
@@ -73,5 +87,6 @@ void mp_request_hold();
 void mp_request_start();
 void mp_request_flush();
 void mp_request_resume();
+void mp_request_optional_pause();
 
 void mp_state_callback();
index 89fb74a3e82581d66162dbe28e25b998d64d5bda..e7801d7f1ea73ee19ca133512632bffb1acce555 100644 (file)
@@ -135,56 +135,18 @@ void pwm_spindle_estop() {
 }
 
 
-// TODO implement these
-float get_max_spin(int index) {
-  return 0;
-}
-
-
-void set_max_spin(int axis, float value) {
-}
-
-
-float get_spin_min_pulse(int index) {
-  return 0;
-}
-
-
-void set_spin_min_pulse(int axis, float value) {
-}
-
-
-float get_spin_max_pulse(int index) {
-  return 0;
-}
-
-
-void set_spin_max_pulse(int axis, float value) {
-}
-
-
-uint8_t get_spin_polarity(int index) {
-  return 0;
-}
-
-
-void set_spin_polarity(int axis, uint8_t value) {
-}
-
-
-float get_spin_up(int index) {
-  return 0;
-}
-
-
-void set_spin_up(int axis, float value) {
-}
-
-
-float get_spin_down(int index) {
-  return 0;
-}
-
-
-void set_spin_down(int axis, float value) {
-}
+// TODO these need more effort and should work with the huanyang spindle too
+float get_max_spin(int index) {return spindle.max_rpm;}
+void set_max_spin(int axis, float value) {spindle.max_rpm = value;}
+float get_min_spin(int index) {return spindle.min_rpm;}
+void set_min_spin(int axis, float value) {spindle.min_rpm = value;}
+float get_spin_min_pulse(int index) {return spindle.min_duty;}
+void set_spin_min_pulse(int axis, float value) {spindle.min_duty = value;}
+float get_spin_max_pulse(int index) {return spindle.max_duty;}
+void set_spin_max_pulse(int axis, float value) {spindle.max_duty = value;}
+uint8_t get_spin_polarity(int index) {return spindle.reverse;}
+void set_spin_polarity(int axis, uint8_t value) {spindle.reverse = value;}
+float get_spin_up(int index) {return 0;}
+void set_spin_up(int axis, float value) {}
+float get_spin_down(int index) {return 0;}
+void set_spin_down(int axis, float value) {}
index 9ef970edafa56a07955bb3f3bfdaeb6398e969fc..8f425ada3d5f6358225ce2b708fb15ba623d5af6 100644 (file)
@@ -82,3 +82,8 @@ bool get_echo() {return usart_is_set(USART_ECHO);}
 void set_echo(bool value) {return usart_set(USART_ECHO, value);}
 PGM_P get_state() {return mp_get_state_pgmstr(mp_get_state());}
 PGM_P get_cycle() {return mp_get_cycle_pgmstr(mp_get_cycle());}
+
+
+PGM_P get_hold_reason() {
+  return mp_get_hold_reason_pgmstr(mp_get_hold_reason());
+}
index ce5053315bcca446d40b9b55ecb7ec8d5b26e317..d2633229d63967bf0c9856696f8f4e869a255740 100644 (file)
@@ -63,7 +63,8 @@ VAR(latch_backoff,  "lb", float,    AXES,   1, 1, "Homing latch backof")
 VAR(zero_backoff,   "zb", float,    AXES,   1, 1, "Homing zero backof")
 
 // Spindle
-VAR(max_spin,       "ss", float,    0,      1, 1, "Maximum spindle speed")
+VAR(max_spin,       "sx", float,    0,      1, 1, "Maximum spindle speed")
+VAR(min_spin,       "sm", float,    0,      1, 1, "Minimum spindle speed")
 VAR(spindle_type,   "st", uint8_t,  0,      1, 1, "PWM=0 or HUANYANG=1")
 VAR(spin_min_pulse, "np", float,    0,      1, 1, "Minimum pulse width")
 VAR(spin_max_pulse, "mp", float,    0,      1, 1, "Maximum pulse width")
@@ -113,5 +114,6 @@ VAR(hw_id,          "id", string,   0,      0, 0, "Hardware ID")
 VAR(echo,           "ec", bool,     0,      1, 0, "Enable or disable echo")
 VAR(estop,          "es", bool,     0,      1, 0, "Emergency stop")
 VAR(estop_reason,   "er", pstring,  0,      0, 0, "Emergency stop reason")
-VAR(state,          "x",  pstring,  0,      0, 0, "Machine state")
-VAR(cycle,          "c",  pstring,  0,      0, 0, "Machine cycle")
+VAR(state,           "x", pstring,  0,      0, 0, "Machine state")
+VAR(cycle,           "c", pstring,  0,      0, 0, "Machine cycle")
+VAR(hold_reason,    "pr", pstring,  0,      0, 0, "Machine pause reason")