My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

endstops.cpp 30KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * endstops.cpp - A singleton object to manage endstops
  24. */
  25. #include "endstops.h"
  26. #include "stepper.h"
  27. #include "../sd/cardreader.h"
  28. #include "temperature.h"
  29. #include "../lcd/marlinui.h"
  30. #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
  31. #include HAL_PATH(../HAL, endstop_interrupts.h)
  32. #endif
  33. #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
  34. #include "printcounter.h" // for print_job_timer
  35. #endif
  36. #if ENABLED(BLTOUCH)
  37. #include "../feature/bltouch.h"
  38. #endif
  39. #if ENABLED(JOYSTICK)
  40. #include "../feature/joystick.h"
  41. #endif
  42. #if HAS_BED_PROBE
  43. #include "probe.h"
  44. #endif
  45. Endstops endstops;
  46. // private:
  47. bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load()
  48. volatile Endstops::endstop_mask_t Endstops::hit_state;
  49. Endstops::endstop_mask_t Endstops::live_state = 0;
  50. #if ENDSTOP_NOISE_THRESHOLD
  51. Endstops::endstop_mask_t Endstops::validated_live_state;
  52. uint8_t Endstops::endstop_poll_count;
  53. #endif
  54. #if HAS_BED_PROBE
  55. volatile bool Endstops::z_probe_enabled = false;
  56. #endif
  57. // Initialized by settings.load()
  58. #if ENABLED(X_DUAL_ENDSTOPS)
  59. float Endstops::x2_endstop_adj;
  60. #endif
  61. #if ENABLED(Y_DUAL_ENDSTOPS)
  62. float Endstops::y2_endstop_adj;
  63. #endif
  64. #if ENABLED(Z_MULTI_ENDSTOPS)
  65. float Endstops::z2_endstop_adj;
  66. #if NUM_Z_STEPPER_DRIVERS >= 3
  67. float Endstops::z3_endstop_adj;
  68. #if NUM_Z_STEPPER_DRIVERS >= 4
  69. float Endstops::z4_endstop_adj;
  70. #endif
  71. #endif
  72. #endif
  73. #if ENABLED(SPI_ENDSTOPS)
  74. Endstops::tmc_spi_homing_t Endstops::tmc_spi_homing; // = 0
  75. #endif
  76. #if ENABLED(IMPROVE_HOMING_RELIABILITY)
  77. millis_t sg_guard_period; // = 0
  78. #endif
  79. /**
  80. * Class and Instance Methods
  81. */
  82. void Endstops::init() {
  83. #if HAS_X_MIN
  84. #if ENABLED(ENDSTOPPULLUP_XMIN)
  85. SET_INPUT_PULLUP(X_MIN_PIN);
  86. #elif ENABLED(ENDSTOPPULLDOWN_XMIN)
  87. SET_INPUT_PULLDOWN(X_MIN_PIN);
  88. #else
  89. SET_INPUT(X_MIN_PIN);
  90. #endif
  91. #endif
  92. #if HAS_X2_MIN
  93. #if ENABLED(ENDSTOPPULLUP_XMIN)
  94. SET_INPUT_PULLUP(X2_MIN_PIN);
  95. #elif ENABLED(ENDSTOPPULLDOWN_XMIN)
  96. SET_INPUT_PULLDOWN(X2_MIN_PIN);
  97. #else
  98. SET_INPUT(X2_MIN_PIN);
  99. #endif
  100. #endif
  101. #if HAS_Y_MIN
  102. #if ENABLED(ENDSTOPPULLUP_YMIN)
  103. SET_INPUT_PULLUP(Y_MIN_PIN);
  104. #elif ENABLED(ENDSTOPPULLDOWN_YMIN)
  105. SET_INPUT_PULLDOWN(Y_MIN_PIN);
  106. #else
  107. SET_INPUT(Y_MIN_PIN);
  108. #endif
  109. #endif
  110. #if HAS_Y2_MIN
  111. #if ENABLED(ENDSTOPPULLUP_YMIN)
  112. SET_INPUT_PULLUP(Y2_MIN_PIN);
  113. #elif ENABLED(ENDSTOPPULLDOWN_YMIN)
  114. SET_INPUT_PULLDOWN(Y2_MIN_PIN);
  115. #else
  116. SET_INPUT(Y2_MIN_PIN);
  117. #endif
  118. #endif
  119. #if HAS_Z_MIN
  120. #if ENABLED(ENDSTOPPULLUP_ZMIN)
  121. SET_INPUT_PULLUP(Z_MIN_PIN);
  122. #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
  123. SET_INPUT_PULLDOWN(Z_MIN_PIN);
  124. #else
  125. SET_INPUT(Z_MIN_PIN);
  126. #endif
  127. #endif
  128. #if HAS_Z2_MIN
  129. #if ENABLED(ENDSTOPPULLUP_ZMIN)
  130. SET_INPUT_PULLUP(Z2_MIN_PIN);
  131. #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
  132. SET_INPUT_PULLDOWN(Z2_MIN_PIN);
  133. #else
  134. SET_INPUT(Z2_MIN_PIN);
  135. #endif
  136. #endif
  137. #if HAS_Z3_MIN
  138. #if ENABLED(ENDSTOPPULLUP_ZMIN)
  139. SET_INPUT_PULLUP(Z3_MIN_PIN);
  140. #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
  141. SET_INPUT_PULLDOWN(Z3_MIN_PIN);
  142. #else
  143. SET_INPUT(Z3_MIN_PIN);
  144. #endif
  145. #endif
  146. #if HAS_Z4_MIN
  147. #if ENABLED(ENDSTOPPULLUP_ZMIN)
  148. SET_INPUT_PULLUP(Z4_MIN_PIN);
  149. #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
  150. SET_INPUT_PULLDOWN(Z4_MIN_PIN);
  151. #else
  152. SET_INPUT(Z4_MIN_PIN);
  153. #endif
  154. #endif
  155. #if HAS_X_MAX
  156. #if ENABLED(ENDSTOPPULLUP_XMAX)
  157. SET_INPUT_PULLUP(X_MAX_PIN);
  158. #elif ENABLED(ENDSTOPPULLDOWN_XMAX)
  159. SET_INPUT_PULLDOWN(X_MAX_PIN);
  160. #else
  161. SET_INPUT(X_MAX_PIN);
  162. #endif
  163. #endif
  164. #if HAS_X2_MAX
  165. #if ENABLED(ENDSTOPPULLUP_XMAX)
  166. SET_INPUT_PULLUP(X2_MAX_PIN);
  167. #elif ENABLED(ENDSTOPPULLDOWN_XMAX)
  168. SET_INPUT_PULLDOWN(X2_MAX_PIN);
  169. #else
  170. SET_INPUT(X2_MAX_PIN);
  171. #endif
  172. #endif
  173. #if HAS_Y_MAX
  174. #if ENABLED(ENDSTOPPULLUP_YMAX)
  175. SET_INPUT_PULLUP(Y_MAX_PIN);
  176. #elif ENABLED(ENDSTOPPULLDOWN_YMAX)
  177. SET_INPUT_PULLDOWN(Y_MAX_PIN);
  178. #else
  179. SET_INPUT(Y_MAX_PIN);
  180. #endif
  181. #endif
  182. #if HAS_Y2_MAX
  183. #if ENABLED(ENDSTOPPULLUP_YMAX)
  184. SET_INPUT_PULLUP(Y2_MAX_PIN);
  185. #elif ENABLED(ENDSTOPPULLDOWN_YMAX)
  186. SET_INPUT_PULLDOWN(Y2_MAX_PIN);
  187. #else
  188. SET_INPUT(Y2_MAX_PIN);
  189. #endif
  190. #endif
  191. #if HAS_Z_MAX
  192. #if ENABLED(ENDSTOPPULLUP_ZMAX)
  193. SET_INPUT_PULLUP(Z_MAX_PIN);
  194. #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
  195. SET_INPUT_PULLDOWN(Z_MAX_PIN);
  196. #else
  197. SET_INPUT(Z_MAX_PIN);
  198. #endif
  199. #endif
  200. #if HAS_Z2_MAX
  201. #if ENABLED(ENDSTOPPULLUP_ZMAX)
  202. SET_INPUT_PULLUP(Z2_MAX_PIN);
  203. #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
  204. SET_INPUT_PULLDOWN(Z2_MAX_PIN);
  205. #else
  206. SET_INPUT(Z2_MAX_PIN);
  207. #endif
  208. #endif
  209. #if HAS_Z3_MAX
  210. #if ENABLED(ENDSTOPPULLUP_ZMAX)
  211. SET_INPUT_PULLUP(Z3_MAX_PIN);
  212. #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
  213. SET_INPUT_PULLDOWN(Z3_MAX_PIN);
  214. #else
  215. SET_INPUT(Z3_MAX_PIN);
  216. #endif
  217. #endif
  218. #if HAS_Z4_MAX
  219. #if ENABLED(ENDSTOPPULLUP_ZMAX)
  220. SET_INPUT_PULLUP(Z4_MAX_PIN);
  221. #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
  222. SET_INPUT_PULLDOWN(Z4_MAX_PIN);
  223. #else
  224. SET_INPUT(Z4_MAX_PIN);
  225. #endif
  226. #endif
  227. #if PIN_EXISTS(CALIBRATION)
  228. #if ENABLED(CALIBRATION_PIN_PULLUP)
  229. SET_INPUT_PULLUP(CALIBRATION_PIN);
  230. #elif ENABLED(CALIBRATION_PIN_PULLDOWN)
  231. SET_INPUT_PULLDOWN(CALIBRATION_PIN);
  232. #else
  233. SET_INPUT(CALIBRATION_PIN);
  234. #endif
  235. #endif
  236. #if HAS_CUSTOM_PROBE_PIN
  237. #if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE)
  238. SET_INPUT_PULLUP(Z_MIN_PROBE_PIN);
  239. #elif ENABLED(ENDSTOPPULLDOWN_ZMIN_PROBE)
  240. SET_INPUT_PULLDOWN(Z_MIN_PROBE_PIN);
  241. #else
  242. SET_INPUT(Z_MIN_PROBE_PIN);
  243. #endif
  244. #endif
  245. #if ENABLED(PROBE_ACTIVATION_SWITCH)
  246. SET_INPUT(PROBE_ACTIVATION_SWITCH_PIN);
  247. #endif
  248. TERN_(PROBE_TARE, probe.tare());
  249. TERN_(ENDSTOP_INTERRUPTS_FEATURE, setup_endstop_interrupts());
  250. // Enable endstops
  251. enable_globally(ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT));
  252. } // Endstops::init
  253. // Called at ~1KHz from Temperature ISR: Poll endstop state if required
  254. void Endstops::poll() {
  255. TERN_(PINS_DEBUGGING, run_monitor()); // Report changes in endstop status
  256. #if DISABLED(ENDSTOP_INTERRUPTS_FEATURE)
  257. update();
  258. #elif ENDSTOP_NOISE_THRESHOLD
  259. if (endstop_poll_count) update();
  260. #endif
  261. }
  262. void Endstops::enable_globally(const bool onoff) {
  263. enabled_globally = enabled = onoff;
  264. resync();
  265. }
  266. // Enable / disable endstop checking
  267. void Endstops::enable(const bool onoff) {
  268. enabled = onoff;
  269. resync();
  270. }
  271. // Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
  272. void Endstops::not_homing() {
  273. enabled = enabled_globally;
  274. }
  275. #if ENABLED(VALIDATE_HOMING_ENDSTOPS)
  276. // If the last move failed to trigger an endstop, call kill
  277. void Endstops::validate_homing_move() {
  278. if (trigger_state()) hit_on_purpose();
  279. else kill(GET_TEXT(MSG_KILL_HOMING_FAILED));
  280. }
  281. #endif
  282. // Enable / disable endstop z-probe checking
  283. #if HAS_BED_PROBE
  284. void Endstops::enable_z_probe(const bool onoff) {
  285. z_probe_enabled = onoff;
  286. resync();
  287. }
  288. #endif
  289. // Get the stable endstop states when enabled
  290. void Endstops::resync() {
  291. if (!abort_enabled()) return; // If endstops/probes are disabled the loop below can hang
  292. // Wait for Temperature ISR to run at least once (runs at 1KHz)
  293. TERN(ENDSTOP_INTERRUPTS_FEATURE, update(), safe_delay(2));
  294. while (TERN0(ENDSTOP_NOISE_THRESHOLD, endstop_poll_count)) safe_delay(1);
  295. }
  296. #if ENABLED(PINS_DEBUGGING)
  297. void Endstops::run_monitor() {
  298. if (!monitor_flag) return;
  299. static uint8_t monitor_count = 16; // offset this check from the others
  300. monitor_count += _BV(1); // 15 Hz
  301. monitor_count &= 0x7F;
  302. if (!monitor_count) monitor(); // report changes in endstop status
  303. }
  304. #endif
  305. void Endstops::event_handler() {
  306. static endstop_mask_t prev_hit_state; // = 0
  307. if (hit_state == prev_hit_state) return;
  308. prev_hit_state = hit_state;
  309. if (hit_state) {
  310. #if HAS_STATUS_MESSAGE
  311. char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
  312. #define _SET_STOP_CHAR(A,C) (chr## A = C)
  313. #else
  314. #define _SET_STOP_CHAR(A,C) NOOP
  315. #endif
  316. #define _ENDSTOP_HIT_ECHO(A,C) do{ \
  317. SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", planner.triggered_position_mm(_AXIS(A))); _SET_STOP_CHAR(A,C); }while(0)
  318. #define _ENDSTOP_HIT_TEST(A,C) \
  319. if (TERN0(HAS_##A##_MIN, TEST(hit_state, A##_MIN)) || TERN0(HAS_##A##_MAX, TEST(hit_state, A##_MAX))) \
  320. _ENDSTOP_HIT_ECHO(A,C)
  321. #define ENDSTOP_HIT_TEST_X() _ENDSTOP_HIT_TEST(X,'X')
  322. #define ENDSTOP_HIT_TEST_Y() _ENDSTOP_HIT_TEST(Y,'Y')
  323. #define ENDSTOP_HIT_TEST_Z() _ENDSTOP_HIT_TEST(Z,'Z')
  324. SERIAL_ECHO_START();
  325. SERIAL_ECHOPGM(STR_ENDSTOPS_HIT);
  326. ENDSTOP_HIT_TEST_X();
  327. ENDSTOP_HIT_TEST_Y();
  328. ENDSTOP_HIT_TEST_Z();
  329. #if HAS_CUSTOM_PROBE_PIN
  330. #define P_AXIS Z_AXIS
  331. if (TEST(hit_state, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
  332. #endif
  333. SERIAL_EOL();
  334. TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %c %c %c %c"), GET_TEXT(MSG_LCD_ENDSTOPS), chrX, chrY, chrZ, chrP));
  335. #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
  336. if (planner.abort_on_endstop_hit) {
  337. card.abortFilePrintNow();
  338. quickstop_stepper();
  339. thermalManager.disable_all_heaters();
  340. print_job_timer.stop();
  341. }
  342. #endif
  343. }
  344. }
  345. static void print_es_state(const bool is_hit, PGM_P const label=nullptr) {
  346. if (label) SERIAL_ECHOPGM_P(label);
  347. SERIAL_ECHOPGM(": ");
  348. SERIAL_ECHOLNPGM_P(is_hit ? PSTR(STR_ENDSTOP_HIT) : PSTR(STR_ENDSTOP_OPEN));
  349. }
  350. void _O2 Endstops::report_states() {
  351. TERN_(BLTOUCH, bltouch._set_SW_mode());
  352. SERIAL_ECHOLNPGM(STR_M119_REPORT);
  353. #define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(STR_##S))
  354. #if HAS_X_MIN
  355. ES_REPORT(X_MIN);
  356. #endif
  357. #if HAS_X2_MIN
  358. ES_REPORT(X2_MIN);
  359. #endif
  360. #if HAS_X_MAX
  361. ES_REPORT(X_MAX);
  362. #endif
  363. #if HAS_X2_MAX
  364. ES_REPORT(X2_MAX);
  365. #endif
  366. #if HAS_Y_MIN
  367. ES_REPORT(Y_MIN);
  368. #endif
  369. #if HAS_Y2_MIN
  370. ES_REPORT(Y2_MIN);
  371. #endif
  372. #if HAS_Y_MAX
  373. ES_REPORT(Y_MAX);
  374. #endif
  375. #if HAS_Y2_MAX
  376. ES_REPORT(Y2_MAX);
  377. #endif
  378. #if HAS_Z_MIN
  379. ES_REPORT(Z_MIN);
  380. #endif
  381. #if HAS_Z2_MIN
  382. ES_REPORT(Z2_MIN);
  383. #endif
  384. #if HAS_Z3_MIN
  385. ES_REPORT(Z3_MIN);
  386. #endif
  387. #if HAS_Z4_MIN
  388. ES_REPORT(Z4_MIN);
  389. #endif
  390. #if HAS_Z_MAX
  391. ES_REPORT(Z_MAX);
  392. #endif
  393. #if HAS_Z2_MAX
  394. ES_REPORT(Z2_MAX);
  395. #endif
  396. #if HAS_Z3_MAX
  397. ES_REPORT(Z3_MAX);
  398. #endif
  399. #if HAS_Z4_MAX
  400. ES_REPORT(Z4_MAX);
  401. #endif
  402. #if BOTH(MARLIN_DEV_MODE, PROBE_ACTIVATION_SWITCH)
  403. print_es_state(probe_switch_activated(), PSTR(STR_PROBE_EN));
  404. #endif
  405. #if HAS_CUSTOM_PROBE_PIN
  406. print_es_state(PROBE_TRIGGERED(), PSTR(STR_Z_PROBE));
  407. #endif
  408. #if MULTI_FILAMENT_SENSOR
  409. #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; state = FIL_RUNOUT##N##_STATE; break;
  410. LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) {
  411. pin_t pin;
  412. uint8_t state;
  413. switch (i) {
  414. default: continue;
  415. REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT)
  416. }
  417. SERIAL_ECHOPGM(STR_FILAMENT_RUNOUT_SENSOR);
  418. if (i > 1) SERIAL_CHAR(' ', '0' + i);
  419. print_es_state(extDigitalRead(pin) != state);
  420. }
  421. #undef _CASE_RUNOUT
  422. #elif HAS_FILAMENT_SENSOR
  423. print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, PSTR(STR_FILAMENT_RUNOUT_SENSOR));
  424. #endif
  425. TERN_(BLTOUCH, bltouch._reset_SW_mode());
  426. TERN_(JOYSTICK_DEBUG, joystick.report());
  427. } // Endstops::report_states
  428. // The following routines are called from an ISR context. It could be the temperature ISR, the
  429. // endstop ISR or the Stepper ISR.
  430. #define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
  431. #define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
  432. #define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
  433. // Check endstops - Could be called from Temperature ISR!
  434. void Endstops::update() {
  435. #if !ENDSTOP_NOISE_THRESHOLD
  436. if (!abort_enabled()) return;
  437. #endif
  438. #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
  439. #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT))
  440. #if BOTH(G38_PROBE_TARGET, HAS_Z_MIN_PROBE_PIN) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  441. // If G38 command is active check Z_MIN_PROBE for ALL movement
  442. if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE);
  443. #endif
  444. // With Dual X, endstops are only checked in the homing direction for the active extruder
  445. #if ENABLED(DUAL_X_CARRIAGE)
  446. #define E0_ACTIVE stepper.last_moved_extruder == 0
  447. #define X_MIN_TEST() ((X_HOME_DIR < 0 && E0_ACTIVE) || (X2_HOME_DIR < 0 && !E0_ACTIVE))
  448. #define X_MAX_TEST() ((X_HOME_DIR > 0 && E0_ACTIVE) || (X2_HOME_DIR > 0 && !E0_ACTIVE))
  449. #else
  450. #define X_MIN_TEST() true
  451. #define X_MAX_TEST() true
  452. #endif
  453. // Use HEAD for core axes, AXIS for others
  454. #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  455. #define X_AXIS_HEAD X_HEAD
  456. #else
  457. #define X_AXIS_HEAD X_AXIS
  458. #endif
  459. #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY)
  460. #define Y_AXIS_HEAD Y_HEAD
  461. #else
  462. #define Y_AXIS_HEAD Y_AXIS
  463. #endif
  464. #if CORE_IS_XZ || CORE_IS_YZ
  465. #define Z_AXIS_HEAD Z_HEAD
  466. #else
  467. #define Z_AXIS_HEAD Z_AXIS
  468. #endif
  469. /**
  470. * Check and update endstops
  471. */
  472. #if HAS_X_MIN && !X_SPI_SENSORLESS
  473. UPDATE_ENDSTOP_BIT(X, MIN);
  474. #if ENABLED(X_DUAL_ENDSTOPS)
  475. #if HAS_X2_MIN
  476. UPDATE_ENDSTOP_BIT(X2, MIN);
  477. #else
  478. COPY_LIVE_STATE(X_MIN, X2_MIN);
  479. #endif
  480. #endif
  481. #endif
  482. #if HAS_X_MAX && !X_SPI_SENSORLESS
  483. UPDATE_ENDSTOP_BIT(X, MAX);
  484. #if ENABLED(X_DUAL_ENDSTOPS)
  485. #if HAS_X2_MAX
  486. UPDATE_ENDSTOP_BIT(X2, MAX);
  487. #else
  488. COPY_LIVE_STATE(X_MAX, X2_MAX);
  489. #endif
  490. #endif
  491. #endif
  492. #if HAS_Y_MIN && !Y_SPI_SENSORLESS
  493. UPDATE_ENDSTOP_BIT(Y, MIN);
  494. #if ENABLED(Y_DUAL_ENDSTOPS)
  495. #if HAS_Y2_MIN
  496. UPDATE_ENDSTOP_BIT(Y2, MIN);
  497. #else
  498. COPY_LIVE_STATE(Y_MIN, Y2_MIN);
  499. #endif
  500. #endif
  501. #endif
  502. #if HAS_Y_MAX && !Y_SPI_SENSORLESS
  503. UPDATE_ENDSTOP_BIT(Y, MAX);
  504. #if ENABLED(Y_DUAL_ENDSTOPS)
  505. #if HAS_Y2_MAX
  506. UPDATE_ENDSTOP_BIT(Y2, MAX);
  507. #else
  508. COPY_LIVE_STATE(Y_MAX, Y2_MAX);
  509. #endif
  510. #endif
  511. #endif
  512. #if HAS_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
  513. UPDATE_ENDSTOP_BIT(Z, MIN);
  514. #if ENABLED(Z_MULTI_ENDSTOPS)
  515. #if HAS_Z2_MIN
  516. UPDATE_ENDSTOP_BIT(Z2, MIN);
  517. #else
  518. COPY_LIVE_STATE(Z_MIN, Z2_MIN);
  519. #endif
  520. #if NUM_Z_STEPPER_DRIVERS >= 3
  521. #if HAS_Z3_MIN
  522. UPDATE_ENDSTOP_BIT(Z3, MIN);
  523. #else
  524. COPY_LIVE_STATE(Z_MIN, Z3_MIN);
  525. #endif
  526. #endif
  527. #if NUM_Z_STEPPER_DRIVERS >= 4
  528. #if HAS_Z4_MIN
  529. UPDATE_ENDSTOP_BIT(Z4, MIN);
  530. #else
  531. COPY_LIVE_STATE(Z_MIN, Z4_MIN);
  532. #endif
  533. #endif
  534. #endif
  535. #endif
  536. #if HAS_BED_PROBE
  537. // When closing the gap check the enabled probe
  538. if (probe_switch_activated())
  539. UPDATE_ENDSTOP_BIT(Z, TERN(HAS_CUSTOM_PROBE_PIN, MIN_PROBE, MIN));
  540. #endif
  541. #if HAS_Z_MAX && !Z_SPI_SENSORLESS
  542. // Check both Z dual endstops
  543. #if ENABLED(Z_MULTI_ENDSTOPS)
  544. UPDATE_ENDSTOP_BIT(Z, MAX);
  545. #if HAS_Z2_MAX
  546. UPDATE_ENDSTOP_BIT(Z2, MAX);
  547. #else
  548. COPY_LIVE_STATE(Z_MAX, Z2_MAX);
  549. #endif
  550. #if NUM_Z_STEPPER_DRIVERS >= 3
  551. #if HAS_Z3_MAX
  552. UPDATE_ENDSTOP_BIT(Z3, MAX);
  553. #else
  554. COPY_LIVE_STATE(Z_MAX, Z3_MAX);
  555. #endif
  556. #endif
  557. #if NUM_Z_STEPPER_DRIVERS >= 4
  558. #if HAS_Z4_MAX
  559. UPDATE_ENDSTOP_BIT(Z4, MAX);
  560. #else
  561. COPY_LIVE_STATE(Z_MAX, Z4_MAX);
  562. #endif
  563. #endif
  564. #elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN
  565. // If this pin isn't the bed probe it's the Z endstop
  566. UPDATE_ENDSTOP_BIT(Z, MAX);
  567. #endif
  568. #endif
  569. #if ENDSTOP_NOISE_THRESHOLD
  570. /**
  571. * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise,
  572. * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution
  573. * of random noise). Then the first sample has a 50% chance to be good or bad. The 2nd sample
  574. * also has a 50% chance to be good or bad. The chances of 2 samples both being bad becomes
  575. * 50% of 50%, or 25%. That was the previous implementation of Marlin endstop handling. It
  576. * reduces chances of bad readings in half, at the cost of 1 extra sample period, but chances
  577. * still exist. The only way to reduce them further is to increase the number of samples.
  578. * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay).
  579. */
  580. static endstop_mask_t old_live_state;
  581. if (old_live_state != live_state) {
  582. endstop_poll_count = ENDSTOP_NOISE_THRESHOLD;
  583. old_live_state = live_state;
  584. }
  585. else if (endstop_poll_count && !--endstop_poll_count)
  586. validated_live_state = live_state;
  587. if (!abort_enabled()) return;
  588. #endif
  589. // Test the current status of an endstop
  590. #define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP))
  591. // Record endstop was hit
  592. #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX))
  593. // Call the endstop triggered routine for single endstops
  594. #define PROCESS_ENDSTOP(AXIS, MINMAX) do { \
  595. if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX))) { \
  596. _ENDSTOP_HIT(AXIS, MINMAX); \
  597. planner.endstop_triggered(_AXIS(AXIS)); \
  598. } \
  599. }while(0)
  600. // Core Sensorless Homing needs to test an Extra Pin
  601. #define CORE_DIAG(QQ,A,MM) (CORE_IS_##QQ && A##_SENSORLESS && !A##_SPI_SENSORLESS && HAS_##A##_##MM)
  602. #define PROCESS_CORE_ENDSTOP(A1,M1,A2,M2) do { \
  603. if (TEST_ENDSTOP(_ENDSTOP(A1,M1))) { \
  604. _ENDSTOP_HIT(A2,M2); \
  605. planner.endstop_triggered(_AXIS(A2)); \
  606. } \
  607. }while(0)
  608. // Call the endstop triggered routine for dual endstops
  609. #define PROCESS_DUAL_ENDSTOP(A, MINMAX) do { \
  610. const byte dual_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1); \
  611. if (dual_hit) { \
  612. _ENDSTOP_HIT(A, MINMAX); \
  613. /* if not performing home or if both endstops were trigged during homing... */ \
  614. if (!stepper.separate_multi_axis || dual_hit == 0b11) \
  615. planner.endstop_triggered(_AXIS(A)); \
  616. } \
  617. }while(0)
  618. #define PROCESS_TRIPLE_ENDSTOP(A, MINMAX) do { \
  619. const byte triple_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(A##3, MINMAX)) << 2); \
  620. if (triple_hit) { \
  621. _ENDSTOP_HIT(A, MINMAX); \
  622. /* if not performing home or if both endstops were trigged during homing... */ \
  623. if (!stepper.separate_multi_axis || triple_hit == 0b111) \
  624. planner.endstop_triggered(_AXIS(A)); \
  625. } \
  626. }while(0)
  627. #define PROCESS_QUAD_ENDSTOP(A, MINMAX) do { \
  628. const byte quad_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(A##3, MINMAX)) << 2) | (TEST_ENDSTOP(_ENDSTOP(A##4, MINMAX)) << 3); \
  629. if (quad_hit) { \
  630. _ENDSTOP_HIT(A, MINMAX); \
  631. /* if not performing home or if both endstops were trigged during homing... */ \
  632. if (!stepper.separate_multi_axis || quad_hit == 0b1111) \
  633. planner.endstop_triggered(_AXIS(A)); \
  634. } \
  635. }while(0)
  636. #if ENABLED(X_DUAL_ENDSTOPS)
  637. #define PROCESS_ENDSTOP_X(MINMAX) PROCESS_DUAL_ENDSTOP(X, MINMAX)
  638. #else
  639. #define PROCESS_ENDSTOP_X(MINMAX) if (X_##MINMAX##_TEST()) PROCESS_ENDSTOP(X, MINMAX)
  640. #endif
  641. #if ENABLED(Y_DUAL_ENDSTOPS)
  642. #define PROCESS_ENDSTOP_Y(MINMAX) PROCESS_DUAL_ENDSTOP(Y, MINMAX)
  643. #else
  644. #define PROCESS_ENDSTOP_Y(MINMAX) PROCESS_ENDSTOP(Y, MINMAX)
  645. #endif
  646. #if DISABLED(Z_MULTI_ENDSTOPS)
  647. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_ENDSTOP(Z, MINMAX)
  648. #elif NUM_Z_STEPPER_DRIVERS == 4
  649. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_QUAD_ENDSTOP(Z, MINMAX)
  650. #elif NUM_Z_STEPPER_DRIVERS == 3
  651. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_TRIPLE_ENDSTOP(Z, MINMAX)
  652. #else
  653. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX)
  654. #endif
  655. #if BOTH(G38_PROBE_TARGET, HAS_Z_MIN_PROBE_PIN) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  656. #if ENABLED(G38_PROBE_AWAY)
  657. #define _G38_OPEN_STATE (G38_move >= 4)
  658. #else
  659. #define _G38_OPEN_STATE LOW
  660. #endif
  661. // If G38 command is active check Z_MIN_PROBE for ALL movement
  662. if (G38_move && TEST_ENDSTOP(_ENDSTOP(Z, MIN_PROBE)) != _G38_OPEN_STATE) {
  663. if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, MIN); planner.endstop_triggered(X_AXIS); }
  664. else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, MIN); planner.endstop_triggered(Y_AXIS); }
  665. else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, MIN); planner.endstop_triggered(Z_AXIS); }
  666. G38_did_trigger = true;
  667. }
  668. #endif
  669. // Signal, after validation, if an endstop limit is pressed or not
  670. if (stepper.axis_is_moving(X_AXIS)) {
  671. if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
  672. #if HAS_X_MIN || (X_SPI_SENSORLESS && X_HOME_DIR < 0)
  673. PROCESS_ENDSTOP_X(MIN);
  674. #if CORE_DIAG(XY, Y, MIN)
  675. PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN);
  676. #elif CORE_DIAG(XY, Y, MAX)
  677. PROCESS_CORE_ENDSTOP(Y,MAX,X,MIN);
  678. #elif CORE_DIAG(XZ, Z, MIN)
  679. PROCESS_CORE_ENDSTOP(Z,MIN,X,MIN);
  680. #elif CORE_DIAG(XZ, Z, MAX)
  681. PROCESS_CORE_ENDSTOP(Z,MAX,X,MIN);
  682. #endif
  683. #endif
  684. }
  685. else { // +direction
  686. #if HAS_X_MAX || (X_SPI_SENSORLESS && X_HOME_DIR > 0)
  687. PROCESS_ENDSTOP_X(MAX);
  688. #if CORE_DIAG(XY, Y, MIN)
  689. PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX);
  690. #elif CORE_DIAG(XY, Y, MAX)
  691. PROCESS_CORE_ENDSTOP(Y,MAX,X,MAX);
  692. #elif CORE_DIAG(XZ, Z, MIN)
  693. PROCESS_CORE_ENDSTOP(Z,MIN,X,MAX);
  694. #elif CORE_DIAG(XZ, Z, MAX)
  695. PROCESS_CORE_ENDSTOP(Z,MAX,X,MAX);
  696. #endif
  697. #endif
  698. }
  699. }
  700. if (stepper.axis_is_moving(Y_AXIS)) {
  701. if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
  702. #if HAS_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_DIR < 0)
  703. PROCESS_ENDSTOP_Y(MIN);
  704. #if CORE_DIAG(XY, X, MIN)
  705. PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN);
  706. #elif CORE_DIAG(XY, X, MAX)
  707. PROCESS_CORE_ENDSTOP(X,MAX,Y,MIN);
  708. #elif CORE_DIAG(YZ, Z, MIN)
  709. PROCESS_CORE_ENDSTOP(Z,MIN,Y,MIN);
  710. #elif CORE_DIAG(YZ, Z, MAX)
  711. PROCESS_CORE_ENDSTOP(Z,MAX,Y,MIN);
  712. #endif
  713. #endif
  714. }
  715. else { // +direction
  716. #if HAS_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_DIR > 0)
  717. PROCESS_ENDSTOP_Y(MAX);
  718. #if CORE_DIAG(XY, X, MIN)
  719. PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX);
  720. #elif CORE_DIAG(XY, X, MAX)
  721. PROCESS_CORE_ENDSTOP(X,MAX,Y,MAX);
  722. #elif CORE_DIAG(YZ, Z, MIN)
  723. PROCESS_CORE_ENDSTOP(Z,MIN,Y,MAX);
  724. #elif CORE_DIAG(YZ, Z, MAX)
  725. PROCESS_CORE_ENDSTOP(Z,MAX,Y,MAX);
  726. #endif
  727. #endif
  728. }
  729. }
  730. if (stepper.axis_is_moving(Z_AXIS)) {
  731. if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
  732. #if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_DIR < 0)
  733. if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled)
  734. && TERN1(HAS_CUSTOM_PROBE_PIN, !z_probe_enabled)
  735. ) PROCESS_ENDSTOP_Z(MIN);
  736. #if CORE_DIAG(XZ, X, MIN)
  737. PROCESS_CORE_ENDSTOP(X,MIN,Z,MIN);
  738. #elif CORE_DIAG(XZ, X, MAX)
  739. PROCESS_CORE_ENDSTOP(X,MAX,Z,MIN);
  740. #elif CORE_DIAG(YZ, Y, MIN)
  741. PROCESS_CORE_ENDSTOP(Y,MIN,Z,MIN);
  742. #elif CORE_DIAG(YZ, Y, MAX)
  743. PROCESS_CORE_ENDSTOP(Y,MAX,Z,MIN);
  744. #endif
  745. #endif
  746. // When closing the gap check the enabled probe
  747. #if HAS_CUSTOM_PROBE_PIN
  748. if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN_PROBE);
  749. #endif
  750. }
  751. else { // Z +direction. Gantry up, bed down.
  752. #if HAS_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_DIR > 0)
  753. #if ENABLED(Z_MULTI_ENDSTOPS)
  754. PROCESS_ENDSTOP_Z(MAX);
  755. #elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN // No probe or probe is Z_MIN || Probe is not Z_MAX
  756. PROCESS_ENDSTOP(Z, MAX);
  757. #endif
  758. #if CORE_DIAG(XZ, X, MIN)
  759. PROCESS_CORE_ENDSTOP(X,MIN,Z,MAX);
  760. #elif CORE_DIAG(XZ, X, MAX)
  761. PROCESS_CORE_ENDSTOP(X,MAX,Z,MAX);
  762. #elif CORE_DIAG(YZ, Y, MIN)
  763. PROCESS_CORE_ENDSTOP(Y,MIN,Z,MAX);
  764. #elif CORE_DIAG(YZ, Y, MAX)
  765. PROCESS_CORE_ENDSTOP(Y,MAX,Z,MAX);
  766. #endif
  767. #endif
  768. }
  769. }
  770. } // Endstops::update()
  771. #if ENABLED(SPI_ENDSTOPS)
  772. bool Endstops::tmc_spi_homing_check() {
  773. bool hit = false;
  774. #if X_SPI_SENSORLESS
  775. if (tmc_spi_homing.x && (stepperX.test_stall_status()
  776. #if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS
  777. || stepperY.test_stall_status()
  778. #elif CORE_IS_XZ && Z_SPI_SENSORLESS
  779. || stepperZ.test_stall_status()
  780. #endif
  781. )) {
  782. SBI(live_state, X_ENDSTOP);
  783. hit = true;
  784. }
  785. #endif
  786. #if Y_SPI_SENSORLESS
  787. if (tmc_spi_homing.y && (stepperY.test_stall_status()
  788. #if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS
  789. || stepperX.test_stall_status()
  790. #elif CORE_IS_YZ && Z_SPI_SENSORLESS
  791. || stepperZ.test_stall_status()
  792. #endif
  793. )) {
  794. SBI(live_state, Y_ENDSTOP);
  795. hit = true;
  796. }
  797. #endif
  798. #if Z_SPI_SENSORLESS
  799. if (tmc_spi_homing.z && (stepperZ.test_stall_status()
  800. #if CORE_IS_XZ && X_SPI_SENSORLESS
  801. || stepperX.test_stall_status()
  802. #elif CORE_IS_YZ && Y_SPI_SENSORLESS
  803. || stepperY.test_stall_status()
  804. #endif
  805. )) {
  806. SBI(live_state, Z_ENDSTOP);
  807. hit = true;
  808. }
  809. #endif
  810. if (TERN0(ENDSTOP_INTERRUPTS_FEATURE, hit)) update();
  811. return hit;
  812. }
  813. void Endstops::clear_endstop_state() {
  814. TERN_(X_SPI_SENSORLESS, CBI(live_state, X_ENDSTOP));
  815. TERN_(Y_SPI_SENSORLESS, CBI(live_state, Y_ENDSTOP));
  816. TERN_(Z_SPI_SENSORLESS, CBI(live_state, Z_ENDSTOP));
  817. }
  818. #endif // SPI_ENDSTOPS
  819. #if ENABLED(PINS_DEBUGGING)
  820. bool Endstops::monitor_flag = false;
  821. /**
  822. * Monitor Endstops and Z Probe for changes
  823. *
  824. * If a change is detected then the LED is toggled and
  825. * a message is sent out the serial port.
  826. *
  827. * Yes, we could miss a rapid back & forth change but
  828. * that won't matter because this is all manual.
  829. */
  830. void Endstops::monitor() {
  831. static uint16_t old_live_state_local = 0;
  832. static uint8_t local_LED_status = 0;
  833. uint16_t live_state_local = 0;
  834. #define ES_GET_STATE(S) if (READ(S##_PIN)) SBI(live_state_local, S)
  835. #if HAS_X_MIN
  836. ES_GET_STATE(X_MIN);
  837. #endif
  838. #if HAS_X_MAX
  839. ES_GET_STATE(X_MAX);
  840. #endif
  841. #if HAS_Y_MIN
  842. ES_GET_STATE(Y_MIN);
  843. #endif
  844. #if HAS_Y_MAX
  845. ES_GET_STATE(Y_MAX);
  846. #endif
  847. #if HAS_Z_MIN
  848. ES_GET_STATE(Z_MIN);
  849. #endif
  850. #if HAS_Z_MAX
  851. ES_GET_STATE(Z_MAX);
  852. #endif
  853. #if HAS_Z_MIN_PROBE_PIN
  854. ES_GET_STATE(Z_MIN_PROBE);
  855. #endif
  856. #if HAS_X2_MIN
  857. ES_GET_STATE(X2_MIN);
  858. #endif
  859. #if HAS_X2_MAX
  860. ES_GET_STATE(X2_MAX);
  861. #endif
  862. #if HAS_Y2_MIN
  863. ES_GET_STATE(Y2_MIN);
  864. #endif
  865. #if HAS_Y2_MAX
  866. ES_GET_STATE(Y2_MAX);
  867. #endif
  868. #if HAS_Z2_MIN
  869. ES_GET_STATE(Z2_MIN);
  870. #endif
  871. #if HAS_Z2_MAX
  872. ES_GET_STATE(Z2_MAX);
  873. #endif
  874. #if HAS_Z3_MIN
  875. ES_GET_STATE(Z3_MIN);
  876. #endif
  877. #if HAS_Z3_MAX
  878. ES_GET_STATE(Z3_MAX);
  879. #endif
  880. #if HAS_Z4_MIN
  881. ES_GET_STATE(Z4_MIN);
  882. #endif
  883. #if HAS_Z4_MAX
  884. ES_GET_STATE(Z4_MAX);
  885. #endif
  886. uint16_t endstop_change = live_state_local ^ old_live_state_local;
  887. #define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPAIR(" " STRINGIFY(S) ":", TEST(live_state_local, S))
  888. if (endstop_change) {
  889. #if HAS_X_MIN
  890. ES_REPORT_CHANGE(X_MIN);
  891. #endif
  892. #if HAS_X_MAX
  893. ES_REPORT_CHANGE(X_MAX);
  894. #endif
  895. #if HAS_Y_MIN
  896. ES_REPORT_CHANGE(Y_MIN);
  897. #endif
  898. #if HAS_Y_MAX
  899. ES_REPORT_CHANGE(Y_MAX);
  900. #endif
  901. #if HAS_Z_MIN
  902. ES_REPORT_CHANGE(Z_MIN);
  903. #endif
  904. #if HAS_Z_MAX
  905. ES_REPORT_CHANGE(Z_MAX);
  906. #endif
  907. #if HAS_Z_MIN_PROBE_PIN
  908. ES_REPORT_CHANGE(Z_MIN_PROBE);
  909. #endif
  910. #if HAS_X2_MIN
  911. ES_REPORT_CHANGE(X2_MIN);
  912. #endif
  913. #if HAS_X2_MAX
  914. ES_REPORT_CHANGE(X2_MAX);
  915. #endif
  916. #if HAS_Y2_MIN
  917. ES_REPORT_CHANGE(Y2_MIN);
  918. #endif
  919. #if HAS_Y2_MAX
  920. ES_REPORT_CHANGE(Y2_MAX);
  921. #endif
  922. #if HAS_Z2_MIN
  923. ES_REPORT_CHANGE(Z2_MIN);
  924. #endif
  925. #if HAS_Z2_MAX
  926. ES_REPORT_CHANGE(Z2_MAX);
  927. #endif
  928. #if HAS_Z3_MIN
  929. ES_REPORT_CHANGE(Z3_MIN);
  930. #endif
  931. #if HAS_Z3_MAX
  932. ES_REPORT_CHANGE(Z3_MAX);
  933. #endif
  934. #if HAS_Z4_MIN
  935. ES_REPORT_CHANGE(Z4_MIN);
  936. #endif
  937. #if HAS_Z4_MAX
  938. ES_REPORT_CHANGE(Z4_MAX);
  939. #endif
  940. SERIAL_ECHOLNPGM("\n");
  941. analogWrite(pin_t(LED_PIN), local_LED_status);
  942. local_LED_status ^= 255;
  943. old_live_state_local = live_state_local;
  944. }
  945. }
  946. #endif // PINS_DEBUGGING