My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

endstops.cpp 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  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 uint8_t Endstops::hit_state;
  49. Endstops::esbits_t Endstops::live_state = 0;
  50. #if ENDSTOP_NOISE_THRESHOLD
  51. Endstops::esbits_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 uint8_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) ;
  315. #endif
  316. #define _ENDSTOP_HIT_ECHO(A,C) do{ \
  317. SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", planner.triggered_position_mm(_AXIS(A))); \
  318. _SET_STOP_CHAR(A,C); }while(0)
  319. #define _ENDSTOP_HIT_TEST(A,C) \
  320. if (TEST(hit_state, A ##_MIN) || TEST(hit_state, A ##_MAX)) \
  321. _ENDSTOP_HIT_ECHO(A,C)
  322. #define ENDSTOP_HIT_TEST_X() _ENDSTOP_HIT_TEST(X,'X')
  323. #define ENDSTOP_HIT_TEST_Y() _ENDSTOP_HIT_TEST(Y,'Y')
  324. #define ENDSTOP_HIT_TEST_Z() _ENDSTOP_HIT_TEST(Z,'Z')
  325. SERIAL_ECHO_START();
  326. SERIAL_ECHOPGM(STR_ENDSTOPS_HIT);
  327. ENDSTOP_HIT_TEST_X();
  328. ENDSTOP_HIT_TEST_Y();
  329. ENDSTOP_HIT_TEST_Z();
  330. #if HAS_CUSTOM_PROBE_PIN
  331. #define P_AXIS Z_AXIS
  332. if (TEST(hit_state, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
  333. #endif
  334. SERIAL_EOL();
  335. 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));
  336. #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
  337. if (planner.abort_on_endstop_hit) {
  338. card.abortFilePrintNow();
  339. quickstop_stepper();
  340. thermalManager.disable_all_heaters();
  341. print_job_timer.stop();
  342. }
  343. #endif
  344. }
  345. }
  346. static void print_es_state(const bool is_hit, PGM_P const label=nullptr) {
  347. if (label) SERIAL_ECHOPGM_P(label);
  348. SERIAL_ECHOPGM(": ");
  349. SERIAL_ECHOLNPGM_P(is_hit ? PSTR(STR_ENDSTOP_HIT) : PSTR(STR_ENDSTOP_OPEN));
  350. }
  351. void _O2 Endstops::report_states() {
  352. TERN_(BLTOUCH, bltouch._set_SW_mode());
  353. SERIAL_ECHOLNPGM(STR_M119_REPORT);
  354. #define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(STR_##S))
  355. #if HAS_X_MIN
  356. ES_REPORT(X_MIN);
  357. #endif
  358. #if HAS_X2_MIN
  359. ES_REPORT(X2_MIN);
  360. #endif
  361. #if HAS_X_MAX
  362. ES_REPORT(X_MAX);
  363. #endif
  364. #if HAS_X2_MAX
  365. ES_REPORT(X2_MAX);
  366. #endif
  367. #if HAS_Y_MIN
  368. ES_REPORT(Y_MIN);
  369. #endif
  370. #if HAS_Y2_MIN
  371. ES_REPORT(Y2_MIN);
  372. #endif
  373. #if HAS_Y_MAX
  374. ES_REPORT(Y_MAX);
  375. #endif
  376. #if HAS_Y2_MAX
  377. ES_REPORT(Y2_MAX);
  378. #endif
  379. #if HAS_Z_MIN
  380. ES_REPORT(Z_MIN);
  381. #endif
  382. #if HAS_Z2_MIN
  383. ES_REPORT(Z2_MIN);
  384. #endif
  385. #if HAS_Z3_MIN
  386. ES_REPORT(Z3_MIN);
  387. #endif
  388. #if HAS_Z4_MIN
  389. ES_REPORT(Z4_MIN);
  390. #endif
  391. #if HAS_Z_MAX
  392. ES_REPORT(Z_MAX);
  393. #endif
  394. #if HAS_Z2_MAX
  395. ES_REPORT(Z2_MAX);
  396. #endif
  397. #if HAS_Z3_MAX
  398. ES_REPORT(Z3_MAX);
  399. #endif
  400. #if HAS_Z4_MAX
  401. ES_REPORT(Z4_MAX);
  402. #endif
  403. #if BOTH(MARLIN_DEV_MODE, PROBE_ACTIVATION_SWITCH)
  404. print_es_state(probe_switch_activated(), PSTR(STR_PROBE_EN));
  405. #endif
  406. #if HAS_CUSTOM_PROBE_PIN
  407. print_es_state(PROBE_TRIGGERED(), PSTR(STR_Z_PROBE));
  408. #endif
  409. #if MULTI_FILAMENT_SENSOR
  410. #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; state = FIL_RUNOUT##N##_STATE; break;
  411. LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) {
  412. pin_t pin;
  413. uint8_t state;
  414. switch (i) {
  415. default: continue;
  416. REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT)
  417. }
  418. SERIAL_ECHOPGM(STR_FILAMENT_RUNOUT_SENSOR);
  419. if (i > 1) SERIAL_CHAR(' ', '0' + i);
  420. print_es_state(extDigitalRead(pin) != state);
  421. }
  422. #undef _CASE_RUNOUT
  423. #elif HAS_FILAMENT_SENSOR
  424. print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, PSTR(STR_FILAMENT_RUNOUT_SENSOR));
  425. #endif
  426. TERN_(BLTOUCH, bltouch._reset_SW_mode());
  427. TERN_(JOYSTICK_DEBUG, joystick.report());
  428. } // Endstops::report_states
  429. // The following routines are called from an ISR context. It could be the temperature ISR, the
  430. // endstop ISR or the Stepper ISR.
  431. #define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
  432. #define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
  433. #define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
  434. // Check endstops - Could be called from Temperature ISR!
  435. void Endstops::update() {
  436. #if !ENDSTOP_NOISE_THRESHOLD
  437. if (!abort_enabled()) return;
  438. #endif
  439. #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
  440. #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT))
  441. #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  442. // If G38 command is active check Z_MIN_PROBE for ALL movement
  443. if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE);
  444. #endif
  445. // With Dual X, endstops are only checked in the homing direction for the active extruder
  446. #if ENABLED(DUAL_X_CARRIAGE)
  447. #define E0_ACTIVE stepper.last_moved_extruder == 0
  448. #define X_MIN_TEST() ((X_HOME_DIR < 0 && E0_ACTIVE) || (X2_HOME_DIR < 0 && !E0_ACTIVE))
  449. #define X_MAX_TEST() ((X_HOME_DIR > 0 && E0_ACTIVE) || (X2_HOME_DIR > 0 && !E0_ACTIVE))
  450. #else
  451. #define X_MIN_TEST() true
  452. #define X_MAX_TEST() true
  453. #endif
  454. // Use HEAD for core axes, AXIS for others
  455. #if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  456. #define X_AXIS_HEAD X_HEAD
  457. #else
  458. #define X_AXIS_HEAD X_AXIS
  459. #endif
  460. #if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY)
  461. #define Y_AXIS_HEAD Y_HEAD
  462. #else
  463. #define Y_AXIS_HEAD Y_AXIS
  464. #endif
  465. #if CORE_IS_XZ || CORE_IS_YZ
  466. #define Z_AXIS_HEAD Z_HEAD
  467. #else
  468. #define Z_AXIS_HEAD Z_AXIS
  469. #endif
  470. /**
  471. * Check and update endstops
  472. */
  473. #if HAS_X_MIN && !X_SPI_SENSORLESS
  474. UPDATE_ENDSTOP_BIT(X, MIN);
  475. #if ENABLED(X_DUAL_ENDSTOPS)
  476. #if HAS_X2_MIN
  477. UPDATE_ENDSTOP_BIT(X2, MIN);
  478. #else
  479. COPY_LIVE_STATE(X_MIN, X2_MIN);
  480. #endif
  481. #endif
  482. #endif
  483. #if HAS_X_MAX && !X_SPI_SENSORLESS
  484. UPDATE_ENDSTOP_BIT(X, MAX);
  485. #if ENABLED(X_DUAL_ENDSTOPS)
  486. #if HAS_X2_MAX
  487. UPDATE_ENDSTOP_BIT(X2, MAX);
  488. #else
  489. COPY_LIVE_STATE(X_MAX, X2_MAX);
  490. #endif
  491. #endif
  492. #endif
  493. #if HAS_Y_MIN && !Y_SPI_SENSORLESS
  494. UPDATE_ENDSTOP_BIT(Y, MIN);
  495. #if ENABLED(Y_DUAL_ENDSTOPS)
  496. #if HAS_Y2_MIN
  497. UPDATE_ENDSTOP_BIT(Y2, MIN);
  498. #else
  499. COPY_LIVE_STATE(Y_MIN, Y2_MIN);
  500. #endif
  501. #endif
  502. #endif
  503. #if HAS_Y_MAX && !Y_SPI_SENSORLESS
  504. UPDATE_ENDSTOP_BIT(Y, MAX);
  505. #if ENABLED(Y_DUAL_ENDSTOPS)
  506. #if HAS_Y2_MAX
  507. UPDATE_ENDSTOP_BIT(Y2, MAX);
  508. #else
  509. COPY_LIVE_STATE(Y_MAX, Y2_MAX);
  510. #endif
  511. #endif
  512. #endif
  513. #if HAS_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
  514. UPDATE_ENDSTOP_BIT(Z, MIN);
  515. #if ENABLED(Z_MULTI_ENDSTOPS)
  516. #if HAS_Z2_MIN
  517. UPDATE_ENDSTOP_BIT(Z2, MIN);
  518. #else
  519. COPY_LIVE_STATE(Z_MIN, Z2_MIN);
  520. #endif
  521. #if NUM_Z_STEPPER_DRIVERS >= 3
  522. #if HAS_Z3_MIN
  523. UPDATE_ENDSTOP_BIT(Z3, MIN);
  524. #else
  525. COPY_LIVE_STATE(Z_MIN, Z3_MIN);
  526. #endif
  527. #endif
  528. #if NUM_Z_STEPPER_DRIVERS >= 4
  529. #if HAS_Z4_MIN
  530. UPDATE_ENDSTOP_BIT(Z4, MIN);
  531. #else
  532. COPY_LIVE_STATE(Z_MIN, Z4_MIN);
  533. #endif
  534. #endif
  535. #endif
  536. #endif
  537. #if HAS_BED_PROBE
  538. // When closing the gap check the enabled probe
  539. if (probe_switch_activated())
  540. UPDATE_ENDSTOP_BIT(Z, TERN(HAS_CUSTOM_PROBE_PIN, MIN_PROBE, MIN));
  541. #endif
  542. #if HAS_Z_MAX && !Z_SPI_SENSORLESS
  543. // Check both Z dual endstops
  544. #if ENABLED(Z_MULTI_ENDSTOPS)
  545. UPDATE_ENDSTOP_BIT(Z, MAX);
  546. #if HAS_Z2_MAX
  547. UPDATE_ENDSTOP_BIT(Z2, MAX);
  548. #else
  549. COPY_LIVE_STATE(Z_MAX, Z2_MAX);
  550. #endif
  551. #if NUM_Z_STEPPER_DRIVERS >= 3
  552. #if HAS_Z3_MAX
  553. UPDATE_ENDSTOP_BIT(Z3, MAX);
  554. #else
  555. COPY_LIVE_STATE(Z_MAX, Z3_MAX);
  556. #endif
  557. #endif
  558. #if NUM_Z_STEPPER_DRIVERS >= 4
  559. #if HAS_Z4_MAX
  560. UPDATE_ENDSTOP_BIT(Z4, MAX);
  561. #else
  562. COPY_LIVE_STATE(Z_MAX, Z4_MAX);
  563. #endif
  564. #endif
  565. #elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN
  566. // If this pin isn't the bed probe it's the Z endstop
  567. UPDATE_ENDSTOP_BIT(Z, MAX);
  568. #endif
  569. #endif
  570. #if ENDSTOP_NOISE_THRESHOLD
  571. /**
  572. * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise,
  573. * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution
  574. * of random noise). Then the first sample has a 50% chance to be good or bad. The 2nd sample
  575. * also has a 50% chance to be good or bad. The chances of 2 samples both being bad becomes
  576. * 50% of 50%, or 25%. That was the previous implementation of Marlin endstop handling. It
  577. * reduces chances of bad readings in half, at the cost of 1 extra sample period, but chances
  578. * still exist. The only way to reduce them further is to increase the number of samples.
  579. * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay).
  580. */
  581. static esbits_t old_live_state;
  582. if (old_live_state != live_state) {
  583. endstop_poll_count = ENDSTOP_NOISE_THRESHOLD;
  584. old_live_state = live_state;
  585. }
  586. else if (endstop_poll_count && !--endstop_poll_count)
  587. validated_live_state = live_state;
  588. if (!abort_enabled()) return;
  589. #endif
  590. // Test the current status of an endstop
  591. #define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP))
  592. // Record endstop was hit
  593. #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX))
  594. // Call the endstop triggered routine for single endstops
  595. #define PROCESS_ENDSTOP(AXIS, MINMAX) do { \
  596. if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX))) { \
  597. _ENDSTOP_HIT(AXIS, MINMAX); \
  598. planner.endstop_triggered(_AXIS(AXIS)); \
  599. } \
  600. }while(0)
  601. // Core Sensorless Homing needs to test an Extra Pin
  602. #define CORE_DIAG(QQ,A,MM) (CORE_IS_##QQ && A##_SENSORLESS && !A##_SPI_SENSORLESS && HAS_##A##_##MM)
  603. #define PROCESS_CORE_ENDSTOP(A1,M1,A2,M2) do { \
  604. if (TEST_ENDSTOP(_ENDSTOP(A1,M1))) { \
  605. _ENDSTOP_HIT(A2,M2); \
  606. planner.endstop_triggered(_AXIS(A2)); \
  607. } \
  608. }while(0)
  609. // Call the endstop triggered routine for dual endstops
  610. #define PROCESS_DUAL_ENDSTOP(A, MINMAX) do { \
  611. const byte dual_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1); \
  612. if (dual_hit) { \
  613. _ENDSTOP_HIT(A, MINMAX); \
  614. /* if not performing home or if both endstops were trigged during homing... */ \
  615. if (!stepper.separate_multi_axis || dual_hit == 0b11) \
  616. planner.endstop_triggered(_AXIS(A)); \
  617. } \
  618. }while(0)
  619. #define PROCESS_TRIPLE_ENDSTOP(A, MINMAX) do { \
  620. const byte triple_hit = TEST_ENDSTOP(_ENDSTOP(A, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(A##2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(A##3, MINMAX)) << 2); \
  621. if (triple_hit) { \
  622. _ENDSTOP_HIT(A, MINMAX); \
  623. /* if not performing home or if both endstops were trigged during homing... */ \
  624. if (!stepper.separate_multi_axis || triple_hit == 0b111) \
  625. planner.endstop_triggered(_AXIS(A)); \
  626. } \
  627. }while(0)
  628. #define PROCESS_QUAD_ENDSTOP(A, MINMAX) do { \
  629. 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); \
  630. if (quad_hit) { \
  631. _ENDSTOP_HIT(A, MINMAX); \
  632. /* if not performing home or if both endstops were trigged during homing... */ \
  633. if (!stepper.separate_multi_axis || quad_hit == 0b1111) \
  634. planner.endstop_triggered(_AXIS(A)); \
  635. } \
  636. }while(0)
  637. #if ENABLED(X_DUAL_ENDSTOPS)
  638. #define PROCESS_ENDSTOP_X(MINMAX) PROCESS_DUAL_ENDSTOP(X, MINMAX)
  639. #else
  640. #define PROCESS_ENDSTOP_X(MINMAX) if (X_##MINMAX##_TEST()) PROCESS_ENDSTOP(X, MINMAX)
  641. #endif
  642. #if ENABLED(Y_DUAL_ENDSTOPS)
  643. #define PROCESS_ENDSTOP_Y(MINMAX) PROCESS_DUAL_ENDSTOP(Y, MINMAX)
  644. #else
  645. #define PROCESS_ENDSTOP_Y(MINMAX) PROCESS_ENDSTOP(Y, MINMAX)
  646. #endif
  647. #if DISABLED(Z_MULTI_ENDSTOPS)
  648. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_ENDSTOP(Z, MINMAX)
  649. #elif NUM_Z_STEPPER_DRIVERS == 4
  650. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_QUAD_ENDSTOP(Z, MINMAX)
  651. #elif NUM_Z_STEPPER_DRIVERS == 3
  652. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_TRIPLE_ENDSTOP(Z, MINMAX)
  653. #else
  654. #define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX)
  655. #endif
  656. #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && NONE(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY)
  657. #if ENABLED(G38_PROBE_AWAY)
  658. #define _G38_OPEN_STATE (G38_move >= 4)
  659. #else
  660. #define _G38_OPEN_STATE LOW
  661. #endif
  662. // If G38 command is active check Z_MIN_PROBE for ALL movement
  663. if (G38_move && TEST_ENDSTOP(_ENDSTOP(Z, MIN_PROBE)) != _G38_OPEN_STATE) {
  664. if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, MIN); planner.endstop_triggered(X_AXIS); }
  665. else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, MIN); planner.endstop_triggered(Y_AXIS); }
  666. else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, MIN); planner.endstop_triggered(Z_AXIS); }
  667. G38_did_trigger = true;
  668. }
  669. #endif
  670. // Signal, after validation, if an endstop limit is pressed or not
  671. if (stepper.axis_is_moving(X_AXIS)) {
  672. if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
  673. #if HAS_X_MIN || (X_SPI_SENSORLESS && X_HOME_DIR < 0)
  674. PROCESS_ENDSTOP_X(MIN);
  675. #if CORE_DIAG(XY, Y, MIN)
  676. PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN);
  677. #elif CORE_DIAG(XY, Y, MAX)
  678. PROCESS_CORE_ENDSTOP(Y,MAX,X,MIN);
  679. #elif CORE_DIAG(XZ, Z, MIN)
  680. PROCESS_CORE_ENDSTOP(Z,MIN,X,MIN);
  681. #elif CORE_DIAG(XZ, Z, MAX)
  682. PROCESS_CORE_ENDSTOP(Z,MAX,X,MIN);
  683. #endif
  684. #endif
  685. }
  686. else { // +direction
  687. #if HAS_X_MAX || (X_SPI_SENSORLESS && X_HOME_DIR > 0)
  688. PROCESS_ENDSTOP_X(MAX);
  689. #if CORE_DIAG(XY, Y, MIN)
  690. PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX);
  691. #elif CORE_DIAG(XY, Y, MAX)
  692. PROCESS_CORE_ENDSTOP(Y,MAX,X,MAX);
  693. #elif CORE_DIAG(XZ, Z, MIN)
  694. PROCESS_CORE_ENDSTOP(Z,MIN,X,MAX);
  695. #elif CORE_DIAG(XZ, Z, MAX)
  696. PROCESS_CORE_ENDSTOP(Z,MAX,X,MAX);
  697. #endif
  698. #endif
  699. }
  700. }
  701. if (stepper.axis_is_moving(Y_AXIS)) {
  702. if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
  703. #if HAS_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_DIR < 0)
  704. PROCESS_ENDSTOP_Y(MIN);
  705. #if CORE_DIAG(XY, X, MIN)
  706. PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN);
  707. #elif CORE_DIAG(XY, X, MAX)
  708. PROCESS_CORE_ENDSTOP(X,MAX,Y,MIN);
  709. #elif CORE_DIAG(YZ, Z, MIN)
  710. PROCESS_CORE_ENDSTOP(Z,MIN,Y,MIN);
  711. #elif CORE_DIAG(YZ, Z, MAX)
  712. PROCESS_CORE_ENDSTOP(Z,MAX,Y,MIN);
  713. #endif
  714. #endif
  715. }
  716. else { // +direction
  717. #if HAS_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_DIR > 0)
  718. PROCESS_ENDSTOP_Y(MAX);
  719. #if CORE_DIAG(XY, X, MIN)
  720. PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX);
  721. #elif CORE_DIAG(XY, X, MAX)
  722. PROCESS_CORE_ENDSTOP(X,MAX,Y,MAX);
  723. #elif CORE_DIAG(YZ, Z, MIN)
  724. PROCESS_CORE_ENDSTOP(Z,MIN,Y,MAX);
  725. #elif CORE_DIAG(YZ, Z, MAX)
  726. PROCESS_CORE_ENDSTOP(Z,MAX,Y,MAX);
  727. #endif
  728. #endif
  729. }
  730. }
  731. if (stepper.axis_is_moving(Z_AXIS)) {
  732. if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
  733. #if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_DIR < 0)
  734. if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled)
  735. && TERN1(HAS_CUSTOM_PROBE_PIN, !z_probe_enabled)
  736. ) PROCESS_ENDSTOP_Z(MIN);
  737. #if CORE_DIAG(XZ, X, MIN)
  738. PROCESS_CORE_ENDSTOP(X,MIN,Z,MIN);
  739. #elif CORE_DIAG(XZ, X, MAX)
  740. PROCESS_CORE_ENDSTOP(X,MAX,Z,MIN);
  741. #elif CORE_DIAG(YZ, Y, MIN)
  742. PROCESS_CORE_ENDSTOP(Y,MIN,Z,MIN);
  743. #elif CORE_DIAG(YZ, Y, MAX)
  744. PROCESS_CORE_ENDSTOP(Y,MAX,Z,MIN);
  745. #endif
  746. #endif
  747. // When closing the gap check the enabled probe
  748. #if HAS_CUSTOM_PROBE_PIN
  749. if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN_PROBE);
  750. #endif
  751. }
  752. else { // Z +direction. Gantry up, bed down.
  753. #if HAS_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_DIR > 0)
  754. #if ENABLED(Z_MULTI_ENDSTOPS)
  755. PROCESS_ENDSTOP_Z(MAX);
  756. #elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN // No probe or probe is Z_MIN || Probe is not Z_MAX
  757. PROCESS_ENDSTOP(Z, MAX);
  758. #endif
  759. #if CORE_DIAG(XZ, X, MIN)
  760. PROCESS_CORE_ENDSTOP(X,MIN,Z,MAX);
  761. #elif CORE_DIAG(XZ, X, MAX)
  762. PROCESS_CORE_ENDSTOP(X,MAX,Z,MAX);
  763. #elif CORE_DIAG(YZ, Y, MIN)
  764. PROCESS_CORE_ENDSTOP(Y,MIN,Z,MAX);
  765. #elif CORE_DIAG(YZ, Y, MAX)
  766. PROCESS_CORE_ENDSTOP(Y,MAX,Z,MAX);
  767. #endif
  768. #endif
  769. }
  770. }
  771. } // Endstops::update()
  772. #if ENABLED(SPI_ENDSTOPS)
  773. bool Endstops::tmc_spi_homing_check() {
  774. bool hit = false;
  775. #if X_SPI_SENSORLESS
  776. if (tmc_spi_homing.x && (stepperX.test_stall_status()
  777. #if ANY(CORE_IS_XY, MARKFORGED_XY) && Y_SPI_SENSORLESS
  778. || stepperY.test_stall_status()
  779. #elif CORE_IS_XZ && Z_SPI_SENSORLESS
  780. || stepperZ.test_stall_status()
  781. #endif
  782. )) {
  783. SBI(live_state, X_ENDSTOP);
  784. hit = true;
  785. }
  786. #endif
  787. #if Y_SPI_SENSORLESS
  788. if (tmc_spi_homing.y && (stepperY.test_stall_status()
  789. #if ANY(CORE_IS_XY, MARKFORGED_XY) && X_SPI_SENSORLESS
  790. || stepperX.test_stall_status()
  791. #elif CORE_IS_YZ && Z_SPI_SENSORLESS
  792. || stepperZ.test_stall_status()
  793. #endif
  794. )) {
  795. SBI(live_state, Y_ENDSTOP);
  796. hit = true;
  797. }
  798. #endif
  799. #if Z_SPI_SENSORLESS
  800. if (tmc_spi_homing.z && (stepperZ.test_stall_status()
  801. #if CORE_IS_XZ && X_SPI_SENSORLESS
  802. || stepperX.test_stall_status()
  803. #elif CORE_IS_YZ && Y_SPI_SENSORLESS
  804. || stepperY.test_stall_status()
  805. #endif
  806. )) {
  807. SBI(live_state, Z_ENDSTOP);
  808. hit = true;
  809. }
  810. #endif
  811. if (TERN0(ENDSTOP_INTERRUPTS_FEATURE, hit)) update();
  812. return hit;
  813. }
  814. void Endstops::clear_endstop_state() {
  815. TERN_(X_SPI_SENSORLESS, CBI(live_state, X_ENDSTOP));
  816. TERN_(Y_SPI_SENSORLESS, CBI(live_state, Y_ENDSTOP));
  817. TERN_(Z_SPI_SENSORLESS, CBI(live_state, Z_ENDSTOP));
  818. }
  819. #endif // SPI_ENDSTOPS
  820. #if ENABLED(PINS_DEBUGGING)
  821. bool Endstops::monitor_flag = false;
  822. /**
  823. * Monitor Endstops and Z Probe for changes
  824. *
  825. * If a change is detected then the LED is toggled and
  826. * a message is sent out the serial port.
  827. *
  828. * Yes, we could miss a rapid back & forth change but
  829. * that won't matter because this is all manual.
  830. */
  831. void Endstops::monitor() {
  832. static uint16_t old_live_state_local = 0;
  833. static uint8_t local_LED_status = 0;
  834. uint16_t live_state_local = 0;
  835. #define ES_GET_STATE(S) if (READ(S##_PIN)) SBI(live_state_local, S)
  836. #if HAS_X_MIN
  837. ES_GET_STATE(X_MIN);
  838. #endif
  839. #if HAS_X_MAX
  840. ES_GET_STATE(X_MAX);
  841. #endif
  842. #if HAS_Y_MIN
  843. ES_GET_STATE(Y_MIN);
  844. #endif
  845. #if HAS_Y_MAX
  846. ES_GET_STATE(Y_MAX);
  847. #endif
  848. #if HAS_Z_MIN
  849. ES_GET_STATE(Z_MIN);
  850. #endif
  851. #if HAS_Z_MAX
  852. ES_GET_STATE(Z_MAX);
  853. #endif
  854. #if HAS_Z_MIN_PROBE_PIN
  855. ES_GET_STATE(Z_MIN_PROBE);
  856. #endif
  857. #if HAS_X2_MIN
  858. ES_GET_STATE(X2_MIN);
  859. #endif
  860. #if HAS_X2_MAX
  861. ES_GET_STATE(X2_MAX);
  862. #endif
  863. #if HAS_Y2_MIN
  864. ES_GET_STATE(Y2_MIN);
  865. #endif
  866. #if HAS_Y2_MAX
  867. ES_GET_STATE(Y2_MAX);
  868. #endif
  869. #if HAS_Z2_MIN
  870. ES_GET_STATE(Z2_MIN);
  871. #endif
  872. #if HAS_Z2_MAX
  873. ES_GET_STATE(Z2_MAX);
  874. #endif
  875. #if HAS_Z3_MIN
  876. ES_GET_STATE(Z3_MIN);
  877. #endif
  878. #if HAS_Z3_MAX
  879. ES_GET_STATE(Z3_MAX);
  880. #endif
  881. #if HAS_Z4_MIN
  882. ES_GET_STATE(Z4_MIN);
  883. #endif
  884. #if HAS_Z4_MAX
  885. ES_GET_STATE(Z4_MAX);
  886. #endif
  887. uint16_t endstop_change = live_state_local ^ old_live_state_local;
  888. #define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPAIR(" " STRINGIFY(S) ":", TEST(live_state_local, S))
  889. if (endstop_change) {
  890. #if HAS_X_MIN
  891. ES_REPORT_CHANGE(X_MIN);
  892. #endif
  893. #if HAS_X_MAX
  894. ES_REPORT_CHANGE(X_MAX);
  895. #endif
  896. #if HAS_Y_MIN
  897. ES_REPORT_CHANGE(Y_MIN);
  898. #endif
  899. #if HAS_Y_MAX
  900. ES_REPORT_CHANGE(Y_MAX);
  901. #endif
  902. #if HAS_Z_MIN
  903. ES_REPORT_CHANGE(Z_MIN);
  904. #endif
  905. #if HAS_Z_MAX
  906. ES_REPORT_CHANGE(Z_MAX);
  907. #endif
  908. #if HAS_Z_MIN_PROBE_PIN
  909. ES_REPORT_CHANGE(Z_MIN_PROBE);
  910. #endif
  911. #if HAS_X2_MIN
  912. ES_REPORT_CHANGE(X2_MIN);
  913. #endif
  914. #if HAS_X2_MAX
  915. ES_REPORT_CHANGE(X2_MAX);
  916. #endif
  917. #if HAS_Y2_MIN
  918. ES_REPORT_CHANGE(Y2_MIN);
  919. #endif
  920. #if HAS_Y2_MAX
  921. ES_REPORT_CHANGE(Y2_MAX);
  922. #endif
  923. #if HAS_Z2_MIN
  924. ES_REPORT_CHANGE(Z2_MIN);
  925. #endif
  926. #if HAS_Z2_MAX
  927. ES_REPORT_CHANGE(Z2_MAX);
  928. #endif
  929. #if HAS_Z3_MIN
  930. ES_REPORT_CHANGE(Z3_MIN);
  931. #endif
  932. #if HAS_Z3_MAX
  933. ES_REPORT_CHANGE(Z3_MAX);
  934. #endif
  935. #if HAS_Z4_MIN
  936. ES_REPORT_CHANGE(Z4_MIN);
  937. #endif
  938. #if HAS_Z4_MAX
  939. ES_REPORT_CHANGE(Z4_MAX);
  940. #endif
  941. SERIAL_ECHOLNPGM("\n");
  942. analogWrite(pin_t(LED_PIN), local_LED_status);
  943. local_LED_status ^= 255;
  944. old_live_state_local = live_state_local;
  945. }
  946. }
  947. #endif // PINS_DEBUGGING