Compare commits

...

231 Commits

Author SHA1 Message Date
InsanityAutomation 988140a467 Update Configuration_adv.h 2021-03-20 13:42:07 -04:00
InsanityAutomation c320503d78 Merge branch 'bugfix-2.0.x' into FunmatHT 2021-03-20 12:30:49 -04:00
InsanityAutomation d90d15817c Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2021-03-20 11:16:35 -04:00
InsanityAutomation 4479f438fd Merge branch 'FunmatHT' of https://github.com/InsanityAutomation/Marlin into FunmatHT 2021-03-20 11:16:23 -04:00
thinkyhead 5573d98ecc [cron] Bump distribution date (2021-03-20) 2021-03-20 00:13:15 +00:00
Scott Lahteine 38b44e3fc9 HAL eeprom cleanup 2021-03-19 04:51:41 -05:00
Scott Lahteine d4ab2024f5 Fix bool++ warning 2021-03-19 04:51:41 -05:00
ellensp 790bba1556 Fix preflight motherboard target check (#21372)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-19 00:05:30 -05:00
Skorpi08 b51aed8aa5 Nextion TFT touch screen (#21324)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-03-18 20:51:19 -05:00
thinkyhead 1f52112d72 [cron] Bump distribution date (2021-03-19) 2021-03-19 00:13:41 +00:00
Scott Lahteine ad907a51e2 Followup to planner cleanup 2021-03-18 00:11:25 -05:00
Scott Lahteine 6673359d89 Move web-ui out of Marlin root folder 2021-03-17 21:36:30 -05:00
Scott Lahteine 560448afed Revert "Fix small wired EEPROM (#21337)"
Reverting commit cc3e878f90 pending further investigation.
2021-03-17 21:36:30 -05:00
Scott Lahteine deaefbf1dc Minor E3 V2 dwin cleanup 2021-03-17 20:06:16 -05:00
Scott Lahteine 9823a37362 E1+ Autotemp and Planner comments 2021-03-17 20:06:16 -05:00
Scott Lahteine 15bda88d04 Un-pause fans on STOP 2021-03-17 19:25:05 -05:00
Scott Lahteine de73b9b934 Update setup() description 2021-03-17 19:25:05 -05:00
thinkyhead 2fc854eda0 [cron] Bump distribution date (2021-03-18) 2021-03-18 00:15:21 +00:00
Scott Lahteine 60607ed18d mftest: usage with error 2021-03-17 02:39:26 -05:00
thinkyhead 546e56ef3d [cron] Bump distribution date (2021-03-17) 2021-03-17 00:13:28 +00:00
Scott Lahteine dc78e0a250 Detect extra ENVS in preflight checks (#21361) 2021-03-16 17:33:10 -05:00
thinkyhead 5ffa6f3331 [cron] Bump distribution date (2021-03-16) 2021-03-16 00:13:07 +00:00
K.3D 1a23ffd776 KRATOS32 / K.32 board and LCD controllers (#21334) 2021-03-15 11:02:40 -05:00
X-Ryl669 c07f99d5e4 Teensy USB / serial followup (#21316) 2021-03-14 20:23:41 -05:00
thinkyhead ae8be31247 [cron] Bump distribution date (2021-03-15) 2021-03-15 00:13:36 +00:00
Victor Oliveira 4f6910c131 Script to generate Marlin TFT Images (#21340) 2021-03-14 12:14:09 -05:00
X-Ryl669 d787cd3076 Fix build with Meatpack only on 2nd port (#21336)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-14 12:11:11 -05:00
Scott Lahteine cc3e878f90 Fix small wired EEPROM (#21337)
Co-Authored-By: jafal99 <26922965+jafal99@users.noreply.github.com>
2021-03-14 11:43:20 -05:00
XDA-Bam b9b9a3115a Update display timing for SKR Pro (#21346) 2021-03-14 11:42:25 -05:00
thinkyhead 36d3b6aa95 [cron] Bump distribution date (2021-03-14) 2021-03-14 00:13:50 +00:00
InsanityAutomation 911cd1a6d3 Custom menu items confirm option (#21338)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-13 07:37:49 -06:00
Victor Oliveira da84b59ee4 No extra build folder for st/jlink upload (#21341) 2021-03-13 05:01:02 -06:00
thinkyhead 11343bb0ea [cron] Bump distribution date (2021-03-13) 2021-03-13 00:16:55 +00:00
InsanityAutomation e05616ada1 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2021-03-12 16:16:33 -05:00
Scott Lahteine 3107d8a0f4 Tweak opt_set, opt_enable 2021-03-12 09:29:48 -06:00
Scott Lahteine 7f1fa0d1ff Add M207/8/9 reporting (#21335) 2021-03-12 09:25:41 -06:00
Scott Lahteine 604c5dedf4 MarlinSerial cleanup 2021-03-12 08:38:52 -06:00
Scott Lahteine 71f2617263 Pause SD queue early on M25 (#21317) 2021-03-12 08:34:22 -06:00
Scott Lahteine 8532c2b9b6 Fix MarlinSerial typo 2021-03-12 07:37:50 -06:00
Scott Lahteine 1affbe2100 Clean up, optimize ExtUI/TFT code (#21333) 2021-03-12 06:54:42 -06:00
X-Ryl669 9dc2712c47 Undef unused 2nd serial option(s) (#21331)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-12 05:25:30 -06:00
Evgeny Z 6e1024737d Lerdge-X I²C EEPROM pins, size (#21322) 2021-03-11 20:12:24 -06:00
thinkyhead 03a41021de [cron] Bump distribution date (2021-03-12) 2021-03-12 00:13:16 +00:00
thinkyhead a73cff8e4f [cron] Bump distribution date (2021-03-11) 2021-03-11 00:13:08 +00:00
ellensp 8857fc6c4b Fix password menu stickiness before first auth (#21295) 2021-03-10 16:02:35 -06:00
Evgeny Z f671e6d138 Lerdge-K TMC 2208/9 UART pins (#21299) 2021-03-10 15:02:29 -06:00
Keith Bennett 4d6ebf95fc Fix LERDGE 'extends' env references (#21305)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-03-10 14:57:54 -06:00
Cal1sto 8c512191b2 Fix TouchMI stow in G34 (#21291) 2021-03-10 14:37:22 -06:00
X-Ryl669 f147a8990a Fix MeatPack with per-serial-port instances (#21306) 2021-03-10 14:22:20 -06:00
Scott Lahteine 048f6b4731 Tricked-out declaration 2021-03-10 13:45:53 -06:00
Scott Lahteine 9cba3c87ef Update MEATPACK test 2021-03-10 13:45:53 -06:00
Scott Lahteine dbd28eecc9 Number serial from 1 to match settings 2021-03-10 13:45:53 -06:00
Scott Lahteine 2c62886c71 Clean up spaces and words 2021-03-10 13:45:53 -06:00
Scott Lahteine fe0b770033 Fix serial index types 2021-03-10 13:45:53 -06:00
Scott Lahteine b75e682c50 Add binary file transfer test 2021-03-10 13:45:53 -06:00
Victor Mateus Oliveira bb6d718e19 fix meat pack internal buffer for multi serial 2021-03-10 06:55:40 -06:00
thinkyhead 28a136d7f4 [cron] Bump distribution date (2021-03-10) 2021-03-10 00:13:12 +00:00
Chris 10ec5c7f34 Fix LPC + TMC boot loop (#21298) 2021-03-09 17:06:00 -06:00
X-Ryl669 55c31fbe9a Distinguish serial index from mask (#21287) 2021-03-09 03:20:37 -06:00
Victor Oliveira 2f1fd4bbaa Host Keepalive followup (#21290)
Followup to #21283

Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-08 20:01:45 -06:00
thinkyhead 18a10c0db1 [cron] Bump distribution date (2021-03-09) 2021-03-09 00:13:12 +00:00
ellensp aad0f517b4 CUSTOM_USER_BUTTONS followup (#21284)
Followup to #18389
2021-03-08 04:14:18 -06:00
Victor Oliveira 1b9ff68f8c Fix Host Keepalive serial target (#21283)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-08 01:11:37 -06:00
ellensp aa054471f2 M303 followup (#21282)
Followup to f2ed18d150
2021-03-07 22:06:33 -06:00
thinkyhead f2ff75f3a2 [cron] Bump distribution date (2021-03-08) 2021-03-08 00:18:19 +00:00
Keith Bennett 5dc8f5cfab Extend Heater Overshoot Options (#21273)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-03-06 22:55:37 -06:00
ellensp ced1bb9404 Update obsolete debug define (#21276) 2021-03-06 21:43:43 -06:00
thinkyhead 9f14127fd6 [cron] Bump distribution date (2021-03-07) 2021-03-07 00:14:45 +00:00
Mike La Spina b95e548ddb Cooler (for Laser) - M143, M193 (#21255) 2021-03-06 14:13:28 -06:00
InsanityAutomation b4402a789a Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2021-03-06 14:13:22 -05:00
Scott Lahteine 87bef13a4c Fix DGUS include paths
Followup to #20609
2021-03-06 10:20:01 -06:00
Sola 72cc5a49e6 MKS H43 fixup (#21267)
Co-authored-by: makerbase <4164049@qq.com>
Co-authored-by: MKS-Sean <56996910+MKS-Sean@users.noreply.github.com>
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-06 09:04:05 -06:00
ellensp a94fa7b476 Fix Creality DWIN - Broken (bool)Serial ? (#21272)
Co-authored-by: ellensp <ellensp@hotmsil.com>
2021-03-06 07:19:15 -06:00
Scott Lahteine 43b712d42b Pins/tests followup 2021-03-06 06:58:00 -06:00
Keith Bennett 2c5967925f Pins/tests followup (#21268)
Missing commit from #21254
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-06 03:50:26 -06:00
Zs.Antal 4182cf3e9e Update Hungarian language (#21266) 2021-03-06 02:00:10 -06:00
qwewer0 a1796ecace Link to bugfix tree (#21263) 2021-03-06 01:56:43 -06:00
Keith Bennett 3eb8e26174 Tweak/Consolidate followup (#21261) 2021-03-06 01:53:44 -06:00
thinkyhead d05bf563a2 [cron] Bump distribution date (2021-03-06) 2021-03-06 00:12:57 +00:00
Scott Lahteine 3ea56ba4c7 Tweak tests, consolidate pins target validation (#21254) 2021-03-05 04:30:52 -06:00
thinkyhead f56929d0df [cron] Bump distribution date (2021-03-05) 2021-03-05 00:17:19 +00:00
Victor Oliveira 101f09aabd Fix multi-serial CRC error crash (#21249) 2021-03-04 17:39:08 -06:00
Tanguy Pruvot a0d312396a Followup to MP_SCARA/TPARA patches (#21248) 2021-03-04 17:34:38 -06:00
Scott Lahteine 6903a2ffc5 Remove extra G42 2021-03-04 16:36:44 -06:00
Oleksii Zelivianskyi 8dee12ff05 Correct fan pins for MKS Robin Nano v3 (#21238) 2021-03-04 03:33:02 -06:00
Keith Bennett 9299f4e98a SMUFF => SMuFF (#21243) 2021-03-04 03:32:02 -06:00
Scott Lahteine 6225870aa9 Implement G42, after all 2021-03-04 03:28:45 -06:00
Scott Lahteine dad486c01b MK2_MULTIPLEXER dependency 2021-03-04 03:25:48 -06:00
Scott Lahteine 0b7e857614 Update some py scripts 2021-03-03 20:48:58 -06:00
Scott Lahteine 431f6bf3a5 Parking Extruder solenoid fix/cleanup 2021-03-03 20:48:33 -06:00
Scott Lahteine 9372aa99af Fix teensy35 tests 2021-03-03 20:48:33 -06:00
thinkyhead 81c29ecc7e [cron] Bump distribution date (2021-03-04) 2021-03-04 00:17:17 +00:00
Scott Lahteine dd388aedfd TPARA followup 2021-03-03 17:57:24 -06:00
Axel a46e025725 TPARA - 3DOF robot arm IK (#21005)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-03-03 17:46:32 -06:00
Scott Lahteine fd270ddc6c misc. cleanup 2021-03-03 00:18:50 -06:00
Scott Lahteine 369ffe518d Improve opt_set (etc.) used for tests 2021-03-03 00:18:50 -06:00
Sola 0afa4cc957 Fix MKS H43 compile (#21240) 2021-03-02 20:58:42 -06:00
thinkyhead 872f031405 [cron] Bump distribution date (2021-03-03) 2021-03-03 00:15:08 +00:00
Scott Lahteine 35791c6371 Trust XY after Quiet Probing short sleep (#21237) 2021-03-01 19:39:43 -06:00
thinkyhead 137f70b122 [cron] Bump distribution date (2021-03-02) 2021-03-02 00:11:00 +00:00
Scott Lahteine dfa33082bb Fix some config builds 2021-03-01 09:14:17 -06:00
Scott Lahteine b2bc85f6f6 build_all_examples -c -s, silent mftest 2021-03-01 09:14:05 -06:00
Scott Lahteine 21372c3d4e Better mftest order 2021-03-01 09:13:54 -06:00
MoellerDi 7ee9aefed7 G-code Digital Buttons (#18389)
Co-Authored-By: android444 <24375898+android444@users.noreply.github.com>
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-03-01 08:03:41 -06:00
Scott Lahteine 8c9a59c29e Fewer warnings 2021-03-01 06:21:51 -06:00
Scott Lahteine 28404f9e87 POWER_LOSS_ZHOME_POS followup 2021-03-01 06:19:38 -06:00
Nick e66e51fa6d Safe Z homing for Power Loss Recovery (#16909) 2021-03-01 04:23:10 -06:00
Ilya 2b9842e094 Default microsteps to axis first stepper (#21230) 2021-03-01 01:33:07 -06:00
Marcio T f52cba6aff Minor FTDI EVE Touch UI fixes (#21232) 2021-02-28 20:52:59 -06:00
Stephan 713de872ce Filament Runout handling for Mixing Extruder (#20327)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-28 20:16:22 -06:00
Scott Lahteine 1aa421efe5 Filament sensor cleanup 2021-02-28 20:02:24 -06:00
Scott Lahteine dd42831cba Serial macros cleanup 2021-02-28 20:02:24 -06:00
thinkyhead f0b662ff58 [cron] Bump distribution date (2021-03-01) 2021-03-01 00:13:41 +00:00
Roman Moravčík e8ca077f30 Update Slovak language (#21224) 2021-02-28 16:12:27 -06:00
Fabio Viappiani 2328f8b9b8 Fix TERN typo (#21229) 2021-02-28 16:09:15 -06:00
Scott Lahteine 680172a084 Tweaks to build scripts 2021-02-27 23:51:56 -06:00
Giuliano Zaro 254b25296b [SAMD51] Respect serial buffer size (#21194) 2021-02-27 22:41:16 -06:00
Scott Lahteine 903d0b91fc Tweaks to build scripts 2021-02-27 22:38:57 -06:00
Scott Lahteine 54ccfcc705 whitespace 2021-02-27 22:34:54 -06:00
ldursw dfacd260bb ST STM32 platform version 12 (#21219) 2021-02-27 22:32:34 -06:00
RudolphRiedel 04b83d50a2 Two additional EVE displays (#18839) 2021-02-27 19:39:32 -06:00
thinkyhead 1236585693 [cron] Bump distribution date (2021-02-28) 2021-02-28 00:13:36 +00:00
Sola c76008bd6a MKS H43 controller (#20609) 2021-02-27 17:35:32 -06:00
LinFor e0aa9ce372 RGB Caselight (#20341) 2021-02-27 16:06:48 -06:00
jbuck2005 ee7701c15b SPEED => FEEDRATE (#21217) 2021-02-27 15:54:43 -06:00
Evgeny Z 6e1c133e33 Apply AUTO_POWER_CONTROL later in setup() (#21193)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-27 13:50:44 -06:00
Kachidoki 969268166e Duplicate fan speed in M106/7 IDEX Duplication Mode (#21208) 2021-02-27 13:45:12 -06:00
Arjan Mels 83a156ef47 Fix M876 when called from EP (#21210) 2021-02-27 13:32:57 -06:00
Giuliano Zaro 6136959a6a [SAMD51] Postmortem Debugging not implemented (#21211) 2021-02-27 13:24:36 -06:00
Giuliano Zaro 4f840c211c [SMUFF] Use EXTRUDERS for extended commands (#21212) 2021-02-27 13:23:00 -06:00
X-Ryl669 db5967472b Fix G-code Queue merge (#21213) 2021-02-27 13:17:21 -06:00
X-Ryl669 e65a84f6ea G-code Queue followup (#21214) 2021-02-27 13:13:04 -06:00
InsanityAutomation b385758e22 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2021-02-27 11:17:18 -05:00
thinkyhead 526924559f [cron] Bump distribution date (2021-02-27) 2021-02-27 00:12:45 +00:00
Alexander D. Kanevskiy 24623d398c Fix preflight complex extend handling (#21191) 2021-02-26 18:03:11 -06:00
X-Ryl669 56462cf082 Make F_CPU a compile-time constant (#21051) 2021-02-26 17:59:28 -06:00
Victor Oliveira f384f81253 Fix GTR / SKR PRO + USB Flash Drive build (#21197) 2021-02-26 17:36:22 -06:00
Victor Oliveira 427b5d61f4 More LERDGE envs followup (#21205) 2021-02-26 17:33:34 -06:00
Fabio Viappiani e27fba0c06 Fix M355 with NEOPIXEL (#21200) 2021-02-26 17:10:50 -06:00
ldursw 7a1ec78563 Init (stow) BLTouch before X/Y homing (#21192) 2021-02-26 17:01:11 -06:00
X-Ryl669 ec42be346d Fix and improve G-code queue (#21122)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-26 16:54:46 -06:00
thinkyhead ccf990a0d7 [cron] Bump distribution date (2021-02-26) 2021-02-26 00:12:56 +00:00
Scott Lahteine fd77251fdd Chamber followup 2021-02-25 10:24:58 -06:00
Vi B-P f7d9305786 Preheat Menu shortcut option (#20350) 2021-02-25 10:23:17 -06:00
swissnorp bcda46e3f3 Combine Z_AFTER_DEACTIVATE with UNKNOWN_Z_NO_RAISE (#20444)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-25 10:09:00 -06:00
Victor Oliveira 7fc75fc482 Zero Endstops followup (#21188) 2021-02-25 09:23:30 -06:00
qwewer0 45fff07a4c Fix LEVEL_CORNERS_USE_PROBE with BLTOUCH_HS_MODE (#21161) 2021-02-25 09:21:17 -06:00
Scott Lahteine 08d54b3d78 Eryone Thinker V2 (#21190)
Co-Authored-By: Bryan Joshua Pedini <b.pedini@bjphoster.com>
2021-02-25 09:16:19 -06:00
Katelyn Schiesser 735c1b6183 PROBING_HEATERS_OFF sub-option WAIT_FOR_HOTEND (#20835) 2021-02-25 08:33:16 -06:00
ellensp bb1039d4c9 Preflight checks for PlatformIO builds (#21068)
Co-authored-by: Alexander D. Kanevskiy <alexander.kanevskiy@intel.com>
2021-02-25 08:15:55 -06:00
Katelyn Schiesser a21d4c06ae Use 'H' value for UBL G29 z-clearance (#21114) 2021-02-25 08:14:24 -06:00
Scott Lahteine 12468f5e9f Tweak case light comment 2021-02-25 05:15:49 -06:00
deirdreobyrne 468e437390 Allow Zero Endstops (e.g., for CNC) (#21120)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-25 04:49:34 -06:00
Tanguy Pruvot d167af4c38 Add BOARD_PREINIT (for Longer3D open drain pins) (#21159) 2021-02-25 04:35:18 -06:00
Scott Lahteine 3061a31c92 Update BLTOUCH_HS_MODE comment 2021-02-25 01:56:47 -06:00
Nick 73e354b7a0 Fix Anycubic Chiron TFT SD menu (#21183) 2021-02-25 01:38:01 -06:00
X-Ryl669 0cc03f912c Let libmaple accept RX/TX_BUFFER_SIZE (#21177) 2021-02-25 01:26:56 -06:00
X-Ryl669 f003e52009 Combined LPC / Serial fixes (#21178)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-25 01:23:29 -06:00
Scott Lahteine 13c4eef637 Expose more env builds in PlatformIO extension 2021-02-25 00:56:15 -06:00
Victor Oliveira d5b06624fb Fix MKS Robin Nano V3 I2C pins (#21174) 2021-02-24 18:36:55 -06:00
Ken Sanislo a3a10b62f2 Chamber Heater PID (#21156)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-24 18:26:51 -06:00
thinkyhead 03160719eb [cron] Bump distribution date (2021-02-25) 2021-02-25 00:12:36 +00:00
Nick b276a7fd17 Fix Chiron TFT serial comms (#21152) 2021-02-23 20:13:24 -06:00
thinkyhead 37e2250992 [cron] Bump distribution date (2021-02-24) 2021-02-24 00:12:40 +00:00
Scott Lahteine bdb8c07bb2 Outdent UBL code 2021-02-23 16:09:54 -06:00
Scott Lahteine 27f9437d31 G92, subcodes flag cleanup 2021-02-23 16:08:00 -06:00
Marcio T ba301fd800 FTDI Touch UI followup (#21167) 2021-02-23 16:03:40 -06:00
Marcio T 34cda524c4 LVGL Touch UI followup (#21167) 2021-02-22 22:38:54 -06:00
thinkyhead 53d7ae4e9b [cron] Bump distribution date (2021-02-23) 2021-02-23 00:12:43 +00:00
thinkyhead 7a027be255 [cron] Bump distribution date (2021-02-22) 2021-02-22 00:12:47 +00:00
Marcio T ece06c26a9 Enhance and fix FTDI Touch UI (#21148) 2021-02-21 04:05:59 -06:00
X-Ryl669 8d28853774 Postmortem Debugging to serial port (#20492) 2021-02-20 20:22:20 -06:00
kpishere fb8b421aac Fix SPI on SMART RAMPS with mega2560 (#21128) 2021-02-20 20:20:55 -06:00
ellensp b3ecede429 Fix G29 missing defines (#21145)
Co-authored-by: ellensp <ellensp@hotmsil.com>
2021-02-20 20:14:47 -06:00
thinkyhead b8d7925d0d [cron] Bump distribution date (2021-02-21) 2021-02-21 00:13:04 +00:00
thinkyhead 95e0ed2826 [cron] Bump distribution date (2021-02-20) 2021-02-20 00:12:21 +00:00
thinkyhead 11e11b8767 [cron] Bump distribution date (2021-02-19) 2021-02-19 00:12:24 +00:00
espr14 a4c73860a1 Fix cleaning_buffer_counter check (#21115) 2021-02-17 23:22:29 -06:00
thinkyhead 241297b6d6 [cron] Bump distribution date (2021-02-18) 2021-02-18 00:12:54 +00:00
Scott Lahteine 65e24f812f Fixes for MP_SCARA (#21113)
Co-Authored-By: svsergo <52426708+svsergo@users.noreply.github.com>
2021-02-17 17:04:51 -06:00
Vert fd455be55c YHCB2004 followup (#21111) 2021-02-16 21:23:54 -06:00
Scott Lahteine 7e172bf456 Fix IDEX broken endstop test (#21110) 2021-02-16 21:13:53 -06:00
jbuck2005 a211dc03b3 Note FAN2_PIN silkscreen label (#21087) 2021-02-16 20:30:54 -06:00
Vert 490d4a504a GT2560 v4.1B, YHCB2004 SPI character LCD (#21091)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
2021-02-16 20:29:55 -06:00
ellensp c076a7f7a2 Swap Trigorilla Pro Z_MIN / MAX endstop pins (#21095) 2021-02-16 20:28:03 -06:00
X-Ryl669 7b23f41fd4 Fix/improve configs build script (#21086) 2021-02-16 18:41:00 -06:00
thinkyhead f2b9becd7e [cron] Bump distribution date (2021-02-17) 2021-02-17 00:12:26 +00:00
Allen Bauer f298cde47e BTT002 pins for FYSETC mini12864 (#21096) 2021-02-16 17:35:31 -06:00
ellensp 28fa18874b Fix "BUTTON_CLICK redefined" warning (#21098) 2021-02-16 16:59:38 -06:00
thinkyhead e699f9cbf6 [cron] Bump distribution date (2021-02-16) 2021-02-16 00:12:28 +00:00
jbuck2005 31a434b9d7 Update platform ststm32 to 11.0 (#20928) 2021-02-15 06:03:44 -06:00
X-Ryl669 d86910ce94 Script to download & build Configurations (#20992)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-15 05:48:11 -06:00
ellensp 79ee2fa20a EXP headers for RAMPS 1.x (#21054)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-15 05:15:08 -06:00
Giuliano Zaro 9e0fc44210 Fix MMU2 compile error (#21065) 2021-02-15 04:45:38 -06:00
ellensp 35e9c131d6 Fix remaining time divide-by-zero (#21080) 2021-02-15 04:42:33 -06:00
Steven Haigh e27a2a96a0 E3V2 Status Area followup (#21072) 2021-02-14 18:21:47 -06:00
thinkyhead 29fa369f71 [cron] Bump distribution date (2021-02-15) 2021-02-15 00:12:40 +00:00
InsanityAutomation db82a25177 E3V2 DWIN live movement (#21035) 2021-02-14 16:45:36 -06:00
InsanityAutomation b2f77bb050 Use configuration website, fix edit color 2021-02-14 16:42:56 -06:00
Scott Lahteine d9e79fd728 Fix a board comment 2021-02-14 16:27:21 -06:00
Scott Lahteine 52e8d8db54 anet_et4_openblt.py => openblt.py 2021-02-13 22:05:35 -06:00
Scott Lahteine cbf325a6b8 Coolant Control sanity-checks 2021-02-13 22:05:25 -06:00
Giuliano Zaro 8fd88eee2b Don't create unused Serial Port instances (#21066)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
2021-02-13 21:04:22 -06:00
Scott Lahteine 98a27bff0d Allow mftest -t to select by number 2021-02-13 19:06:55 -06:00
Scott Lahteine 00985cffea Update helpful links 2021-02-13 19:05:53 -06:00
thinkyhead 0fe1051101 [cron] Bump distribution date (2021-02-14) 2021-02-14 00:12:44 +00:00
Scott Lahteine fd2477923c Minor serial code cleanup 2021-02-12 19:33:19 -06:00
thinkyhead d4fb372899 [cron] Bump distribution date (2021-02-13) 2021-02-13 00:12:10 +00:00
InsanityAutomation 900047298e Update pins_INTAMSYS40.h 2020-08-01 12:56:16 -04:00
InsanityAutomation c86c85437f Update Configuration_adv.h 2020-08-01 12:54:39 -04:00
InsanityAutomation 18d0e1b365 Update Configuration.h 2020-08-01 12:54:38 -04:00
InsanityAutomation a34b4471b5 more config 2020-08-01 12:54:38 -04:00
InsanityAutomation ae9372bc16 ITS ALIVE! 2020-08-01 12:53:45 -04:00
InsanityAutomation 848e9ea241 progress 2020-08-01 12:53:39 -04:00
InsanityAutomation d21d6f6c9e Support all but motion 2020-08-01 12:52:13 -04:00
InsanityAutomation b35d0c61b9 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-08-01 12:49:56 -04:00
InsanityAutomation 5c1c99da0c Update Configuration_adv.h 2020-07-23 11:47:55 -04:00
InsanityAutomation 261778e540 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-03-30 20:11:40 -04:00
InsanityAutomation 6ee6205e18 Update Configuration.h 2020-03-26 12:25:08 -04:00
InsanityAutomation d47ceb2e8b more config 2020-03-26 10:55:46 -04:00
InsanityAutomation 75beeb7b25 Update pins_INTAMSYS40.h 2020-03-26 09:54:50 -04:00
InsanityAutomation 522735b858 ITS ALIVE! 2020-03-26 09:54:50 -04:00
InsanityAutomation 4f7d610c96 progress 2020-03-26 09:54:50 -04:00
InsanityAutomation d2cee0be7a Support all but motion 2020-03-26 09:54:49 -04:00
InsanityAutomation 20c60fe8f1 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-03-26 09:54:31 -04:00
InsanityAutomation 877b3c65f9 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-03-14 16:28:14 -04:00
InsanityAutomation aa9b6280ff Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-01-29 23:12:48 -05:00
InsanityAutomation 2a9ecf46a5 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-01-27 20:52:29 -05:00
InsanityAutomation cf9a8e184e Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-01-18 23:29:55 -05:00
InsanityAutomation b12fe74d75 Merge branch 'bugfix-2.0.x' of https://github.com/MarlinFirmware/Marlin into bugfix-2.0.x 2020-01-02 23:00:52 -05:00
Scott Lahteine 8b927a283e Fix binary protocol buffer overrun 2019-10-07 19:13:53 -05:00
616 changed files with 20064 additions and 8944 deletions
+198 -97
View File
@@ -1,5 +1,4 @@
/**
* Marlin 3D Printer Firmware
/** Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
@@ -42,35 +41,34 @@
//===========================================================================
/**
* Here are some standard links for getting your machine calibrated:
* Here are some useful links to help get your machine configured and calibrated:
*
* https://reprap.org/wiki/Calibration
* https://youtu.be/wAL9d7FgInk
* http://calculator.josefprusa.cz
* https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
* https://www.thingiverse.com/thing:5573
* https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
* https://www.thingiverse.com/thing:298812
* Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all
*
* Průša Calculator: https://blog.prusaprinters.org/calculator_3416/
*
* Calibration Guides: https://reprap.org/wiki/Calibration
* https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
* https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
* https://youtu.be/wAL9d7FgInk
*
* Calibration Objects: https://www.thingiverse.com/thing:5573
* https://www.thingiverse.com/thing:1278865
*/
//===========================================================================
//============================= DELTA Printer ===============================
//========================== DELTA / SCARA / TPARA ==========================
//===========================================================================
// For a Delta printer, start with one of the configuration files in the config/examples/delta directory
// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
//===========================================================================
//============================= SCARA Printer ===============================
//===========================================================================
// For a SCARA printer, start with one of the configuration files in the config/examples/SCARA directory
// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
// Download configurations from the link above and customize for your machine.
// Examples are located in config/examples/delta, .../SCARA, and .../TPARA.
//
//===========================================================================
// @section info
// Author info of this build printed to the host during boot and M115
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
#define STRING_CONFIG_H_AUTHOR "3DXtech / Insanity Automation" // Who made the changes.
//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
/**
@@ -128,7 +126,7 @@
// Choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
#define MOTHERBOARD BOARD_RAMPS_14_EFB
#define MOTHERBOARD BOARD_INTAMSYS40
#endif
// Name displayed in the LCD "Ready" message and Info menu
@@ -164,8 +162,8 @@
* PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version)
* PRUSA_MMU2 : Průša MMU2
* PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
* SMUFF_EMU_MMU2 : Technik Gegg SMUFF (Průša MMU2 emulation mode)
* SMUFF_EMU_MMU2S : Technik Gegg SMUFF (Průša MMU2S emulation mode)
* SMUFF_EMU_MMU2 : Technik Gegg SMuFF (Průša MMU2 emulation mode)
* SMUFF_EMU_MMU2S : Technik Gegg SMuFF (Průša MMU2S emulation mode)
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* See additional options in Configuration_adv.h.
@@ -312,27 +310,29 @@
* Enable and connect the power supply to the PS_ON_PIN.
* Specify whether the power supply is active HIGH or active LOW.
*/
//#define PSU_CONTROL
#define PSU_CONTROL
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
#define PSU_ACTIVE_STATE HIGH // Set 'LOW' for ATX, 'HIGH' for X-Box
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
//#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)
//#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
#if ENABLED(AUTO_POWER_CONTROL)
#define AUTO_POWER_FANS // Turn on PSU if fans need power
#define AUTO_POWER_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
#define AUTO_POWER_COOLER_FAN
#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) Turn on PSU if the cooler is over this temperature
#define POWER_TIMEOUT 120 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#endif
@@ -408,7 +408,7 @@
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
*/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_0 20
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
@@ -416,9 +416,10 @@
#define TEMP_SENSOR_5 0
#define TEMP_SENSOR_6 0
#define TEMP_SENSOR_7 0
#define TEMP_SENSOR_BED 0
#define TEMP_SENSOR_BED 1
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 0
#define TEMP_SENSOR_CHAMBER 1
#define TEMP_SENSOR_COOLER 0
// Dummy thermistor constant temperature readings, for use with 998 and 999
#define DUMMY_THERMISTOR_998_VALUE 25
@@ -435,14 +436,18 @@
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_RESIDENCY_TIME 3 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 3 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 5 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_RESIDENCY_TIME 5 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_CHAMBER_HYSTERESIS 5 // (°C) Temperature proximity considered "close enough" to the target
// Below this temperature the heater will be switched off
// because it probably indicates a broken thermistor wire.
#define HEATER_0_MINTEMP 5
@@ -454,11 +459,12 @@
#define HEATER_6_MINTEMP 5
#define HEATER_7_MINTEMP 5
#define BED_MINTEMP 5
#define CHAMBER_MINTEMP 5
// Above this temperature the heater will be switched off.
// This can protect components from overheating, but NOT from shorts and failures.
// (Use MINTEMP for thermistor short/failure protection.)
#define HEATER_0_MAXTEMP 275
#define HEATER_0_MAXTEMP 415
#define HEATER_1_MAXTEMP 275
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
@@ -467,6 +473,16 @@
#define HEATER_6_MAXTEMP 275
#define HEATER_7_MAXTEMP 275
#define BED_MAXTEMP 150
#define CHAMBER_MAXTEMP 80
/**
* Thermal Overshoot
* During heatup (and printing) the temperature can often "overshoot" the target by many degrees
* (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees
* a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP.
*/
#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
//===========================================================================
//============================= PID Settings ================================
@@ -480,8 +496,8 @@
#define PID_K1 0.95 // Smoothing factor within any PID loop
#if ENABLED(PIDTEMP)
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
@@ -492,9 +508,9 @@
#define DEFAULT_Ki_LIST { 1.08, 1.08 }
#define DEFAULT_Kd_LIST { 114.00, 114.00 }
#else
#define DEFAULT_Kp 22.20
#define DEFAULT_Ki 1.08
#define DEFAULT_Kd 114.00
#define DEFAULT_Kp 10.5
#define DEFAULT_Ki 0.45
#define DEFAULT_Kd 70
#endif
#endif // PIDTEMP
@@ -515,7 +531,7 @@
* heater. If your configuration is significantly different than this and you don't understand
* the issues involved, don't use bed PID until someone else verifies that your hardware works.
*/
//#define PIDTEMPBED
#define PIDTEMPBED
//#define BED_LIMIT_SWITCHING
@@ -531,16 +547,60 @@
//#define MIN_BED_POWER 0
//#define PID_BED_DEBUG // Sends debug data to the serial port.
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 10.00
#define DEFAULT_bedKi .023
#define DEFAULT_bedKd 305.4
//120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 104.28
#define DEFAULT_bedKi 20.53
#define DEFAULT_bedKd 353.10
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
#if EITHER(PIDTEMP, PIDTEMPBED)
//===========================================================================
//==================== PID > Chamber Temperature Control ====================
//===========================================================================
/**
* PID Chamber Heating
*
* If this option is enabled set PID constants below.
* If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable
* hysteresis.
*
* The PID frequency will be the same as the extruder PWM.
* If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz,
* which is fine for driving a square wave into a resistive load and does not significantly
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
* heater. If your configuration is significantly different than this and you don't understand
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
*/
//#define PIDTEMPCHAMBER
//#define CHAMBER_LIMIT_SWITCHING
/**
* Max Chamber Power
* Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis).
* When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider
* so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER)
*/
#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current
#if ENABLED(PIDTEMPCHAMBER)
#define MIN_CHAMBER_POWER 0
//#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
// and placed inside the small Creality printer enclosure tent.
//
#define DEFAULT_chamberKp 37.04
#define DEFAULT_chamberKi 1.40
#define DEFAULT_chamberKd 655.17
// M309 P37.04 I1.04 D655.17
// FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles.
#endif // PIDTEMPCHAMBER
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
@@ -587,6 +647,7 @@
#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders
#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed
#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber
#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling
//===========================================================================
//============================= Mechanical Settings =========================
@@ -647,13 +708,13 @@
#endif
// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
#define X_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
#define X_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING true // Set to true to invert the logic of the probe.
/**
* Stepper Drivers
@@ -736,14 +797,14 @@
* Override with M92
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 }
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 800, 92.6 }
/**
* Default Max Feed Rate (mm/s)
* Override with M203
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 }
#define DEFAULT_MAX_FEEDRATE { 300, 300, 20, 70 }
//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2
#if ENABLED(LIMITED_MAX_FR_EDITING)
@@ -756,7 +817,7 @@
* Override with M201
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 }
#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 }
//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
@@ -783,7 +844,7 @@
* When changing speed and direction, if the difference is less than the
* value set here, it may happen instantaneously.
*/
//#define CLASSIC_JERK
#define CLASSIC_JERK
#if ENABLED(CLASSIC_JERK)
#define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.0
@@ -820,7 +881,7 @@
*
* See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained
*/
//#define S_CURVE_ACCELERATION
#define S_CURVE_ACCELERATION
//===========================================================================
//============================= Z Probe Options =============================
@@ -993,13 +1054,13 @@
#define PROBING_MARGIN 10
// X and Y axis travel speed (mm/min) between probes
#define XY_PROBE_SPEED (133*60)
#define XY_PROBE_FEEDRATE (133*60)
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
#define Z_PROBE_SPEED_FAST (4*60)
#define Z_PROBE_FEEDRATE_FAST (4*60)
// Feedrate (mm/min) for the "accurate" probe of each point
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2)
/**
* Probe Activation Switch
@@ -1062,8 +1123,8 @@
#define Z_PROBE_LOW_POINT -2 // Farthest distance below the trigger-point to go before stopping
// For M851 give a range for adjusting the Z probe offset
#define Z_PROBE_OFFSET_RANGE_MIN -20
#define Z_PROBE_OFFSET_RANGE_MAX 20
#define Z_PROBE_OFFSET_RANGE_MIN -9
#define Z_PROBE_OFFSET_RANGE_MAX 9
// Enable the M48 repeatability test to test probe accuracy
//#define Z_MIN_PROBE_REPEATABILITY_TEST
@@ -1084,6 +1145,7 @@
//#define PROBING_HEATERS_OFF // Turn heaters off when probing
#if ENABLED(PROBING_HEATERS_OFF)
//#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy)
//#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude)
#endif
//#define PROBING_FANS_OFF // Turn fans off when probing
//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
@@ -1120,9 +1182,9 @@
// @section machine
// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
#define INVERT_X_DIR false
#define INVERT_Y_DIR true
#define INVERT_Z_DIR false
#define INVERT_X_DIR true
#define INVERT_Y_DIR false
#define INVERT_Z_DIR true
// @section extruder
@@ -1140,7 +1202,13 @@
//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety.
//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety.
//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
/**
* Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled.
* - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed.
* - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle.
*/
//#define Z_IDLE_HEIGHT Z_HOME_POS
//#define Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
// Be sure to have this much clearance over your Z_MAX_POS to prevent grinding.
@@ -1156,8 +1224,8 @@
// @section machine
// The size of the print bed
#define X_BED_SIZE 200
#define Y_BED_SIZE 200
#define X_BED_SIZE 260
#define Y_BED_SIZE 260
// Travel limits (mm) after homing, corresponding to endstop positions.
#define X_MIN_POS 0
@@ -1165,7 +1233,7 @@
#define Z_MIN_POS 0
#define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 200
#define Z_MAX_POS 260
/**
* Software Endstops
@@ -1193,7 +1261,7 @@
#endif
#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
//#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD
#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD
#endif
/**
@@ -1209,7 +1277,7 @@
* RAMPS-based boards use SERVO3_PIN for the first runout sensor.
* For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc.
*/
//#define FILAMENT_RUNOUT_SENSOR
#define FILAMENT_RUNOUT_SENSOR
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500.
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
@@ -1217,6 +1285,8 @@
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
//#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder.
// This is automatically enabled for MIXING_EXTRUDERs.
// Override individually if the runout sensors vary
//#define FIL_RUNOUT1_STATE LOW
@@ -1251,14 +1321,15 @@
//#define FIL_RUNOUT8_PULLUP
//#define FIL_RUNOUT8_PULLDOWN
// Set one or more commands to execute on filament runout.
// (After 'M412 H' Marlin will ask the host to handle the process.)
// Commands to execute on filament runout.
// With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c")
// NOTE: After 'M412 H1' the host handles filament runout and this script does not apply.
#define FILAMENT_RUNOUT_SCRIPT "M600"
// After a runout is detected, continue printing this length of filament
// before executing the runout script. Useful for a sensor at the end of
// a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead.
//#define FILAMENT_RUNOUT_DISTANCE_MM 25
#define FILAMENT_RUNOUT_DISTANCE_MM 5
#ifdef FILAMENT_RUNOUT_DISTANCE_MM
// Enable this option to use an encoder disc that toggles the runout pin
@@ -1310,14 +1381,14 @@
//#define AUTO_BED_LEVELING_LINEAR
//#define AUTO_BED_LEVELING_BILINEAR
//#define AUTO_BED_LEVELING_UBL
//#define MESH_BED_LEVELING
#define MESH_BED_LEVELING
/**
* Normally G28 leaves leveling disabled on completion. Enable one of
* these options to restore the prior leveling state or to always enable
* leveling immediately after G28.
*/
//#define RESTORE_LEVELING_AFTER_G28
#define RESTORE_LEVELING_AFTER_G28
//#define ENABLE_LEVELING_AFTER_G28
/**
@@ -1354,7 +1425,7 @@
/**
* Enable the G26 Mesh Validation Pattern tool.
*/
//#define G26_MESH_VALIDATION
#define G26_MESH_VALIDATION
#if ENABLED(G26_MESH_VALIDATION)
#define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle.
#define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26.
@@ -1419,7 +1490,7 @@
//===========================================================================
#define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed
#define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited.
#define GRID_MAX_POINTS_X 5 // Don't use more than 7 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
//#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS
@@ -1430,16 +1501,16 @@
* Add a bed leveling sub-menu for ABL or MBL.
* Include a guided procedure if manual probing is enabled.
*/
//#define LCD_BED_LEVELING
#define LCD_BED_LEVELING
#if ENABLED(LCD_BED_LEVELING)
#define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis.
#define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
//#define MESH_EDIT_MENU // Add a menu to edit mesh points
#define MESH_EDIT_MENU // Add a menu to edit mesh points
#endif
// Add a menu item to move between bed corners for manual bed adjustment
//#define LEVEL_BED_CORNERS
#define LEVEL_BED_CORNERS
#if ENABLED(LEVEL_BED_CORNERS)
#define LEVEL_CORNERS_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
@@ -1584,12 +1655,12 @@
* M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes)
* M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.)
*/
//#define EEPROM_SETTINGS // Persistent storage with M500 and M501
#define EEPROM_SETTINGS // Persistent storage with M500 and M501
//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release!
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
//#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
#endif
//
@@ -1620,11 +1691,13 @@
#define PREHEAT_1_LABEL "PLA"
#define PREHEAT_1_TEMP_HOTEND 180
#define PREHEAT_1_TEMP_BED 70
#define PREHEAT_1_TEMP_CHAMBER 35
#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255
#define PREHEAT_2_LABEL "ABS"
#define PREHEAT_2_TEMP_HOTEND 240
#define PREHEAT_2_TEMP_BED 110
#define PREHEAT_2_TEMP_CHAMBER 45
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
/**
@@ -1638,11 +1711,11 @@
* P1 Raise the nozzle always to Z-park height.
* P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS.
*/
//#define NOZZLE_PARK_FEATURE
#define NOZZLE_PARK_FEATURE
#if ENABLED(NOZZLE_PARK_FEATURE)
// Specify a park position as { X, Y, Z_raise }
#define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
#define NOZZLE_PARK_POINT { (X_CENTER), (Y_CENTER), 20 }
//#define NOZZLE_PARK_X_ONLY // X move only is required to park
//#define NOZZLE_PARK_Y_ONLY // Y move only is required to park
#define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance
@@ -1846,7 +1919,7 @@
* SD Card support is disabled by default. If your controller has an SD slot,
* you must uncomment the following option or it won't work.
*/
//#define SDSUPPORT
#define SDSUPPORT
/**
* SD CARD: ENABLE CRC
@@ -1916,7 +1989,7 @@
//
// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu.
//
//#define INDIVIDUAL_AXIS_HOMING_MENU
#define INDIVIDUAL_AXIS_HOMING_MENU
//
// SPEAKER/BUZZER
@@ -1924,7 +1997,7 @@
// If you have a speaker that can produce tones, enable it here.
// By default Marlin assumes you have a buzzer with a fixed frequency.
//
//#define SPEAKER
#define SPEAKER
//
// The duration and frequency for the UI feedback sound.
@@ -1949,6 +2022,14 @@
//
//#define REPRAP_DISCOUNT_SMART_CONTROLLER
//
// GT2560 (YHCB2004) LCD Display
//
// Requires Testato, Koepel softwarewire library and
// Andriy Golovnya's LiquidCrystal_AIP31068 library.
//
//#define YHCB2004
//
// Original RADDS LCD Display+Encoder+SDCardReader
// http://doku.radds.org/dokumentation/lcd-display/
@@ -2097,7 +2178,12 @@
// RepRapDiscount FULL GRAPHIC Smart Controller
// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
//
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
//
// K.3D Full Graphic Smart Controller
//
//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER
//
// ReprapWorld Graphical LCD
@@ -2236,7 +2322,7 @@
//#define OLED_PANEL_TINYBOY2
//
// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER
// MKS OLED 1.3" 128×64 Full Graphics Controller
// https://reprap.org/wiki/MKS_12864OLED
//
// Tiny, but very sharp OLED display
@@ -2245,7 +2331,7 @@
//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller
//
// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER
// Zonestar OLED 128×64 Full Graphics Controller
//
//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller
//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default)
@@ -2262,10 +2348,15 @@
//#define OVERLORD_OLED
//
// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB
// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB
// Where to find : https://www.aliexpress.com/item/4000345255731.html
//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller
//
// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller
//
//#define K3D_242_OLED_CONTROLLER // Software SPI
//=============================================================================
//========================== Extensible UI Displays ===========================
//=============================================================================
@@ -2278,6 +2369,7 @@
//#define DGUS_LCD_UI_ORIGIN
//#define DGUS_LCD_UI_FYSETC
//#define DGUS_LCD_UI_HIPRECY
//#define DGUS_LCD_UI_MKS
//
// Touch-screen LCD for Malyan M200/M300 printers
@@ -2303,6 +2395,14 @@
//#define ANYCUBIC_LCD_DEBUG
#endif
//
// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028
//
//#define NEXTION_TFT
#if ENABLED(NEXTION_TFT)
#define LCD_SERIAL_PORT 1 // Default is 1 for Nextion
#endif
//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extui'.
@@ -2579,6 +2679,7 @@
// Use a single NeoPixel LED for static (background) lighting
//#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use
//#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W
//#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off
#endif
/**
+294 -180
View File
@@ -113,6 +113,12 @@
#define CHAMBER_BETA 3950 // Beta value
#endif
#if TEMP_SENSOR_COOLER == 1000
#define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
#define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
#define COOLER_BETA 3950 // Beta value
#endif
#if TEMP_SENSOR_PROBE == 1000
#define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
#define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
@@ -143,13 +149,17 @@
//
// Heated Chamber options
//
#if DISABLED(PIDTEMPCHAMBER)
#define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control
#if ENABLED(CHAMBER_LIMIT_SWITCHING)
#define CHAMBER_HYSTERESIS 5 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS
#endif
#endif
#if TEMP_SENSOR_CHAMBER
#define CHAMBER_MINTEMP 5
#define CHAMBER_MAXTEMP 60
#define TEMP_CHAMBER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
//#define CHAMBER_LIMIT_SWITCHING
//#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin
//#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug)
//#define HEATER_CHAMBER_INVERTING false
//#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug)
//#define CHAMBER_FAN // Enable a fan on the chamber
#if ENABLED(CHAMBER_FAN)
@@ -175,6 +185,25 @@
#endif
#endif
//
// Laser Cooler options
//
#if TEMP_SENSOR_COOLER
#define COOLER_MINTEMP 8 // (°C)
#define COOLER_MAXTEMP 26 // (°C)
#define COOLER_DEFAULT_TEMP 16 // (°C)
#define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
#define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element e.g. TEC, External chiller via relay
#define COOLER_INVERTING false
#define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required.
#define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc.
#define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g.
#if ENABLED(COOLER_FAN)
#define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target
#define COOLER_FAN_FACTOR 25 // PWM increase per °C above target
#endif
#endif
/**
* Thermal Protection provides additional protection to your printer from damage
* and fire. Marlin always includes safe min and max temperature ranges which
@@ -192,12 +221,12 @@
* THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD
*/
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
#define THERMAL_PROTECTION_PERIOD 70 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius
//#define ADAPTIVE_FAN_SLOWING // Slow part cooling fan if temperature drops
#define ADAPTIVE_FAN_SLOWING // Slow part cooling fan if temperature drops
#if BOTH(ADAPTIVE_FAN_SLOWING, PIDTEMP)
//#define NO_FAN_SLOWING_IN_PID_TUNING // Don't slow fan speed during M303
#define NO_FAN_SLOWING_IN_PID_TUNING // Don't slow fan speed during M303
#endif
/**
@@ -212,7 +241,7 @@
* and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set
* below 2.
*/
#define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_PERIOD 40 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
#endif
@@ -220,30 +249,44 @@
* Thermal Protection parameters for the bed are just as above for hotends.
*/
#if ENABLED(THERMAL_PROTECTION_BED)
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_PERIOD 30 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
/**
* As described above, except for the bed (M140/M190/M303).
*/
#define WATCH_BED_TEMP_PERIOD 60 // Seconds
#define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius
#define WATCH_BED_TEMP_INCREASE 1 // Degrees Celsius
#endif
/**
* Thermal Protection parameters for the heated chamber.
*/
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
#define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_CHAMBER_PERIOD 60 // Seconds
#define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // Degrees Celsius
/**
* Heated chamber watch settings (M141/M191).
*/
#define WATCH_CHAMBER_TEMP_PERIOD 60 // Seconds
#define WATCH_CHAMBER_TEMP_PERIOD 360 // Seconds
#define WATCH_CHAMBER_TEMP_INCREASE 2 // Degrees Celsius
#endif
/**
* Thermal Protection parameters for the laser cooler.
*/
#if ENABLED(THERMAL_PROTECTION_COOLER)
#define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds
#define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius
/**
* Laser cooling watch settings (M143/M193).
*/
#define WATCH_COOLER_TEMP_PERIOD 60 // Seconds
#define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius
#endif
#if ENABLED(PIDTEMP)
// Add an experimental additional term to the heater power, proportional to the extrusion speed.
// A well-chosen Kc value should add just enough power to melt the increased material volume.
@@ -489,11 +532,15 @@
#define E6_AUTO_FAN_PIN -1
#define E7_AUTO_FAN_PIN -1
#define CHAMBER_AUTO_FAN_PIN -1
#define COOLER_AUTO_FAN_PIN -1
#define COOLER_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed
#define CHAMBER_AUTO_FAN_TEMPERATURE 30
#define CHAMBER_AUTO_FAN_SPEED 255
#define COOLER_AUTO_FAN_TEMPERATURE 18
#define COOLER_AUTO_FAN_SPEED 255
/**
* Part-Cooling Fan Multiplexer
@@ -509,18 +556,23 @@
/**
* M355 Case Light on-off / brightness
*/
//#define CASE_LIGHT_ENABLE
#define CASE_LIGHT_ENABLE
#if ENABLED(CASE_LIGHT_ENABLE)
//#define CASE_LIGHT_PIN 4 // Override the default pin if needed
#define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW
#define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin)
//#define CASE_LIGHT_MAX_PWM 128 // Limit pwm
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 255 // Set default power-up brightness (0-255, requires PWM pin)
#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
//#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255)
//#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
//#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light, requires NEOPIXEL_LED.
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
#define CASE_LIGHT_NEOPIXEL_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
#if ENABLED(NEOPIXEL_LED)
//#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light
#endif
#if EITHER(RGB_LED, RGBW_LED)
//#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light
#endif
#if EITHER(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED)
#define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
#endif
#endif
@@ -672,7 +724,7 @@
//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (mm) Backoff from endstops after homing
//#define QUICK_HOME // If G28 contains XY do a diagonal move first
#define QUICK_HOME // If G28 contains XY do a diagonal move first
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe).
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
@@ -736,8 +788,8 @@
/**
* Use "HIGH SPEED" mode for probing.
* Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems.
* This feature was designed for Delta's with very fast Z moves however higher speed cartesians may function
* If the machine cannot raise the probe fast enough after a trigger, it may enter a fault state.
* This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians
* might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM.
*/
//#define BLTOUCH_HS_MODE
@@ -846,10 +898,10 @@
//#define MULTI_NOZZLE_DUPLICATION
// By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
#define INVERT_X_STEP_PIN false
#define INVERT_Y_STEP_PIN false
#define INVERT_Z_STEP_PIN false
#define INVERT_E_STEP_PIN false
#define INVERT_X_STEP_PIN true
#define INVERT_Y_STEP_PIN true
#define INVERT_Z_STEP_PIN true
#define INVERT_E_STEP_PIN true
/**
* Idle Stepper Shutdown
@@ -862,9 +914,6 @@
#define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part!
#define DISABLE_INACTIVE_E true
// If the Nozzle or Bed falls when the Z stepper is disabled, set its resting position here.
//#define Z_AFTER_DEACTIVATE Z_HOME_POS
// Default Minimum Feedrates for printing and travel moves
#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S.
#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T.
@@ -923,7 +972,7 @@
// increments while checking for the contact to be broken.
#define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm)
#define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm)
#define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/min)
#define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min)
#endif
#endif
#endif
@@ -1026,7 +1075,7 @@
* M908 - BQ_ZUM_MEGA_3D, RAMBO, PRINTRBOARD_REVF, RIGIDBOARD_V2 & SCOOVO_X9H
* M909, M910 & LCD - only PRINTRBOARD_REVF & RIGIDBOARD_V2
*/
//#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps
#define PWM_MOTOR_CURRENT { 1300, 1300, 1250 } // Values in milliamps
//#define DIGIPOT_MOTOR_CURRENT { 135,135,135,135,135 } // Values 0-255 (RAMBO 135 = ~0.75A, 185 = ~1A)
//#define DAC_MOTOR_CURRENT_DEFAULT { 70, 80, 90, 80 } // Default drive percent - X, Y, Z, E axis
@@ -1143,11 +1192,14 @@
#endif
#endif
// Insert a menu for preheating at the top level to allow for quick access
//#define PREHEAT_SHORTCUT_MENU_ITEM
#endif // HAS_LCD_MENU
#if HAS_DISPLAY
// The timeout (in ms) to return to the status screen from sub-menus
//#define LCD_TIMEOUT_TO_STATUS 15000
#define LCD_TIMEOUT_TO_STATUS 15000
#if ENABLED(SHOW_BOOTSCREEN)
#define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
@@ -1157,13 +1209,13 @@
#endif
// Scroll a longer status message into view
//#define STATUS_MESSAGE_SCROLLING
#define STATUS_MESSAGE_SCROLLING
// On the Info Screen, display XY with one decimal place when possible
//#define LCD_DECIMAL_SMALL_XY
// Add an 'M73' G-code to set the current percentage
//#define LCD_SET_PROGRESS_MANUALLY
#define LCD_SET_PROGRESS_MANUALLY
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
@@ -1247,7 +1299,6 @@
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
//#define POWER_LOSS_RECOVER_ZHOME // Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
//#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
@@ -1259,6 +1310,12 @@
// Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card,
// especially with "vase mode" printing. Set too high and vases cannot be continued.
#define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data
// Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#define POWER_LOSS_RECOVER_ZHOME
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
//#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed
#endif
#endif
/**
@@ -1304,10 +1361,10 @@
//#define UTF_FILENAME_SUPPORT
// This allows hosts to request long names for files and folders with M33
//#define LONG_FILENAME_HOST_SUPPORT
#define LONG_FILENAME_HOST_SUPPORT
// Enable this option to scroll long filenames in the SD card menu
//#define SCROLL_LONG_FILENAMES
#define SCROLL_LONG_FILENAMES
// Leave the heaters on after Stop Print (not recommended!)
//#define SD_ABORT_NO_COOLDOWN
@@ -1329,7 +1386,7 @@
/**
* Auto-report SdCard status with M27 S<seconds>
*/
//#define AUTO_REPORT_SD_STATUS
#define AUTO_REPORT_SD_STATUS
/**
* Support for USB thumb drives using an Arduino USB Host Shield or
@@ -1481,10 +1538,12 @@
#define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating
#define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating
//#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active
//#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling
//#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap
//#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap
//#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames
//#define STATUS_HEAT_PERCENT // Show heating in a progress bar
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving 399 bytes of flash)
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of PROGMEM.
// Frivolous Game Options
@@ -1508,12 +1567,12 @@
#define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates
#if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY)
#if ANY(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS, DGUS_LCD_UI_HIPRECY)
#define DGUS_PRINT_FILENAME // Display the filename during printing
#define DGUS_PREHEAT_UI // Display a preheat screen during heatup
#if ENABLED(DGUS_LCD_UI_FYSETC)
//#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for UI_FYSETC
#if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS)
//#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS
#else
#define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY
#endif
@@ -1556,6 +1615,8 @@
//#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480)
//#define LCD_ALEPHOBJECTS_CLCD_UI // Aleph Objects Color LCD UI
//#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480)
//#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815
//#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813
// Correct the resolution if not using the stock TFT panel.
//#define TOUCH_UI_320x240
@@ -1675,33 +1736,34 @@
*
* Warning: Does not respect endstops!
*/
//#define BABYSTEPPING
#define BABYSTEPPING
#if ENABLED(BABYSTEPPING)
//#define INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR
#define INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR
//#define BABYSTEP_WITHOUT_HOMING
//#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement).
#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement).
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
#define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way
//#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps
#define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep
#define BABYSTEP_MULTIPLICATOR_Z 20 // (steps or mm) Steps or millimeter distance for each Z babystep
#define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep
//#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
#if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING)
#define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
// Note: Extra time may be added to mitigate controller latency.
#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement).
//#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle.
#if ENABLED(MOVE_Z_WHEN_IDLE)
#define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size.
#endif
#endif
//#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28
#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28
//#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
//#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets
//#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
#endif
#endif
@@ -2012,6 +2074,12 @@
//#define SERIAL_STATS_DROPPED_RX
#endif
// Monitor RX buffer usage
// Dump an error to the serial port if the serial receive buffer overflows.
// If you see these errors, increase the RX_BUFFER_SIZE value.
// Not supported on all platforms.
//#define RX_BUFFER_MONITOR
/**
* Emergency Command Parser
*
@@ -2020,16 +2088,16 @@
* Currently handles M108, M112, M410, M876
* NOTE: Not yet implemented for all platforms.
*/
//#define EMERGENCY_PARSER
#define EMERGENCY_PARSER
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.
// This "wait" is only sent when the buffer is empty. 1 second is a good value here.
//#define NO_TIMEOUTS 1000 // Milliseconds
#define NO_TIMEOUTS 1000 // Milliseconds
// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary.
//#define ADVANCED_OK
#define ADVANCED_OK
// Printrun may have trouble receiving long strings all at once.
// This option inserts short delays between lines of serial output.
@@ -2163,7 +2231,7 @@
* Requires NOZZLE_PARK_FEATURE.
* This feature is required for the default FILAMENT_RUNOUT_SCRIPT.
*/
//#define ADVANCED_PAUSE_FEATURE
#define ADVANCED_PAUSE_FEATURE
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate.
#define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract.
@@ -2189,7 +2257,7 @@
// Filament can be extruded repeatedly from the Filament Change menu
// until extrusion is consistent, and to purge old filament.
#define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park.
//#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
// Filament Unload does a Retract, Delay, and Purge first:
#define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length.
@@ -2198,14 +2266,14 @@
#define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
#define FILAMENT_CHANGE_ALERT_BEEPS 2 // Number of alert beeps to play when a response is needed.
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
//#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
//#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
//#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
#endif
// @section tmc
@@ -2227,7 +2295,7 @@
#if AXIS_DRIVER_TYPE_X2(TMC26X)
#define X2_MAX_CURRENT 1000
#define X2_SENSE_RESISTOR 91
#define X2_MICROSTEPS 16
#define X2_MICROSTEPS X_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Y(TMC26X)
@@ -2239,7 +2307,7 @@
#if AXIS_DRIVER_TYPE_Y2(TMC26X)
#define Y2_MAX_CURRENT 1000
#define Y2_SENSE_RESISTOR 91
#define Y2_MICROSTEPS 16
#define Y2_MICROSTEPS Y_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z(TMC26X)
@@ -2251,19 +2319,19 @@
#if AXIS_DRIVER_TYPE_Z2(TMC26X)
#define Z2_MAX_CURRENT 1000
#define Z2_SENSE_RESISTOR 91
#define Z2_MICROSTEPS 16
#define Z2_MICROSTEPS Z_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
#define Z3_MAX_CURRENT 1000
#define Z3_SENSE_RESISTOR 91
#define Z3_MICROSTEPS 16
#define Z3_MICROSTEPS Z_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
#define Z4_MAX_CURRENT 1000
#define Z4_SENSE_RESISTOR 91
#define Z4_MICROSTEPS 16
#define Z4_MICROSTEPS Z_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
@@ -2275,43 +2343,43 @@
#if AXIS_DRIVER_TYPE_E1(TMC26X)
#define E1_MAX_CURRENT 1000
#define E1_SENSE_RESISTOR 91
#define E1_MICROSTEPS 16
#define E1_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E2(TMC26X)
#define E2_MAX_CURRENT 1000
#define E2_SENSE_RESISTOR 91
#define E2_MICROSTEPS 16
#define E2_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E3(TMC26X)
#define E3_MAX_CURRENT 1000
#define E3_SENSE_RESISTOR 91
#define E3_MICROSTEPS 16
#define E3_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E4(TMC26X)
#define E4_MAX_CURRENT 1000
#define E4_SENSE_RESISTOR 91
#define E4_MICROSTEPS 16
#define E4_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E5(TMC26X)
#define E5_MAX_CURRENT 1000
#define E5_SENSE_RESISTOR 91
#define E5_MICROSTEPS 16
#define E5_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E6(TMC26X)
#define E6_MAX_CURRENT 1000
#define E6_SENSE_RESISTOR 91
#define E6_MICROSTEPS 16
#define E6_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E7(TMC26X)
#define E7_MAX_CURRENT 1000
#define E7_SENSE_RESISTOR 91
#define E7_MICROSTEPS 16
#define E7_MICROSTEPS E0_MICROSTEPS
#endif
#endif // TMC26X
@@ -2356,7 +2424,7 @@
#if AXIS_IS_TMC(X2)
#define X2_CURRENT 800
#define X2_CURRENT_HOME X2_CURRENT
#define X2_MICROSTEPS 16
#define X2_MICROSTEPS X_MICROSTEPS
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
//#define X2_INTERPOLATE true
@@ -2374,7 +2442,7 @@
#if AXIS_IS_TMC(Y2)
#define Y2_CURRENT 800
#define Y2_CURRENT_HOME Y2_CURRENT
#define Y2_MICROSTEPS 16
#define Y2_MICROSTEPS Y_MICROSTEPS
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
//#define Y2_INTERPOLATE true
@@ -2392,7 +2460,7 @@
#if AXIS_IS_TMC(Z2)
#define Z2_CURRENT 800
#define Z2_CURRENT_HOME Z2_CURRENT
#define Z2_MICROSTEPS 16
#define Z2_MICROSTEPS Z_MICROSTEPS
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
//#define Z2_INTERPOLATE true
@@ -2401,7 +2469,7 @@
#if AXIS_IS_TMC(Z3)
#define Z3_CURRENT 800
#define Z3_CURRENT_HOME Z3_CURRENT
#define Z3_MICROSTEPS 16
#define Z3_MICROSTEPS Z_MICROSTEPS
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
//#define Z3_INTERPOLATE true
@@ -2410,7 +2478,7 @@
#if AXIS_IS_TMC(Z4)
#define Z4_CURRENT 800
#define Z4_CURRENT_HOME Z4_CURRENT
#define Z4_MICROSTEPS 16
#define Z4_MICROSTEPS Z_MICROSTEPS
#define Z4_RSENSE 0.11
#define Z4_CHAIN_POS -1
//#define Z4_INTERPOLATE true
@@ -2426,7 +2494,7 @@
#if AXIS_IS_TMC(E1)
#define E1_CURRENT 800
#define E1_MICROSTEPS 16
#define E1_MICROSTEPS E0_MICROSTEPS
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
//#define E1_INTERPOLATE true
@@ -2434,7 +2502,7 @@
#if AXIS_IS_TMC(E2)
#define E2_CURRENT 800
#define E2_MICROSTEPS 16
#define E2_MICROSTEPS E0_MICROSTEPS
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
//#define E2_INTERPOLATE true
@@ -2442,7 +2510,7 @@
#if AXIS_IS_TMC(E3)
#define E3_CURRENT 800
#define E3_MICROSTEPS 16
#define E3_MICROSTEPS E0_MICROSTEPS
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
//#define E3_INTERPOLATE true
@@ -2450,7 +2518,7 @@
#if AXIS_IS_TMC(E4)
#define E4_CURRENT 800
#define E4_MICROSTEPS 16
#define E4_MICROSTEPS E0_MICROSTEPS
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
//#define E4_INTERPOLATE true
@@ -2458,7 +2526,7 @@
#if AXIS_IS_TMC(E5)
#define E5_CURRENT 800
#define E5_MICROSTEPS 16
#define E5_MICROSTEPS E0_MICROSTEPS
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
//#define E5_INTERPOLATE true
@@ -2466,7 +2534,7 @@
#if AXIS_IS_TMC(E6)
#define E6_CURRENT 800
#define E6_MICROSTEPS 16
#define E6_MICROSTEPS E0_MICROSTEPS
#define E6_RSENSE 0.11
#define E6_CHAIN_POS -1
//#define E6_INTERPOLATE true
@@ -2474,7 +2542,7 @@
#if AXIS_IS_TMC(E7)
#define E7_CURRENT 800
#define E7_MICROSTEPS 16
#define E7_MICROSTEPS E0_MICROSTEPS
#define E7_RSENSE 0.11
#define E7_CHAIN_POS -1
//#define E7_INTERPOLATE true
@@ -2749,138 +2817,138 @@
#endif
#if AXIS_IS_L64XX(X2)
#define X2_MICROSTEPS 128
#define X2_OVERCURRENT 2000
#define X2_STALLCURRENT 1500
#define X2_MAX_VOLTAGE 127
#define X2_CHAIN_POS -1
#define X2_SLEW_RATE 1
#define X2_MICROSTEPS X_MICROSTEPS
#define X2_OVERCURRENT 2000
#define X2_STALLCURRENT 1500
#define X2_MAX_VOLTAGE 127
#define X2_CHAIN_POS -1
#define X2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Y)
#define Y_MICROSTEPS 128
#define Y_OVERCURRENT 2000
#define Y_STALLCURRENT 1500
#define Y_MAX_VOLTAGE 127
#define Y_CHAIN_POS -1
#define Y_SLEW_RATE 1
#define Y_MICROSTEPS 128
#define Y_OVERCURRENT 2000
#define Y_STALLCURRENT 1500
#define Y_MAX_VOLTAGE 127
#define Y_CHAIN_POS -1
#define Y_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Y2)
#define Y2_MICROSTEPS 128
#define Y2_OVERCURRENT 2000
#define Y2_STALLCURRENT 1500
#define Y2_MAX_VOLTAGE 127
#define Y2_CHAIN_POS -1
#define Y2_SLEW_RATE 1
#define Y2_MICROSTEPS Y_MICROSTEPS
#define Y2_OVERCURRENT 2000
#define Y2_STALLCURRENT 1500
#define Y2_MAX_VOLTAGE 127
#define Y2_CHAIN_POS -1
#define Y2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z)
#define Z_MICROSTEPS 128
#define Z_OVERCURRENT 2000
#define Z_STALLCURRENT 1500
#define Z_MAX_VOLTAGE 127
#define Z_CHAIN_POS -1
#define Z_SLEW_RATE 1
#define Z_MICROSTEPS 128
#define Z_OVERCURRENT 2000
#define Z_STALLCURRENT 1500
#define Z_MAX_VOLTAGE 127
#define Z_CHAIN_POS -1
#define Z_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z2)
#define Z2_MICROSTEPS 128
#define Z2_OVERCURRENT 2000
#define Z2_STALLCURRENT 1500
#define Z2_MAX_VOLTAGE 127
#define Z2_CHAIN_POS -1
#define Z2_SLEW_RATE 1
#define Z2_MICROSTEPS Z_MICROSTEPS
#define Z2_OVERCURRENT 2000
#define Z2_STALLCURRENT 1500
#define Z2_MAX_VOLTAGE 127
#define Z2_CHAIN_POS -1
#define Z2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z3)
#define Z3_MICROSTEPS 128
#define Z3_OVERCURRENT 2000
#define Z3_STALLCURRENT 1500
#define Z3_MAX_VOLTAGE 127
#define Z3_CHAIN_POS -1
#define Z3_SLEW_RATE 1
#define Z3_MICROSTEPS Z_MICROSTEPS
#define Z3_OVERCURRENT 2000
#define Z3_STALLCURRENT 1500
#define Z3_MAX_VOLTAGE 127
#define Z3_CHAIN_POS -1
#define Z3_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z4)
#define Z4_MICROSTEPS 128
#define Z4_OVERCURRENT 2000
#define Z4_STALLCURRENT 1500
#define Z4_MAX_VOLTAGE 127
#define Z4_CHAIN_POS -1
#define Z4_SLEW_RATE 1
#define Z4_MICROSTEPS Z_MICROSTEPS
#define Z4_OVERCURRENT 2000
#define Z4_STALLCURRENT 1500
#define Z4_MAX_VOLTAGE 127
#define Z4_CHAIN_POS -1
#define Z4_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E0)
#define E0_MICROSTEPS 128
#define E0_OVERCURRENT 2000
#define E0_STALLCURRENT 1500
#define E0_MAX_VOLTAGE 127
#define E0_CHAIN_POS -1
#define E0_SLEW_RATE 1
#define E0_MICROSTEPS 128
#define E0_OVERCURRENT 2000
#define E0_STALLCURRENT 1500
#define E0_MAX_VOLTAGE 127
#define E0_CHAIN_POS -1
#define E0_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E1)
#define E1_MICROSTEPS 128
#define E1_OVERCURRENT 2000
#define E1_STALLCURRENT 1500
#define E1_MAX_VOLTAGE 127
#define E1_CHAIN_POS -1
#define E1_SLEW_RATE 1
#define E1_MICROSTEPS E0_MICROSTEPS
#define E1_OVERCURRENT 2000
#define E1_STALLCURRENT 1500
#define E1_MAX_VOLTAGE 127
#define E1_CHAIN_POS -1
#define E1_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E2)
#define E2_MICROSTEPS 128
#define E2_OVERCURRENT 2000
#define E2_STALLCURRENT 1500
#define E2_MAX_VOLTAGE 127
#define E2_CHAIN_POS -1
#define E2_SLEW_RATE 1
#define E2_MICROSTEPS E0_MICROSTEPS
#define E2_OVERCURRENT 2000
#define E2_STALLCURRENT 1500
#define E2_MAX_VOLTAGE 127
#define E2_CHAIN_POS -1
#define E2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E3)
#define E3_MICROSTEPS 128
#define E3_OVERCURRENT 2000
#define E3_STALLCURRENT 1500
#define E3_MAX_VOLTAGE 127
#define E3_CHAIN_POS -1
#define E3_SLEW_RATE 1
#define E3_MICROSTEPS E0_MICROSTEPS
#define E3_OVERCURRENT 2000
#define E3_STALLCURRENT 1500
#define E3_MAX_VOLTAGE 127
#define E3_CHAIN_POS -1
#define E3_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E4)
#define E4_MICROSTEPS 128
#define E4_OVERCURRENT 2000
#define E4_STALLCURRENT 1500
#define E4_MAX_VOLTAGE 127
#define E4_CHAIN_POS -1
#define E4_SLEW_RATE 1
#define E4_MICROSTEPS E0_MICROSTEPS
#define E4_OVERCURRENT 2000
#define E4_STALLCURRENT 1500
#define E4_MAX_VOLTAGE 127
#define E4_CHAIN_POS -1
#define E4_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E5)
#define E5_MICROSTEPS 128
#define E5_OVERCURRENT 2000
#define E5_STALLCURRENT 1500
#define E5_MAX_VOLTAGE 127
#define E5_CHAIN_POS -1
#define E5_SLEW_RATE 1
#define E5_MICROSTEPS E0_MICROSTEPS
#define E5_OVERCURRENT 2000
#define E5_STALLCURRENT 1500
#define E5_MAX_VOLTAGE 127
#define E5_CHAIN_POS -1
#define E5_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E6)
#define E6_MICROSTEPS 128
#define E6_OVERCURRENT 2000
#define E6_STALLCURRENT 1500
#define E6_MAX_VOLTAGE 127
#define E6_CHAIN_POS -1
#define E6_SLEW_RATE 1
#define E6_MICROSTEPS E0_MICROSTEPS
#define E6_OVERCURRENT 2000
#define E6_STALLCURRENT 1500
#define E6_MAX_VOLTAGE 127
#define E6_CHAIN_POS -1
#define E6_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E7)
#define E7_MICROSTEPS 128
#define E7_OVERCURRENT 2000
#define E7_STALLCURRENT 1500
#define E7_MAX_VOLTAGE 127
#define E7_CHAIN_POS -1
#define E7_SLEW_RATE 1
#define E7_MICROSTEPS E0_MICROSTEPS
#define E7_OVERCURRENT 2000
#define E7_STALLCURRENT 1500
#define E7_MAX_VOLTAGE 127
#define E7_CHAIN_POS -1
#define E7_SLEW_RATE 1
#endif
/**
@@ -3307,7 +3375,9 @@
//#define GCODE_QUOTED_STRINGS // Support for quoted string parameters
#endif
//#define MEATPACK // Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack)
// Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack)
//#define MEATPACK_ON_SERIAL_PORT_1
//#define MEATPACK_ON_SERIAL_PORT_2
//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase
@@ -3347,6 +3417,37 @@
#define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro
#endif
/**
* User-defined buttons to run custom G-code.
* Up to 25 may be defined.
*/
//#define CUSTOM_USER_BUTTONS
#if ENABLED(CUSTOM_USER_BUTTONS)
//#define BUTTON1_PIN -1
#if PIN_EXISTS(BUTTON1)
#define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH.
#define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing?
#define BUTTON1_GCODE "G28"
#define BUTTON1_DESC "Homing" // Optional string to set the LCD status
#endif
//#define BUTTON2_PIN -1
#if PIN_EXISTS(BUTTON2)
#define BUTTON2_HIT_STATE LOW
#define BUTTON2_WHEN_PRINTING false
#define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
#define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL
#endif
//#define BUTTON3_PIN -1
#if PIN_EXISTS(BUTTON3)
#define BUTTON3_HIT_STATE LOW
#define BUTTON3_WHEN_PRINTING false
#define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
#define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL
#endif
#endif
/**
* User-defined menu items to run custom G-code.
* Up to 25 may be defined, but the actual number is LCD-dependent.
@@ -3356,22 +3457,28 @@
//#define CUSTOM_USER_MENU_TITLE "Custom Commands"
#define USER_SCRIPT_DONE "M117 User Script Done"
#define USER_SCRIPT_AUDIBLE_FEEDBACK
//#define USER_SCRIPT_RETURN // Return to status screen after a script
//#define USER_SCRIPT_RETURN // Return to status screen after a script
#define CUSTOM_MENU_ONLY_IDLE // Only show custom menu when the machine is idle
#define USER_DESC_1 "Home & UBL Info"
#define USER_GCODE_1 "G28\nG29W"
//#define USER_CONFIRM_1 // Show a confirmation dialog before this action
#define USER_DESC_2 "Preheat for " PREHEAT_1_LABEL
#define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
//#define USER_CONFIRM_2
#define USER_DESC_3 "Preheat for " PREHEAT_2_LABEL
#define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
//#define USER_CONFIRM_3
#define USER_DESC_4 "Heat Bed/Home/Level"
#define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
//#define USER_CONFIRM_4
#define USER_DESC_5 "Home & Info"
#define USER_GCODE_5 "G28\nM503"
//#define USER_CONFIRM_5
#endif
/**
@@ -3388,10 +3495,10 @@
* Host Prompt Support enables Marlin to use the host for user prompts so
* filament runout and other processes can be managed from the host side.
*/
//#define HOST_ACTION_COMMANDS
#define HOST_ACTION_COMMANDS
#if ENABLED(HOST_ACTION_COMMANDS)
//#define HOST_PROMPT_SUPPORT
//#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
#define HOST_PROMPT_SUPPORT
#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
#endif
/**
@@ -3728,7 +3835,14 @@
//
// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe
//
//#define PINS_DEBUGGING
#define PINS_DEBUGGING
// Enable Marlin dev mode which adds some special commands
//#define MARLIN_DEV_MODE
/**
* Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial.
* When running in the debugger it will break for debugging. This is useful to help understand
* a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash.
*/
//#define POSTMORTEM_DEBUGGING
+2
View File
@@ -323,6 +323,8 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1203)
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
# Rambo ThinkerV2
else ifeq ($(HARDWARE_MOTHERBOARD),1206)
#
# Other ATmega1280, ATmega2560
+103
View File
@@ -0,0 +1,103 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Custom Bitmap for splashscreen
*
* You may use one of the following tools to generate the C++ bitmap array from
* a black and white image:
*
* - http://www.marlinfw.org/tools/u8glib/converter.html
* - http://www.digole.com/tools/PicturetoC_Hex_converter.php
*/
#include <avr/pgmspace.h>
#define CUSTOM_BOOTSCREEN_TIMEOUT 2500
#define CUSTOM_BOOTSCREEN_BMPWIDTH 125
//#define CUSTOM_BOOTSCREEN_INVERTED
const unsigned char custom_start_bmp[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................##................................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................##.##.............................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................#...#...........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................###..###........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // .................................................................###...##.......................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x40,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................................................##.....#......................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................................................####....#.....................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................########..#.....................................................
0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x00,0x87,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // ...............................................######...........#....########...................................................
0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x00,0x83,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................##....##..........#.....#####.....................................................
0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x00,0x81,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // .............................................##.....##..........#......###......................................................
0x00,0x00,0x00,0x00,0x00,0x0C,0x06,0x00,0x80,0xE3,0x00,0x00,0x00,0x00,0x00,0x00, // ............................................##.......##.........#.......###...##................................................
0x00,0x00,0x00,0x00,0x00,0x18,0x06,0x00,0x80,0x6F,0x80,0x00,0x00,0x00,0x00,0x00, // ...........................................##........##.........#........##.#####...............................................
0x00,0x00,0x00,0x00,0x1C,0x38,0x02,0x00,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00, // ...................................###....###.........#.........#.........####..##..............................................
0x00,0x00,0x00,0x00,0x1F,0x30,0x03,0x00,0xC0,0x3C,0x60,0x00,0x00,0x00,0x00,0x00, // ...................................#####..##..........##........##........####...##.............................................
0x00,0x00,0x00,0x00,0x77,0xB0,0x02,0xFF,0x60,0x3C,0x30,0x00,0x00,0x00,0x00,0x00, // .................................###.####.##..........#.########.##.......####....##............................................
0x00,0x00,0x00,0x00,0xE0,0xF8,0x06,0xFF,0xB0,0x3C,0x18,0x00,0x00,0x00,0x00,0x00, // ................................###.....#####........##.#########.##......####.....##...........................................
0x00,0x00,0x00,0x00,0xC0,0xD8,0x0D,0x81,0x98,0x1C,0x08,0x00,0x00,0x00,0x00,0x00, // ................................##......##.##.......##.##......##..##......###......#...........................................
0x00,0x00,0x00,0x03,0x80,0xD8,0x09,0x80,0xDC,0xFC,0x08,0x00,0x00,0x00,0x00,0x00, // ..............................###.......##.##.......#..##.......##.###..######......#...........................................
0x00,0x00,0x00,0x02,0x00,0xD8,0x1B,0x00,0x6F,0xE4,0x0C,0x00,0x00,0x00,0x00,0x00, // ..............................#.........##.##......##.##.........##.#######..#......##..........................................
0x00,0x00,0x00,0x02,0x00,0xDF,0xFB,0x00,0x37,0x06,0x0C,0x00,0x00,0x00,0x00,0x00, // ..............................#.........##.##########.##..........##.###.....##.....##..........................................
0x00,0x00,0x00,0x06,0x00,0xE7,0xF6,0x00,0x18,0x03,0x04,0x00,0x00,0x00,0x00,0x00, // .............................##.........###..#######.##............##.........##.....#..........................................
0x00,0x00,0x00,0x06,0x00,0xE0,0x0E,0x00,0x18,0x0F,0x04,0x00,0x00,0x00,0x00,0x00, // .............................##.........###.........###............##.......####.....#..........................................
0x00,0x00,0x00,0x06,0x00,0xC0,0x2E,0x00,0x1B,0xFF,0xC6,0x00,0x00,0x00,0x00,0x00, // .............................##.........##........#.###............##.############...##.........................................
0x3F,0xFC,0x1F,0xF6,0x7D,0x81,0xE6,0x00,0x1B,0xC7,0xC6,0x00,0x00,0x00,0x00,0x00, // ..############.....#########.##..#####.##......####..##............##.####...#####...##.........................................
0x7F,0xFE,0x3F,0xFF,0x1F,0x8F,0xC3,0xFF,0xFF,0xFF,0xFC,0x1F,0xFF,0x38,0x03,0xC0, // .##############...##############...######...######....################################.....#############..###.........####......
0xFF,0xFF,0xFF,0xFF,0x8F,0x1F,0xC7,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0x3C,0x03,0xE0, // #################################...####...#######...################################...################..####........#####.....
0x10,0x0F,0xF0,0x0F,0x8F,0xFF,0x83,0xFF,0xF7,0xFF,0xF8,0xFF,0xFC,0x3C,0x03,0xE0, // ...#........########........#####...#############.....##############.################...##############....####........#####.....
0x00,0x0F,0xF0,0x07,0xFF,0xFF,0x01,0x9E,0x27,0xFC,0xC2,0xF8,0x00,0x3E,0x03,0xE0, // ............########.........###################.......##..####...#..#########..##....#.#####.............#####.......#####.....
0x0F,0xFF,0xF0,0x03,0xDF,0xFE,0x01,0xCE,0x6C,0xFC,0x47,0xF8,0x00,0x3F,0xFF,0xE0, // ....################..........####.############........###..###..##.##..######...#...########.............#################.....
0x1F,0xFF,0xF0,0x03,0xC3,0xFC,0x00,0xFF,0xCC,0xFF,0xFF,0xF0,0x00,0x3F,0xFF,0xE0, // ...#################..........####....########..........##########..##..####################..............#################.....
0x1F,0xFF,0xF0,0x03,0xC3,0xFC,0x00,0x0E,0x1C,0xFF,0xF9,0xE0,0x00,0x3F,0xFF,0xE0, // ...#################..........####....########..............###....###..#############..####...............#################.....
0x00,0x0F,0xF0,0x0F,0xC7,0xFC,0x00,0x0E,0x1C,0xFF,0xF1,0xE0,0x00,0x3F,0xFF,0xE0, // ............########........######...#########..............###....###..############...####...............#################.....
0x00,0x0F,0xF8,0x0F,0x87,0xFE,0x00,0x0E,0x0C,0xF8,0xF0,0xF0,0x00,0x3C,0x03,0xE0, // ............#########.......#####....##########.............###.....##..#####...####....####..............####........#####.....
0x7F,0xFF,0xFF,0xFF,0xBF,0x8F,0x00,0x3F,0xE6,0xF8,0xE0,0xFC,0x00,0x3C,0x03,0xE0, // .################################.#######...####..........#########..##.#####...###.....######............####........#####.....
0x7F,0xFF,0xFF,0xFF,0xFF,0x07,0xC0,0xFF,0xE7,0xFF,0xFC,0xFF,0xFF,0x3C,0x03,0xE0, // .#######################################.....#####......###########..#################..################..####........#####.....
0xFF,0xFF,0xFF,0xFF,0xFE,0x03,0xE0,0x8E,0x33,0xFF,0xFC,0x1F,0xFF,0x3C,0x03,0xE0, // #######################################.......#####.....#...###...##..################.....#############..####........#####.....
0x7F,0xFC,0x3F,0xF0,0x3C,0x01,0xF1,0x9E,0x31,0xFF,0xF9,0x0F,0xFE,0x3C,0x03,0xC0, // .#############....##########......####.........#####...##..####...##...##############..#....###########...####........####......
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x19,0xFF,0xC1,0x00,0x00,0x00,0x00,0x00, // ......................................................##...........##..###########.....#........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0xE0,0xC1,0x00,0x00,0x00,0x00,0x00, // ......................................................##............##..###.....##.....#........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x42,0x00,0x00,0x00,0x00,0x00, // .....................................................##.............##...........#....#.........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x01,0x62,0x00,0x00,0x00,0x00,0x00, // .....................................................##..............##........#.##...#.........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x06,0x3F,0x62,0x00,0x00,0x00,0x00,0x00, // ....................................................##...............##...######.##...#.........................................
0x00,0x00,0x00,0x00,0x00,0x38,0x0E,0x00,0x0D,0xFD,0xEE,0x00,0x00,0x00,0x00,0x00, // ..........................................###.......###.............##.#######.####.###.........................................
0x00,0x00,0x00,0x00,0x00,0x7F,0xE6,0x00,0x19,0x81,0xFC,0x00,0x00,0x00,0x00,0x00, // .........................................##########..##............##..##......#######..........................................
0x00,0x00,0x00,0x00,0x00,0xEF,0xF7,0x00,0x1B,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, // ........................................###.########.###...........##.##.......#####............................................
0x00,0x00,0x00,0x00,0x00,0xC0,0x33,0x00,0x33,0x01,0xC8,0x00,0x00,0x00,0x00,0x00, // ........................................##........##..##..........##..##.......###..#...........................................
0x00,0x00,0x00,0x00,0x00,0x80,0x1B,0x00,0x36,0x01,0x98,0x00,0x00,0x00,0x00,0x00, // ........................................#..........##.##..........##.##........##..##...........................................
0x00,0x00,0x00,0x00,0x01,0x80,0x0D,0xFF,0xEC,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, // .......................................##...........##.############.##.........#####............................................
0x00,0x00,0x00,0x00,0x01,0x00,0x0E,0xFF,0xD8,0x01,0xE0,0x00,0x00,0x00,0x00,0x00, // .......................................#............###.##########.##..........####.............................................
0x00,0x00,0x00,0x01,0xF1,0x80,0x06,0x60,0x38,0x07,0xA0,0x00,0x00,0x00,0x00,0x00, // ...............................#####...##............##..##.......###........####.#.............................................
0x00,0x00,0x00,0x01,0xFD,0x80,0x03,0x00,0x18,0x05,0x40,0x00,0x00,0x00,0x00,0x00, // ...............................#######.##.............##...........##........#.#.#..............................................
0x00,0x00,0x00,0x01,0x8F,0xC0,0x06,0xFF,0xDC,0x0A,0x80,0x00,0x00,0x00,0x00,0x00, // ...............................##...######...........##.##########.###......#.#.#...............................................
0x00,0x00,0x00,0x00,0x81,0xE0,0x0C,0xFF,0xCC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, // ................................#......####.........##..##########..##.....#####................................................
0x00,0x00,0x00,0x00,0x81,0xF0,0x0D,0x80,0x6C,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, // ................................#......#####........##.##........##.##..#######.................................................
0x00,0x00,0x00,0x00,0x40,0xFE,0x1B,0x00,0x67,0x8C,0x00,0x00,0x00,0x00,0x00,0x00, // .................................#......#######....##.##.........##..####...##..................................................
0x00,0x00,0x00,0x00,0x20,0x7F,0xF6,0x00,0x20,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................#......###########.##...........#........##...................................................
0x00,0x00,0x00,0x00,0x10,0x30,0x6E,0x00,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // ...................................#......##.....##.###...........##########....................................................
0x00,0x00,0x00,0x00,0x04,0x30,0x0E,0x00,0xFF,0xA0,0x00,0x00,0x00,0x00,0x00,0x00, // .....................................#....##........###.........#########.#.....................................................
0x00,0x00,0x00,0x00,0x03,0x30,0x06,0x00,0xE1,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ......................................##..##.........##.........###....#........................................................
0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0x03,0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .......................................#####..........##......#####...#.........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .......................................................##########...#...........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................#...##............................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // .............................................................###................................................................
};
+72
View File
@@ -0,0 +1,72 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Custom Status Screen bitmap
*
* Place this file in the root with your configuration files
* and enable CUSTOM_STATUS_SCREEN_IMAGE in Configuration.h.
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
//
// Status Screen Logo bitmap
//
#define STATUS_LOGO_Y 1
#define STATUS_LOGO_WIDTH 32
const unsigned char status_logo_bmp[] PROGMEM = {
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x10,0x00, // ...................#............
0x00,0x00,0x06,0x00, // .....................##.........
0x00,0x00,0x00,0x00, // ................................
0x01,0x00,0x00,0x00, // .......#........................
0x08,0x00,0x01,0x00, // ....#..................#........
0x01,0x00,0x41,0x00, // .......#.........#.....#........
0x01,0x00,0x02,0x00, // .......#..............#.........
0x00,0xE0,0x00,0x00, // ........###.....................
0x80,0x08,0x10,0x80, // #...........#......#....#.......
0x04,0x00,0x00,0x40, // .....#...................#......
0x08,0x00,0x08,0x00, // ....#...............#...........
0x10,0x04,0x00,0x00, // ...#.........#..................
0x00,0x00,0x00,0x30, // ..........................##....
0x00,0x00,0x00,0x20, // ..........................#.....
0x00,0x01,0xE8,0x20, // ...............####.#.....#.....
0x00,0x00,0x00,0x60, // .........................##.....
0x00,0x00,0x02,0x00, // ......................#.........
0x00,0x08,0x00,0x00, // ............#...................
0x00,0x00,0x01,0x20, // .......................#..#.....
0x02,0xE8,0x10,0x60, // ......#.###.#......#.....##.....
0x00,0x00,0x00,0x40, // .........................#......
0x00,0x03,0xC0,0x60, // ..............####.......##.....
0x64,0x00,0x10,0x00, // .##..#.............#............
0x04,0x03,0xC0,0x00, // .....#........####..............
0x02,0x00,0x20,0x00, // ......#...........#.............
0x00,0x28,0x00,0x00, // ..........#.#...................
0x00,0x08,0x20,0x00, // ............#.....#.............
0x00,0x00,0x40,0x00, // .................#..............
0x00,0x00,0x00,0x00 // ................................
};
+1 -1
View File
@@ -25,7 +25,7 @@
#include "HAL.h"
#ifdef USBCON
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial0(false, Serial);
#ifdef BLUETOOTH
BTSerial btSerial(false, bluetoothSerial);
#endif
+6 -6
View File
@@ -83,25 +83,25 @@ typedef int8_t pin_t;
// Serial ports
#ifdef USBCON
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
#ifdef BLUETOOTH
typedef ForwardSerial0Type< decltype(bluetoothSerial) > BTSerial;
typedef ForwardSerial1Class< decltype(bluetoothSerial) > BTSerial;
extern BTSerial btSerial;
#endif
#define MYSERIAL0 TERN(BLUETOOTH, btSerial, MSerial)
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#define MYSERIAL0 customizedSerial1
#define MYSERIAL1 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define MYSERIAL1 customizedSerial2
#define MYSERIAL2 customizedSerial2
#endif
#endif
+1 -1
View File
@@ -566,7 +566,7 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Because of the template definition above, it's required to instantiate the template to have all method generated
// Because of the template definition above, it's required to instantiate the template to have all methods generated
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;
MSerialT customizedSerial1(MSerialT::HasEmergencyParser);
+16 -27
View File
@@ -238,11 +238,11 @@
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#ifdef SERIAL_PORT_2
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
@@ -252,17 +252,17 @@
template <uint8_t serial>
struct MMU2SerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = 32;
static constexpr unsigned int TX_SIZE = 32;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
static constexpr unsigned int RX_SIZE = 32;
static constexpr unsigned int TX_SIZE = 32;
static constexpr bool RX_OVERRUNS = false;
};
typedef Serial0Type< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialT3;
typedef Serial1Class< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialT3;
extern MSerialT3 mmuSerial;
#endif
@@ -270,34 +270,23 @@
template <uint8_t serial>
struct LCDSerialCfg {
static constexpr int PORT = serial;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
#if HAS_DGUS_LCD
static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
#elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
static constexpr unsigned int RX_SIZE = 64;
static constexpr unsigned int TX_SIZE = 128;
static constexpr bool RX_OVERRUNS = false;
#else
static constexpr unsigned int RX_SIZE = 64;
static constexpr unsigned int TX_SIZE = 128;
static constexpr bool RX_OVERRUNS = false
#endif
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = TERN(HAS_DGUS_LCD, DGUS_RX_BUFFER_SIZE, 64);
static constexpr unsigned int TX_SIZE = TERN(HAS_DGUS_LCD, DGUS_TX_BUFFER_SIZE, 128);
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
};
typedef Serial0Type< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialT4;
typedef Serial1Class< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialT4;
extern MSerialT4 lcdSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
typedef Serial0Type<HardwareSerial> MSerialT5;
typedef Serial1Class<HardwareSerial> MSerialT5;
extern MSerialT5 bluetoothSerial;
#endif
+1 -1
View File
@@ -285,7 +285,7 @@ enum ClockSource2 : char {
*/
// Determine which harware PWMs are already in use
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN)
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
#else
+7
View File
@@ -56,3 +56,10 @@
#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#endif
/**
* Postmortem debugging
*/
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
#endif
-342
View File
@@ -1,342 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../core/macros.h"
#include "../../core/serial.h"
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include <stdarg.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
// Disable UART interrupt in NVIC
NVIC_DisableIRQ( UART_IRQn );
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// Disable clock
pmc_disable_periph_clk( ID_UART );
// Configure PMC
pmc_enable_periph_clk( ID_UART );
// Disable PDC channel
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
// Reset and disable receiver and transmitter
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
// Configure mode: 8bit, No parity, 1 bit stop
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
// Enable receiver and transmitter
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
// Send character through UART with no interrupts
static void TX(char c) {
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
UART->UART_THR = c;
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
, UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Disable USB
otg_disable();
// Restart watchdog
WDT_Restart(WDT);
// Reset controller
NVIC_SystemReset();
for (;;) WDT_Restart(WDT);
}
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
#endif // ARDUINO_ARCH_SAM
+16 -6
View File
@@ -40,6 +40,8 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
// HAL initialization task
void HAL_init() {
// Initialize the USB stack
@@ -47,6 +49,7 @@ void HAL_init() {
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
usb_task_init();
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
@@ -102,11 +105,18 @@ uint16_t HAL_adc_get_result() {
return HAL_adc_result;
}
// Forward the default serial port
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial1(false, Serial1);
DefaultSerial2 MSerial2(false, Serial2);
DefaultSerial3 MSerial3(false, Serial3);
// Forward the default serial ports
#if ANY_SERIAL_IS(0)
DefaultSerial1 MSerial0(false, Serial);
#endif
#if ANY_SERIAL_IS(1)
DefaultSerial2 MSerial1(false, Serial1);
#endif
#if ANY_SERIAL_IS(2)
DefaultSerial3 MSerial2(false, Serial2);
#endif
#if ANY_SERIAL_IS(3)
DefaultSerial4 MSerial3(false, Serial3);
#endif
#endif // ARDUINO_ARCH_SAM
+13 -14
View File
@@ -37,34 +37,33 @@
#include <stdint.h>
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
typedef ForwardSerial0Type< decltype(Serial2) > DefaultSerial2;
typedef ForwardSerial0Type< decltype(Serial3) > DefaultSerial3;
extern DefaultSerial1 MSerial1;
extern DefaultSerial2 MSerial2;
extern DefaultSerial3 MSerial3;
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
// Define MYSERIAL0/1 before MarlinSerial includes!
// Define MYSERIAL1/2 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL0 customizedSerial1
#define MYSERIAL1 customizedSerial1
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL1 customizedSerial2
#define MYSERIAL2 customizedSerial2
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
+91
View File
@@ -0,0 +1,91 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include <stdarg.h>
static void TXBegin() {
// Disable UART interrupt in NVIC
NVIC_DisableIRQ( UART_IRQn );
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// Disable clock
pmc_disable_periph_clk( ID_UART );
// Configure PMC
pmc_enable_periph_clk( ID_UART );
// Disable PDC channel
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
// Reset and disable receiver and transmitter
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
// Configure mode: 8bit, No parity, 1 bit stop
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
// Enable receiver and transmitter
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
UART->UART_THR = c;
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE)
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // ARDUINO_ARCH_SAM
+2 -2
View File
@@ -141,11 +141,11 @@ struct MarlinSerialCfg {
};
#if SERIAL_PORT >= 0
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
+5 -6
View File
@@ -92,12 +92,11 @@ int MarlinSerialUSB::read() {
return c;
}
bool MarlinSerialUSB::available() {
/* If Pending chars */
return pending_char >= 0 ||
/* or USB CDC enumerated and configured on the PC side and some
bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
int MarlinSerialUSB::available() {
if (pending_char > 0) return pending_char;
return pending_char == 0 ||
// or USB CDC enumerated and configured on the PC side and some bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
void MarlinSerialUSB::flush() { }
+2 -2
View File
@@ -39,7 +39,7 @@ struct MarlinSerialUSB {
int peek();
int read();
void flush();
bool available();
int available();
size_t write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
@@ -50,7 +50,7 @@ struct MarlinSerialUSB {
FORCE_INLINE int rxMaxEnqueued() { return 0; }
#endif
};
typedef Serial0Type<MarlinSerialUSB> MSerialT;
typedef Serial1Class<MarlinSerialUSB> MSerialT;
#if SERIAL_PORT == -1
extern MSerialT customizedSerial1;
+1 -1
View File
@@ -57,5 +57,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on the DUE platform."
#endif
@@ -20,11 +20,10 @@
*
*/
#include "FlushableHardwareSerial.h"
#ifdef ARDUINO_ARCH_ESP32
#include "FlushableHardwareSerial.h"
Serial0Type<FlushableHardwareSerial> flushableSerial(false, 0);
Serial1Class<FlushableHardwareSerial> flushableSerial(false, 0);
#endif // ARDUINO_ARCH_ESP32
#endif
@@ -21,9 +21,9 @@
*/
#pragma once
#ifdef ARDUINO_ARCH_ESP32
#include <HardwareSerial.h>
#include "../shared/Marduino.h"
#include "../../core/serial_hook.h"
class FlushableHardwareSerial : public HardwareSerial {
@@ -31,6 +31,4 @@ public:
FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {}
};
extern Serial0Type<FlushableHardwareSerial> flushableSerial;
#endif // ARDUINO_ARCH_ESP32
extern Serial1Class<FlushableHardwareSerial> flushableSerial;
+2 -1
View File
@@ -41,7 +41,7 @@
#endif
#if ENABLED(ESP3D_WIFISUPPORT)
DefaultSerial MSerial(false, Serial2Socket);
DefaultSerial1 MSerial0(false, Serial2Socket);
#endif
// ------------------------
@@ -185,6 +185,7 @@ void HAL_adc_init() {
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
+5 -5
View File
@@ -51,15 +51,15 @@
extern portMUX_TYPE spinlock;
#define MYSERIAL0 flushableSerial
#define MYSERIAL1 flushableSerial
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
typedef ForwardSerial0Type< decltype(Serial2Socket) > DefaultSerial;
extern DefaultSerial MSerial;
#define MYSERIAL1 MSerial
typedef ForwardSerial1Class< decltype(Serial2Socket) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
#define MYSERIAL2 MSerial0
#else
#define MYSERIAL1 webSocketSerial
#define MYSERIAL2 webSocketSerial
#endif
#endif
+1 -1
View File
@@ -81,5 +81,5 @@ public:
#endif
};
typedef Serial0Type<WebSocketSerial> MSerialT;
typedef Serial1Class<WebSocketSerial> MSerialT;
extern MSerialT webSocketSerial;
+5 -1
View File
@@ -30,9 +30,13 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on ESP32."
#endif
#if BOTH(WIFISUPPORT, ESP3D_WIFISUPPORT)
#error "Only enable one WiFi option, either WIFISUPPORT or ESP3D_WIFISUPPORT."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on ESP32."
#endif
-6
View File
@@ -29,12 +29,6 @@
#include HAL_PATH(.,HAL.h)
#ifdef SERIAL_PORT_2
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
+1 -1
View File
@@ -61,7 +61,7 @@ uint8_t _getc();
#define SHARED_SERVOS HAS_SERVOS
extern MSerialT usb_serial;
#define MYSERIAL0 usb_serial
#define MYSERIAL1 usb_serial
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
+5 -1
View File
@@ -35,5 +35,9 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on LINUX."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on LINUX."
#endif
+1 -1
View File
@@ -115,4 +115,4 @@ struct HalSerial {
volatile bool host_connected;
};
typedef Serial0Type<HalSerial> MSerialT;
typedef Serial1Class<HalSerial> MSerialT;
+2 -2
View File
@@ -105,8 +105,8 @@ int main() {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
#ifdef MYSERIAL0
MYSERIAL0.begin(BAUDRATE);
#ifdef MYSERIAL1
MYSERIAL1.begin(BAUDRATE);
SERIAL_ECHOLNPGM("x86_64 Initialized");
SERIAL_FLUSHTX();
#endif
-322
View File
@@ -1,322 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../core/macros.h"
#include "../../core/serial.h"
#include <stdarg.h>
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include "watchdog.h"
#include <debug_frmwrk.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
}
// Send character through UART with no interrupts
static void TX(char c) {
_DBC(c);
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
,UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Clear cause of reset to prevent entering smoothie bootstrap
HAL_clear_reset_source();
// Restart watchdog
#if ENABLED(USE_WATCHDOG)
//WDT_Restart(WDT);
watchdog_init();
#endif
// Reset controller
NVIC_SystemReset();
// Nothing below here is compiled because NVIC_SystemReset loops forever
for (;;) { TERN_(USE_WATCHDOG, watchdog_init()); }
}
extern "C" {
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_IRQHandler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
}
#endif // TARGET_LPC1768
+1 -1
View File
@@ -29,7 +29,7 @@
#include "watchdog.h"
#endif
DefaultSerial USBSerial(false, UsbSerial);
DefaultSerial1 USBSerial(false, UsbSerial);
uint32_t HAL_adc_reading = 0;
+6 -7
View File
@@ -60,26 +60,25 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
typedef ForwardSerial0Type< decltype(UsbSerial) > DefaultSerial;
extern DefaultSerial USBSerial;
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 USBSerial
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 USBSerial
#define MYSERIAL2 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
+50
View File
@@ -0,0 +1,50 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "HAL.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include <debug_frmwrk.h>
static void TX(char c) { _DBC(c); }
void install_min_serial() { HAL_min_serial_out = &TX; }
#if DISABLED(DYNAMIC_VECTORTABLE)
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // TARGET_LPC1768
+34 -8
View File
@@ -25,20 +25,46 @@
#include "MarlinSerial.h"
#if ANY_SERIAL_IS(0)
MSerialT MSerial(true, LPC_UART0);
extern "C" void UART0_IRQHandler() { MSerial.IRQHandler(); }
MarlinSerial _MSerial(LPC_UART0);
MSerialT MSerial0(true, _MSerial);
extern "C" void UART0_IRQHandler() { _MSerial.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(1)
MSerialT MSerial1(true, (LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); }
MarlinSerial _MSerial1((LPC_UART_TypeDef *) LPC_UART1);
MSerialT MSerial1(true, _MSerial1);
extern "C" void UART1_IRQHandler() { _MSerial1.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(2)
MSerialT MSerial2(true, LPC_UART2);
extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); }
MarlinSerial _MSerial2(LPC_UART2);
MSerialT MSerial2(true, _MSerial2);
extern "C" void UART2_IRQHandler() { _MSerial2.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(3)
MSerialT MSerial3(true, LPC_UART3);
extern "C" void UART3_IRQHandler() { MSerial3.IRQHandler(); }
MarlinSerial _MSerial3(LPC_UART3);
MSerialT MSerial3(true, _MSerial3);
extern "C" void UART3_IRQHandler() { _MSerial3.IRQHandler(); }
#endif
#if ENABLED(EMERGENCY_PARSER)
bool MarlinSerial::recv_callback(const char c) {
// Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro)
if (false) {}
#if ANY_SERIAL_IS(0)
else if (this == &_MSerial) emergency_parser.update(MSerial0.emergency_state, c);
#endif
#if ANY_SERIAL_IS(1)
else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c);
#endif
#if ANY_SERIAL_IS(2)
else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c);
#endif
#if ANY_SERIAL_IS(3)
else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c);
#endif
return true;
}
#endif
#endif // TARGET_LPC1768
+12 -6
View File
@@ -47,15 +47,21 @@ public:
void end() {}
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override {
emergency_parser.update(static_cast<Serial0Type<MarlinSerial> *>(this)->emergency_state, c);
return true; // do not discard character
}
bool recv_callback(const char c) override;
#endif
};
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial;
// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads
// of 'available' and 'read' method are not used in this multiple inheritance scenario.
// Instead, use a ForwardSerial here that adapts the interface.
typedef ForwardSerial1Class<MarlinSerial> MSerialT;
extern MSerialT MSerial0;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
// Consequently, we can't use a RuntimeSerial either. The workaround would be to use a RuntimeSerial<ForwardSerial<MarlinSerial>> type here
// Right now, let's ignore this until it's actually required.
#if ENABLED(SERIAL_RUNTIME_HOOK)
#error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x."
#endif
+3 -4
View File
@@ -83,14 +83,13 @@ bool PersistentStore::access_finish() {
static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
PGM_P const rw_str = write ? PSTR("write") : PSTR("read");
SERIAL_CHAR(' ');
serialprintPGM(rw_str);
SERIAL_ECHOPGM_P(rw_str);
SERIAL_ECHOLNPAIR("_data(", pos, ",", value, ",", size, ", ...)");
if (total) {
SERIAL_ECHOPGM(" f_");
serialprintPGM(rw_str);
SERIAL_ECHOPGM_P(rw_str);
SERIAL_ECHOPAIR("()=", s, "\n size=", size, "\n bytes_");
serialprintPGM(write ? PSTR("written=") : PSTR("read="));
SERIAL_ECHOLN(total);
SERIAL_ECHOLNPAIR_P(write ? PSTR("written=") : PSTR("read="), total);
}
else
SERIAL_ECHOLNPAIR(" f_lseek()=", s);
@@ -30,6 +30,5 @@
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
// TODO: Which other boards are incompatible?
#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0
#warning "To prevent step loss, motion will pause for PRINTCOUNTER auto-save."
#define PRINTCOUNTER_SYNC 1
#endif
+2 -2
View File
@@ -270,7 +270,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x."
#endif
+5 -3
View File
@@ -46,6 +46,8 @@ extern "C" {
void SysTick_Callback() { disk_timerproc(); }
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
void HAL_init() {
// Init LEDs
@@ -123,9 +125,7 @@ void HAL_init() {
delay(1000); // Give OS time to notice
USB_Connect(true);
#if HAS_SD_HOST_DRIVE
MSC_SD_Init(0); // Enable USB SD card access
#endif
TERN_(HAS_SD_HOST_DRIVE, MSC_SD_Init(0)); // Enable USB SD card access
const millis_t usb_timeout = millis() + 2000;
while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
@@ -137,6 +137,8 @@ void HAL_init() {
}
HAL_timer_init();
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
@@ -8,9 +8,7 @@ from __future__ import print_function
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
import os
import getpass
import platform
import os,getpass,platform
current_OS = platform.system()
Import("env")
@@ -33,9 +31,8 @@ try:
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess
import subprocess,string
from ctypes import windll
import string
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
+2 -2
View File
@@ -29,8 +29,8 @@
EmergencyParser::State emergency_state;
bool CDC_RecvCallback(const char buffer) {
emergency_parser.update(emergency_state, buffer);
bool CDC_RecvCallback(const char c) {
emergency_parser.update(emergency_state, c);
return true;
}
+29 -2
View File
@@ -25,8 +25,21 @@
#include <wiring_private.h>
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial1(false, Serial1);
#if ANY_SERIAL_IS(-1)
DefaultSerial1 MSerial0(false, Serial);
#endif
#if ANY_SERIAL_IS(0)
DefaultSerial2 MSerial1(false, Serial1);
#endif
#if ANY_SERIAL_IS(1)
DefaultSerial3 MSerial2(false, Serial2);
#endif
#if ANY_SERIAL_IS(2)
DefaultSerial4 MSerial3(false, Serial3);
#endif
#if ANY_SERIAL_IS(3)
DefaultSerial5 MSerial4(false, Serial4);
#endif
#endif
// ------------------------
@@ -44,6 +57,7 @@
#define GET_PROBE_ADC() TERN(HAS_TEMP_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1)
#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1)
#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1)
#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1)
@@ -53,6 +67,7 @@
|| GET_PROBE_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
|| GET_COOLER_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_BUTTONS_ADC() == n \
)
@@ -131,6 +146,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
TEMP_CHAMBER_PIN,
#endif
#if GET_COOLER_ADC() == 0
TEMP_COOLER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
@@ -171,6 +189,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
TEMP_CHAMBER_PIN,
#endif
#if GET_COOLER_ADC() == 1
TEMP_COOLER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
@@ -219,6 +240,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_COOLER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
@@ -268,6 +292,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_COOLER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
+17 -11
View File
@@ -32,30 +32,36 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
extern DefaultSerial1 MSerial1;
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
typedef ForwardSerial1Class< decltype(Serial4) > DefaultSerial5;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
extern DefaultSerial5 MSerial4;
// MYSERIAL0 required before MarlinSerial includes!
// MYSERIAL1 required before MarlinSerial includes!
#define __MSERIAL(X) MSerial##X
#define _MSERIAL(X) __MSERIAL(X)
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1
#define MYSERIAL0 MSerial
#define MYSERIAL1 MSerial0
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 MSerial
#define MYSERIAL2 MSerial0
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
@@ -63,7 +69,7 @@
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial
#define MMU2_SERIAL MSerial0
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
@@ -73,7 +79,7 @@
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL MSerial
#define LCD_SERIAL MSerial0
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
+1 -1
View File
@@ -22,7 +22,7 @@
#include "../../core/serial_hook.h"
typedef Serial0Type<Uart> UartT;
typedef Serial1Class<Uart> UartT;
extern UartT Serial2;
extern UartT Serial3;
+4
View File
@@ -50,3 +50,7 @@
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on SAMD51."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on AGCM4."
#endif
+11 -1
View File
@@ -29,7 +29,7 @@
#include "../shared/Delay.h"
#ifdef USBCON
DefaultSerial MSerial(false, SerialUSB);
DefaultSerial1 MSerial0(false, SerialUSB);
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
@@ -57,10 +57,18 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
// HAL initialization task
void HAL_init() {
FastIO_init();
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
@@ -83,6 +91,8 @@ void HAL_init() {
USB_Hook_init();
#endif
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
#if HAS_SD_HOST_DRIVE
MSC_SD_init(); // Enable USB SD card access
#endif
+8 -8
View File
@@ -40,8 +40,8 @@
#ifdef USBCON
#include <USBSerial.h>
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(SerialUSB) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial1Class< decltype(SerialUSB) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
#endif
// ------------------------
@@ -51,18 +51,18 @@
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
#define MYSERIAL0 MSerial
#define MYSERIAL1 MSerial0
#elif WITHIN(SERIAL_PORT, 1, 6)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 MSerial
#define MYSERIAL2 MSerial0
#elif WITHIN(SERIAL_PORT_2, 1, 6)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
#endif
@@ -70,7 +70,7 @@
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial
#define MMU2_SERIAL MSerial0
#elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
@@ -80,7 +80,7 @@
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL MSerial
#define LCD_SERIAL MSerial0
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
+152
View File
@@ -0,0 +1,152 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2017 Victor Perez
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include "watchdog.h"
/* Instruction Synchronization Barrier */
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
/* Data Synchronization Barrier */
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
// Dumb mapping over the registers of a USART device on STM32
struct USARTMin {
volatile uint32_t SR;
volatile uint32_t DR;
volatile uint32_t BRR;
volatile uint32_t CR1;
volatile uint32_t CR2;
};
#if WITHIN(SERIAL_PORT, 1, 6)
// Depending on the CPU, the serial port is different for USART1
static const uintptr_t regsAddr[] = {
TERN(STM32F1xx, 0x40013800, 0x40011000), // USART1
0x40004400, // USART2
0x40004800, // USART3
0x40004C00, // UART4_BASE
0x40005000, // UART5_BASE
0x40011400 // USART6
};
static USARTMin * regs = (USARTMin*)regsAddr[SERIAL_PORT - 1];
#endif
static void TXBegin() {
#if !WITHIN(SERIAL_PORT, 1, 6)
#warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error."
#warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port."
#else
// This is common between STM32F1/STM32F2 and STM32F4
const int nvicUART[] = { /* NVIC_USART1 */ 37, /* NVIC_USART2 */ 38, /* NVIC_USART3 */ 39, /* NVIC_UART4 */ 52, /* NVIC_UART5 */ 53, /* NVIC_USART6 */ 71 };
int nvicIndex = nvicUART[SERIAL_PORT - 1];
struct NVICMin {
volatile uint32_t ISER[32];
volatile uint32_t ICER[32];
};
NVICMin * nvicBase = (NVICMin*)0xE000E100;
nvicBase->ICER[nvicIndex / 32] |= _BV32(nvicIndex % 32);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
dsb();
isb();
// Example for USART1 disable: (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
// Too difficult to reimplement here, let's query the STM32duino macro here
#if SERIAL_PORT == 1
__HAL_RCC_USART1_CLK_DISABLE();
__HAL_RCC_USART1_CLK_ENABLE();
#elif SERIAL_PORT == 2
__HAL_RCC_USART2_CLK_DISABLE();
__HAL_RCC_USART2_CLK_ENABLE();
#elif SERIAL_PORT == 3
__HAL_RCC_USART3_CLK_DISABLE();
__HAL_RCC_USART3_CLK_ENABLE();
#elif SERIAL_PORT == 4
__HAL_RCC_UART4_CLK_DISABLE(); // BEWARE: UART4 and not USART4 here
__HAL_RCC_UART4_CLK_ENABLE();
#elif SERIAL_PORT == 5
__HAL_RCC_UART5_CLK_DISABLE(); // BEWARE: UART5 and not USART5 here
__HAL_RCC_UART5_CLK_ENABLE();
#elif SERIAL_PORT == 6
__HAL_RCC_USART6_CLK_DISABLE();
__HAL_RCC_USART6_CLK_ENABLE();
#endif
uint32_t brr = regs->BRR;
regs->CR1 = 0; // Reset the USART
regs->CR2 = 0; // 1 stop bit
// If we don't touch the BRR (baudrate register), we don't need to recompute.
regs->BRR = brr;
regs->CR1 = _BV(3) | _BV(13); // 8 bits, no parity, 1 stop bit (TE | UE)
#endif
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
#if WITHIN(SERIAL_PORT, 1, 6)
constexpr uint32_t usart_sr_txe = _BV(7);
while (!(regs->SR & usart_sr_txe)) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
sw_barrier();
}
regs->DR = c;
#else
// Let's hope a mystical guru will fix this, one day by writting interrupt-free USB CDC ACM code (or, at least, by polling the registers since interrupt will be queued but will never trigger)
// For now, it's completely lost to oblivion.
#endif
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // ARDUINO_ARCH_STM32
+1 -1
View File
@@ -42,7 +42,7 @@ protected:
usart_rx_callback_t _rx_callback;
};
typedef Serial0Type<MarlinSerial> MSerialT;
typedef Serial1Class<MarlinSerial> MSerialT;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
+1 -1
View File
@@ -48,7 +48,7 @@
#include "stm32_def.h"
#define DEBUG_OUT ENABLED(EEPROM_CHITCHAT)
#include "src/core/debug_out.h"
#include "../../core/debug_out.h"
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
@@ -24,3 +24,9 @@
#if defined(USBD_USE_CDC_MSC) && DISABLED(NO_SD_HOST_DRIVE)
#define HAS_SD_HOST_DRIVE 1
#endif
// Fix F_CPU not being a compile-time constant in STSTM32 framework
#ifdef BOARD_F_CPU
#undef F_CPU
#define F_CPU BOARD_F_CPU
#endif
+2 -2
View File
@@ -47,9 +47,9 @@
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on STM32."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#error "SERIAL_STATS_DROPPED_RX is not supported on STM32."
#endif
#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32F4xx, STM32F1xx)
+3 -3
View File
@@ -207,12 +207,12 @@ void TFT_SPI::Transmit(uint16_t Data) {
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
if (TFT_MISO_PIN != TFT_MOSI_PIN)
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); // Clear overrun flag in 2 Lines communication mode because received is not read
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
// Wait last dma finish, to start another
while(isBusy()) { }
while (isBusy()) { /* nada */ }
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
@@ -225,7 +225,7 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
+14 -2
View File
@@ -84,7 +84,7 @@
#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
USBSerial SerialUSB;
DefaultSerial MSerial(true, SerialUSB);
DefaultSerial1 MSerial0(true, SerialUSB);
#if ENABLED(EMERGENCY_PARSER)
#include "../libmaple/usb/stm32f1/usb_reg_map.h"
@@ -107,7 +107,7 @@
len = usb_cdcacm_peek(buf, total);
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MSerial.emergency_state, buf[i + total - len]);
emergency_parser.update(MSerial0.emergency_state, buf[i + total - len]);
}
#endif
#endif
@@ -132,6 +132,9 @@ const uint8_t adc_pins[] = {
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER_PIN,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1_PIN,
#endif
@@ -189,6 +192,9 @@ enum TempPinIndex : char {
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1,
#endif
@@ -272,6 +278,8 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
} }
#endif
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
void HAL_init() {
NVIC_SetPriorityGrouping(0x3);
#if PIN_EXISTS(LED)
@@ -287,6 +295,7 @@ void HAL_init() {
delay(1000); // Give OS time to notice
OUT_WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING);
#endif
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler
}
// HAL idle task
@@ -382,6 +391,9 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if HAS_TEMP_CHAMBER
case TEMP_CHAMBER_PIN: pin_index = TEMP_CHAMBER; break;
#endif
#if HAS_TEMP_COOLER
case TEMP_COOLER_PIN: pin_index = TEMP_COOLER; break;
#endif
#if HAS_TEMP_ADC_1
case TEMP_1_PIN: pin_index = TEMP_1; break;
#endif
+7 -7
View File
@@ -61,11 +61,11 @@
#endif
#ifdef SERIAL_USB
typedef ForwardSerial0Type< USBSerial > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial1Class< USBSerial > DefaultSerial1;
extern DefaultSerial1 MSerial0;
#if !HAS_SD_HOST_DRIVE
#define UsbSerial MSerial
#define UsbSerial MSerial0
#else
#define UsbSerial MarlinCompositeSerial
#endif
@@ -81,9 +81,9 @@
#endif
#if SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
#define MYSERIAL1 UsbSerial
#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#elif NUM_UARTS == 5
#error "SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
#else
@@ -92,9 +92,9 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
#define MYSERIAL2 UsbSerial
#elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#elif NUM_UARTS == 5
#error "SERIAL_PORT_2 must be -1 or from 1 to 5. Please update your configuration."
#else
+118
View File
@@ -0,0 +1,118 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2017 Victor Perez
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef __STM32F1__
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include "watchdog.h"
#include <libmaple/usart.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
/* Instruction Synchronization Barrier */
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
/* Data Synchronization Barrier */
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
static void TXBegin() {
#if !WITHIN(SERIAL_PORT, 1, 6)
#warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error."
#warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port."
#else
// We use MYSERIAL1 here, so we need to figure out how to get the linked register
struct usart_dev* dev = MYSERIAL1.c_dev();
// Or use this if removing libmaple
// int irq = dev->irq_num;
// int nvicUART[] = { NVIC_USART1 /* = 37 */, NVIC_USART2 /* = 38 */, NVIC_USART3 /* = 39 */, NVIC_UART4 /* = 52 */, NVIC_UART5 /* = 53 */ };
// Disabling irq means setting the bit in the NVIC ICER register located at
// Disable UART interrupt in NVIC
nvic_irq_disable(dev->irq_num);
// Use this if removing libmaple
//NVIC_BASE->ICER[1] |= _BV(irq - 32);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
dsb();
isb();
rcc_clk_disable(dev->clk_id);
rcc_clk_enable(dev->clk_id);
usart_reg_map *regs = dev->regs;
regs->CR1 = 0; // Reset the USART
regs->CR2 = 0; // 1 stop bit
// If we don't touch the BRR (baudrate register), we don't need to recompute. Else we would need to call
usart_set_baud_rate(dev, 0, BAUDRATE);
regs->CR1 = (USART_CR1_TE | USART_CR1_UE); // 8 bits, no parity, 1 stop bit
#endif
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
#if WITHIN(SERIAL_PORT, 1, 6)
struct usart_dev* dev = MYSERIAL1.c_dev();
while (!(dev->regs->SR & USART_SR_TXE)) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
sw_barrier();
}
dev->regs->DR = c;
#endif
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't branch to a symbol that's too far, so we have a specific hack for them
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_hardfault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_busfault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_usagefault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_memmanage();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_nmi();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception7();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception8();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception9();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception10();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception13();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // __STM32F1__
+3 -3
View File
@@ -134,12 +134,12 @@ constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; }
// If you encounter this error, replace SerialX with MSerialX, for example MSerial3.
// Non-TMC ports were already validated in HAL.h, so do not require verbose error messages.
#ifdef MYSERIAL0
CHECK_CFG_SERIAL(MYSERIAL0);
#endif
#ifdef MYSERIAL1
CHECK_CFG_SERIAL(MYSERIAL1);
#endif
#ifdef MYSERIAL2
CHECK_CFG_SERIAL(MYSERIAL2);
#endif
#ifdef LCD_SERIAL
CHECK_CFG_SERIAL(LCD_SERIAL);
#endif
+1 -1
View File
@@ -47,7 +47,7 @@ struct MarlinSerial : public HardwareSerial {
#endif
};
typedef Serial0Type<MarlinSerial> MSerialT;
typedef Serial1Class<MarlinSerial> MSerialT;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
+1 -1
View File
@@ -40,7 +40,7 @@ void eeprom_init() { BL24CXX::init(); }
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const unsigned eeprom_address = (unsigned)pos;
return BL24CXX::writeOneByte(eeprom_address, value);
}
+2 -2
View File
@@ -34,9 +34,9 @@
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on the STM32F1 platform."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#error "SERIAL_STATS_DROPPED_RX is not supported on the STM32F1 platform."
#endif
#if ENABLED(NEOPIXEL_LED)
+19 -18
View File
@@ -24,7 +24,7 @@
#define PRODUCT_ID 0x29
USBMassStorage MarlinMSC;
Serial0Type<USBCompositeSerial> MarlinCompositeSerial(true);
Serial1Class<USBCompositeSerial> MarlinCompositeSerial(true);
#include "../../inc/MarlinConfig.h"
@@ -43,26 +43,27 @@ Serial0Type<USBCompositeSerial> MarlinCompositeSerial(true);
#if ENABLED(EMERGENCY_PARSER)
// The original callback is not called (no way to retrieve address).
// That callback detects a special STM32 reset sequence: this functionality is not essential
// as M997 achieves the same.
void my_rx_callback(unsigned int, void*) {
// max length of 16 is enough to contain all emergency commands
uint8 buf[16];
// The original callback is not called (no way to retrieve address).
// That callback detects a special STM32 reset sequence: this functionality is not essential
// as M997 achieves the same.
void my_rx_callback(unsigned int, void*) {
// max length of 16 is enough to contain all emergency commands
uint8 buf[16];
//rx is usbSerialPart.endpoints[2]
uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address);
uint32 total = composite_cdcacm_data_available();
//rx is usbSerialPart.endpoints[2]
uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address);
uint32 total = composite_cdcacm_data_available();
if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
return;
if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
return;
// cannot get character by character due to bug in composite_cdcacm_peek_ex
len = composite_cdcacm_peek(buf, total);
// cannot get character by character due to bug in composite_cdcacm_peek_ex
len = composite_cdcacm_peek(buf, total);
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]);
}
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]);
}
#endif
void MSC_SD_init() {
@@ -87,7 +88,7 @@ void MSC_SD_init() {
MarlinCompositeSerial.registerComponent();
USBComposite.begin();
#if ENABLED(EMERGENCY_PARSER)
composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback);
composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback);
#endif
}
+1 -1
View File
@@ -21,6 +21,6 @@
#include "../../core/serial_hook.h"
extern USBMassStorage MarlinMSC;
extern Serial0Type<USBCompositeSerial> MarlinCompositeSerial;
extern Serial1Class<USBCompositeSerial> MarlinCompositeSerial;
void MSC_SD_init();
+5 -1
View File
@@ -31,7 +31,11 @@
#include <Wire.h>
DefaultSerial MSerial(false);
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result;
+11 -6
View File
@@ -51,19 +51,24 @@
#endif
#include "../../core/serial_hook.h"
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 USBSerial
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#endif
#define HAL_SERVO_LIB libServo
+5 -1
View File
@@ -34,5 +34,9 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on Teensy 3.1/3.2."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.1/3.2."
#endif
+6 -1
View File
@@ -31,7 +31,12 @@
#include <Wire.h>
DefaultSerial MSerial(false);
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result, HAL_adc_select;
+11 -6
View File
@@ -54,19 +54,24 @@
#endif
#include "../../core/serial_hook.h"
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 USBSerial
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
DECLARE_SERIAL(SERIAL_PORT);
#endif
#define HAL_SERVO_LIB libServo
+5 -1
View File
@@ -34,5 +34,9 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on Teensy 3.5/3.6."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.5/3.6."
#endif
+5 -1
View File
@@ -32,7 +32,11 @@
#include <Wire.h>
DefaultSerial MSerial(false);
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result, HAL_adc_select;
+13 -9
View File
@@ -56,30 +56,34 @@
#endif
#include "../../core/serial_hook.h"
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#define MYSERIAL1 SerialUSB
#elif WITHIN(SERIAL_PORT, 0, 8)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 8. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 usbSerial
#define MYSERIAL2 usbSerial
#elif SERIAL_PORT_2 == -2
#define MYSERIAL1 ethernet.telnetClient
#define MYSERIAL2 ethernet.telnetClient
#elif WITHIN(SERIAL_PORT_2, 0, 8)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -2 to 8. Please update your configuration."
#endif
+5 -1
View File
@@ -34,5 +34,9 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on this platform."
#error "TMC220x Software Serial is not supported on Teensy 4.0/4.1."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 4.0/4.1."
#endif
+6 -9
View File
@@ -51,7 +51,7 @@
// Use hardware cycle counter instead, it's much safer
void delay_dwt(uint32_t count) {
// Reuse the ASM_CYCLES_PER_ITERATION variable to avoid wasting another useless variable
register uint32_t start = HW_REG(_DWT_CYCCNT) - ASM_CYCLES_PER_ITERATION, elapsed;
uint32_t start = HW_REG(_DWT_CYCCNT) - ASM_CYCLES_PER_ITERATION, elapsed;
do {
elapsed = HW_REG(_DWT_CYCCNT) - start;
} while (elapsed < count);
@@ -109,12 +109,12 @@
void dump_delay_accuracy_check() {
auto report_call_time = [](PGM_P const name, PGM_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) {
SERIAL_ECHOPGM("Calling ");
serialprintPGM(name);
SERIAL_ECHOPGM_P(name);
SERIAL_ECHOLNPAIR(" for ", cycles);
serialprintPGM(unit);
SERIAL_ECHOPGM_P(unit);
SERIAL_ECHOLNPAIR(" took: ", total);
serialprintPGM(unit);
if (do_flush) SERIAL_FLUSH();
SERIAL_ECHOPGM_P(unit);
if (do_flush) SERIAL_FLUSHTX();
};
uint32_t s, e;
@@ -169,10 +169,7 @@
void calibrate_delay_loop() {}
#if ENABLED(MARLIN_DEV_MODE)
void dump_delay_accuracy_check() {
static PGMSTR(none, "N/A on this platform");
serialprintPGM(none);
}
void dump_delay_accuracy_check() { SERIAL_ECHOPGM_P(PSTR("N/A on this platform")); }
#endif
#endif
+33
View File
@@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "HAL_MinSerial.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
void HAL_min_serial_init_default() {}
void HAL_min_serial_out_default(char ch) { SERIAL_CHAR(ch); }
void (*HAL_min_serial_init)() = &HAL_min_serial_init_default;
void (*HAL_min_serial_out)(char) = &HAL_min_serial_out_default;
bool MinSerial::force_using_default_output = false;
#endif
+79
View File
@@ -0,0 +1,79 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../core/serial.h"
#include <stdint.h>
// Serial stuff here
// Inside an exception handler, the CPU state is not safe, we can't expect the handler to resume
// and the software to continue. UART communication can't rely on later callback/interrupt as it might never happen.
// So, you need to provide some method to send one byte to the usual UART with the interrupts disabled
// By default, the method uses SERIAL_CHAR but it's 100% guaranteed to break (couldn't be worse than nothing...)7
extern void (*HAL_min_serial_init)();
extern void (*HAL_min_serial_out)(char ch);
struct MinSerial {
static bool force_using_default_output;
// Serial output
static void TX(char ch) {
if (force_using_default_output)
SERIAL_CHAR(ch);
else
HAL_min_serial_out(ch);
}
// Send String through UART
static void TX(const char* s) { while (*s) TX(*s++); }
// Send a digit through UART
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number through UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number through UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
static void init() { if (!force_using_default_output) HAL_min_serial_init(); }
};
+18 -10
View File
@@ -25,7 +25,7 @@
#include "unwinder.h"
#include "unwmemaccess.h"
#include "../../../core/serial.h"
#include "../HAL_MinSerial.h"
#include <stdarg.h>
// Dump a backtrace entry
@@ -34,10 +34,12 @@ static bool UnwReportOut(void* ctx, const UnwReport* bte) {
(*p)++;
SERIAL_CHAR('#'); SERIAL_ECHO(*p); SERIAL_ECHOPGM(" : ");
SERIAL_ECHOPGM(bte->name ? bte->name : "unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function, PrintBase::Hex);
SERIAL_CHAR('+'); SERIAL_ECHO(bte->address - bte->function);
SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address, PrintBase::Hex); SERIAL_CHAR('\n');
const uint32_t a = bte->address, f = bte->function;
MinSerial::TX('#'); MinSerial::TXDec(*p); MinSerial::TX(" : ");
MinSerial::TX(bte->name?:"unknown"); MinSerial::TX('@'); MinSerial::TXHex(f);
MinSerial::TX('+'); MinSerial::TXDec(a - f);
MinSerial::TX(" PC:"); MinSerial::TXHex(a);
MinSerial::TX('\n');
return true;
}
@@ -48,7 +50,7 @@ static bool UnwReportOut(void* ctx, const UnwReport* bte) {
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
MinSerial::TX(&dest[0]);
}
#endif
@@ -63,10 +65,10 @@ static const UnwindCallbacks UnwCallbacks = {
#endif
};
// Perform a backtrace to the serial port
void backtrace() {
UnwindFrame btf;
uint32_t sp = 0, lr = 0, pc = 0;
unsigned long sp = 0, lr = 0, pc = 0;
// Capture the values of the registers to perform the traceback
__asm__ __volatile__ (
@@ -79,6 +81,12 @@ void backtrace() {
::
);
backtrace_ex(sp, lr, pc);
}
void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) {
UnwindFrame btf;
// Fill the traceback structure
btf.sp = sp;
btf.fp = btf.sp;
@@ -86,7 +94,7 @@ void backtrace() {
btf.pc = pc | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
SERIAL_ERROR_MSG("Backtrace:");
MinSerial::TX("Backtrace:");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
}
@@ -95,4 +103,4 @@ void backtrace() {
void backtrace() {}
#endif
#endif // __arm__ || __thumb__
@@ -23,3 +23,6 @@
// Perform a backtrace to the serial port
void backtrace();
// Perform a backtrace to the serial port
void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc);
@@ -41,27 +41,16 @@
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00080000
#elif 0
// For STM32F103CBT6
// SRAM (0x20000000 - 0x20005000) (20kb)
// FLASH (0x00000000 - 0x00020000) (128kb)
//
#define START_SRAM_ADDR 0x20000000
#define END_SRAM_ADDR 0x20005000
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00020000
#elif defined(__STM32F1__) || defined(STM32F1xx) || defined(STM32F0xx)
// For STM32F103ZET6/STM32F103VET6/STM32F0xx
// SRAM (0x20000000 - 0x20010000) (64kb)
// FLASH (0x00000000 - 0x00080000) (512kb)
// FLASH (0x08000000 - 0x08080000) (512kb)
//
#define START_SRAM_ADDR 0x20000000
#define END_SRAM_ADDR 0x20010000
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00080000
#define START_FLASH_ADDR 0x08000000
#define END_FLASH_ADDR 0x08080000
#elif defined(STM32F4) || defined(STM32F4xx)
@@ -142,20 +131,57 @@
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00100000
#else
// Generic ARM code, that's testing if an access to the given address would cause a fault or not
// It can't guarantee an address is in RAM or Flash only, but we usually don't care
#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status Reg.
#define NVIC_CFG_CTRL 0xE000ED14 // Configuration Control Register
#define NVIC_FAULT_STAT_BFARV 0x00008000 // BFAR is valid
#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore bus fault in NMI/fault
#define HW_REG(X) (*((volatile unsigned long *)(X)))
static bool validate_addr(uint32_t read_address) {
bool works = true;
uint32_t intDisabled = 0;
// Read current interrupt state
__asm__ __volatile__ ("MRS %[result], PRIMASK\n\t" : [result]"=r"(intDisabled) :: ); // 0 is int enabled, 1 for disabled
// Clear bus fault indicator first (write 1 to clear)
HW_REG(NVIC_FAULT_STAT) |= NVIC_FAULT_STAT_BFARV;
// Ignore bus fault interrupt
HW_REG(NVIC_CFG_CTRL) |= NVIC_CFG_CTRL_BFHFNMIGN;
// Disable interrupts if not disabled previously
if (!intDisabled) __asm__ __volatile__ ("CPSID f");
// Probe address
*(volatile uint32_t*)read_address;
// Check if a fault happened
if ((HW_REG(NVIC_FAULT_STAT) & NVIC_FAULT_STAT_BFARV) != 0)
works = false;
// Enable interrupts again if previously disabled
if (!intDisabled) __asm__ __volatile__ ("CPSIE f");
// Enable fault interrupt flag
HW_REG(NVIC_CFG_CTRL) &= ~NVIC_CFG_CTRL_BFHFNMIGN;
return works;
}
#endif
static bool validate_addr(uint32_t addr) {
#ifdef START_SRAM_ADDR
static bool validate_addr(uint32_t addr) {
// Address must be in SRAM range
if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
return true;
// Address must be in SRAM range
if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
return true;
// Or in FLASH range
if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
return true;
// Or in FLASH range
if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
return true;
return false;
}
return false;
}
#endif
bool UnwReadW(const uint32_t a, uint32_t *v) {
if (!validate_addr(a))
@@ -0,0 +1,379 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2020 Cyril Russo
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/***************************************************************************
* ARM CPU Exception handler
***************************************************************************/
#if defined(__arm__) || defined(__thumb__)
/*
On ARM CPUs exception handling is quite powerful.
By default, upon a crash, the CPU enters the handlers that have a higher priority than any other interrupts,
so, in effect, no (real) interrupt can "interrupt" the handler (it's acting like if interrupts were disabled).
If the handler is not called as re-entrant (that is, if the crash is not happening inside an interrupt or an handler),
then it'll patch the return address to a dumping function (resume_from_fault) and save the crash state.
The CPU will exit the handler and, as such, re-allow the other interrupts, and jump to the dumping function.
In this function, the usual serial port (USB / HW) will be used to dump the crash (no special configuration required).
The only case where it requires hardware UART is when it's crashing in an interrupt or a crash handler.
In that case, instead of returning to the resume_from_fault function (and thus, re-enabling interrupts),
it jumps to this function directly (so with interrupts disabled), after changing the behavior of the serial output
wrapper to use the HW uart (and in effect, calling MinSerial::init which triggers a warning if you are using
a USB serial port).
In the case you have a USB serial port, this part will be disabled, and only that part (so that's the reason for
the warning).
This means that you can't have a crash report if the crash happens in an interrupt or an handler if you are using
a USB serial port since it's physically impossible.
You will get a crash report in all other cases.
*/
#include "exception_hook.h"
#include "../backtrace/backtrace.h"
#include "../HAL_MinSerial.h"
#define HW_REG(X) (*((volatile unsigned long *)(X)))
// Default function use the CPU VTOR register to get the vector table.
// Accessing the CPU VTOR register is done in assembly since it's the only way that's common to all current tool
unsigned long get_vtor() { return HW_REG(0xE000ED08); } // Even if it looks like an error, it is not an error
void * hook_get_hardfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x03); }
void * hook_get_memfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x04); }
void * hook_get_busfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x05); }
void * hook_get_usagefault_vector_address(unsigned vtor) { return (void*)(vtor + 0x06); }
void * hook_get_reserved_vector_address(unsigned vtor) { return (void*)(vtor + 0x07); }
// Common exception frame for ARM, should work for all ARM CPU
// Described here (modified for convenience): https://interrupt.memfault.com/blog/cortex-m-fault-debug
struct __attribute__((packed)) ContextStateFrame {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t xpsr;
};
struct __attribute__((packed)) ContextSavedFrame {
uint32_t R0;
uint32_t R1;
uint32_t R2;
uint32_t R3;
uint32_t R12;
uint32_t LR;
uint32_t PC;
uint32_t XPSR;
uint32_t CFSR;
uint32_t HFSR;
uint32_t DFSR;
uint32_t AFSR;
uint32_t MMAR;
uint32_t BFAR;
uint32_t ESP;
uint32_t ELR;
};
#if DISABLED(STM32F0xx)
extern "C"
__attribute__((naked)) void CommonHandler_ASM() {
__asm__ __volatile__ (
// Bit 2 of LR tells which stack pointer to use (either main or process, only main should be used anyway)
"tst lr, #4\n"
"ite eq\n"
"mrseq r0, msp\n"
"mrsne r0, psp\n"
// Save the LR in use when being interrupted
"mov r1, lr\n"
// Get the exception number from the ICSR register
"ldr r2, =0xE000ED00\n"
"ldr r2, [r2, #4]\n"
"b CommonHandler_C\n"
);
}
#else // Cortex M0 does not support conditional mov and testing with a constant, so let's have a specific handler for it
extern "C"
__attribute__((naked)) void CommonHandler_ASM() {
__asm__ __volatile__ (
".syntax unified\n"
// Save the LR in use when being interrupted
"mov r1, lr\n"
// Get the exception number from the ICSR register
"ldr r2, =0xE000ED00\n"
"ldr r2, [r2, #4]\n"
"movs r0, #4\n"
"tst r1, r0\n"
"beq _MSP\n"
"mrs r0, psp\n"
"b CommonHandler_C\n"
"_MSP:\n"
"mrs r0, msp\n"
"b CommonHandler_C\n"
);
}
#if DISABLED(DYNAMIC_VECTORTABLE) // Cortex M0 requires the handler's address to be within 32kB to the actual function to be able to branch to it
extern "C" {
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_hardfault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_busfault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_usagefault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_memmanage();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_nmi();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception7();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception8();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception9();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception10();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception13();
}
//TODO When going off from libmaple, you'll need to replace those by the one from STM32/HAL_MinSerial.cpp
#endif
#endif
// Must be a macro to avoid creating a function frame
#define HALT_IF_DEBUGGING() \
do { \
if (HW_REG(0xE000EDF0) & _BV(0)) { \
__asm("bkpt 1"); \
} \
} while (0)
// Resume from a fault (if possible) so we can still use interrupt based code for serial output
// In that case, we will not jump back to the faulty code, but instead to a dumping code and then a
// basic loop with watchdog calling or manual resetting
static ContextSavedFrame savedFrame;
static uint8_t lastCause;
bool resume_from_fault() {
static const char* causestr[] = { "Thread", "Rsvd", "NMI", "Hard", "Mem", "Bus", "Usage", "7", "8", "9", "10", "SVC", "Dbg", "13", "PendSV", "SysTk", "IRQ" };
// Reinit the serial link (might only work if implemented in each of your boards)
MinSerial::init();
MinSerial::TX("\n\n## Software Fault detected ##\n");
MinSerial::TX("Cause: "); MinSerial::TX(causestr[min(lastCause, (uint8_t)16)]); MinSerial::TX('\n');
MinSerial::TX("R0 : "); MinSerial::TXHex(savedFrame.R0); MinSerial::TX('\n');
MinSerial::TX("R1 : "); MinSerial::TXHex(savedFrame.R1); MinSerial::TX('\n');
MinSerial::TX("R2 : "); MinSerial::TXHex(savedFrame.R2); MinSerial::TX('\n');
MinSerial::TX("R3 : "); MinSerial::TXHex(savedFrame.R3); MinSerial::TX('\n');
MinSerial::TX("R12 : "); MinSerial::TXHex(savedFrame.R12); MinSerial::TX('\n');
MinSerial::TX("LR : "); MinSerial::TXHex(savedFrame.LR); MinSerial::TX('\n');
MinSerial::TX("PC : "); MinSerial::TXHex(savedFrame.PC); MinSerial::TX('\n');
MinSerial::TX("PSR : "); MinSerial::TXHex(savedFrame.XPSR); MinSerial::TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
MinSerial::TX("CFSR : "); MinSerial::TXHex(savedFrame.CFSR); MinSerial::TX('\n');
// Hard Fault Status Register
MinSerial::TX("HFSR : "); MinSerial::TXHex(savedFrame.HFSR); MinSerial::TX('\n');
// Debug Fault Status Register
MinSerial::TX("DFSR : "); MinSerial::TXHex(savedFrame.DFSR); MinSerial::TX('\n');
// Auxiliary Fault Status Register
MinSerial::TX("AFSR : "); MinSerial::TXHex(savedFrame.AFSR); MinSerial::TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
MinSerial::TX("MMAR : "); MinSerial::TXHex(savedFrame.MMAR); MinSerial::TX('\n');
// Bus Fault Address Register
MinSerial::TX("BFAR : "); MinSerial::TXHex(savedFrame.BFAR); MinSerial::TX('\n');
MinSerial::TX("ExcLR: "); MinSerial::TXHex(savedFrame.ELR); MinSerial::TX('\n');
MinSerial::TX("ExcSP: "); MinSerial::TXHex(savedFrame.ESP); MinSerial::TX('\n');
// The stack pointer is pushed by 8 words upon entering an exception, so we need to revert this
backtrace_ex(savedFrame.ESP + 8*4, savedFrame.LR, savedFrame.PC);
// Call the last resort function here
hook_last_resort_func();
const uint32_t start = millis(), end = start + 100; // 100ms should be enough
// We need to wait for the serial buffers to be output but we don't know for how long
// So we'll just need to refresh the watchdog for a while and then stop for the system to reboot
uint32_t last = start;
while (PENDING(last, end)) {
watchdog_refresh();
while (millis() == last) { /* nada */ }
last = millis();
MinSerial::TX('.');
}
// Reset now by reinstantiating the bootloader's vector table
HW_REG(0xE000ED08) = 0;
// Restart watchdog
#if DISABLED(USE_WATCHDOG)
// No watchdog, let's perform ARMv7 reset instead by writing to AIRCR register with VECTKEY set to SYSRESETREQ
HW_REG(0xE000ED0C) = (HW_REG(0xE000ED0C) & 0x0000FFFF) | 0x05FA0004;
#endif
while(1) {} // Bad luck, nothing worked
}
// Make sure the compiler does not optimize the frame argument away
extern "C"
__attribute__((optimize("O0")))
void CommonHandler_C(ContextStateFrame * frame, unsigned long lr, unsigned long cause) {
// If you are using it'll stop here
HALT_IF_DEBUGGING();
// Save the state to backtrace later on (don't call memcpy here since the stack can be corrupted)
savedFrame.R0 = frame->r0;
savedFrame.R1 = frame->r1;
savedFrame.R2 = frame->r2;
savedFrame.R3 = frame->r3;
savedFrame.R12 = frame->r12;
savedFrame.LR = frame->lr;
savedFrame.PC = frame->pc;
savedFrame.XPSR= frame->xpsr;
lastCause = cause & 0x1FF;
volatile uint32_t &CFSR = HW_REG(0xE000ED28);
savedFrame.CFSR = CFSR;
savedFrame.HFSR = HW_REG(0xE000ED2C);
savedFrame.DFSR = HW_REG(0xE000ED30);
savedFrame.AFSR = HW_REG(0xE000ED3C);
savedFrame.MMAR = HW_REG(0xE000ED34);
savedFrame.BFAR = HW_REG(0xE000ED38);
savedFrame.ESP = (unsigned long)frame; // Even on return, this should not be overwritten by the CPU
savedFrame.ELR = lr;
// First check if we can resume from this exception to our own handler safely
// If we can, then we don't need to disable interrupts and the usual serial code
// can be used
//const uint32_t non_usage_fault_mask = 0x0000FFFF;
//const bool non_usage_fault_occurred = (CFSR & non_usage_fault_mask) != 0;
// the bottom 8 bits of the xpsr hold the exception number of the
// executing exception or 0 if the processor is in Thread mode
const bool faulted_from_exception = ((frame->xpsr & 0xFF) != 0);
if (!faulted_from_exception) { // Not sure about the non_usage_fault, we want to try anyway, don't we ? && !non_usage_fault_occurred)
// Try to resume to our handler here
CFSR |= CFSR; // The ARM programmer manual says you must write to 1 all fault bits to clear them so this instruction is correct
// The frame will not be valid when returning anymore, let's clean it
savedFrame.CFSR = 0;
frame->pc = (uint32_t)resume_from_fault; // Patch where to return to
frame->lr = 0xDEADBEEF; // If our handler returns (it shouldn't), let's make it trigger an exception immediately
frame->xpsr = _BV(24); // Need to clean the PSR register to thumb II only
MinSerial::force_using_default_output = true;
return; // The CPU will resume in our handler hopefully, and we'll try to use default serial output
}
// Sorry, we need to emergency code here since the fault is too dangerous to recover from
MinSerial::force_using_default_output = false;
resume_from_fault();
}
void hook_cpu_exceptions() {
#if ENABLED(DYNAMIC_VECTORTABLE)
// On ARM 32bits CPU, the vector table is like this:
// 0x0C => Hardfault
// 0x10 => MemFault
// 0x14 => BusFault
// 0x18 => UsageFault
// Unfortunately, it's usually run from flash, and we can't write to flash here directly to hook our instruction
// We could set an hardware breakpoint, and hook on the fly when it's being called, but this
// is hard to get right and would probably break debugger when attached
// So instead, we'll allocate a new vector table filled with the previous value except
// for the fault we are interested in.
// Now, comes the issue to figure out what is the current vector table size
// There is nothing telling us what is the vector table as it's per-cpu vendor specific.
// BUT: we are being called at the end of the setup, so we assume the setup is done
// Thus, we can read the current vector table until we find an address that's not in flash, and it would mark the
// end of the vector table (skipping the fist entry obviously)
// The position of the program in flash is expected to be at 0x08xxx xxxx on all known platform for ARM and the
// flash size is available via register 0x1FFFF7E0 on STM32 family, but it's not the case for all ARM boards
// (accessing this register might trigger a fault if it's not implemented).
// So we'll simply mask the top 8 bits of the first handler as an hint of being in the flash or not -that's poor and will
// probably break if the flash happens to be more than 128MB, but in this case, we are not magician, we need help from outside.
unsigned long * vecAddr = (unsigned long*)get_vtor();
SERIAL_ECHO("Vector table addr: ");
SERIAL_PRINTLN(get_vtor(), HEX);
#ifdef VECTOR_TABLE_SIZE
uint32_t vec_size = VECTOR_TABLE_SIZE;
alignas(128) static unsigned long vectable[VECTOR_TABLE_SIZE] ;
#else
#ifndef IS_IN_FLASH
#define IS_IN_FLASH(X) (((unsigned long)X & 0xFF000000) == 0x08000000)
#endif
// When searching for the end of the vector table, this acts as a limit not to overcome
#ifndef VECTOR_TABLE_SENTINEL
#define VECTOR_TABLE_SENTINEL 80
#endif
// Find the vector table size
uint32_t vec_size = 1;
while (IS_IN_FLASH(vecAddr[vec_size]) && vec_size < VECTOR_TABLE_SENTINEL)
vec_size++;
// We failed to find a valid vector table size, let's abort hooking up
if (vec_size == VECTOR_TABLE_SENTINEL) return;
// Poor method that's wasting RAM here, but allocating with malloc and alignment would be worst
// 128 bytes alignement is required for writing the VTOR register
alignas(128) static unsigned long vectable[VECTOR_TABLE_SENTINEL];
SERIAL_ECHO("Detected vector table size: ");
SERIAL_PRINTLN(vec_size, HEX);
#endif
uint32_t defaultFaultHandler = vecAddr[(unsigned)7];
// Copy the current vector table into the new table
for (uint32_t i = 0; i < vec_size; i++) {
vectable[i] = vecAddr[i];
// Replace all default handler by our own handler
if (vectable[i] == defaultFaultHandler)
vectable[i] = (unsigned long)&CommonHandler_ASM;
}
// Let's hook now with our functions
vectable[(unsigned long)hook_get_hardfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_memfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_busfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_usagefault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
// Finally swap with our own vector table
// This is supposed to be atomic, but let's do that with interrupt disabled
HW_REG(0xE000ED08) = (unsigned long)vectable | _BV32(29); // 29th bit is for telling the CPU the table is now in SRAM (should be present already)
SERIAL_ECHOLN("Installed fault handlers");
#endif
}
#endif // __arm__ || __thumb__
@@ -0,0 +1,28 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "exception_hook.h"
void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned) { return 0; }
void __attribute__((weak)) hook_last_resort_func() {}
@@ -0,0 +1,54 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/* Here is the expected behavior of a system producing a CPU exception with this hook installed:
1. Before the system is crashed
1.1 Upon validation (not done yet in this code, but we could be using DEBUG flags here to allow/disallow hooking)
1.2 Install the hook by overwriting the vector table exception handler with the hooked function
2. Upon system crash (for example, by a dereference of a NULL pointer or anything else)
2.1 The CPU triggers its exception and jump into the vector table for the exception type
2.2 Instead of finding the default handler, it finds the updated pointer to our hook
2.3 The CPU jumps into our hook function (likely a naked function to keep all information about crash point intact)
2.4 The hook (naked) function saves the important registers (stack pointer, program counter, current mode) and jumps to a common exception handler (in C)
2.5 The common exception handler dumps the registers on the serial link and perform a backtrace around the crashing point
2.6 Once the backtrace is performed the last resort function is called (platform specific).
On some platform with a LCD screen, this might display the crash information as a QR code or as text for the
user to capture by taking a picture
2.7 The CPU is reset and/or halted by triggering a debug breakpoint if a debugger is attached */
// Hook into CPU exception interrupt table to call the backtracing code upon an exception
// Most platform will simply do nothing here, but those who can will install/overwrite the default exception handler
// with a more performant exception handler
void hook_cpu_exceptions();
// Some platform might deal without a hard fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned base_address);
// Some platform might deal without a memory management fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned base_address);
// Some platform might deal without a bus fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned base_address);
// Some platform might deal without a usage fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned base_address);
// Last resort function that can be called after the exception handler was called.
void __attribute__((weak)) hook_last_resort_func();
+1 -1
View File
@@ -25,5 +25,5 @@
// EEPROM
//
void eeprom_init();
void eeprom_write_byte(uint8_t *pos, unsigned char value);
void eeprom_write_byte(uint8_t *pos, uint8_t value);
uint8_t eeprom_read_byte(uint8_t *pos);
+15 -10
View File
@@ -32,7 +32,13 @@
#include "eeprom_if.h"
#include <Wire.h>
void eeprom_init() { Wire.begin(); }
void eeprom_init() {
Wire.begin(
#if PINS_EXIST(I2C_SCL, I2C_SDA)
uint8_t(I2C_SDA_PIN), uint8_t(I2C_SCL_PIN)
#endif
);
}
#if ENABLED(USE_SHARED_EEPROM)
@@ -49,12 +55,15 @@ static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRE
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
static void _eeprom_begin(uint8_t * const pos) {
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
Wire.write(int(eeprom_address >> 8)); // Address High
Wire.write(int(eeprom_address & 0xFF)); // Address Low
}
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
_eeprom_begin(pos);
Wire.write(value);
Wire.endTransmission();
@@ -64,11 +73,7 @@ void eeprom_write_byte(uint8_t *pos, unsigned char value) {
}
uint8_t eeprom_read_byte(uint8_t *pos) {
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
_eeprom_begin(pos);
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)1);
return Wire.available() ? Wire.read() : 0xFF;
+27 -30
View File
@@ -43,44 +43,41 @@ void eeprom_init() {}
#define EEPROM_WRITE_DELAY 7
#endif
uint8_t eeprom_read_byte(uint8_t* pos) {
uint8_t v;
uint8_t eeprom_temp[3];
// set read location
// begin transmission from device
eeprom_temp[0] = CMD_READ;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; // addr High
eeprom_temp[2] = (unsigned)pos& 0xFF; // addr Low
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM1_CS, LOW);
static void _eeprom_begin(uint8_t * const pos, const uint8_t cmd) {
const uint8_t eeprom_temp[3] = {
cmd,
(unsigned(pos) >> 8) & 0xFF, // Address High
unsigned(pos) & 0xFF // Address Low
};
WRITE(SPI_EEPROM1_CS, HIGH); // Usually free already
WRITE(SPI_EEPROM1_CS, LOW); // Activate the Bus
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
// Leave the Bus in-use
}
uint8_t eeprom_read_byte(uint8_t* pos) {
_eeprom_begin(pos, CMD_READ); // Set read location and begin transmission
const uint8_t v = spiRec(SPI_CHAN_EEPROM1); // After READ a value sits on the Bus
WRITE(SPI_EEPROM1_CS, HIGH); // Done with device
v = spiRec(SPI_CHAN_EEPROM1);
WRITE(SPI_EEPROM1_CS, HIGH);
return v;
}
void eeprom_write_byte(uint8_t* pos, uint8_t value) {
uint8_t eeprom_temp[3];
/*write enable*/
eeprom_temp[0] = CMD_WREN;
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const uint8_t eeprom_temp = CMD_WREN;
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(1);
spiSend(SPI_CHAN_EEPROM1, &eeprom_temp, 1); // Write Enable
/*write addr*/
eeprom_temp[0] = CMD_WRITE;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; //addr High
eeprom_temp[2] = (unsigned)pos & 0xFF; //addr Low
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(1); // For a small amount of time
spiSend(SPI_CHAN_EEPROM1, value);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(EEPROM_WRITE_DELAY); // wait for page write to complete
_eeprom_begin(pos, CMD_WRITE); // Set write address and begin transmission
spiSend(SPI_CHAN_EEPROM1, value); // Send the value to be written
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(EEPROM_WRITE_DELAY); // Give page write time to complete
}
#endif // USE_SHARED_EEPROM
+299 -53
View File
@@ -36,6 +36,7 @@
#include "HAL/shared/Delay.h"
#include "HAL/shared/esp_wifi.h"
#include "HAL/shared/cpu_exception/exception_hook.h"
#ifdef ARDUINO
#include <pins_arduino.h>
@@ -230,6 +231,10 @@
#include "feature/password/password.h"
#endif
#if ENABLED(DGUS_LCD_UI_MKS)
#include "lcd/extui/lib/dgus/DGUSScreenHandler.h"
#endif
PGMSTR(M112_KILL_STR, "M112 Shutdown");
MarlinState marlin_state = MF_INITIALIZING;
@@ -387,6 +392,7 @@ void startOrResumeJob() {
if (queue.enqueue_one_P(PSTR("M1001"))) {
marlin_state = MF_RUNNING;
TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
TERN_(DGUS_LCD_UI_MKS, ScreenHandler.SDPrintingFinished());
}
}
@@ -400,13 +406,14 @@ void startOrResumeJob() {
* - Check if CHDK_PIN needs to go LOW
* - Check for KILL button held down
* - Check for HOME button held down
* - Check for CUSTOM USER button held down
* - Check if cooling fan needs to be switched on
* - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
* - Pulse FET_SAFETY_PIN if it exists
*/
inline void manage_inactivity(const bool ignore_stepper_queue=false) {
if (queue.length < BUFSIZE) queue.get_available_commands();
queue.get_available_commands();
const millis_t ms = millis();
@@ -492,6 +499,102 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
}
#endif
#if ENABLED(CUSTOM_USER_BUTTONS)
// Handle a custom user button if defined
const bool printer_not_busy = !printingIsActive();
#define HAS_CUSTOM_USER_BUTTON(N) (PIN_EXISTS(BUTTON##N) && defined(BUTTON##N##_HIT_STATE) && defined(BUTTON##N##_GCODE) && defined(BUTTON##N##_DESC))
#define CHECK_CUSTOM_USER_BUTTON(N) do{ \
constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \
static millis_t next_cub_ms_##N; \
if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \
const millis_t ms = millis(); \
if (ELAPSED(ms, next_cub_ms_##N)) { \
next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \
if (strlen(BUTTON##N##_DESC)) \
LCD_MESSAGEPGM_P(PSTR(BUTTON##N##_DESC)); \
queue.inject_P(PSTR(BUTTON##N##_GCODE)); \
} \
} \
}while(0)
#if HAS_CUSTOM_USER_BUTTON(1)
CHECK_CUSTOM_USER_BUTTON(1);
#endif
#if HAS_CUSTOM_USER_BUTTON(2)
CHECK_CUSTOM_USER_BUTTON(2);
#endif
#if HAS_CUSTOM_USER_BUTTON(3)
CHECK_CUSTOM_USER_BUTTON(3);
#endif
#if HAS_CUSTOM_USER_BUTTON(4)
CHECK_CUSTOM_USER_BUTTON(4);
#endif
#if HAS_CUSTOM_USER_BUTTON(5)
CHECK_CUSTOM_USER_BUTTON(5);
#endif
#if HAS_CUSTOM_USER_BUTTON(6)
CHECK_CUSTOM_USER_BUTTON(6);
#endif
#if HAS_CUSTOM_USER_BUTTON(7)
CHECK_CUSTOM_USER_BUTTON(7);
#endif
#if HAS_CUSTOM_USER_BUTTON(8)
CHECK_CUSTOM_USER_BUTTON(8);
#endif
#if HAS_CUSTOM_USER_BUTTON(9)
CHECK_CUSTOM_USER_BUTTON(9);
#endif
#if HAS_CUSTOM_USER_BUTTON(10)
CHECK_CUSTOM_USER_BUTTON(10);
#endif
#if HAS_CUSTOM_USER_BUTTON(11)
CHECK_CUSTOM_USER_BUTTON(11);
#endif
#if HAS_CUSTOM_USER_BUTTON(12)
CHECK_CUSTOM_USER_BUTTON(12);
#endif
#if HAS_CUSTOM_USER_BUTTON(13)
CHECK_CUSTOM_USER_BUTTON(13);
#endif
#if HAS_CUSTOM_USER_BUTTON(14)
CHECK_CUSTOM_USER_BUTTON(14);
#endif
#if HAS_CUSTOM_USER_BUTTON(15)
CHECK_CUSTOM_USER_BUTTON(15);
#endif
#if HAS_CUSTOM_USER_BUTTON(16)
CHECK_CUSTOM_USER_BUTTON(16);
#endif
#if HAS_CUSTOM_USER_BUTTON(17)
CHECK_CUSTOM_USER_BUTTON(17);
#endif
#if HAS_CUSTOM_USER_BUTTON(18)
CHECK_CUSTOM_USER_BUTTON(18);
#endif
#if HAS_CUSTOM_USER_BUTTON(19)
CHECK_CUSTOM_USER_BUTTON(19);
#endif
#if HAS_CUSTOM_USER_BUTTON(20)
CHECK_CUSTOM_USER_BUTTON(20);
#endif
#if HAS_CUSTOM_USER_BUTTON(21)
CHECK_CUSTOM_USER_BUTTON(21);
#endif
#if HAS_CUSTOM_USER_BUTTON(22)
CHECK_CUSTOM_USER_BUTTON(22);
#endif
#if HAS_CUSTOM_USER_BUTTON(23)
CHECK_CUSTOM_USER_BUTTON(23);
#endif
#if HAS_CUSTOM_USER_BUTTON(24)
CHECK_CUSTOM_USER_BUTTON(24);
#endif
#if HAS_CUSTOM_USER_BUTTON(25)
CHECK_CUSTOM_USER_BUTTON(25);
#endif
#endif
TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down
TERN_(AUTO_POWER_CONTROL, powerManager.check());
@@ -786,8 +889,8 @@ void stop() {
print_job_timer.stop();
#if ENABLED(PROBING_FANS_OFF)
if (thermalManager.fans_paused) thermalManager.set_fans_paused(false); // put things back the way they were
#if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE)
thermalManager.set_fans_paused(false); // Un-pause fans for safety
#endif
if (IsRunning()) {
@@ -850,25 +953,97 @@ inline void tmc_standby_setup() {
}
/**
* Marlin entry-point: Set up before the program loop
* - Set up the kill pin, filament runout, power hold
* - Start the serial port
* Marlin Firmware entry-point. Abandon Hope All Ye Who Enter Here.
* Setup before the program loop:
*
* - Call any special pre-init set for the board
* - Put TMC drivers into Low Power Standby mode
* - Init the serial ports (so setup can be debugged)
* - Set up the kill and suicide pins
* - Prepare (disable) board JTAG and Debug ports
* - Init serial for a connected MKS TFT with WiFi
* - Install Marlin custom Exception Handlers, if set.
* - Init Marlin's HAL interfaces (for SPI, i2c, etc.)
* - Init some optional hardware and features:
* • MAX Thermocouple pins
* • Duet Smart Effector
* • Filament Runout Sensor
* • TMC220x Stepper Drivers (Serial)
* • PSU control
* • Power-loss Recovery
* • L64XX Stepper Drivers (SPI)
* • Stepper Driver Reset: DISABLE
* • TMC Stepper Drivers (SPI)
* • Run BOARD_INIT if defined
* • ESP WiFi
* - Get the Reset Reason and report it
* - Print startup messages and diagnostics
* - Get EEPROM or default settings
* - Initialize managers for:
* • temperature
* • planner
* • watchdog
* • stepper
* • photo pin
* • servos
* • LCD controller
* • Digipot I2C
* • Z probe sled
* • status LEDs
* • Max7219
* - Calibrate the HAL DELAY for precise timing
* - Init the buzzer, possibly a custom timer
* - Init more optional hardware:
* • Color LED illumination
* • Neopixel illumination
* • Controller Fan
* • Creality DWIN LCD (show boot image)
* • Tare the Probe if possible
* - Mount the (most likely external) SD Card
* - Load settings from EEPROM (or use defaults)
* - Init the Ethernet Port
* - Init Touch Buttons (for emulated DOGLCD)
* - Adjust the (certainly wrong) current position by the home offset
* - Init the Planner::position (steps) based on current (native) position
* - Initialize more managers and peripherals:
* • Temperatures
* • Print Job Timer
* • Endstops and Endstop Interrupts
* • Stepper ISR - Kind of Important!
* • Servos
* • Servo-based Probe
* • Photograph Pin
* • Laser/Spindle tool Power / PWM
* • Coolant Control
* • Bed Probe
* • Stepper Driver Reset: ENABLE
* • Digipot I2C - Stepper driver current control
* • Stepper DAC - Stepper driver current control
* • Solenoid (probe, or for other use)
* • Home Pin
* • Custom User Buttons
* • Red/Blue Status LEDs
* • Case Light
* • Prusa MMU filament changer
* • Fan Multiplexer
* • Mixing Extruder
* • BLTouch Probe
* • I2C Position Encoders
* • Custom I2C Bus handlers
* • Enhanced tools or extruders:
* • Switching Extruder
* • Switching Nozzle
* • Parking Extruder
* • Magnetic Parking Extruder
* • Switching Toolhead
* • Electromagnetic Switching Toolhead
* • Watchdog Timer - Also Kind of Important!
* • Closed Loop Controller
* - Run Startup Commands, if defined
* - Tell host to close Host Prompts
* - Test Trinamic driver connections
* - Init Prusa MMU2 filament changer
* - Init and test BL24Cxx EEPROM
* - Init Creality DWIN encoder, show faux progress bar
* - Reset Status Message / Show Service Messages
* - Init MAX7219 LED Matrix
* - Init Direct Stepping (Klipper-style motion control)
* - Init TFT LVGL UI (with 3D Graphics)
* - Apply Password Lock - Hold for Authentication
* - Open Touch Screen Calibration screen, if not calibrated
* - Set Marlin to RUNNING State
*/
void setup() {
#ifdef BOARD_PREINIT
BOARD_PREINIT(); // Low-level init (before serial init)
#endif
tmc_standby_setup(); // TMC Low Power Standby pins must be set early or they're not usable
@@ -876,8 +1051,7 @@ void setup() {
auto log_current_ms = [&](PGM_P const msg) {
SERIAL_ECHO_START();
SERIAL_CHAR('['); SERIAL_ECHO(millis()); SERIAL_ECHOPGM("] ");
serialprintPGM(msg);
SERIAL_EOL();
SERIAL_ECHOLNPGM_P(msg);
};
#define SETUP_LOG(M) log_current_ms(PSTR(M))
#else
@@ -885,14 +1059,14 @@ void setup() {
#endif
#define SETUP_RUN(C) do{ SETUP_LOG(STRINGIFY(C)); C; }while(0)
MYSERIAL0.begin(BAUDRATE);
MYSERIAL1.begin(BAUDRATE);
millis_t serial_connect_timeout = millis() + 1000UL;
while (!MYSERIAL0.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#if HAS_MULTI_SERIAL && !HAS_ETHERNET
MYSERIAL1.begin(BAUDRATE);
MYSERIAL2.begin(BAUDRATE);
serial_connect_timeout = millis() + 1000UL;
while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
SERIAL_ECHOLNPGM("start");
@@ -911,12 +1085,6 @@ void setup() {
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
#if ENABLED(PSU_CONTROL)
SETUP_LOG("PSU_CONTROL");
powersupply_on = ENABLED(PSU_DEFAULT_OFF);
if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
#endif
#if EITHER(DISABLE_DEBUG, DISABLE_JTAG)
// Disable any hardware debug to free up pins for IO
#if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE)
@@ -935,6 +1103,8 @@ void setup() {
while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
TERN_(DYNAMIC_VECTORTABLE, hook_cpu_exceptions()); // If supported, install Marlin exception handlers at runtime
SETUP_RUN(HAL_init());
// Init and disable SPI thermocouples; this is still needed
@@ -945,10 +1115,6 @@ void setup() {
OUT_WRITE(MAX6675_SS2_PIN, HIGH); // Disable
#endif
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode
#endif
@@ -957,12 +1123,22 @@ void setup() {
SETUP_RUN(runout.setup());
#endif
#if HAS_TMC220x
SETUP_RUN(tmc_serial_begin());
#endif
#if ENABLED(PSU_CONTROL)
SETUP_LOG("PSU_CONTROL");
powersupply_on = ENABLED(PSU_DEFAULT_OFF);
if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
SETUP_RUN(recovery.setup());
#endif
#if HAS_TMC220x
SETUP_RUN(tmc_serial_begin());
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if HAS_STEPPER_RESET
@@ -992,7 +1168,7 @@ void setup() {
if (mcu & RST_SOFTWARE) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET);
HAL_clear_reset_source();
serialprintPGM(GET_TEXT(MSG_MARLIN));
SERIAL_ECHOPGM_P(GET_TEXT(MSG_MARLIN));
SERIAL_CHAR(' ');
SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION);
SERIAL_EOL();
@@ -1121,19 +1297,95 @@ void setup() {
SET_INPUT_PULLUP(HOME_PIN);
#endif
#if ENABLED(CUSTOM_USER_BUTTONS)
#define INIT_CUSTOM_USER_BUTTON_PIN(N) do{ SET_INPUT(BUTTON##N##_PIN); WRITE(BUTTON##N##_PIN, !BUTTON##N##_HIT_STATE); }while(0)
#if HAS_CUSTOM_USER_BUTTON(1)
INIT_CUSTOM_USER_BUTTON_PIN(1);
#endif
#if HAS_CUSTOM_USER_BUTTON(2)
INIT_CUSTOM_USER_BUTTON_PIN(2);
#endif
#if HAS_CUSTOM_USER_BUTTON(3)
INIT_CUSTOM_USER_BUTTON_PIN(3);
#endif
#if HAS_CUSTOM_USER_BUTTON(4)
INIT_CUSTOM_USER_BUTTON_PIN(4);
#endif
#if HAS_CUSTOM_USER_BUTTON(5)
INIT_CUSTOM_USER_BUTTON_PIN(5);
#endif
#if HAS_CUSTOM_USER_BUTTON(6)
INIT_CUSTOM_USER_BUTTON_PIN(6);
#endif
#if HAS_CUSTOM_USER_BUTTON(7)
INIT_CUSTOM_USER_BUTTON_PIN(7);
#endif
#if HAS_CUSTOM_USER_BUTTON(8)
INIT_CUSTOM_USER_BUTTON_PIN(8);
#endif
#if HAS_CUSTOM_USER_BUTTON(9)
INIT_CUSTOM_USER_BUTTON_PIN(9);
#endif
#if HAS_CUSTOM_USER_BUTTON(10)
INIT_CUSTOM_USER_BUTTON_PIN(10);
#endif
#if HAS_CUSTOM_USER_BUTTON(11)
INIT_CUSTOM_USER_BUTTON_PIN(11);
#endif
#if HAS_CUSTOM_USER_BUTTON(12)
INIT_CUSTOM_USER_BUTTON_PIN(12);
#endif
#if HAS_CUSTOM_USER_BUTTON(13)
INIT_CUSTOM_USER_BUTTON_PIN(13);
#endif
#if HAS_CUSTOM_USER_BUTTON(14)
INIT_CUSTOM_USER_BUTTON_PIN(14);
#endif
#if HAS_CUSTOM_USER_BUTTON(15)
INIT_CUSTOM_USER_BUTTON_PIN(15);
#endif
#if HAS_CUSTOM_USER_BUTTON(16)
INIT_CUSTOM_USER_BUTTON_PIN(16);
#endif
#if HAS_CUSTOM_USER_BUTTON(17)
INIT_CUSTOM_USER_BUTTON_PIN(17);
#endif
#if HAS_CUSTOM_USER_BUTTON(18)
INIT_CUSTOM_USER_BUTTON_PIN(18);
#endif
#if HAS_CUSTOM_USER_BUTTON(19)
INIT_CUSTOM_USER_BUTTON_PIN(19);
#endif
#if HAS_CUSTOM_USER_BUTTON(20)
INIT_CUSTOM_USER_BUTTON_PIN(20);
#endif
#if HAS_CUSTOM_USER_BUTTON(21)
INIT_CUSTOM_USER_BUTTON_PIN(21);
#endif
#if HAS_CUSTOM_USER_BUTTON(22)
INIT_CUSTOM_USER_BUTTON_PIN(22);
#endif
#if HAS_CUSTOM_USER_BUTTON(23)
INIT_CUSTOM_USER_BUTTON_PIN(23);
#endif
#if HAS_CUSTOM_USER_BUTTON(24)
INIT_CUSTOM_USER_BUTTON_PIN(24);
#endif
#if HAS_CUSTOM_USER_BUTTON(25)
INIT_CUSTOM_USER_BUTTON_PIN(25);
#endif
#endif
#if PIN_EXISTS(STAT_LED_RED)
OUT_WRITE(STAT_LED_RED_PIN, LOW); // OFF
#endif
#if PIN_EXISTS(STAT_LED_BLUE)
OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF
#endif
#if ENABLED(CASE_LIGHT_ENABLE)
#if DISABLED(CASE_LIGHT_USE_NEOPIXEL)
if (PWM_PIN(CASE_LIGHT_PIN)) SET_PWM(CASE_LIGHT_PIN); else SET_OUTPUT(CASE_LIGHT_PIN);
#endif
SETUP_RUN(caselight.update_brightness());
SETUP_RUN(caselight.init());
#endif
#if HAS_PRUSA_MMU1
@@ -1180,19 +1432,13 @@ void setup() {
#endif
#endif
#if ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#endif
#if ENABLED(PARKING_EXTRUDER)
SETUP_RUN(pe_solenoid_init());
#endif
#if ENABLED(SWITCHING_TOOLHEAD)
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#elif ENABLED(SWITCHING_TOOLHEAD)
SETUP_RUN(swt_init());
#endif
#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
#elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
SETUP_RUN(est_init());
#endif
+3 -1
View File
@@ -126,6 +126,7 @@
#define BOARD_EINSY_RAMBO 1203 // Einsy Rambo
#define BOARD_EINSY_RETRO 1204 // Einsy Retro
#define BOARD_SCOOVO_X9H 1205 // abee Scoovo X9H
#define BOARD_RAMBO_THINKERV2 1206 // ThinkerV2
//
// Other ATmega1280, ATmega2560
@@ -278,6 +279,7 @@
#define BOARD_ARCHIM2 3024 // UltiMachine Archim2 (with TMC2130 drivers)
#define BOARD_ALLIGATOR 3025 // Alligator Board R2
#define BOARD_CNCONTROLS_15D 3026 // Cartesio CN Controls V15 on DUE
#define BOARD_KRATOS32 3027 // K.3D Kratos32 (Arduino Due Shield)
//
// SAM3X8C ARM Cortex M3
@@ -327,7 +329,7 @@
#define BOARD_LONGER3D_LK 4034 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
#define BOARD_CCROBOT_MEEB_3DP 4035 // ccrobot-online.com MEEB_3DP (STM32F103RC)
#define BOARD_CHITU3D_V5 4036 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CHITU3D_V6 4037 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CHITU3D_V6 4037 // Chitu3D TronXY X5SA V6 Board
#define BOARD_CREALITY_V4 4038 // Creality v4.x (STM32F103RE)
#define BOARD_CREALITY_V427 4039 // Creality v4.2.7 (STM32F103RE)
#define BOARD_CREALITY_V4210 4040 // Creality v4.2.10 (STM32F103RE) as found in the CR-30
+37
View File
@@ -0,0 +1,37 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Copyright (c) 2021 X-Ryl669 [https://blog.cyril.by]
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
// We need SERIAL_ECHOPAIR and macros.h
#include "serial.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
// Useful macro for stopping the CPU on an unexpected condition
// This is used like SERIAL_ECHOPAIR, that is: a key-value call of the local variables you want
// to dump to the serial port before stopping the CPU.
#define BUG_ON(V...) do { SERIAL_ECHOPAIR(ONLY_FILENAME, __LINE__, ": "); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0)
#elif ENABLED(MARLIN_DEV_MODE)
// Don't stop the CPU here, but at least dump the bug on the serial port
#define BUG_ON(V...) do { SERIAL_ECHOPAIR(ONLY_FILENAME, __LINE__, ": BUG!\n"); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); } while(0)
#else
// Release mode, let's ignore the bug
#define BUG_ON(V...) NOOP
#endif
+3 -3
View File
@@ -27,7 +27,7 @@
//
#undef DEBUG_SECTION
#undef DEBUG_PRINT_P
#undef DEBUG_ECHOPGM_P
#undef DEBUG_ECHO_START
#undef DEBUG_ERROR_START
#undef DEBUG_CHAR
@@ -59,7 +59,7 @@
#include "debug_section.h"
#define DEBUG_SECTION(N,S,D) SectionLog N(PSTR(S),D)
#define DEBUG_PRINT_P(P) serialprintPGM(P)
#define DEBUG_ECHOPGM_P(P) SERIAL_ECHOPGM_P(P)
#define DEBUG_ECHO_START SERIAL_ECHO_START
#define DEBUG_ERROR_START SERIAL_ERROR_START
#define DEBUG_CHAR SERIAL_CHAR
@@ -89,7 +89,7 @@
#else
#define DEBUG_SECTION(...) NOOP
#define DEBUG_PRINT_P(P) NOOP
#define DEBUG_ECHOPGM_P(P) NOOP
#define DEBUG_ECHO_START() NOOP
#define DEBUG_ERROR_START() NOOP
#define DEBUG_CHAR(...) NOOP
+2 -2
View File
@@ -38,10 +38,10 @@ private:
bool debug;
void echo_msg(PGM_P const pre) {
serialprintPGM(pre);
SERIAL_ECHOPGM_P(pre);
if (the_msg) {
SERIAL_CHAR(' ');
serialprintPGM(the_msg);
SERIAL_ECHOPGM_P(the_msg);
}
SERIAL_CHAR(' ');
print_xyz(current_position);
+4 -1
View File
@@ -131,6 +131,7 @@
#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required."
#define STR_ERR_KILLED "Printer halted. kill() called!"
#define STR_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define STR_ERR_SERIAL_MISMATCH "Serial status mismatch"
#define STR_BUSY_PROCESSING "busy: processing"
#define STR_BUSY_PAUSED_FOR_USER "busy: paused for user"
#define STR_BUSY_PAUSED_FOR_INPUT "busy: paused for input"
@@ -221,7 +222,7 @@
// temperature.cpp strings
#define STR_PID_AUTOTUNE_START "PID Autotune start"
#define STR_PID_BAD_EXTRUDER_NUM "PID Autotune failed! Bad extruder number"
#define STR_PID_BAD_HEATER_ID "PID Autotune failed! Bad heater id"
#define STR_PID_TEMP_TOO_HIGH "PID Autotune failed! Temperature too high"
#define STR_PID_TIMEOUT "PID Autotune failed! timeout"
#define STR_BIAS " bias: "
@@ -246,6 +247,8 @@
#define STR_HEATER_BED "bed"
#define STR_HEATER_CHAMBER "chamber"
#define STR_COOLER "cooler"
#define STR_LASER_TEMP "laser temperature"
#define STR_STOPPED_HEATER ", system stopped! Heater_ID: "
#define STR_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !"
+26
View File
@@ -104,6 +104,7 @@
#define RADIANS(d) ((d)*float(M_PI)/180.0f)
#define DEGREES(r) ((r)*180.0f/float(M_PI))
#define HYPOT2(x,y) (sq(x)+sq(y))
#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R)))
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
@@ -349,6 +350,31 @@
#define CALL_IF_EXISTS(Return, That, Method, ...) \
static_cast<Return>(Private::Call_ ## Method(That, ##__VA_ARGS__))
// Compile-time string manipulation
namespace CompileTimeString {
// Simple compile-time parser to find the position of the end of a string
constexpr const char* findStringEnd(const char *str) {
return *str ? findStringEnd(str + 1) : str;
}
// Check whether a string contains a slash
constexpr bool containsSlash(const char *str) {
return *str == '/' ? true : (*str ? containsSlash(str + 1) : false);
}
// Find the last position of the slash
constexpr const char* findLastSlashPos(const char* str) {
return *str == '/' ? (str + 1) : findLastSlashPos(str - 1);
}
// Compile-time evaluation of the last part of a file path
// Typically used to shorten the path to file in compiled strings
// CompileTimeString::baseName(__FILE__) returns "macros.h" and not /path/to/Marlin/src/core/macros.h
constexpr const char* baseName(const char* str) {
return containsSlash(str) ? findLastSlashPos(findStringEnd(str)) : str;
}
}
#define ONLY_FILENAME CompileTimeString::baseName(__FILE__)
#else
#define MIN_2(a,b) ((a)<(b)?(a):(b))
+14 -11
View File
@@ -37,19 +37,22 @@ PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E");
PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
// Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
SerialLeafT1 mpSerial1(false, _SERIAL_LEAF_1);
#endif
#if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2);
#endif
// Step 2: For multiserial, handle the second serial port as well
#if HAS_MULTI_SERIAL
#ifdef SERIAL_CATCHALL
SerialOutputT multiSerial(MYSERIAL, SERIAL_CATCHALL);
#else
#if HAS_ETHERNET
// Runtime checking of the condition variable
ConditionalSerial<decltype(MYSERIAL1)> serialOut1(ethernet.have_telnet_client, MYSERIAL1, false); // Takes reference here
#else
// Don't pay for runtime checking a true variable, instead use the output directly
#define serialOut1 MYSERIAL1
#endif
SerialOutputT multiSerial(MYSERIAL0, serialOut1);
#if HAS_ETHERNET
// We need a definition here
SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false);
#endif
SerialOutputT multiSerial(SERIAL_LEAF_1, SERIAL_LEAF_2);
#endif
void serialprintPGM(PGM_P str) {
+60 -18
View File
@@ -24,6 +24,10 @@
#include "../inc/MarlinConfig.h"
#include "serial_hook.h"
#if HAS_MEATPACK
#include "../feature/meatpack.h"
#endif
// Commonly-used strings in serial output
extern const char NUL_STR[], SP_P_STR[], SP_T_STR[],
X_STR[], Y_STR[], Z_STR[], E_STR[],
@@ -58,28 +62,66 @@ extern uint8_t marlin_debug_flags;
//
// Serial redirection
//
typedef int8_t serial_index_t;
#define SERIAL_ALL 0x7F
#if HAS_MULTI_SERIAL
#define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
#define SERIAL_ASSERT(P) if(multiSerial.portMask!=(P)){ debugger(); }
#ifdef SERIAL_CATCHALL
typedef MultiSerial<decltype(MYSERIAL), decltype(SERIAL_CATCHALL), 0> SerialOutputT;
#else
typedef MultiSerial<decltype(MYSERIAL0), TERN(HAS_ETHERNET, ConditionalSerial<decltype(MYSERIAL1)>, decltype(MYSERIAL1)), 0> SerialOutputT;
#endif
extern SerialOutputT multiSerial;
#define SERIAL_IMPL multiSerial
// Step 1: Find what's the first serial leaf
#if BOTH(HAS_MULTI_SERIAL, SERIAL_CATCHALL)
#define _SERIAL_LEAF_1 MYSERIAL
#else
#define _PORT_REDIRECT(n,p) NOOP
#define SERIAL_ASSERT(P) NOOP
#define SERIAL_IMPL MYSERIAL0
#define _SERIAL_LEAF_1 MYSERIAL1
#endif
// Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
typedef MeatpackSerial<decltype(_SERIAL_LEAF_1)> SerialLeafT1;
extern SerialLeafT1 mpSerial1;
#define SERIAL_LEAF_1 mpSerial1
#else
#define SERIAL_LEAF_1 _SERIAL_LEAF_1
#endif
// Step 2: For multiserial, handle the second serial port as well
#if HAS_MULTI_SERIAL
#define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
#define _PORT_RESTORE(n,p) RESTORE(n)
#define SERIAL_ASSERT(P) if(multiSerial.portMask!=(P)){ debugger(); }
// If we have a catchall, use that directly
#ifdef SERIAL_CATCHALL
#define _SERIAL_LEAF_2 SERIAL_CATCHALL
#else
#if HAS_ETHERNET
// We need to create an instance here
typedef ConditionalSerial<decltype(MYSERIAL2)> SerialLeafT2;
extern SerialLeafT2 msSerial2;
#define _SERIAL_LEAF_2 msSerial2
#else
// Don't create a useless instance here, directly use the existing instance
#define _SERIAL_LEAF_2 MYSERIAL2
#endif
#endif
// Hook Meatpack if it's enabled on the second leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
typedef MeatpackSerial<decltype(_SERIAL_LEAF_2)> SerialLeafT2;
extern SerialLeafT2 mpSerial2;
#define SERIAL_LEAF_2 mpSerial2
#else
#define SERIAL_LEAF_2 _SERIAL_LEAF_2
#endif
typedef MultiSerial<decltype(SERIAL_LEAF_1), decltype(SERIAL_LEAF_2), 0> SerialOutputT;
extern SerialOutputT multiSerial;
#define SERIAL_IMPL multiSerial
#else
#define _PORT_REDIRECT(n,p) NOOP
#define _PORT_RESTORE(n) NOOP
#define SERIAL_ASSERT(P) NOOP
#define SERIAL_IMPL SERIAL_LEAF_1
#endif
#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define SERIAL_PORTMASK(P) _BV(P)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define PORT_RESTORE() _PORT_RESTORE(1)
#define SERIAL_PORTMASK(P) SerialMask::from(P)
//
// SERIAL_CHAR - Print one or more individual chars
@@ -292,7 +334,7 @@ void serialprintPGM(PGM_P str);
#endif
#define SERIAL_ECHOPGM_P(P) (serialprintPGM(P))
#define SERIAL_ECHOLNPGM_P(P) (serialprintPGM(P "\n"))
#define SERIAL_ECHOLNPGM_P(P) do{ serialprintPGM(P); SERIAL_EOL(); }while(0)
#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S)))
#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n")))
+26 -9
View File
@@ -22,14 +22,31 @@
#pragma once
#include "../inc/MarlinConfigPre.h"
#include "macros.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../feature/e_parser.h"
#endif
// Used in multiple places
// You can build it but not manipulate it.
// There are only few places where it's required to access the underlying member: GCodeQueue, SerialMask and MultiSerial
struct serial_index_t {
// A signed index, where -1 is a special case meaning no action (neither output or input)
int8_t index;
// Check if the index is within the range [a ... b]
constexpr inline bool within(const int8_t a, const int8_t b) const { return WITHIN(index, a, b); }
constexpr inline bool valid() const { return WITHIN(index, 0, 7); } // At most, 8 bits
// Construction is either from an index
constexpr serial_index_t(const int8_t index) : index(index) {}
// Default to "no index"
constexpr serial_index_t() : index(-1) {}
};
// flushTX is not implemented in all HAL, so use SFINAE to call the method where it is.
CALL_IF_EXISTS_IMPL(void, flushTX );
CALL_IF_EXISTS_IMPL(void, flushTX);
CALL_IF_EXISTS_IMPL(bool, connected, true);
// In order to catch usage errors in code, we make the base to encode number explicit
@@ -42,14 +59,14 @@ enum class PrintBase {
Bin = 2
};
// A simple forward struct that prevent the compiler to select print(double, int) as a default overload for any type different than
// A simple forward struct that prevent the compiler to select print(double, int) as a default overload for any type different than
// double or float. For double or float, a conversion exists so the call will be transparent
struct EnsureDouble {
double a;
FORCE_INLINE operator double() { return a; }
// If the compiler breaks on ambiguity here, it's likely because you're calling print(X, base) with X not a double or a float, and a
// base that's not one of PrintBase's value. This exact code is made to detect such error, you NEED to set a base explicitely like this:
// SERIAL_PRINT(v, PrintBase::Hex)
// SERIAL_PRINT(v, PrintBase::Hex)
FORCE_INLINE EnsureDouble(double a) : a(a) {}
FORCE_INLINE EnsureDouble(float a) : a(a) {}
};
@@ -79,10 +96,10 @@ struct SerialBase {
void end() { static_cast<Child*>(this)->end(); }
/** Check for available data from the port
@param index The port index, usually 0 */
bool available(uint8_t index = 0) { return static_cast<Child*>(this)->available(index); }
int available(serial_index_t index = 0) { return static_cast<Child*>(this)->available(index); }
/** Read a value from the port
@param index The port index, usually 0 */
int read(uint8_t index = 0) { return static_cast<Child*>(this)->read(index); }
int read(serial_index_t index = 0) { return static_cast<Child*>(this)->read(index); }
// Check if the serial port is connected (usually bypassed)
bool connected() { return static_cast<Child*>(this)->connected(); }
// Redirect flush
@@ -147,13 +164,13 @@ struct SerialBase {
else write('0');
}
void printNumber(signed long n, const uint8_t base) {
if (base == 10 && n < 0) {
if (base == 10 && n < 0) {
n = -n; // This works because all platforms Marlin's builds on are using 2-complement encoding for negative number
// On such CPU, changing the sign of a number is done by inverting the bits and adding one, so if n = 0x80000000 = -2147483648 then
// -n = 0x7FFFFFFF + 1 => 0x80000000 = 2147483648 (if interpreted as unsigned) or -2147483648 if interpreted as signed.
// On non 2-complement CPU, there would be no possible representation for 2147483648.
write('-');
}
write('-');
}
printNumber((unsigned long)n , base);
}
+83 -59
View File
@@ -21,9 +21,33 @@
*/
#pragma once
#include "macros.h"
#include "serial_base.h"
// A mask containing a bitmap of the serial port to act upon
// This is written to ensure a serial index is never used as a serial mask
class SerialMask {
uint8_t mask;
// This constructor is private to ensure you can't convert an index to a mask
// The compiler will stop here if you are mixing index and mask in your code.
// If you need to, you'll have to use the explicit static "from" method here
SerialMask(const serial_index_t);
public:
inline constexpr bool enabled(const SerialMask PortMask) const { return mask & PortMask.mask; }
inline constexpr SerialMask combine(const SerialMask other) const { return SerialMask(mask | other.mask); }
inline constexpr SerialMask operator<< (const int offset) const { return SerialMask(mask << offset); }
static inline SerialMask from(const serial_index_t index) {
if (index.valid()) return SerialMask(_BV(index.index));
return SerialMask(0); // A invalid index mean no output
}
constexpr SerialMask(const uint8_t mask) : mask(mask) {}
constexpr SerialMask(const SerialMask & other) : mask(other.mask) {} // Can't use = default here since not all framework support this
static constexpr uint8_t All = 0xFF;
};
// The most basic serial class: it dispatch to the base serial class with no hook whatsoever. This will compile to nothing but the base serial class
template <class SerialT>
struct BaseSerial : public SerialBase< BaseSerial<SerialT> >, public SerialT {
@@ -35,8 +59,9 @@ struct BaseSerial : public SerialBase< BaseSerial<SerialT> >, public SerialT {
void msgDone() {}
bool available(uint8_t index) { return index == 0 && SerialT::available(); }
int read(uint8_t index) { return index == 0 ? SerialT::read() : -1; }
// We don't care about indices here, since if one can call us, it's the right index anyway
int available(serial_index_t) { return (int)SerialT::available(); }
int read(serial_index_t) { return (int)SerialT::read(); }
bool connected() { return CALL_IF_EXISTS(bool, static_cast<SerialT*>(this), connected);; }
void flushTX() { CALL_IF_EXISTS(void, static_cast<SerialT*>(this), flushTX); }
@@ -65,18 +90,18 @@ struct ConditionalSerial : public SerialBase< ConditionalSerial<SerialT> > {
bool & condition;
SerialT & out;
NO_INLINE size_t write(uint8_t c) { if (condition) return out.write(c); return 0; }
void flush() { if (condition) out.flush(); }
void begin(long br) { out.begin(br); }
void end() { out.end(); }
void flush() { if (condition) out.flush(); }
void begin(long br) { out.begin(br); }
void end() { out.end(); }
void msgDone() {}
bool connected() { return CALL_IF_EXISTS(bool, &out, connected); }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
bool connected() { return CALL_IF_EXISTS(bool, &out, connected); }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
bool available(uint8_t index) { return index == 0 && out.available(); }
int read(uint8_t index) { return index == 0 ? out.read() : -1; }
using BaseClassT::available;
using BaseClassT::read;
int available(serial_index_t ) { return (int)out.available(); }
int read(serial_index_t ) { return (int)out.read(); }
int available() { return (int)out.available(); }
int read() { return (int)out.read(); }
ConditionalSerial(bool & conditionVariable, SerialT & out, const bool e) : BaseClassT(e), condition(conditionVariable), out(out) {}
};
@@ -97,10 +122,10 @@ struct ForwardSerial : public SerialBase< ForwardSerial<SerialT> > {
bool connected() { return Private::HasMember_connected<SerialT>::value ? CALL_IF_EXISTS(bool, &out, connected) : (bool)out; }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
bool available(uint8_t index) { return index == 0 && out.available(); }
int read(uint8_t index) { return index == 0 ? out.read() : -1; }
bool available() { return out.available(); }
int read() { return out.read(); }
int available(serial_index_t) { return (int)out.available(); }
int read(serial_index_t) { return (int)out.read(); }
int available() { return (int)out.available(); }
int read() { return (int)out.read(); }
ForwardSerial(const bool e, SerialT & out) : BaseClassT(e), out(out) {}
};
@@ -125,8 +150,8 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
if (eofHook) eofHook(userPointer);
}
bool available(uint8_t index) { return index == 0 && SerialT::available(); }
int read(uint8_t index) { return index == 0 ? SerialT::read() : -1; }
int available(serial_index_t) { return (int)SerialT::available(); }
int read(serial_index_t) { return (int)SerialT::read(); }
using SerialT::available;
using SerialT::read;
using SerialT::flush;
@@ -157,60 +182,59 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
// Forward constructor
template <typename... Args>
RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...) {}
RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {}
};
// A class that's duplicating its output conditionally to 2 serial interface
template <class Serial0T, class Serial1T, const uint8_t offset = 0>
struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset> > {
typedef SerialBase< MultiSerial<Serial0T, Serial1T, offset> > BaseClassT;
// A class that duplicates its output conditionally to 2 serial interfaces
template <class Serial0T, class Serial1T, const uint8_t offset = 0, const uint8_t step = 1>
struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > {
typedef SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > BaseClassT;
uint8_t portMask;
SerialMask portMask;
Serial0T & serial0;
Serial1T & serial1;
enum Masks {
FirstOutputMask = (1 << offset),
SecondOutputMask = (1 << (offset + 1)),
AllMask = FirstOutputMask | SecondOutputMask,
};
static constexpr uint8_t Usage = ((1 << step) - 1); // A bit mask containing as many bits as step
static constexpr uint8_t FirstOutput = (Usage << offset);
static constexpr uint8_t SecondOutput = (Usage << (offset + step));
static constexpr uint8_t Both = FirstOutput | SecondOutput;
NO_INLINE size_t write(uint8_t c) {
size_t ret = 0;
if (portMask & FirstOutputMask) ret = serial0.write(c);
if (portMask & SecondOutputMask) ret = serial1.write(c) | ret;
if (portMask.enabled(FirstOutput)) ret = serial0.write(c);
if (portMask.enabled(SecondOutput)) ret = serial1.write(c) | ret;
return ret;
}
NO_INLINE void msgDone() {
if (portMask & FirstOutputMask) serial0.msgDone();
if (portMask & SecondOutputMask) serial1.msgDone();
if (portMask.enabled(FirstOutput)) serial0.msgDone();
if (portMask.enabled(SecondOutput)) serial1.msgDone();
}
bool available(uint8_t index) {
switch(index) {
case 0 + offset: return serial0.available();
case 1 + offset: return serial1.available();
default: return false;
}
int available(serial_index_t index) {
if (index.within(0 + offset, step + offset - 1))
return serial0.available(index);
else if (index.within(step + offset, 2 * step + offset - 1))
return serial1.available(index);
return false;
}
NO_INLINE int read(uint8_t index) {
switch(index) {
case 0 + offset: return serial0.read();
case 1 + offset: return serial1.read();
default: return -1;
}
int read(serial_index_t index) {
if (index.within(0 + offset, step + offset - 1))
return serial0.read(index);
else if (index.within(step + offset, 2 * step + offset - 1))
return serial1.read(index);
return -1;
}
void begin(const long br) {
if (portMask & FirstOutputMask) serial0.begin(br);
if (portMask & SecondOutputMask) serial1.begin(br);
if (portMask.enabled(FirstOutput)) serial0.begin(br);
if (portMask.enabled(SecondOutput)) serial1.begin(br);
}
void end() {
if (portMask & FirstOutputMask) serial0.end();
if (portMask & SecondOutputMask) serial1.end();
if (portMask.enabled(FirstOutput)) serial0.end();
if (portMask.enabled(SecondOutput)) serial1.end();
}
bool connected() {
bool ret = true;
if (portMask & FirstOutputMask) ret = CALL_IF_EXISTS(bool, &serial0, connected);
if (portMask & SecondOutputMask) ret = ret && CALL_IF_EXISTS(bool, &serial1, connected);
if (portMask.enabled(FirstOutput)) ret = CALL_IF_EXISTS(bool, &serial0, connected);
if (portMask.enabled(SecondOutput)) ret = ret && CALL_IF_EXISTS(bool, &serial1, connected);
return ret;
}
@@ -219,22 +243,22 @@ struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset>
// Redirect flush
NO_INLINE void flush() {
if (portMask & FirstOutputMask) serial0.flush();
if (portMask & SecondOutputMask) serial1.flush();
if (portMask.enabled(FirstOutput)) serial0.flush();
if (portMask.enabled(SecondOutput)) serial1.flush();
}
NO_INLINE void flushTX() {
if (portMask & FirstOutputMask) CALL_IF_EXISTS(void, &serial0, flushTX);
if (portMask & SecondOutputMask) CALL_IF_EXISTS(void, &serial1, flushTX);
if (portMask.enabled(FirstOutput)) CALL_IF_EXISTS(void, &serial0, flushTX);
if (portMask.enabled(SecondOutput)) CALL_IF_EXISTS(void, &serial1, flushTX);
}
MultiSerial(Serial0T & serial0, Serial1T & serial1, int8_t mask = AllMask, const bool e = false) :
MultiSerial(Serial0T & serial0, Serial1T & serial1, const SerialMask mask = Both, const bool e = false) :
BaseClassT(e),
portMask(mask), serial0(serial0), serial1(serial1) {}
};
// Build the actual serial object depending on current configuration
#define Serial0Type TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, BaseSerial)
#define ForwardSerial0Type TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
#define Serial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, BaseSerial)
#define ForwardSerial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
#ifdef HAS_MULTI_SERIAL
#define Serial1Type ConditionalSerial
#define Serial2Class ConditionalSerial
#endif
+3 -3
View File
@@ -92,9 +92,9 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM(" (Aligned With");
if (probe.offset_xy.y > 0)
serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back"));
SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back"));
else if (probe.offset_xy.y < 0)
serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front"));
SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front"));
else if (probe.offset_xy.x != 0)
SERIAL_ECHOPGM("-Center");
@@ -102,7 +102,7 @@ void safe_delay(millis_t ms) {
#endif
serialprintPGM(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as"));
SERIAL_ECHOPGM_P(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as"));
SERIAL_ECHOLNPGM(" Nozzle)");
#endif
+1 -1
View File
@@ -98,7 +98,7 @@ TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved(
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
void set_z_fade_height(const float zfh, const bool do_report/*=true*/) {
void set_z_fade_height(const float &zfh, const bool do_report/*=true*/) {
if (planner.z_fade_height == zfh) return;
+1 -1
View File
@@ -38,7 +38,7 @@ void set_bed_leveling_enabled(const bool enable=true);
void reset_bed_level();
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
void set_z_fade_height(const float zfh, const bool do_report=true);
void set_z_fade_height(const float &zfh, const bool do_report=true);
#endif
#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY)
+204 -204
View File
@@ -24,234 +24,234 @@
#if ENABLED(AUTO_BED_LEVELING_UBL)
#include "../bedlevel.h"
#include "../bedlevel.h"
unified_bed_leveling ubl;
unified_bed_leveling ubl;
#include "../../../MarlinCore.h"
#include "../../../gcode/gcode.h"
#include "../../../MarlinCore.h"
#include "../../../gcode/gcode.h"
#include "../../../module/settings.h"
#include "../../../module/planner.h"
#include "../../../module/motion.h"
#include "../../../module/probe.h"
#include "../../../module/settings.h"
#include "../../../module/planner.h"
#include "../../../module/motion.h"
#include "../../../module/probe.h"
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
#endif
#include "math.h"
void unified_bed_leveling::echo_name() { SERIAL_ECHOPGM("Unified Bed Leveling"); }
void unified_bed_leveling::report_current_mesh() {
if (!leveling_is_valid()) return;
SERIAL_ECHO_MSG(" G29 I999");
GRID_LOOP(x, y)
if (!isnan(z_values[x][y])) {
SERIAL_ECHO_START();
SERIAL_ECHOPAIR(" M421 I", x, " J", y);
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
serial_delay(75); // Prevent Printrun from exploding
}
}
void unified_bed_leveling::report_state() {
echo_name();
SERIAL_ECHO_TERNARY(planner.leveling_active, " System v" UBL_VERSION " ", "", "in", "active\n");
serial_delay(50);
}
int8_t unified_bed_leveling::storage_slot;
float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST))
const float
unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X,
_GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3),
_GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7),
_GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11),
_GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15)
),
unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y,
_GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3),
_GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7),
_GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11),
_GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15)
);
volatile int16_t unified_bed_leveling::encoder_diff;
unified_bed_leveling::unified_bed_leveling() { reset(); }
void unified_bed_leveling::reset() {
const bool was_enabled = planner.leveling_active;
set_bed_leveling_enabled(false);
storage_slot = -1;
ZERO(z_values);
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0);
#endif
if (was_enabled) report_current_position();
}
#include "math.h"
void unified_bed_leveling::invalidate() {
set_bed_leveling_enabled(false);
set_all_mesh_points_to_value(NAN);
}
void unified_bed_leveling::echo_name() { SERIAL_ECHOPGM("Unified Bed Leveling"); }
void unified_bed_leveling::set_all_mesh_points_to_value(const float value) {
GRID_LOOP(x, y) {
z_values[x][y] = value;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value));
}
}
void unified_bed_leveling::report_current_mesh() {
if (!leveling_is_valid()) return;
SERIAL_ECHO_MSG(" G29 I999");
GRID_LOOP(x, y)
if (!isnan(z_values[x][y])) {
SERIAL_ECHO_START();
SERIAL_ECHOPAIR(" M421 I", x, " J", y);
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
serial_delay(75); // Prevent Printrun from exploding
}
#if ENABLED(OPTIMIZED_MESH_STORAGE)
constexpr float mesh_store_scaling = 1000;
constexpr int16_t Z_STEPS_NAN = INT16_MAX;
void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) {
auto z_to_store = [](const float &z) {
if (isnan(z)) return Z_STEPS_NAN;
const int32_t z_scaled = TRUNC(z * mesh_store_scaling);
if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX))
return Z_STEPS_NAN; // If Z is out of range, return our custom 'NaN'
return int16_t(z_scaled);
};
GRID_LOOP(x, y) stored_values[x][y] = z_to_store(in_values[x][y]);
}
void unified_bed_leveling::report_state() {
echo_name();
SERIAL_ECHO_TERNARY(planner.leveling_active, " System v" UBL_VERSION " ", "", "in", "active\n");
serial_delay(50);
void unified_bed_leveling::set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values) {
auto store_to_z = [](const int16_t z_scaled) {
return z_scaled == Z_STEPS_NAN ? NAN : z_scaled / mesh_store_scaling;
};
GRID_LOOP(x, y) out_values[x][y] = store_to_z(stored_values[x][y]);
}
int8_t unified_bed_leveling::storage_slot;
#endif // OPTIMIZED_MESH_STORAGE
float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
SERIAL_ECHO_SP(sp);
SERIAL_CHAR('(');
if (x < 100) { SERIAL_CHAR(' '); if (x < 10) SERIAL_CHAR(' '); }
SERIAL_ECHO(x);
SERIAL_CHAR(',');
if (y < 100) { SERIAL_CHAR(' '); if (y < 10) SERIAL_CHAR(' '); }
SERIAL_ECHO(y);
SERIAL_CHAR(')');
serial_delay(5);
}
#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST))
const float
unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X,
_GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3),
_GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7),
_GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11),
_GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15)
),
unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y,
_GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3),
_GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7),
_GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11),
_GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15)
);
volatile int16_t unified_bed_leveling::encoder_diff;
unified_bed_leveling::unified_bed_leveling() { reset(); }
void unified_bed_leveling::reset() {
const bool was_enabled = planner.leveling_active;
set_bed_leveling_enabled(false);
storage_slot = -1;
ZERO(z_values);
#if ENABLED(EXTENSIBLE_UI)
GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0);
#endif
if (was_enabled) report_current_position();
}
void unified_bed_leveling::invalidate() {
set_bed_leveling_enabled(false);
set_all_mesh_points_to_value(NAN);
}
void unified_bed_leveling::set_all_mesh_points_to_value(const float value) {
GRID_LOOP(x, y) {
z_values[x][y] = value;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value));
}
}
#if ENABLED(OPTIMIZED_MESH_STORAGE)
constexpr float mesh_store_scaling = 1000;
constexpr int16_t Z_STEPS_NAN = INT16_MAX;
void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) {
auto z_to_store = [](const float &z) {
if (isnan(z)) return Z_STEPS_NAN;
const int32_t z_scaled = TRUNC(z * mesh_store_scaling);
if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX))
return Z_STEPS_NAN; // If Z is out of range, return our custom 'NaN'
return int16_t(z_scaled);
};
GRID_LOOP(x, y) stored_values[x][y] = z_to_store(in_values[x][y]);
}
void unified_bed_leveling::set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values) {
auto store_to_z = [](const int16_t z_scaled) {
return z_scaled == Z_STEPS_NAN ? NAN : z_scaled / mesh_store_scaling;
};
GRID_LOOP(x, y) out_values[x][y] = store_to_z(stored_values[x][y]);
}
#endif // OPTIMIZED_MESH_STORAGE
static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
static void serial_echo_column_labels(const uint8_t sp) {
SERIAL_ECHO_SP(7);
LOOP_L_N(i, GRID_MAX_POINTS_X) {
if (i < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(i);
SERIAL_ECHO_SP(sp);
SERIAL_CHAR('(');
if (x < 100) { SERIAL_CHAR(' '); if (x < 10) SERIAL_CHAR(' '); }
SERIAL_ECHO(x);
SERIAL_CHAR(',');
if (y < 100) { SERIAL_CHAR(' '); if (y < 10) SERIAL_CHAR(' '); }
SERIAL_ECHO(y);
SERIAL_CHAR(')');
serial_delay(5);
}
serial_delay(10);
}
/**
* Produce one of these mesh maps:
* 0: Human-readable
* 1: CSV format for spreadsheet import
* 2: TODO: Display on Graphical LCD
* 4: Compact Human-Readable
*/
void unified_bed_leveling::display_map(const int map_type) {
const bool was = gcode.set_autoreport_paused(true);
constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567]
twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each
const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4;
SERIAL_ECHOPGM("\nBed Topography Report");
if (human) {
SERIAL_ECHOLNPGM(":\n");
serial_echo_xy(4, MESH_MIN_X, MESH_MAX_Y);
serial_echo_xy(twixt, MESH_MAX_X, MESH_MAX_Y);
SERIAL_EOL();
serial_echo_column_labels(eachsp - 2);
}
else {
SERIAL_ECHOPGM(" for ");
SERIAL_ECHOPGM_P(csv ? PSTR("CSV:\n") : PSTR("LCD:\n"));
}
static void serial_echo_column_labels(const uint8_t sp) {
SERIAL_ECHO_SP(7);
// Add XY probe offset from extruder because probe.probe_at_point() subtracts them when
// moving to the XY position to be measured. This ensures better agreement between
// the current Z position after G28 and the mesh values.
const xy_int8_t curr = closest_indexes(xy_pos_t(current_position) + probe.offset_xy);
if (!lcd) SERIAL_EOL();
for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
// Row Label (J index)
if (human) {
if (j < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(j);
SERIAL_ECHOPGM(" |");
}
// Row Values (I indexes)
LOOP_L_N(i, GRID_MAX_POINTS_X) {
if (i < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(i);
SERIAL_ECHO_SP(sp);
// Opening Brace or Space
const bool is_current = i == curr.x && j == curr.y;
if (human) SERIAL_CHAR(is_current ? '[' : ' ');
// Z Value at current I, J
const float f = z_values[i][j];
if (lcd) {
// TODO: Display on Graphical LCD
}
else if (isnan(f))
SERIAL_ECHOPGM_P(human ? PSTR(" . ") : PSTR("NAN"));
else if (human || csv) {
if (human && f >= 0.0) SERIAL_CHAR(f > 0 ? '+' : ' '); // Display sign also for positive numbers (' ' for 0)
SERIAL_ECHO_F(f, 3); // Positive: 5 digits, Negative: 6 digits
}
if (csv && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR('\t');
// Closing Brace or Space
if (human) SERIAL_CHAR(is_current ? ']' : ' ');
SERIAL_FLUSHTX();
idle_no_sleep();
}
serial_delay(10);
}
/**
* Produce one of these mesh maps:
* 0: Human-readable
* 1: CSV format for spreadsheet import
* 2: TODO: Display on Graphical LCD
* 4: Compact Human-Readable
*/
void unified_bed_leveling::display_map(const int map_type) {
const bool was = gcode.set_autoreport_paused(true);
constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567]
twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each
const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4;
SERIAL_ECHOPGM("\nBed Topography Report");
if (human) {
SERIAL_ECHOLNPGM(":\n");
serial_echo_xy(4, MESH_MIN_X, MESH_MAX_Y);
serial_echo_xy(twixt, MESH_MAX_X, MESH_MAX_Y);
SERIAL_EOL();
serial_echo_column_labels(eachsp - 2);
}
else {
SERIAL_ECHOPGM(" for ");
serialprintPGM(csv ? PSTR("CSV:\n") : PSTR("LCD:\n"));
}
// Add XY probe offset from extruder because probe.probe_at_point() subtracts them when
// moving to the XY position to be measured. This ensures better agreement between
// the current Z position after G28 and the mesh values.
const xy_int8_t curr = closest_indexes(xy_pos_t(current_position) + probe.offset_xy);
if (!lcd) SERIAL_EOL();
for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
// Row Label (J index)
if (human) {
if (j < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(j);
SERIAL_ECHOPGM(" |");
}
// Row Values (I indexes)
LOOP_L_N(i, GRID_MAX_POINTS_X) {
// Opening Brace or Space
const bool is_current = i == curr.x && j == curr.y;
if (human) SERIAL_CHAR(is_current ? '[' : ' ');
// Z Value at current I, J
const float f = z_values[i][j];
if (lcd) {
// TODO: Display on Graphical LCD
}
else if (isnan(f))
serialprintPGM(human ? PSTR(" . ") : PSTR("NAN"));
else if (human || csv) {
if (human && f >= 0.0) SERIAL_CHAR(f > 0 ? '+' : ' '); // Display sign also for positive numbers (' ' for 0)
SERIAL_ECHO_F(f, 3); // Positive: 5 digits, Negative: 6 digits
}
if (csv && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR('\t');
// Closing Brace or Space
if (human) SERIAL_CHAR(is_current ? ']' : ' ');
SERIAL_FLUSHTX();
idle_no_sleep();
}
if (!lcd) SERIAL_EOL();
// A blank line between rows (unless compact)
if (j && human && !comp) SERIAL_ECHOLNPGM(" |");
}
if (human) {
serial_echo_column_labels(eachsp - 2);
SERIAL_EOL();
serial_echo_xy(4, MESH_MIN_X, MESH_MIN_Y);
serial_echo_xy(twixt, MESH_MAX_X, MESH_MIN_Y);
SERIAL_EOL();
SERIAL_EOL();
}
gcode.set_autoreport_paused(was);
// A blank line between rows (unless compact)
if (j && human && !comp) SERIAL_ECHOLNPGM(" |");
}
bool unified_bed_leveling::sanity_check() {
uint8_t error_flag = 0;
if (settings.calc_num_meshes() < 1) {
SERIAL_ECHOLNPGM("?Mesh too big for EEPROM.");
error_flag++;
}
return !!error_flag;
if (human) {
serial_echo_column_labels(eachsp - 2);
SERIAL_EOL();
serial_echo_xy(4, MESH_MIN_X, MESH_MIN_Y);
serial_echo_xy(twixt, MESH_MAX_X, MESH_MIN_Y);
SERIAL_EOL();
SERIAL_EOL();
}
gcode.set_autoreport_paused(was);
}
bool unified_bed_leveling::sanity_check() {
uint8_t error_flag = 0;
if (settings.calc_num_meshes() < 1) {
SERIAL_ECHOLNPGM("?Mesh too big for EEPROM.");
error_flag++;
}
return !!error_flag;
}
#endif // AUTO_BED_LEVELING_UBL
+230 -230
View File
@@ -46,275 +46,275 @@ struct mesh_index_pair;
#endif
class unified_bed_leveling {
private:
private:
static int g29_verbose_level,
g29_phase_value,
g29_repetition_cnt,
g29_storage_slot,
g29_map_type;
static bool g29_c_flag;
static float g29_card_thickness,
g29_constant;
static xy_pos_t g29_pos;
static xy_bool_t xy_seen;
static int g29_verbose_level,
g29_phase_value,
g29_repetition_cnt,
g29_storage_slot,
g29_map_type;
static bool g29_c_flag;
static float g29_card_thickness,
g29_constant;
static xy_pos_t g29_pos;
static xy_bool_t xy_seen;
#if HAS_BED_PROBE
static int g29_grid_size;
#endif
#if HAS_BED_PROBE
static int g29_grid_size;
#endif
#if IS_NEWPANEL
static void move_z_with_encoder(const float &multiplier);
static float measure_point_with_encoder();
static float measure_business_card_thickness();
static void manually_probe_remaining_mesh(const xy_pos_t&, const float&, const float&, const bool) _O0;
static void fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) _O0;
#endif
#if IS_NEWPANEL
static void move_z_with_encoder(const float &multiplier);
static float measure_point_with_encoder();
static float measure_business_card_thickness();
static void manually_probe_remaining_mesh(const xy_pos_t&, const float&, const float&, const bool) _O0;
static void fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) _O0;
#endif
static bool g29_parameter_parsing() _O0;
static void shift_mesh_height();
static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) _O0;
static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
static inline bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) {
return smart_fill_one(pos.x, pos.y, dir.x, dir.y);
}
static void smart_fill_mesh();
static bool g29_parameter_parsing() _O0;
static void shift_mesh_height();
static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) _O0;
static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
static inline bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) {
return smart_fill_one(pos.x, pos.y, dir.x, dir.y);
}
static void smart_fill_mesh();
#if ENABLED(UBL_DEVEL_DEBUGGING)
static void g29_what_command();
static void g29_eeprom_dump();
static void g29_compare_current_mesh_to_stored_mesh();
#endif
#if ENABLED(UBL_DEVEL_DEBUGGING)
static void g29_what_command();
static void g29_eeprom_dump();
static void g29_compare_current_mesh_to_stored_mesh();
#endif
public:
public:
static void echo_name();
static void report_current_mesh();
static void report_state();
static void save_ubl_active_state_and_disable();
static void restore_ubl_active_state_and_leave();
static void display_map(const int) _O0;
static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) _O0;
static mesh_index_pair find_furthest_invalid_mesh_point() _O0;
static void reset();
static void invalidate();
static void set_all_mesh_points_to_value(const float value);
static void adjust_mesh_to_mean(const bool cflag, const float value);
static bool sanity_check();
static void echo_name();
static void report_current_mesh();
static void report_state();
static void save_ubl_active_state_and_disable();
static void restore_ubl_active_state_and_leave();
static void display_map(const int) _O0;
static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) _O0;
static mesh_index_pair find_furthest_invalid_mesh_point() _O0;
static void reset();
static void invalidate();
static void set_all_mesh_points_to_value(const float value);
static void adjust_mesh_to_mean(const bool cflag, const float value);
static bool sanity_check();
static void G29() _O0; // O0 for no optimization
static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
static void G29() _O0; // O0 for no optimization
static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
static int8_t storage_slot;
static int8_t storage_slot;
static bed_mesh_t z_values;
#if ENABLED(OPTIMIZED_MESH_STORAGE)
static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values);
static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values);
#endif
static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
_mesh_index_to_ypos[GRID_MAX_POINTS_Y];
static bed_mesh_t z_values;
#if ENABLED(OPTIMIZED_MESH_STORAGE)
static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values);
static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values);
#endif
static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X],
_mesh_index_to_ypos[GRID_MAX_POINTS_Y];
#if HAS_LCD_MENU
static bool lcd_map_control;
static void steppers_were_disabled();
#else
static inline void steppers_were_disabled() {}
#endif
#if HAS_LCD_MENU
static bool lcd_map_control;
static void steppers_were_disabled();
#else
static inline void steppers_were_disabled() {}
#endif
static volatile int16_t encoder_diff; // Volatile because buttons may changed it at interrupt time
static volatile int16_t encoder_diff; // Volatile because buttons may changed it at interrupt time
unified_bed_leveling();
unified_bed_leveling();
FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
static int8_t cell_index_x_raw(const float &x) {
return FLOOR((x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST));
static int8_t cell_index_x_raw(const float &x) {
return FLOOR((x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST));
}
static int8_t cell_index_y_raw(const float &y) {
return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST));
}
static int8_t cell_index_x_valid(const float &x) {
return WITHIN(cell_index_x_raw(x), 0, (GRID_MAX_POINTS_X - 2));
}
static int8_t cell_index_y_valid(const float &y) {
return WITHIN(cell_index_y_raw(y), 0, (GRID_MAX_POINTS_Y - 2));
}
static int8_t cell_index_x(const float &x) {
return constrain(cell_index_x_raw(x), 0, (GRID_MAX_POINTS_X) - 2);
}
static int8_t cell_index_y(const float &y) {
return constrain(cell_index_y_raw(y), 0, (GRID_MAX_POINTS_Y) - 2);
}
static inline xy_int8_t cell_indexes(const float &x, const float &y) {
return { cell_index_x(x), cell_index_y(y) };
}
static inline xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
static int8_t closest_x_index(const float &x) {
const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST);
return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
}
static int8_t closest_y_index(const float &y) {
const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * RECIPROCAL(MESH_Y_DIST);
return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
}
static inline xy_int8_t closest_indexes(const xy_pos_t &xy) {
return { closest_x_index(xy.x), closest_y_index(xy.y) };
}
/**
* z2 --|
* z0 | |
* | | + (z2-z1)
* z1 | | |
* ---+-------------+--------+-- --|
* a1 a0 a2
* |<---delta_a---------->|
*
* calc_z0 is the basis for all the Mesh Based correction. It is used to
* find the expected Z Height at a position between two known Z-Height locations.
*
* It is fairly expensive with its 4 floating point additions and 2 floating point
* multiplications.
*/
FORCE_INLINE static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
}
#ifdef UBL_Z_RAISE_WHEN_OFF_MESH
#define _UBL_OUTER_Z_RAISE UBL_Z_RAISE_WHEN_OFF_MESH
#else
#define _UBL_OUTER_Z_RAISE NAN
#endif
/**
* z_correction_for_x_on_horizontal_mesh_line is an optimization for
* the case where the printer is making a vertical line that only crosses horizontal mesh lines.
*/
static inline float z_correction_for_x_on_horizontal_mesh_line(const float &rx0, const int x1_i, const int yi) {
if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
if (DEBUGGING(LEVELING)) {
if (WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1)) DEBUG_ECHOPGM("yi"); else DEBUG_ECHOPGM("x1_i");
DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0, ",x1_i=", x1_i, ",yi=", yi, ")");
}
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
return _UBL_OUTER_Z_RAISE;
}
static int8_t cell_index_y_raw(const float &y) {
return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST));
const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * RECIPROCAL(MESH_X_DIST),
z1 = z_values[x1_i][yi];
return z1 + xratio * (z_values[_MIN(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
}
//
// See comments above for z_correction_for_x_on_horizontal_mesh_line
//
static inline float z_correction_for_y_on_vertical_mesh_line(const float &ry0, const int xi, const int y1_i) {
if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
if (DEBUGGING(LEVELING)) {
if (WITHIN(xi, 0, GRID_MAX_POINTS_X - 1)) DEBUG_ECHOPGM("y1_i"); else DEBUG_ECHOPGM("xi");
DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0, ", xi=", xi, ", y1_i=", y1_i, ")");
}
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
return _UBL_OUTER_Z_RAISE;
}
static int8_t cell_index_x_valid(const float &x) {
return WITHIN(cell_index_x_raw(x), 0, (GRID_MAX_POINTS_X - 2));
}
const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * RECIPROCAL(MESH_Y_DIST),
z1 = z_values[xi][y1_i];
static int8_t cell_index_y_valid(const float &y) {
return WITHIN(cell_index_y_raw(y), 0, (GRID_MAX_POINTS_Y - 2));
}
return z1 + yratio * (z_values[xi][_MIN(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
}
static int8_t cell_index_x(const float &x) {
return constrain(cell_index_x_raw(x), 0, (GRID_MAX_POINTS_X) - 2);
}
static int8_t cell_index_y(const float &y) {
return constrain(cell_index_y_raw(y), 0, (GRID_MAX_POINTS_Y) - 2);
}
static inline xy_int8_t cell_indexes(const float &x, const float &y) {
return { cell_index_x(x), cell_index_y(y) };
}
static inline xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
static int8_t closest_x_index(const float &x) {
const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST);
return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
}
static int8_t closest_y_index(const float &y) {
const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * RECIPROCAL(MESH_Y_DIST);
return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
}
static inline xy_int8_t closest_indexes(const xy_pos_t &xy) {
return { closest_x_index(xy.x), closest_y_index(xy.y) };
}
/**
* This is the generic Z-Correction. It works anywhere within a Mesh Cell. It first
* does a linear interpolation along both of the bounding X-Mesh-Lines to find the
* Z-Height at both ends. Then it does a linear interpolation of these heights based
* on the Y position within the cell.
*/
static float get_z_correction(const float &rx0, const float &ry0) {
const int8_t cx = cell_index_x(rx0), cy = cell_index_y(ry0); // return values are clamped
/**
* z2 --|
* z0 | |
* | | + (z2-z1)
* z1 | | |
* ---+-------------+--------+-- --|
* a1 a0 a2
* |<---delta_a---------->|
*
* calc_z0 is the basis for all the Mesh Based correction. It is used to
* find the expected Z Height at a position between two known Z-Height locations.
*
* It is fairly expensive with its 4 floating point additions and 2 floating point
* multiplications.
* Check if the requested location is off the mesh. If so, and
* UBL_Z_RAISE_WHEN_OFF_MESH is specified, that value is returned.
*/
FORCE_INLINE static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
}
#ifdef UBL_Z_RAISE_WHEN_OFF_MESH
#define _UBL_OUTER_Z_RAISE UBL_Z_RAISE_WHEN_OFF_MESH
#else
#define _UBL_OUTER_Z_RAISE NAN
if (!WITHIN(rx0, MESH_MIN_X, MESH_MAX_X) || !WITHIN(ry0, MESH_MIN_Y, MESH_MAX_Y))
return UBL_Z_RAISE_WHEN_OFF_MESH;
#endif
/**
* z_correction_for_x_on_horizontal_mesh_line is an optimization for
* the case where the printer is making a vertical line that only crosses horizontal mesh lines.
*/
static inline float z_correction_for_x_on_horizontal_mesh_line(const float &rx0, const int x1_i, const int yi) {
if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
const float z1 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][cy],
mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, GRID_MAX_POINTS_X - 2) + 1][cy]);
if (DEBUGGING(LEVELING)) {
if (WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1)) DEBUG_ECHOPGM("yi"); else DEBUG_ECHOPGM("x1_i");
DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0, ",x1_i=", x1_i, ",yi=", yi, ")");
}
const float z2 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][_MIN(cy, GRID_MAX_POINTS_Y - 2) + 1],
mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, GRID_MAX_POINTS_X - 2) + 1][_MIN(cy, GRID_MAX_POINTS_Y - 2) + 1]);
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
return _UBL_OUTER_Z_RAISE;
}
float z0 = calc_z0(ry0,
mesh_index_to_ypos(cy), z1,
mesh_index_to_ypos(cy + 1), z2);
const float xratio = (rx0 - mesh_index_to_xpos(x1_i)) * RECIPROCAL(MESH_X_DIST),
z1 = z_values[x1_i][yi];
return z1 + xratio * (z_values[_MIN(x1_i, GRID_MAX_POINTS_X - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
if (DEBUGGING(MESH_ADJUST)) {
DEBUG_ECHOPAIR(" raw get_z_correction(", rx0);
DEBUG_CHAR(','); DEBUG_ECHO(ry0);
DEBUG_ECHOPAIR_F(") = ", z0, 6);
DEBUG_ECHOLNPAIR_F(" >>>---> ", z0, 6);
}
//
// See comments above for z_correction_for_x_on_horizontal_mesh_line
//
static inline float z_correction_for_y_on_vertical_mesh_line(const float &ry0, const int xi, const int y1_i) {
if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
if (DEBUGGING(LEVELING)) {
if (WITHIN(xi, 0, GRID_MAX_POINTS_X - 1)) DEBUG_ECHOPGM("y1_i"); else DEBUG_ECHOPGM("xi");
DEBUG_ECHOLNPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0, ", xi=", xi, ", y1_i=", y1_i, ")");
}
// The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN.
return _UBL_OUTER_Z_RAISE;
}
const float yratio = (ry0 - mesh_index_to_ypos(y1_i)) * RECIPROCAL(MESH_Y_DIST),
z1 = z_values[xi][y1_i];
return z1 + yratio * (z_values[xi][_MIN(y1_i, GRID_MAX_POINTS_Y - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array
// If it is, it is clamped to the last element of the
// z_values[][] array and no correction is applied.
}
/**
* This is the generic Z-Correction. It works anywhere within a Mesh Cell. It first
* does a linear interpolation along both of the bounding X-Mesh-Lines to find the
* Z-Height at both ends. Then it does a linear interpolation of these heights based
* on the Y position within the cell.
*/
static float get_z_correction(const float &rx0, const float &ry0) {
const int8_t cx = cell_index_x(rx0), cy = cell_index_y(ry0); // return values are clamped
/**
* Check if the requested location is off the mesh. If so, and
* UBL_Z_RAISE_WHEN_OFF_MESH is specified, that value is returned.
*/
#ifdef UBL_Z_RAISE_WHEN_OFF_MESH
if (!WITHIN(rx0, MESH_MIN_X, MESH_MAX_X) || !WITHIN(ry0, MESH_MIN_Y, MESH_MAX_Y))
return UBL_Z_RAISE_WHEN_OFF_MESH;
#endif
const float z1 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][cy],
mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, GRID_MAX_POINTS_X - 2) + 1][cy]);
const float z2 = calc_z0(rx0,
mesh_index_to_xpos(cx), z_values[cx][_MIN(cy, GRID_MAX_POINTS_Y - 2) + 1],
mesh_index_to_xpos(cx + 1), z_values[_MIN(cx, GRID_MAX_POINTS_X - 2) + 1][_MIN(cy, GRID_MAX_POINTS_Y - 2) + 1]);
float z0 = calc_z0(ry0,
mesh_index_to_ypos(cy), z1,
mesh_index_to_ypos(cy + 1), z2);
if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN
z0 = 0.0; // in ubl.z_values[][] and propagate through the
// calculations. If our correction is NAN, we throw it out
// because part of the Mesh is undefined and we don't have the
// information we need to complete the height correction.
if (DEBUGGING(MESH_ADJUST)) {
DEBUG_ECHOPAIR(" raw get_z_correction(", rx0);
DEBUG_CHAR(','); DEBUG_ECHO(ry0);
DEBUG_ECHOPAIR_F(") = ", z0, 6);
DEBUG_ECHOLNPAIR_F(" >>>---> ", z0, 6);
DEBUG_ECHOPAIR("??? Yikes! NAN in get_z_correction(", rx0);
DEBUG_CHAR(',');
DEBUG_ECHO(ry0);
DEBUG_CHAR(')');
DEBUG_EOL();
}
if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN
z0 = 0.0; // in ubl.z_values[][] and propagate through the
// calculations. If our correction is NAN, we throw it out
// because part of the Mesh is undefined and we don't have the
// information we need to complete the height correction.
if (DEBUGGING(MESH_ADJUST)) {
DEBUG_ECHOPAIR("??? Yikes! NAN in get_z_correction(", rx0);
DEBUG_CHAR(',');
DEBUG_ECHO(ry0);
DEBUG_CHAR(')');
DEBUG_EOL();
}
}
return z0;
}
static inline float get_z_correction(const xy_pos_t &pos) { return get_z_correction(pos.x, pos.y); }
return z0;
}
static inline float get_z_correction(const xy_pos_t &pos) { return get_z_correction(pos.x, pos.y); }
static inline float mesh_index_to_xpos(const uint8_t i) {
return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST);
}
static inline float mesh_index_to_ypos(const uint8_t i) {
return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
}
static inline float mesh_index_to_xpos(const uint8_t i) {
return i < GRID_MAX_POINTS_X ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST);
}
static inline float mesh_index_to_ypos(const uint8_t i) {
return i < GRID_MAX_POINTS_Y ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST);
}
#if UBL_SEGMENTED
static bool line_to_destination_segmented(const feedRate_t &scaled_fr_mm_s);
#else
static void line_to_destination_cartesian(const feedRate_t &scaled_fr_mm_s, const uint8_t e);
#endif
#if UBL_SEGMENTED
static bool line_to_destination_segmented(const feedRate_t &scaled_fr_mm_s);
#else
static void line_to_destination_cartesian(const feedRate_t &scaled_fr_mm_s, const uint8_t e);
#endif
static inline bool mesh_is_valid() {
GRID_LOOP(x, y) if (isnan(z_values[x][y])) return false;
return true;
}
static inline bool mesh_is_valid() {
GRID_LOOP(x, y) if (isnan(z_values[x][y])) return false;
return true;
}
}; // class unified_bed_leveling

Some files were not shown because too many files have changed in this diff Show More