Example #1
0
void coolant_init()
{
  COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT);
  #ifdef ENABLE_M7
    COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT);
  #endif
  coolant_stop();
}
void coolant_init()
{
  current_coolant_mode = COOLANT_DISABLE;
  #ifdef ENABLE_M7
    COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT);
  #endif
  COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT);
  coolant_stop();
}
Example #3
0
void coolant_init(void) {
  current_coolant_mode = COOLANT_OFF;
  #ifdef CSPRAY_ENABLE
    host_gpio_direction(CSPRAY_ENABLE, HOST_GPIO_DIRECTION_OUTPUT, HOST_GPIO_MODE_BIT);
  #endif
  #ifdef CFLOOD_ENABLE
    host_gpio_direction(CFLOOD_ENABLE, HOST_GPIO_DIRECTION_OUTPUT, HOST_GPIO_MODE_BIT);
  #endif
  coolant_stop();
}
Example #4
0
void coolant_set_state(uint8_t mode)
{
  if (mode == COOLANT_FLOOD_ENABLE) {
    COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);

  #ifdef ENABLE_M7  
    } else if (mode == COOLANT_MIST_ENABLE) {
      COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
  #endif

  } else {
    coolant_stop();
  }
}
Example #5
0
void coolant_run(uint8_t mode)
{
    protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program.
    if (mode == COOLANT_FLOOD_ENABLE) {
        COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);

#ifdef ENABLE_M7
    } else if (mode == COOLANT_MIST_ENABLE) {
        COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
#endif

    } else {
        coolant_stop();
    }
}
Example #6
0
void coolant_run(uint8_t mode) {
  /* If we need to change state, we must wait for all moves to complete before
   * doing so. */
  if(mode != current_coolant_mode) {
    plan_synchronize();
    if(mode != COOLANT_OFF) {
      #ifdef CSPRAY_ENABLE
        if(mode & COOLANT_MIST)
          host_gpio_write(CSPRAY_ENABLE, true, HOST_GPIO_MODE_BIT);
      #endif
      #ifdef CFLOOD_ENABLE
        if(mode & COOLANT_FLOOD)
          host_gpio_write(CFLOOD_ENABLE, true, HOST_GPIO_MODE_BIT);
      #endif
    } else coolant_stop();
    current_coolant_mode = mode;
  }
}
Example #7
0
void coolant_run(uint8_t mode)
{
#if 0
  if (mode != current_coolant_mode)
  { 
    plan_synchronize(); // Ensure coolant turns on when specified in program.
    if (mode == COOLANT_FLOOD_ENABLE) { 
      COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
    #ifdef ENABLE_M7  
      } else if (mode == COOLANT_MIST_ENABLE) {
          COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
    #endif
    } else {
      coolant_stop();
    }
    current_coolant_mode = mode;
  }
#endif
}
// Method to ready the system to reset by setting the runtime reset command and killing any
// active processes in the system. This also checks if a system reset is issued while Grbl
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
// runtime abort command and hard limits. So, keep to a minimum.
void mc_reset()
{
  // Only this function can set the system reset. Helps prevent multiple kill calls.
  if (bit_isfalse(sys.execute, EXEC_RESET)) {
    bit_true_atomic(sys.execute, EXEC_RESET);

    // Kill spindle and coolant.
    spindle_stop();
    coolant_stop();

    // Kill steppers only if in any motion state, i.e. cycle, feed hold, homing, or jogging
    // NOTE: If steppers are kept enabled via the step idle delay setting, this also keeps
    // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is
    // violated, by which, all bets are off.
    if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_HOMING)) {
      bit_true_atomic(sys.execute, EXEC_ALARM); // Flag main program to execute alarm state.
      st_go_idle(); // Force kill steppers. Position has likely been lost.
    }
  }
}
// Method to ready the system to reset by setting the runtime reset command and killing any
// active processes in the system. This also checks if a system reset is issued while Grbl
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
// runtime abort command and hard limits. So, keep to a minimum.
void mc_reset()
{
  // Only this function can set the system reset. Helps prevent multiple kill calls.
  if (bit_isfalse(sys.execute, EXEC_RESET)) {
    sys.execute |= EXEC_RESET;

    // Kill spindle and coolant.   
    spindle_stop();
    coolant_stop();

    // Kill steppers only if in any motion state, i.e. cycle, feed hold, homing, or jogging
    // NOTE: If steppers are kept enabled via the step idle delay setting, this also keeps
    // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is
    // violated, by which, all bets are off.
    switch (sys.state) {
      case STATE_CYCLE: case STATE_HOLD: case STATE_HOMING: // case STATE_JOG:
        sys.execute |= EXEC_ALARM; // Execute alarm state.
        st_go_idle(); // Execute alarm force kills steppers. Position likely lost.
    }
  }
}
Example #10
0
// Method to ready the system to reset by setting the realtime reset command and killing any
// active processes in the system. This also checks if a system reset is issued while Grbl
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
// realtime abort command and hard limits. So, keep to a minimum.
void mc_reset()
{
  // Only this function can set the system reset. Helps prevent multiple kill calls.
  if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) {
    bit_true_atomic(sys_rt_exec_state, EXEC_RESET);

    // Kill spindle and coolant.   
    spindle_stop();
    coolant_stop();

    // Kill steppers only if in any motion state, i.e. cycle, actively holding, or homing.
    // NOTE: If steppers are kept enabled via the step idle delay setting, this also keeps
    // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is
    // violated, by which, all bets are off.
    if ((sys.state & (STATE_CYCLE | STATE_HOMING)) || (sys.suspend == SUSPEND_ENABLE_HOLD)) {
      if (sys.state == STATE_HOMING) { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_HOMING_FAIL); }
      else { bit_true_atomic(sys_rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); }
      st_go_idle(); // Force kill steppers. Position has likely been lost.
    }
  }
}
Example #11
0
// Method to ready the system to reset by setting the realtime reset command and killing any
// active processes in the system. This also checks if a system reset is issued while Grbl
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
// lost, since there was an abrupt uncontrolled deceleration. Called at an interrupt level by
// realtime abort command and hard limits. So, keep to a minimum.
void mc_reset()
{
  // Only this function can set the system reset. Helps prevent multiple kill calls.
  if (bit_isfalse(sys_rt_exec_state, EXEC_RESET)) {
    system_set_exec_state_flag(EXEC_RESET);

    // Kill spindle and coolant.
    spindle_stop();
    coolant_stop();

    // Kill steppers only if in any motion state, i.e. cycle, actively holding, or homing.
    // NOTE: If steppers are kept enabled via the step idle delay setting, this also keeps
    // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is
    // violated, by which, all bets are off.
    if ((sys.state & (STATE_CYCLE | STATE_HOMING | STATE_JOG)) ||
    		(sys.step_control & (STEP_CONTROL_EXECUTE_HOLD | STEP_CONTROL_EXECUTE_SYS_MOTION))) {
      if (sys.state == STATE_HOMING) { 
        if (!sys_rt_exec_alarm) {system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_RESET); }
      } else { system_set_exec_alarm(EXEC_ALARM_ABORT_CYCLE); }
      st_go_idle(); // Force kill steppers. Position has likely been lost.
    }
  }
}
Example #12
0
// A helper method to set settings from command line
void settings_store_setting(int parameter, double value) {
  switch(parameter) {
	case 0: case 1: case 2:   // X, Y, Z
        if (value <= 0.0) {
          printPgmString(PSTR("Steps/mm must be > 0.0\r\n"));
          return;
        }
        settings.steps_per_mm[parameter] = value;
        break;
    case 3 :   // axe T : linear -> U or V or W,  rotary -> A or B or C
		if (value <= 0.0) {
	#if AXIS_T_TYPE == LINEAR
			printPgmString(PSTR("Steps/mm must be > 0.0\r\n"));
    #else
			printPgmString(PSTR("Steps/degree must be > 0.0\r\n"));
    #endif
          return;
        }
    #if AXIS_T_TYPE == LINEAR
        settings.steps_per_mm[parameter] = value;
    #else
		settings.steps_per_degree[parameter] = value;
    #endif

		break;
    case 4:
        if (value < 3) {
            printPgmString(PSTR("Step pulse must be >= 3 microseconds\r\n"));
            return;
        }
        settings.pulse_microseconds = round(value);
        break;
    case 5:
        settings.default_feed_rate = value;
        break;
    case 6:
        settings.default_seek_rate = value;
        break;
    case 7:
        settings.mm_per_arc_segment = value;
        break;
    case 8:
        settings.invert_mask_stepdir = trunc(value);
        break;
    case 9:
        settings.invert_mask_limit = trunc(value);
        break;
    case 10:
        settings.acceleration = value*60*60;
        break; // Convert to mm/min^2 for grbl internal use.
    case 11:
        settings.junction_deviation = fabs(value);
        break;
    case 12:
        settings.spindle_pwm = value;
        break;
    case 13:
        settings.default_spindle = value;
        break;
    case 14:
        settings.max_spindle = value;
        break;
    case 1000:
    	value ? st_enable(): st_disable();
    	if (!value) {
    		coolant_stop();
    		spindle_stop();
    	}
    	return;
        break;
    default:
      printPgmString(PSTR("Unknown parameter\r\n"));
      return;
  }
  write_settings();
  printPgmString(PSTR("Stored new setting\r\n"));
}
Example #13
0
// Executes run-time commands, when required. This is called from various check points in the main
// program, primarily where there may be a while loop waiting for a buffer to clear space or any
// point where the execution time from the last check point may be more than a fraction of a second.
// This is a way to execute realtime commands asynchronously (aka multitasking) with grbl's g-code
// parsing and planning functions. This function also serves as an interface for the interrupts to 
// set the system realtime flags, where only the main program handles them, removing the need to
// define more computationally-expensive volatile variables. This also provides a controlled way to 
// execute certain tasks without having two or more instances of the same task, such as the planner
// recalculating the buffer upon a feedhold or override.
// NOTE: The sys_rt_exec_state variable flags are set by any process, step or serial interrupts, pinouts,
// limit switches, or the main program.
void protocol_execute_realtime()
{
  uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times.

  do { // If system is suspended, suspend loop restarts here.
    
  // Check and execute alarms. 
  rt_exec = sys_rt_exec_alarm; // Copy volatile sys_rt_exec_alarm.
  if (rt_exec) { // Enter only if any bit flag is true
    // System alarm. Everything has shutdown by something that has gone severely wrong. Report
    // the source of the error to the user. If critical, Grbl disables by entering an infinite
    // loop until system reset/abort.
    sys.state = STATE_ALARM; // Set system alarm state
    if (rt_exec & EXEC_ALARM_HARD_LIMIT) {
      report_alarm_message(ALARM_HARD_LIMIT_ERROR); 
    } else if (rt_exec & EXEC_ALARM_SOFT_LIMIT) {
      report_alarm_message(ALARM_SOFT_LIMIT_ERROR);
    } else if (rt_exec & EXEC_ALARM_ABORT_CYCLE) {      
      report_alarm_message(ALARM_ABORT_CYCLE);
    } else if (rt_exec & EXEC_ALARM_PROBE_FAIL) {
      report_alarm_message(ALARM_PROBE_FAIL);
    } else if (rt_exec & EXEC_ALARM_HOMING_FAIL) {
      report_alarm_message(ALARM_HOMING_FAIL);
    }
    // Halt everything upon a critical event flag. Currently hard and soft limits flag this.
    if (rt_exec & EXEC_CRITICAL_EVENT) {
      report_feedback_message(MESSAGE_CRITICAL_EVENT);
      bit_false_atomic(sys_rt_exec_state,EXEC_RESET); // Disable any existing reset
      do { 
        // Nothing. Block EVERYTHING until user issues reset or power cycles. Hard limits
        // typically occur while unattended or not paying attention. Gives the user time
        // to do what is needed before resetting, like killing the incoming stream. The 
        // same could be said about soft limits. While the position is not lost, the incoming
        // stream could be still engaged and cause a serious crash if it continues afterwards.
        
        // TODO: Allow status reports during a critical alarm. Still need to think about implications of this.
//         if (sys_rt_exec_state & EXEC_STATUS_REPORT) { 
//           report_realtime_status();
//           bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT); 
//         }
      } while (bit_isfalse(sys_rt_exec_state,EXEC_RESET));
    }
    bit_false_atomic(sys_rt_exec_alarm,0xFF); // Clear all alarm flags
  }
  
  // Check amd execute realtime commands
  rt_exec = sys_rt_exec_state; // Copy volatile sys_rt_exec_state.
  if (rt_exec) { // Enter only if any bit flag is true
  
    // Execute system abort. 
    if (rt_exec & EXEC_RESET) {
      sys.abort = true;  // Only place this is set true.
      return; // Nothing else to do but exit.
    }
    
    // Execute and serial print status
    if (rt_exec & EXEC_STATUS_REPORT) { 
      report_realtime_status();
      bit_false_atomic(sys_rt_exec_state,EXEC_STATUS_REPORT);
    }
  
    // Execute hold states.
    // NOTE: The math involved to calculate the hold should be low enough for most, if not all, 
    // operational scenarios. Once hold is initiated, the system enters a suspend state to block
    // all main program processes until either reset or resumed.
    if (rt_exec & (EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR)) {
      
      // TODO: CHECK MODE? How to handle this? Likely nothing, since it only works when IDLE and then resets Grbl.
                
      // State check for allowable states for hold methods.
      if ((sys.state == STATE_IDLE) || (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_MOTION_CANCEL | STATE_HOLD | STATE_SAFETY_DOOR))) {

        // If in CYCLE state, all hold states immediately initiate a motion HOLD.
        if (sys.state == STATE_CYCLE) {
          st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.
          sys.suspend = SUSPEND_ENABLE_HOLD; // Initiate holding cycle with flag.
        }
        // If IDLE, Grbl is not in motion. Simply indicate suspend ready state.
        if (sys.state == STATE_IDLE) { sys.suspend = SUSPEND_ENABLE_READY; }
        
        // Execute and flag a motion cancel with deceleration and return to idle. Used primarily by probing cycle
        // to halt and cancel the remainder of the motion.
        if (rt_exec & EXEC_MOTION_CANCEL) {
          // MOTION_CANCEL only occurs during a CYCLE, but a HOLD and SAFETY_DOOR may been initiated beforehand
          // to hold the CYCLE. If so, only flag that motion cancel is complete.
          if (sys.state == STATE_CYCLE) { sys.state = STATE_MOTION_CANCEL; }
          sys.suspend |= SUSPEND_MOTION_CANCEL; // Indicate motion cancel when resuming. Special motion complete.
        }
    
        // Execute a feed hold with deceleration, only during cycle.
        if (rt_exec & EXEC_FEED_HOLD) {
          // Block SAFETY_DOOR state from prematurely changing back to HOLD.
          if (bit_isfalse(sys.state,STATE_SAFETY_DOOR)) { sys.state = STATE_HOLD; }
        }
  
        // Execute a safety door stop with a feed hold, only during a cycle, and disable spindle/coolant.
        // NOTE: Safety door differs from feed holds by stopping everything no matter state, disables powered
        // devices (spindle/coolant), and blocks resuming until switch is re-engaged. The power-down is 
        // executed here, if IDLE, or when the CYCLE completes via the EXEC_CYCLE_STOP flag.
        if (rt_exec & EXEC_SAFETY_DOOR) {
          report_feedback_message(MESSAGE_SAFETY_DOOR_AJAR); 
          // If already in active, ready-to-resume HOLD, set CYCLE_STOP flag to force de-energize.
          // NOTE: Only temporarily sets the 'rt_exec' variable, not the volatile 'rt_exec_state' variable.
          if (sys.suspend & SUSPEND_ENABLE_READY) { bit_true(rt_exec,EXEC_CYCLE_STOP); }
          sys.suspend |= SUSPEND_ENERGIZE;
          sys.state = STATE_SAFETY_DOOR;
        }
         
      }
      bit_false_atomic(sys_rt_exec_state,(EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR));      
    }
          
    // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue.
    if (rt_exec & EXEC_CYCLE_START) {
      // Block if called at same time as the hold commands: feed hold, motion cancel, and safety door.
      // Ensures auto-cycle-start doesn't resume a hold without an explicit user-input.
      if (!(rt_exec & (EXEC_FEED_HOLD | EXEC_MOTION_CANCEL | EXEC_SAFETY_DOOR))) { 
        // Cycle start only when IDLE or when a hold is complete and ready to resume.
        // NOTE: SAFETY_DOOR is implicitly blocked. It reverts to HOLD when the door is closed.
        if ((sys.state == STATE_IDLE) || ((sys.state & (STATE_HOLD | STATE_MOTION_CANCEL)) && (sys.suspend & SUSPEND_ENABLE_READY))) {
          // Re-energize powered components, if disabled by SAFETY_DOOR.
          if (sys.suspend & SUSPEND_ENERGIZE) { 
            // Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle.
            if (gc_state.modal.spindle != SPINDLE_DISABLE) { 
              spindle_set_state(gc_state.modal.spindle, gc_state.spindle_speed); 
              delay_ms(SAFETY_DOOR_SPINDLE_DELAY); // TODO: Blocking function call. Need a non-blocking one eventually.
            }
            if (gc_state.modal.coolant != COOLANT_DISABLE) { 
              coolant_set_state(gc_state.modal.coolant); 
              delay_ms(SAFETY_DOOR_COOLANT_DELAY); // TODO: Blocking function call. Need a non-blocking one eventually.
            }
            // TODO: Install return to pre-park position.
          }
          // Start cycle only if queued motions exist in planner buffer and the motion is not canceled.
          if (plan_get_current_block() && bit_isfalse(sys.suspend,SUSPEND_MOTION_CANCEL)) {
            sys.state = STATE_CYCLE;
            st_prep_buffer(); // Initialize step segment buffer before beginning cycle.
            st_wake_up();
          } else { // Otherwise, do nothing. Set and resume IDLE state.
            sys.state = STATE_IDLE;
          }
          sys.suspend = SUSPEND_DISABLE; // Break suspend state.
        }
      }    
      bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_START);
    }
    
    // Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by 
    // realtime command execution in the main program, ensuring that the planner re-plans safely.
    // NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper
    // cycle reinitializations. The stepper path should continue exactly as if nothing has happened.   
    // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.
    if (rt_exec & EXEC_CYCLE_STOP) {
      if (sys.state & (STATE_HOLD | STATE_SAFETY_DOOR)) {
        // Hold complete. Set to indicate ready to resume.  Remain in HOLD or DOOR states until user
        // has issued a resume command or reset.
        if (sys.suspend & SUSPEND_ENERGIZE) { // De-energize system if safety door has been opened.
          spindle_stop();
          coolant_stop();
          // TODO: Install parking motion here.
        }
        bit_true(sys.suspend,SUSPEND_ENABLE_READY);
      } else { // Motion is complete. Includes CYCLE, HOMING, and MOTION_CANCEL states.
        sys.suspend = SUSPEND_DISABLE;
        sys.state = STATE_IDLE;
      }
      bit_false_atomic(sys_rt_exec_state,EXEC_CYCLE_STOP);
    }
    
  }

  // Overrides flag byte (sys.override) and execution should be installed here, since they 
  // are realtime and require a direct and controlled interface to the main stepper program.

  // Reload step segment buffer
  if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_MOTION_CANCEL | STATE_SAFETY_DOOR | STATE_HOMING)) { st_prep_buffer(); }  
  
  // If safety door was opened, actively check when safety door is closed and ready to resume.
  // NOTE: This unlocks the SAFETY_DOOR state to a HOLD state, such that CYCLE_START can activate a resume.
  if (sys.state == STATE_SAFETY_DOOR) { 
    if (bit_istrue(sys.suspend,SUSPEND_ENABLE_READY)) { 
      #ifndef DEFAULTS_TRINAMIC
      if (!(system_check_safety_door_ajar())) {
        sys.state = STATE_HOLD; // Update to HOLD state to indicate door is closed and ready to resume.
      }
      #endif
    }
  }

  } while(sys.suspend); // Check for system suspend state before exiting.
  
}