/* limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl Copyright (c) 2012-2014 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 #include #include #include #include "stepper.h" #include "settings.h" #include "nuts_bolts.h" #include "config.h" #include "spindle_control.h" #include "motion_control.h" #include "planner.h" #include "protocol.h" #include "limits.h" #include "report.h" void limits_init() { LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { LIMIT_PORT &= ~(LIMIT_MASK); // Normal low operation. Requires external pull-down. } else { LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation. } 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< settings.max_travel[Y_AXIS]) { max_travel = settings.max_travel[Y_AXIS]; } if (max_travel > settings.max_travel[Z_AXIS]) { max_travel = settings.max_travel[Z_AXIS]; } max_travel *= -1.25; // Ensure homing switches engaged by over-estimating max travel. if (!approach) { max_travel = -max_travel; } // Set target location and rate for active axes. float target[N_AXIS]; uint8_t n_active_axis = 0; uint8_t i; for (i=0; i 0 || target[idx] < settings.max_travel[idx]) { // NOTE: max_travel is stored as negative // 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) { st_feed_hold(); while (sys.state == STATE_HOLD) { protocol_execute_runtime(); if (sys.abort) { return; } } } mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. sys.execute |= EXEC_CRIT_EVENT; // Indicate soft limit critical event protocol_execute_runtime(); // Execute to enter critical event loop and system abort return; } } }