/* limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Grbl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ #include "grbl.h" // Homing axis search distance multiplier. Computed by this value times the cycle travel. #ifndef HOMING_AXIS_SEARCH_SCALAR #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. #endif #ifndef HOMING_AXIS_LOCATE_SCALAR #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. #endif #ifdef ENABLE_DUAL_AXIS // Flags for dual axis async limit trigger check. #define DUAL_AXIS_CHECK_DISABLE 0 // Must be zero #define DUAL_AXIS_CHECK_ENABLE bit(0) #define DUAL_AXIS_CHECK_TRIGGER_1 bit(1) #define DUAL_AXIS_CHECK_TRIGGER_2 bit(2) #endif void limits_init() { printf("%s:%s:%d Not supported yet..\n",__FILE__,__FUNCTION__,__LINE__); //LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins // //#ifdef DISABLE_LIMIT_PIN_PULL_UP // LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down. //#else // LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation. //#endif // //if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) { // LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt // PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt //} else { // limits_disable(); //} // //#ifdef ENABLE_SOFTWARE_DEBOUNCE // MCUSR &= ~(1<condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); // #ifdef USE_LINE_NUMBERS // pl_data->line_number = HOMING_CYCLE_LINE_NUMBER; // #endif // // // Initialize variables used for homing computations. // uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); // uint8_t step_pin[N_AXIS]; // #ifdef ENABLE_DUAL_AXIS // uint8_t step_pin_dual; // uint8_t dual_axis_async_check; // int32_t dual_trigger_position; // #if (DUAL_AXIS_SELECT == X_AXIS) // float fail_distance = (-DUAL_AXIS_HOMING_FAIL_AXIS_LENGTH_PERCENT/100.0)*settings.max_travel[Y_AXIS]; // #else // float fail_distance = (-DUAL_AXIS_HOMING_FAIL_AXIS_LENGTH_PERCENT/100.0)*settings.max_travel[X_AXIS]; // #endif // fail_distance = min_grbl(fail_distance, DUAL_AXIS_HOMING_FAIL_DISTANCE_MAX); // fail_distance = max_grbl(fail_distance, DUAL_AXIS_HOMING_FAIL_DISTANCE_MIN); // int32_t dual_fail_distance = trunc(fail_distance*settings.steps_per_mm[DUAL_AXIS_SELECT]); // // int32_t dual_fail_distance = trunc((DUAL_AXIS_HOMING_TRIGGER_FAIL_DISTANCE)*settings.steps_per_mm[DUAL_AXIS_SELECT]); // #endif // float target[N_AXIS]; // float max_travel = 0.0; // uint8_t idx; // for (idx=0; idxfeed_rate = homing_rate; // Set current homing rate. // plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion. // // sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags. // st_prep_buffer(); // Prep and fill segment buffer from newly planned block. // st_wake_up(); // Initiate motion // do { // if (approach) { // // Check limit state. Lock out cycle axes when they change. // limit_state = limits_get_state(); // for (idx=0; idx dual_fail_distance) { // system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_DUAL_APPROACH); // mc_reset(); // protocol_execute_realtime(); // return; // } // } // } else { // dual_axis_async_check |= DUAL_AXIS_CHECK_ENABLE; // dual_trigger_position = sys_position[DUAL_AXIS_SELECT]; // } // } // #endif // } // // st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // // // Exit routines: No time to run protocol_execute_realtime() in this loop. // if (sys_rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { // uint8_t rt_exec = sys_rt_exec_state; // // Homing failure condition: Reset issued during cycle. // if (rt_exec & EXEC_RESET) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_RESET); } // // Homing failure condition: Safety door was opened. // if (rt_exec & EXEC_SAFETY_DOOR) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_DOOR); } // // Homing failure condition: Limit switch still engaged after pull-off motion // if (!approach && (limits_get_state() & cycle_mask)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_PULLOFF); } // // Homing failure condition: Limit switch not found during approach. // if (approach && (rt_exec & EXEC_CYCLE_STOP)) { system_set_exec_alarm(EXEC_ALARM_HOMING_FAIL_APPROACH); } // if (sys_rt_exec_alarm) { // mc_reset(); // Stop motors, if they are running. // protocol_execute_realtime(); // return; // } else { // // Pull-off motion complete. Disable CYCLE_STOP from executing. // system_clear_exec_state_flag(EXEC_CYCLE_STOP); // break; // } // } // // #ifdef ENABLE_DUAL_AXIS // } while ((STEP_MASK & axislock) || (sys.homing_axis_lock_dual)); // #else // } while (STEP_MASK & axislock); // #endif // // st_reset(); // Immediately force kill steppers and reset step segment buffer. // delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. // // // Reverse direction and reset homing rate for locate cycle(s). // approach = !approach; // // // After first cycle, homing enters locating phase. Shorten search to pull-off distance. // if (approach) { // max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR; // homing_rate = settings.homing_feed_rate; // } else { // max_travel = settings.homing_pulloff; // homing_rate = settings.homing_seek_rate; // } // // } while (n_cycle-- > 0); // // // The active cycle axes should now be homed and machine limits have been located. By // // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // // can be on either side of an axes, check and set axes machine zero appropriately. Also, // // set up pull-off maneuver from axes limit switches that have been homed. This provides // // some initial clearance off the switches and should also help prevent them from falsely // // triggering when hard limits are enabled or when more than one axes shares a limit pin. // int32_t set_axis_position; // // Set machine positions for homed limit switches. Don't update non-homed axes. // for (idx=0; idx