/* limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon 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 void limits_init() { 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< 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. #ifdef COREXY int32_t off_axis_position = 0; #endif int32_t set_axis_position; // Set machine positions for homed limit switches. Don't update non-homed axes. for (idx=0; idx -settings.max_travel[idx]) { sys.soft_limit = true; } } else { if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { sys.soft_limit = true; } } #else // NOTE: max_travel is stored as negative if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { sys.soft_limit = true; } #endif if (sys.soft_limit) { // Force feed hold if cycle is active. All buffered blocks are guaranteed to be within // workspace volume so just come to a controlled stop so position is not lost. When complete // enter alarm mode. if (sys.state == STATE_CYCLE) { system_set_exec_state_flag(EXEC_FEED_HOLD); do { protocol_execute_realtime(); if (sys.abort) { return; } } while ( sys.state != STATE_IDLE ); } mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. system_set_exec_alarm_flag((EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event protocol_execute_realtime(); // Execute to enter critical event loop and system abort return; } } }