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

settings.cpp 97KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * settings.cpp
  24. *
  25. * Settings and EEPROM storage
  26. *
  27. * IMPORTANT: Whenever there are changes made to the variables stored in EEPROM
  28. * in the functions below, also increment the version number. This makes sure that
  29. * the default values are used whenever there is a change to the data, to prevent
  30. * wrong data being written to the variables.
  31. *
  32. * ALSO: Variables in the Store and Retrieve sections must be in the same order.
  33. * If a feature is disabled, some data must still be written that, when read,
  34. * either sets a Sane Default, or results in No Change to the existing value.
  35. */
  36. // Change EEPROM version if the structure changes
  37. #define EEPROM_VERSION "V86"
  38. #define EEPROM_OFFSET 100
  39. // Check the integrity of data offsets.
  40. // Can be disabled for production build.
  41. //#define DEBUG_EEPROM_READWRITE
  42. #include "settings.h"
  43. #include "endstops.h"
  44. #include "planner.h"
  45. #include "stepper.h"
  46. #include "temperature.h"
  47. #include "../lcd/marlinui.h"
  48. #include "../libs/vector_3.h" // for matrix_3x3
  49. #include "../gcode/gcode.h"
  50. #include "../MarlinCore.h"
  51. #if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
  52. #include "../HAL/shared/eeprom_api.h"
  53. #endif
  54. #include "probe.h"
  55. #if HAS_LEVELING
  56. #include "../feature/bedlevel/bedlevel.h"
  57. #if ENABLED(X_AXIS_TWIST_COMPENSATION)
  58. #include "../feature/bedlevel/abl/x_twist.h"
  59. #endif
  60. #endif
  61. #if ENABLED(Z_STEPPER_AUTO_ALIGN)
  62. #include "../feature/z_stepper_align.h"
  63. #endif
  64. #if ENABLED(EXTENSIBLE_UI)
  65. #include "../lcd/extui/ui_api.h"
  66. #elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
  67. #include "../lcd/e3v2/enhanced/dwin.h"
  68. #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
  69. #include "../lcd/e3v2/jyersui/dwin.h"
  70. #endif
  71. #if HAS_SERVOS
  72. #include "servo.h"
  73. #endif
  74. #if HAS_SERVOS && HAS_SERVO_ANGLES
  75. #define EEPROM_NUM_SERVOS NUM_SERVOS
  76. #else
  77. #define EEPROM_NUM_SERVOS NUM_SERVO_PLUGS
  78. #endif
  79. #include "../feature/fwretract.h"
  80. #if ENABLED(POWER_LOSS_RECOVERY)
  81. #include "../feature/powerloss.h"
  82. #endif
  83. #if HAS_POWER_MONITOR
  84. #include "../feature/power_monitor.h"
  85. #endif
  86. #include "../feature/pause.h"
  87. #if ENABLED(BACKLASH_COMPENSATION)
  88. #include "../feature/backlash.h"
  89. #endif
  90. #if HAS_FILAMENT_SENSOR
  91. #include "../feature/runout.h"
  92. #ifndef FIL_RUNOUT_ENABLED_DEFAULT
  93. #define FIL_RUNOUT_ENABLED_DEFAULT true
  94. #endif
  95. #endif
  96. #if ENABLED(EXTRA_LIN_ADVANCE_K)
  97. extern float other_extruder_advance_K[EXTRUDERS];
  98. #endif
  99. #if HAS_MULTI_EXTRUDER
  100. #include "tool_change.h"
  101. void M217_report(const bool eeprom);
  102. #endif
  103. #if ENABLED(BLTOUCH)
  104. #include "../feature/bltouch.h"
  105. #endif
  106. #if HAS_TRINAMIC_CONFIG
  107. #include "stepper/indirection.h"
  108. #include "../feature/tmc_util.h"
  109. #endif
  110. #if HAS_PTC
  111. #include "../feature/probe_temp_comp.h"
  112. #endif
  113. #include "../feature/controllerfan.h"
  114. #if ENABLED(CASE_LIGHT_ENABLE)
  115. #include "../feature/caselight.h"
  116. #endif
  117. #if ENABLED(PASSWORD_FEATURE)
  118. #include "../feature/password/password.h"
  119. #endif
  120. #if ENABLED(TOUCH_SCREEN_CALIBRATION)
  121. #include "../lcd/tft_io/touch_calibration.h"
  122. #endif
  123. #if HAS_ETHERNET
  124. #include "../feature/ethernet.h"
  125. #endif
  126. #if ENABLED(SOUND_MENU_ITEM)
  127. #include "../libs/buzzer.h"
  128. #endif
  129. #if HAS_FANCHECK
  130. #include "../feature/fancheck.h"
  131. #endif
  132. #if ENABLED(DGUS_LCD_UI_MKS)
  133. #include "../lcd/extui/dgus/DGUSScreenHandler.h"
  134. #include "../lcd/extui/dgus/DGUSDisplayDef.h"
  135. #endif
  136. #pragma pack(push, 1) // No padding between variables
  137. #if HAS_ETHERNET
  138. void ETH0_report();
  139. void MAC_report();
  140. #endif
  141. #define _EN_ITEM(N) , E##N
  142. typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
  143. typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_hybrid_threshold_t;
  144. typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
  145. typedef struct { bool LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stealth_enabled_t;
  146. #undef _EN_ITEM
  147. // Limit an index to an array size
  148. #define ALIM(I,ARR) _MIN(I, (signed)COUNT(ARR) - 1)
  149. // Defaults for reset / fill in on load
  150. static const uint32_t _DMA[] PROGMEM = DEFAULT_MAX_ACCELERATION;
  151. static const float _DASU[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT;
  152. static const feedRate_t _DMF[] PROGMEM = DEFAULT_MAX_FEEDRATE;
  153. /**
  154. * Current EEPROM Layout
  155. *
  156. * Keep this data structure up to date so
  157. * EEPROM size is known at compile time!
  158. */
  159. typedef struct SettingsDataStruct {
  160. char version[4]; // Vnn\0
  161. #if ENABLED(EEPROM_INIT_NOW)
  162. uint32_t build_hash; // Unique build hash
  163. #endif
  164. uint16_t crc; // Data Checksum
  165. //
  166. // DISTINCT_E_FACTORS
  167. //
  168. uint8_t e_factors; // DISTINCT_AXES - LINEAR_AXES
  169. //
  170. // Planner settings
  171. //
  172. planner_settings_t planner_settings;
  173. xyze_float_t planner_max_jerk; // M205 XYZE planner.max_jerk
  174. float planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
  175. //
  176. // Home Offset
  177. //
  178. xyz_pos_t home_offset; // M206 XYZ / M665 TPZ
  179. //
  180. // Hotend Offset
  181. //
  182. #if HAS_HOTEND_OFFSET
  183. xyz_pos_t hotend_offset[HOTENDS - 1]; // M218 XYZ
  184. #endif
  185. //
  186. // FILAMENT_RUNOUT_SENSOR
  187. //
  188. bool runout_sensor_enabled; // M412 S
  189. float runout_distance_mm; // M412 D
  190. //
  191. // ENABLE_LEVELING_FADE_HEIGHT
  192. //
  193. float planner_z_fade_height; // M420 Zn planner.z_fade_height
  194. //
  195. // MESH_BED_LEVELING
  196. //
  197. float mbl_z_offset; // mbl.z_offset
  198. uint8_t mesh_num_x, mesh_num_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y
  199. float mbl_z_values[TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3)] // mbl.z_values
  200. [TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3)];
  201. //
  202. // HAS_BED_PROBE
  203. //
  204. xyz_pos_t probe_offset;
  205. //
  206. // ABL_PLANAR
  207. //
  208. matrix_3x3 planner_bed_level_matrix; // planner.bed_level_matrix
  209. //
  210. // AUTO_BED_LEVELING_BILINEAR
  211. //
  212. uint8_t grid_max_x, grid_max_y; // GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y
  213. xy_pos_t bilinear_grid_spacing, bilinear_start; // G29 L F
  214. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  215. bed_mesh_t z_values; // G29
  216. #if ENABLED(X_AXIS_TWIST_COMPENSATION)
  217. XATC xatc; // TBD
  218. #endif
  219. #else
  220. float z_values[3][3];
  221. #endif
  222. //
  223. // AUTO_BED_LEVELING_UBL
  224. //
  225. bool planner_leveling_active; // M420 S planner.leveling_active
  226. int8_t ubl_storage_slot; // ubl.storage_slot
  227. //
  228. // SERVO_ANGLES
  229. //
  230. uint16_t servo_angles[EEPROM_NUM_SERVOS][2]; // M281 P L U
  231. //
  232. // Temperature first layer compensation values
  233. //
  234. #if HAS_PTC
  235. #if ENABLED(PTC_PROBE)
  236. int16_t z_offsets_probe[COUNT(ptc.z_offsets_probe)]; // M871 P I V
  237. #endif
  238. #if ENABLED(PTC_BED)
  239. int16_t z_offsets_bed[COUNT(ptc.z_offsets_bed)]; // M871 B I V
  240. #endif
  241. #if ENABLED(PTC_HOTEND)
  242. int16_t z_offsets_hotend[COUNT(ptc.z_offsets_hotend)]; // M871 E I V
  243. #endif
  244. #endif
  245. //
  246. // BLTOUCH
  247. //
  248. bool bltouch_od_5v_mode;
  249. #ifdef BLTOUCH_HS_MODE
  250. bool bltouch_high_speed_mode; // M401 S
  251. #endif
  252. //
  253. // Kinematic Settings
  254. //
  255. #if IS_KINEMATIC
  256. float segments_per_second; // M665 S
  257. #if ENABLED(DELTA)
  258. float delta_height; // M666 H
  259. abc_float_t delta_endstop_adj; // M666 X Y Z
  260. float delta_radius, // M665 R
  261. delta_diagonal_rod; // M665 L
  262. abc_float_t delta_tower_angle_trim, // M665 X Y Z
  263. delta_diagonal_rod_trim; // M665 A B C
  264. #endif
  265. #endif
  266. //
  267. // Extra Endstops offsets
  268. //
  269. #if HAS_EXTRA_ENDSTOPS
  270. float x2_endstop_adj, // M666 X
  271. y2_endstop_adj, // M666 Y
  272. z2_endstop_adj, // M666 (S2) Z
  273. z3_endstop_adj, // M666 (S3) Z
  274. z4_endstop_adj; // M666 (S4) Z
  275. #endif
  276. //
  277. // Z_STEPPER_AUTO_ALIGN, Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS
  278. //
  279. #if ENABLED(Z_STEPPER_AUTO_ALIGN)
  280. xy_pos_t z_stepper_align_xy[NUM_Z_STEPPER_DRIVERS]; // M422 S X Y
  281. #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
  282. xy_pos_t z_stepper_align_stepper_xy[NUM_Z_STEPPER_DRIVERS]; // M422 W X Y
  283. #endif
  284. #endif
  285. //
  286. // Material Presets
  287. //
  288. #if HAS_PREHEAT
  289. preheat_t ui_material_preset[PREHEAT_COUNT]; // M145 S0 H B F
  290. #endif
  291. //
  292. // PIDTEMP
  293. //
  294. PIDCF_t hotendPID[HOTENDS]; // M301 En PIDCF / M303 En U
  295. int16_t lpq_len; // M301 L
  296. //
  297. // PIDTEMPBED
  298. //
  299. PID_t bedPID; // M304 PID / M303 E-1 U
  300. //
  301. // PIDTEMPCHAMBER
  302. //
  303. PID_t chamberPID; // M309 PID / M303 E-2 U
  304. //
  305. // User-defined Thermistors
  306. //
  307. #if HAS_USER_THERMISTORS
  308. user_thermistor_t user_thermistor[USER_THERMISTORS]; // M305 P0 R4700 T100000 B3950
  309. #endif
  310. //
  311. // Power monitor
  312. //
  313. uint8_t power_monitor_flags; // M430 I V W
  314. //
  315. // HAS_LCD_CONTRAST
  316. //
  317. uint8_t lcd_contrast; // M250 C
  318. //
  319. // HAS_LCD_BRIGHTNESS
  320. //
  321. uint8_t lcd_brightness; // M256 B
  322. //
  323. // Controller fan settings
  324. //
  325. controllerFan_settings_t controllerFan_settings; // M710
  326. //
  327. // POWER_LOSS_RECOVERY
  328. //
  329. bool recovery_enabled; // M413 S
  330. //
  331. // FWRETRACT
  332. //
  333. fwretract_settings_t fwretract_settings; // M207 S F Z W, M208 S F W R
  334. bool autoretract_enabled; // M209 S
  335. //
  336. // !NO_VOLUMETRIC
  337. //
  338. bool parser_volumetric_enabled; // M200 S parser.volumetric_enabled
  339. float planner_filament_size[EXTRUDERS]; // M200 T D planner.filament_size[]
  340. float planner_volumetric_extruder_limit[EXTRUDERS]; // M200 T L planner.volumetric_extruder_limit[]
  341. //
  342. // HAS_TRINAMIC_CONFIG
  343. //
  344. tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
  345. tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
  346. tmc_sgt_t tmc_sgt; // M914 X Y Z X2 Y2 Z2 Z3 Z4
  347. tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
  348. //
  349. // LIN_ADVANCE
  350. //
  351. float planner_extruder_advance_K[_MAX(EXTRUDERS, 1)]; // M900 K planner.extruder_advance_K
  352. //
  353. // HAS_MOTOR_CURRENT_PWM
  354. //
  355. #ifndef MOTOR_CURRENT_COUNT
  356. #define MOTOR_CURRENT_COUNT LINEAR_AXES
  357. #endif
  358. uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // M907 X Z E ...
  359. //
  360. // CNC_COORDINATE_SYSTEMS
  361. //
  362. xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS]; // G54-G59.3
  363. //
  364. // SKEW_CORRECTION
  365. //
  366. skew_factor_t planner_skew_factor; // M852 I J K planner.skew_factor
  367. //
  368. // ADVANCED_PAUSE_FEATURE
  369. //
  370. #if HAS_EXTRUDERS
  371. fil_change_settings_t fc_settings[EXTRUDERS]; // M603 T U L
  372. #endif
  373. //
  374. // Tool-change settings
  375. //
  376. #if HAS_MULTI_EXTRUDER
  377. toolchange_settings_t toolchange_settings; // M217 S P R
  378. #endif
  379. //
  380. // BACKLASH_COMPENSATION
  381. //
  382. xyz_float_t backlash_distance_mm; // M425 X Y Z
  383. uint8_t backlash_correction; // M425 F
  384. float backlash_smoothing_mm; // M425 S
  385. //
  386. // EXTENSIBLE_UI
  387. //
  388. #if ENABLED(EXTENSIBLE_UI)
  389. uint8_t extui_data[ExtUI::eeprom_data_size];
  390. #endif
  391. //
  392. // Ender-3 V2 DWIN
  393. //
  394. #if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
  395. uint8_t dwin_data[eeprom_data_size];
  396. #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
  397. uint8_t dwin_settings[CrealityDWIN.eeprom_data_size];
  398. #endif
  399. //
  400. // CASELIGHT_USES_BRIGHTNESS
  401. //
  402. #if CASELIGHT_USES_BRIGHTNESS
  403. uint8_t caselight_brightness; // M355 P
  404. #endif
  405. //
  406. // PASSWORD_FEATURE
  407. //
  408. #if ENABLED(PASSWORD_FEATURE)
  409. bool password_is_set;
  410. uint32_t password_value;
  411. #endif
  412. //
  413. // TOUCH_SCREEN_CALIBRATION
  414. //
  415. #if ENABLED(TOUCH_SCREEN_CALIBRATION)
  416. touch_calibration_t touch_calibration_data;
  417. #endif
  418. // Ethernet settings
  419. #if HAS_ETHERNET
  420. bool ethernet_hardware_enabled; // M552 S
  421. uint32_t ethernet_ip, // M552 P
  422. ethernet_dns,
  423. ethernet_gateway, // M553 P
  424. ethernet_subnet; // M554 P
  425. #endif
  426. //
  427. // Buzzer enable/disable
  428. //
  429. #if ENABLED(SOUND_MENU_ITEM)
  430. bool buzzer_enabled;
  431. #endif
  432. //
  433. // Fan tachometer check
  434. //
  435. #if HAS_FANCHECK
  436. bool fan_check_enabled;
  437. #endif
  438. //
  439. // MKS UI controller
  440. //
  441. #if ENABLED(DGUS_LCD_UI_MKS)
  442. uint8_t mks_language_index; // Display Language
  443. xy_int_t mks_corner_offsets[5]; // Bed Tramming
  444. xyz_int_t mks_park_pos; // Custom Parking (without NOZZLE_PARK)
  445. celsius_t mks_min_extrusion_temp; // Min E Temp (shadow M302 value)
  446. #endif
  447. #if HAS_MULTI_LANGUAGE
  448. uint8_t ui_language; // M414 S
  449. #endif
  450. } SettingsData;
  451. //static_assert(sizeof(SettingsData) <= MARLIN_EEPROM_SIZE, "EEPROM too small to contain SettingsData!");
  452. MarlinSettings settings;
  453. uint16_t MarlinSettings::datasize() { return sizeof(SettingsData); }
  454. /**
  455. * Post-process after Retrieve or Reset
  456. */
  457. #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
  458. float new_z_fade_height;
  459. #endif
  460. void MarlinSettings::postprocess() {
  461. xyze_pos_t oldpos = current_position;
  462. // steps per s2 needs to be updated to agree with units per s2
  463. planner.reset_acceleration_rates();
  464. // Make sure delta kinematics are updated before refreshing the
  465. // planner position so the stepper counts will be set correctly.
  466. TERN_(DELTA, recalc_delta_settings());
  467. TERN_(PIDTEMP, thermalManager.updatePID());
  468. #if DISABLED(NO_VOLUMETRICS)
  469. planner.calculate_volumetric_multipliers();
  470. #elif EXTRUDERS
  471. for (uint8_t i = COUNT(planner.e_factor); i--;)
  472. planner.refresh_e_factor(i);
  473. #endif
  474. // Software endstops depend on home_offset
  475. LOOP_LINEAR_AXES(i) {
  476. update_workspace_offset((AxisEnum)i);
  477. update_software_endstops((AxisEnum)i);
  478. }
  479. TERN_(ENABLE_LEVELING_FADE_HEIGHT, set_z_fade_height(new_z_fade_height, false)); // false = no report
  480. TERN_(AUTO_BED_LEVELING_BILINEAR, refresh_bed_level());
  481. TERN_(HAS_MOTOR_CURRENT_PWM, stepper.refresh_motor_power());
  482. TERN_(FWRETRACT, fwretract.refresh_autoretract());
  483. TERN_(HAS_LINEAR_E_JERK, planner.recalculate_max_e_jerk());
  484. TERN_(CASELIGHT_USES_BRIGHTNESS, caselight.update_brightness());
  485. TERN_(EXTENSIBLE_UI, ExtUI::onPostprocessSettings());
  486. // Refresh mm_per_step with the reciprocal of axis_steps_per_mm
  487. // and init stepper.count[], planner.position[] with current_position
  488. planner.refresh_positioning();
  489. // Various factors can change the current position
  490. if (oldpos != current_position)
  491. report_current_position();
  492. }
  493. #if BOTH(PRINTCOUNTER, EEPROM_SETTINGS)
  494. #include "printcounter.h"
  495. static_assert(
  496. !WITHIN(STATS_EEPROM_ADDRESS, EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)) &&
  497. !WITHIN(STATS_EEPROM_ADDRESS + sizeof(printStatistics), EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)),
  498. "STATS_EEPROM_ADDRESS collides with EEPROM settings storage."
  499. );
  500. #endif
  501. #if ENABLED(SD_FIRMWARE_UPDATE)
  502. #if ENABLED(EEPROM_SETTINGS)
  503. static_assert(
  504. !WITHIN(SD_FIRMWARE_UPDATE_EEPROM_ADDR, EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)),
  505. "SD_FIRMWARE_UPDATE_EEPROM_ADDR collides with EEPROM settings storage."
  506. );
  507. #endif
  508. bool MarlinSettings::sd_update_status() {
  509. uint8_t val;
  510. persistentStore.read_data(SD_FIRMWARE_UPDATE_EEPROM_ADDR, &val);
  511. return (val == SD_FIRMWARE_UPDATE_ACTIVE_VALUE);
  512. }
  513. bool MarlinSettings::set_sd_update_status(const bool enable) {
  514. if (enable != sd_update_status())
  515. persistentStore.write_data(
  516. SD_FIRMWARE_UPDATE_EEPROM_ADDR,
  517. enable ? SD_FIRMWARE_UPDATE_ACTIVE_VALUE : SD_FIRMWARE_UPDATE_INACTIVE_VALUE
  518. );
  519. return true;
  520. }
  521. #endif // SD_FIRMWARE_UPDATE
  522. #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
  523. static_assert(EEPROM_OFFSET + sizeof(SettingsData) < ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE,
  524. "ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE is insufficient to capture all EEPROM data.");
  525. #endif
  526. //
  527. // This file simply uses the DEBUG_ECHO macros to implement EEPROM_CHITCHAT.
  528. // For deeper debugging of EEPROM issues enable DEBUG_EEPROM_READWRITE.
  529. //
  530. #define DEBUG_OUT EITHER(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE)
  531. #include "../core/debug_out.h"
  532. #if ENABLED(EEPROM_SETTINGS)
  533. #define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_ERROR_MSG(ERR); eeprom_error = true; } }while(0)
  534. #if ENABLED(DEBUG_EEPROM_READWRITE)
  535. #define _FIELD_TEST(FIELD) \
  536. EEPROM_ASSERT( \
  537. eeprom_error || eeprom_index == offsetof(SettingsData, FIELD) + EEPROM_OFFSET, \
  538. "Field " STRINGIFY(FIELD) " mismatch." \
  539. )
  540. #else
  541. #define _FIELD_TEST(FIELD) NOOP
  542. #endif
  543. const char version[4] = EEPROM_VERSION;
  544. #if ENABLED(EEPROM_INIT_NOW)
  545. constexpr uint32_t strhash32(const char *s, const uint32_t h=0) {
  546. return *s ? strhash32(s + 1, ((h + *s) << (*s & 3)) ^ *s) : h;
  547. }
  548. constexpr uint32_t build_hash = strhash32(__DATE__ __TIME__);
  549. #endif
  550. bool MarlinSettings::eeprom_error, MarlinSettings::validating;
  551. int MarlinSettings::eeprom_index;
  552. uint16_t MarlinSettings::working_crc;
  553. bool MarlinSettings::size_error(const uint16_t size) {
  554. if (size != datasize()) {
  555. DEBUG_ERROR_MSG("EEPROM datasize error."
  556. #if ENABLED(MARLIN_DEV_MODE)
  557. " (Actual:", size, " Expected:", datasize(), ")"
  558. #endif
  559. );
  560. return true;
  561. }
  562. return false;
  563. }
  564. /**
  565. * M500 - Store Configuration
  566. */
  567. bool MarlinSettings::save() {
  568. float dummyf = 0;
  569. char ver[4] = "ERR";
  570. if (!EEPROM_START(EEPROM_OFFSET)) return false;
  571. eeprom_error = false;
  572. // Write or Skip version. (Flash doesn't allow rewrite without erase.)
  573. TERN(FLASH_EEPROM_EMULATION, EEPROM_SKIP, EEPROM_WRITE)(ver);
  574. #if ENABLED(EEPROM_INIT_NOW)
  575. EEPROM_SKIP(build_hash); // Skip the hash slot
  576. #endif
  577. EEPROM_SKIP(working_crc); // Skip the checksum slot
  578. working_crc = 0; // clear before first "real data"
  579. const uint8_t e_factors = DISTINCT_AXES - (LINEAR_AXES);
  580. _FIELD_TEST(e_factors);
  581. EEPROM_WRITE(e_factors);
  582. //
  583. // Planner Motion
  584. //
  585. {
  586. EEPROM_WRITE(planner.settings);
  587. #if HAS_CLASSIC_JERK
  588. EEPROM_WRITE(planner.max_jerk);
  589. #if HAS_LINEAR_E_JERK
  590. dummyf = float(DEFAULT_EJERK);
  591. EEPROM_WRITE(dummyf);
  592. #endif
  593. #else
  594. const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4);
  595. EEPROM_WRITE(planner_max_jerk);
  596. #endif
  597. TERN_(CLASSIC_JERK, dummyf = 0.02f);
  598. EEPROM_WRITE(TERN(CLASSIC_JERK, dummyf, planner.junction_deviation_mm));
  599. }
  600. //
  601. // Home Offset
  602. //
  603. {
  604. _FIELD_TEST(home_offset);
  605. #if HAS_SCARA_OFFSET
  606. EEPROM_WRITE(scara_home_offset);
  607. #else
  608. #if !HAS_HOME_OFFSET
  609. const xyz_pos_t home_offset{0};
  610. #endif
  611. EEPROM_WRITE(home_offset);
  612. #endif
  613. }
  614. //
  615. // Hotend Offsets, if any
  616. //
  617. {
  618. #if HAS_HOTEND_OFFSET
  619. // Skip hotend 0 which must be 0
  620. LOOP_S_L_N(e, 1, HOTENDS)
  621. EEPROM_WRITE(hotend_offset[e]);
  622. #endif
  623. }
  624. //
  625. // Filament Runout Sensor
  626. //
  627. {
  628. #if HAS_FILAMENT_SENSOR
  629. const bool &runout_sensor_enabled = runout.enabled;
  630. #else
  631. constexpr int8_t runout_sensor_enabled = -1;
  632. #endif
  633. _FIELD_TEST(runout_sensor_enabled);
  634. EEPROM_WRITE(runout_sensor_enabled);
  635. #if HAS_FILAMENT_RUNOUT_DISTANCE
  636. const float &runout_distance_mm = runout.runout_distance();
  637. #else
  638. constexpr float runout_distance_mm = 0;
  639. #endif
  640. EEPROM_WRITE(runout_distance_mm);
  641. }
  642. //
  643. // Global Leveling
  644. //
  645. {
  646. const float zfh = TERN(ENABLE_LEVELING_FADE_HEIGHT, planner.z_fade_height, (DEFAULT_LEVELING_FADE_HEIGHT));
  647. EEPROM_WRITE(zfh);
  648. }
  649. //
  650. // Mesh Bed Leveling
  651. //
  652. {
  653. #if ENABLED(MESH_BED_LEVELING)
  654. static_assert(
  655. sizeof(mbl.z_values) == (GRID_MAX_POINTS) * sizeof(mbl.z_values[0][0]),
  656. "MBL Z array is the wrong size."
  657. );
  658. #else
  659. dummyf = 0;
  660. #endif
  661. const uint8_t mesh_num_x = TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_X, 3),
  662. mesh_num_y = TERN(MESH_BED_LEVELING, GRID_MAX_POINTS_Y, 3);
  663. EEPROM_WRITE(TERN(MESH_BED_LEVELING, mbl.z_offset, dummyf));
  664. EEPROM_WRITE(mesh_num_x);
  665. EEPROM_WRITE(mesh_num_y);
  666. #if ENABLED(MESH_BED_LEVELING)
  667. EEPROM_WRITE(mbl.z_values);
  668. #else
  669. for (uint8_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_WRITE(dummyf);
  670. #endif
  671. }
  672. //
  673. // Probe XYZ Offsets
  674. //
  675. {
  676. _FIELD_TEST(probe_offset);
  677. #if HAS_BED_PROBE
  678. const xyz_pos_t &zpo = probe.offset;
  679. #else
  680. constexpr xyz_pos_t zpo{0};
  681. #endif
  682. EEPROM_WRITE(zpo);
  683. }
  684. //
  685. // Planar Bed Leveling matrix
  686. //
  687. {
  688. #if ABL_PLANAR
  689. EEPROM_WRITE(planner.bed_level_matrix);
  690. #else
  691. dummyf = 0;
  692. for (uint8_t q = 9; q--;) EEPROM_WRITE(dummyf);
  693. #endif
  694. }
  695. //
  696. // Bilinear Auto Bed Leveling
  697. //
  698. {
  699. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  700. static_assert(
  701. sizeof(z_values) == (GRID_MAX_POINTS) * sizeof(z_values[0][0]),
  702. "Bilinear Z array is the wrong size."
  703. );
  704. #if ENABLED(X_AXIS_TWIST_COMPENSATION)
  705. static_assert(
  706. sizeof(xatc.z_values) == (XATC_MAX_POINTS) * sizeof(xatc.z_values[0]),
  707. "Z-offset mesh is the wrong size."
  708. );
  709. #endif
  710. #else
  711. const xy_pos_t bilinear_start{0}, bilinear_grid_spacing{0};
  712. #endif
  713. const uint8_t grid_max_x = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_X, 3),
  714. grid_max_y = TERN(AUTO_BED_LEVELING_BILINEAR, GRID_MAX_POINTS_Y, 3);
  715. EEPROM_WRITE(grid_max_x);
  716. EEPROM_WRITE(grid_max_y);
  717. EEPROM_WRITE(bilinear_grid_spacing);
  718. EEPROM_WRITE(bilinear_start);
  719. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  720. EEPROM_WRITE(z_values); // 9-256 floats
  721. #if ENABLED(X_AXIS_TWIST_COMPENSATION)
  722. EEPROM_WRITE(xatc);
  723. #endif
  724. #else
  725. dummyf = 0;
  726. for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_WRITE(dummyf);
  727. #endif
  728. }
  729. //
  730. // Unified Bed Leveling
  731. //
  732. {
  733. _FIELD_TEST(planner_leveling_active);
  734. const bool ubl_active = TERN(AUTO_BED_LEVELING_UBL, planner.leveling_active, false);
  735. const int8_t storage_slot = TERN(AUTO_BED_LEVELING_UBL, ubl.storage_slot, -1);
  736. EEPROM_WRITE(ubl_active);
  737. EEPROM_WRITE(storage_slot);
  738. }
  739. //
  740. // Servo Angles
  741. //
  742. {
  743. _FIELD_TEST(servo_angles);
  744. #if !HAS_SERVO_ANGLES
  745. uint16_t servo_angles[EEPROM_NUM_SERVOS][2] = { { 0, 0 } };
  746. #endif
  747. EEPROM_WRITE(servo_angles);
  748. }
  749. //
  750. // Thermal first layer compensation values
  751. //
  752. #if HAS_PTC
  753. #if ENABLED(PTC_PROBE)
  754. EEPROM_WRITE(ptc.z_offsets_probe);
  755. #endif
  756. #if ENABLED(PTC_BED)
  757. EEPROM_WRITE(ptc.z_offsets_bed);
  758. #endif
  759. #if ENABLED(PTC_HOTEND)
  760. EEPROM_WRITE(ptc.z_offsets_hotend);
  761. #endif
  762. #else
  763. // No placeholder data for this feature
  764. #endif
  765. //
  766. // BLTOUCH
  767. //
  768. {
  769. _FIELD_TEST(bltouch_od_5v_mode);
  770. const bool bltouch_od_5v_mode = TERN0(BLTOUCH, bltouch.od_5v_mode);
  771. EEPROM_WRITE(bltouch_od_5v_mode);
  772. #ifdef BLTOUCH_HS_MODE
  773. _FIELD_TEST(bltouch_high_speed_mode);
  774. const bool bltouch_high_speed_mode = TERN0(BLTOUCH, bltouch.high_speed_mode);
  775. EEPROM_WRITE(bltouch_high_speed_mode);
  776. #endif
  777. }
  778. //
  779. // Kinematic Settings
  780. //
  781. #if IS_KINEMATIC
  782. {
  783. EEPROM_WRITE(segments_per_second);
  784. #if ENABLED(DELTA)
  785. _FIELD_TEST(delta_height);
  786. EEPROM_WRITE(delta_height); // 1 float
  787. EEPROM_WRITE(delta_endstop_adj); // 3 floats
  788. EEPROM_WRITE(delta_radius); // 1 float
  789. EEPROM_WRITE(delta_diagonal_rod); // 1 float
  790. EEPROM_WRITE(delta_tower_angle_trim); // 3 floats
  791. EEPROM_WRITE(delta_diagonal_rod_trim); // 3 floats
  792. #endif
  793. }
  794. #endif
  795. //
  796. // Extra Endstops offsets
  797. //
  798. #if HAS_EXTRA_ENDSTOPS
  799. {
  800. _FIELD_TEST(x2_endstop_adj);
  801. // Write dual endstops in X, Y, Z order. Unused = 0.0
  802. dummyf = 0;
  803. EEPROM_WRITE(TERN(X_DUAL_ENDSTOPS, endstops.x2_endstop_adj, dummyf)); // 1 float
  804. EEPROM_WRITE(TERN(Y_DUAL_ENDSTOPS, endstops.y2_endstop_adj, dummyf)); // 1 float
  805. EEPROM_WRITE(TERN(Z_MULTI_ENDSTOPS, endstops.z2_endstop_adj, dummyf)); // 1 float
  806. #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3
  807. EEPROM_WRITE(endstops.z3_endstop_adj); // 1 float
  808. #else
  809. EEPROM_WRITE(dummyf);
  810. #endif
  811. #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
  812. EEPROM_WRITE(endstops.z4_endstop_adj); // 1 float
  813. #else
  814. EEPROM_WRITE(dummyf);
  815. #endif
  816. }
  817. #endif
  818. #if ENABLED(Z_STEPPER_AUTO_ALIGN)
  819. EEPROM_WRITE(z_stepper_align.xy);
  820. #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
  821. EEPROM_WRITE(z_stepper_align.stepper_xy);
  822. #endif
  823. #endif
  824. //
  825. // LCD Preheat settings
  826. //
  827. #if HAS_PREHEAT
  828. _FIELD_TEST(ui_material_preset);
  829. EEPROM_WRITE(ui.material_preset);
  830. #endif
  831. //
  832. // PIDTEMP
  833. //
  834. {
  835. _FIELD_TEST(hotendPID);
  836. HOTEND_LOOP() {
  837. PIDCF_t pidcf = {
  838. #if DISABLED(PIDTEMP)
  839. NAN, NAN, NAN,
  840. NAN, NAN
  841. #else
  842. PID_PARAM(Kp, e),
  843. unscalePID_i(PID_PARAM(Ki, e)),
  844. unscalePID_d(PID_PARAM(Kd, e)),
  845. PID_PARAM(Kc, e),
  846. PID_PARAM(Kf, e)
  847. #endif
  848. };
  849. EEPROM_WRITE(pidcf);
  850. }
  851. _FIELD_TEST(lpq_len);
  852. #if DISABLED(PID_EXTRUSION_SCALING)
  853. const int16_t lpq_len = 20;
  854. #endif
  855. EEPROM_WRITE(TERN(PID_EXTRUSION_SCALING, thermalManager.lpq_len, lpq_len));
  856. }
  857. //
  858. // PIDTEMPBED
  859. //
  860. {
  861. _FIELD_TEST(bedPID);
  862. const PID_t bed_pid = {
  863. #if DISABLED(PIDTEMPBED)
  864. NAN, NAN, NAN
  865. #else
  866. // Store the unscaled PID values
  867. thermalManager.temp_bed.pid.Kp,
  868. unscalePID_i(thermalManager.temp_bed.pid.Ki),
  869. unscalePID_d(thermalManager.temp_bed.pid.Kd)
  870. #endif
  871. };
  872. EEPROM_WRITE(bed_pid);
  873. }
  874. //
  875. // PIDTEMPCHAMBER
  876. //
  877. {
  878. _FIELD_TEST(chamberPID);
  879. const PID_t chamber_pid = {
  880. #if DISABLED(PIDTEMPCHAMBER)
  881. NAN, NAN, NAN
  882. #else
  883. // Store the unscaled PID values
  884. thermalManager.temp_chamber.pid.Kp,
  885. unscalePID_i(thermalManager.temp_chamber.pid.Ki),
  886. unscalePID_d(thermalManager.temp_chamber.pid.Kd)
  887. #endif
  888. };
  889. EEPROM_WRITE(chamber_pid);
  890. }
  891. //
  892. // User-defined Thermistors
  893. //
  894. #if HAS_USER_THERMISTORS
  895. {
  896. _FIELD_TEST(user_thermistor);
  897. EEPROM_WRITE(thermalManager.user_thermistor);
  898. }
  899. #endif
  900. //
  901. // Power monitor
  902. //
  903. {
  904. #if HAS_POWER_MONITOR
  905. const uint8_t &power_monitor_flags = power_monitor.flags;
  906. #else
  907. constexpr uint8_t power_monitor_flags = 0x00;
  908. #endif
  909. _FIELD_TEST(power_monitor_flags);
  910. EEPROM_WRITE(power_monitor_flags);
  911. }
  912. //
  913. // LCD Contrast
  914. //
  915. {
  916. _FIELD_TEST(lcd_contrast);
  917. const uint8_t lcd_contrast = TERN(HAS_LCD_CONTRAST, ui.contrast, 127);
  918. EEPROM_WRITE(lcd_contrast);
  919. }
  920. //
  921. // LCD Brightness
  922. //
  923. {
  924. _FIELD_TEST(lcd_brightness);
  925. const uint8_t lcd_brightness = TERN(HAS_LCD_BRIGHTNESS, ui.brightness, 255);
  926. EEPROM_WRITE(lcd_brightness);
  927. }
  928. //
  929. // Controller Fan
  930. //
  931. {
  932. _FIELD_TEST(controllerFan_settings);
  933. #if ENABLED(USE_CONTROLLER_FAN)
  934. const controllerFan_settings_t &cfs = controllerFan.settings;
  935. #else
  936. controllerFan_settings_t cfs = controllerFan_defaults;
  937. #endif
  938. EEPROM_WRITE(cfs);
  939. }
  940. //
  941. // Power-Loss Recovery
  942. //
  943. {
  944. _FIELD_TEST(recovery_enabled);
  945. const bool recovery_enabled = TERN(POWER_LOSS_RECOVERY, recovery.enabled, ENABLED(PLR_ENABLED_DEFAULT));
  946. EEPROM_WRITE(recovery_enabled);
  947. }
  948. //
  949. // Firmware Retraction
  950. //
  951. {
  952. _FIELD_TEST(fwretract_settings);
  953. #if DISABLED(FWRETRACT)
  954. const fwretract_settings_t autoretract_defaults = { 3, 45, 0, 0, 0, 13, 0, 8 };
  955. #endif
  956. EEPROM_WRITE(TERN(FWRETRACT, fwretract.settings, autoretract_defaults));
  957. #if DISABLED(FWRETRACT_AUTORETRACT)
  958. const bool autoretract_enabled = false;
  959. #endif
  960. EEPROM_WRITE(TERN(FWRETRACT_AUTORETRACT, fwretract.autoretract_enabled, autoretract_enabled));
  961. }
  962. //
  963. // Volumetric & Filament Size
  964. //
  965. {
  966. _FIELD_TEST(parser_volumetric_enabled);
  967. #if DISABLED(NO_VOLUMETRICS)
  968. EEPROM_WRITE(parser.volumetric_enabled);
  969. EEPROM_WRITE(planner.filament_size);
  970. #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
  971. EEPROM_WRITE(planner.volumetric_extruder_limit);
  972. #else
  973. dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
  974. for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
  975. #endif
  976. #else
  977. const bool volumetric_enabled = false;
  978. EEPROM_WRITE(volumetric_enabled);
  979. dummyf = DEFAULT_NOMINAL_FILAMENT_DIA;
  980. for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
  981. dummyf = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
  982. for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummyf);
  983. #endif
  984. }
  985. //
  986. // TMC Configuration
  987. //
  988. {
  989. _FIELD_TEST(tmc_stepper_current);
  990. tmc_stepper_current_t tmc_stepper_current{0};
  991. #if HAS_TRINAMIC_CONFIG
  992. #if AXIS_IS_TMC(X)
  993. tmc_stepper_current.X = stepperX.getMilliamps();
  994. #endif
  995. #if AXIS_IS_TMC(Y)
  996. tmc_stepper_current.Y = stepperY.getMilliamps();
  997. #endif
  998. #if AXIS_IS_TMC(Z)
  999. tmc_stepper_current.Z = stepperZ.getMilliamps();
  1000. #endif
  1001. #if AXIS_IS_TMC(I)
  1002. tmc_stepper_current.I = stepperI.getMilliamps();
  1003. #endif
  1004. #if AXIS_IS_TMC(J)
  1005. tmc_stepper_current.J = stepperJ.getMilliamps();
  1006. #endif
  1007. #if AXIS_IS_TMC(K)
  1008. tmc_stepper_current.K = stepperK.getMilliamps();
  1009. #endif
  1010. #if AXIS_IS_TMC(X2)
  1011. tmc_stepper_current.X2 = stepperX2.getMilliamps();
  1012. #endif
  1013. #if AXIS_IS_TMC(Y2)
  1014. tmc_stepper_current.Y2 = stepperY2.getMilliamps();
  1015. #endif
  1016. #if AXIS_IS_TMC(Z2)
  1017. tmc_stepper_current.Z2 = stepperZ2.getMilliamps();
  1018. #endif
  1019. #if AXIS_IS_TMC(Z3)
  1020. tmc_stepper_current.Z3 = stepperZ3.getMilliamps();
  1021. #endif
  1022. #if AXIS_IS_TMC(Z4)
  1023. tmc_stepper_current.Z4 = stepperZ4.getMilliamps();
  1024. #endif
  1025. #if AXIS_IS_TMC(E0)
  1026. tmc_stepper_current.E0 = stepperE0.getMilliamps();
  1027. #endif
  1028. #if AXIS_IS_TMC(E1)
  1029. tmc_stepper_current.E1 = stepperE1.getMilliamps();
  1030. #endif
  1031. #if AXIS_IS_TMC(E2)
  1032. tmc_stepper_current.E2 = stepperE2.getMilliamps();
  1033. #endif
  1034. #if AXIS_IS_TMC(E3)
  1035. tmc_stepper_current.E3 = stepperE3.getMilliamps();
  1036. #endif
  1037. #if AXIS_IS_TMC(E4)
  1038. tmc_stepper_current.E4 = stepperE4.getMilliamps();
  1039. #endif
  1040. #if AXIS_IS_TMC(E5)
  1041. tmc_stepper_current.E5 = stepperE5.getMilliamps();
  1042. #endif
  1043. #if AXIS_IS_TMC(E6)
  1044. tmc_stepper_current.E6 = stepperE6.getMilliamps();
  1045. #endif
  1046. #if AXIS_IS_TMC(E7)
  1047. tmc_stepper_current.E7 = stepperE7.getMilliamps();
  1048. #endif
  1049. #endif
  1050. EEPROM_WRITE(tmc_stepper_current);
  1051. }
  1052. //
  1053. // TMC Hybrid Threshold, and placeholder values
  1054. //
  1055. {
  1056. _FIELD_TEST(tmc_hybrid_threshold);
  1057. #if ENABLED(HYBRID_THRESHOLD)
  1058. tmc_hybrid_threshold_t tmc_hybrid_threshold{0};
  1059. TERN_(X_HAS_STEALTHCHOP, tmc_hybrid_threshold.X = stepperX.get_pwm_thrs());
  1060. TERN_(Y_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y = stepperY.get_pwm_thrs());
  1061. TERN_(Z_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z = stepperZ.get_pwm_thrs());
  1062. TERN_(I_HAS_STEALTHCHOP, tmc_hybrid_threshold.I = stepperI.get_pwm_thrs());
  1063. TERN_(J_HAS_STEALTHCHOP, tmc_hybrid_threshold.J = stepperJ.get_pwm_thrs());
  1064. TERN_(K_HAS_STEALTHCHOP, tmc_hybrid_threshold.K = stepperK.get_pwm_thrs());
  1065. TERN_(X2_HAS_STEALTHCHOP, tmc_hybrid_threshold.X2 = stepperX2.get_pwm_thrs());
  1066. TERN_(Y2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y2 = stepperY2.get_pwm_thrs());
  1067. TERN_(Z2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z2 = stepperZ2.get_pwm_thrs());
  1068. TERN_(Z3_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z3 = stepperZ3.get_pwm_thrs());
  1069. TERN_(Z4_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z4 = stepperZ4.get_pwm_thrs());
  1070. TERN_(E0_HAS_STEALTHCHOP, tmc_hybrid_threshold.E0 = stepperE0.get_pwm_thrs());
  1071. TERN_(E1_HAS_STEALTHCHOP, tmc_hybrid_threshold.E1 = stepperE1.get_pwm_thrs());
  1072. TERN_(E2_HAS_STEALTHCHOP, tmc_hybrid_threshold.E2 = stepperE2.get_pwm_thrs());
  1073. TERN_(E3_HAS_STEALTHCHOP, tmc_hybrid_threshold.E3 = stepperE3.get_pwm_thrs());
  1074. TERN_(E4_HAS_STEALTHCHOP, tmc_hybrid_threshold.E4 = stepperE4.get_pwm_thrs());
  1075. TERN_(E5_HAS_STEALTHCHOP, tmc_hybrid_threshold.E5 = stepperE5.get_pwm_thrs());
  1076. TERN_(E6_HAS_STEALTHCHOP, tmc_hybrid_threshold.E6 = stepperE6.get_pwm_thrs());
  1077. TERN_(E7_HAS_STEALTHCHOP, tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs());
  1078. #else
  1079. #define _EN_ITEM(N) , .E##N = 30
  1080. const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
  1081. LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3),
  1082. .X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
  1083. REPEAT(E_STEPPERS, _EN_ITEM)
  1084. };
  1085. #undef _EN_ITEM
  1086. #endif
  1087. EEPROM_WRITE(tmc_hybrid_threshold);
  1088. }
  1089. //
  1090. // TMC StallGuard threshold
  1091. //
  1092. {
  1093. tmc_sgt_t tmc_sgt{0};
  1094. #if USE_SENSORLESS
  1095. LINEAR_AXIS_CODE(
  1096. TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
  1097. TERN_(Y_SENSORLESS, tmc_sgt.Y = stepperY.homing_threshold()),
  1098. TERN_(Z_SENSORLESS, tmc_sgt.Z = stepperZ.homing_threshold()),
  1099. TERN_(I_SENSORLESS, tmc_sgt.I = stepperI.homing_threshold()),
  1100. TERN_(J_SENSORLESS, tmc_sgt.J = stepperJ.homing_threshold()),
  1101. TERN_(K_SENSORLESS, tmc_sgt.K = stepperK.homing_threshold())
  1102. );
  1103. TERN_(X2_SENSORLESS, tmc_sgt.X2 = stepperX2.homing_threshold());
  1104. TERN_(Y2_SENSORLESS, tmc_sgt.Y2 = stepperY2.homing_threshold());
  1105. TERN_(Z2_SENSORLESS, tmc_sgt.Z2 = stepperZ2.homing_threshold());
  1106. TERN_(Z3_SENSORLESS, tmc_sgt.Z3 = stepperZ3.homing_threshold());
  1107. TERN_(Z4_SENSORLESS, tmc_sgt.Z4 = stepperZ4.homing_threshold());
  1108. #endif
  1109. EEPROM_WRITE(tmc_sgt);
  1110. }
  1111. //
  1112. // TMC stepping mode
  1113. //
  1114. {
  1115. _FIELD_TEST(tmc_stealth_enabled);
  1116. tmc_stealth_enabled_t tmc_stealth_enabled = { false };
  1117. TERN_(X_HAS_STEALTHCHOP, tmc_stealth_enabled.X = stepperX.get_stored_stealthChop());
  1118. TERN_(Y_HAS_STEALTHCHOP, tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop());
  1119. TERN_(Z_HAS_STEALTHCHOP, tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop());
  1120. TERN_(I_HAS_STEALTHCHOP, tmc_stealth_enabled.I = stepperI.get_stored_stealthChop());
  1121. TERN_(J_HAS_STEALTHCHOP, tmc_stealth_enabled.J = stepperJ.get_stored_stealthChop());
  1122. TERN_(K_HAS_STEALTHCHOP, tmc_stealth_enabled.K = stepperK.get_stored_stealthChop());
  1123. TERN_(X2_HAS_STEALTHCHOP, tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop());
  1124. TERN_(Y2_HAS_STEALTHCHOP, tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop());
  1125. TERN_(Z2_HAS_STEALTHCHOP, tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop());
  1126. TERN_(Z3_HAS_STEALTHCHOP, tmc_stealth_enabled.Z3 = stepperZ3.get_stored_stealthChop());
  1127. TERN_(Z4_HAS_STEALTHCHOP, tmc_stealth_enabled.Z4 = stepperZ4.get_stored_stealthChop());
  1128. TERN_(E0_HAS_STEALTHCHOP, tmc_stealth_enabled.E0 = stepperE0.get_stored_stealthChop());
  1129. TERN_(E1_HAS_STEALTHCHOP, tmc_stealth_enabled.E1 = stepperE1.get_stored_stealthChop());
  1130. TERN_(E2_HAS_STEALTHCHOP, tmc_stealth_enabled.E2 = stepperE2.get_stored_stealthChop());
  1131. TERN_(E3_HAS_STEALTHCHOP, tmc_stealth_enabled.E3 = stepperE3.get_stored_stealthChop());
  1132. TERN_(E4_HAS_STEALTHCHOP, tmc_stealth_enabled.E4 = stepperE4.get_stored_stealthChop());
  1133. TERN_(E5_HAS_STEALTHCHOP, tmc_stealth_enabled.E5 = stepperE5.get_stored_stealthChop());
  1134. TERN_(E6_HAS_STEALTHCHOP, tmc_stealth_enabled.E6 = stepperE6.get_stored_stealthChop());
  1135. TERN_(E7_HAS_STEALTHCHOP, tmc_stealth_enabled.E7 = stepperE7.get_stored_stealthChop());
  1136. EEPROM_WRITE(tmc_stealth_enabled);
  1137. }
  1138. //
  1139. // Linear Advance
  1140. //
  1141. {
  1142. _FIELD_TEST(planner_extruder_advance_K);
  1143. #if ENABLED(LIN_ADVANCE)
  1144. EEPROM_WRITE(planner.extruder_advance_K);
  1145. #else
  1146. dummyf = 0;
  1147. for (uint8_t q = _MAX(EXTRUDERS, 1); q--;) EEPROM_WRITE(dummyf);
  1148. #endif
  1149. }
  1150. //
  1151. // Motor Current PWM
  1152. //
  1153. {
  1154. _FIELD_TEST(motor_current_setting);
  1155. #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
  1156. EEPROM_WRITE(stepper.motor_current_setting);
  1157. #else
  1158. const uint32_t no_current[MOTOR_CURRENT_COUNT] = { 0 };
  1159. EEPROM_WRITE(no_current);
  1160. #endif
  1161. }
  1162. //
  1163. // CNC Coordinate Systems
  1164. //
  1165. _FIELD_TEST(coordinate_system);
  1166. #if DISABLED(CNC_COORDINATE_SYSTEMS)
  1167. const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } };
  1168. #endif
  1169. EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system));
  1170. //
  1171. // Skew correction factors
  1172. //
  1173. _FIELD_TEST(planner_skew_factor);
  1174. EEPROM_WRITE(planner.skew_factor);
  1175. //
  1176. // Advanced Pause filament load & unload lengths
  1177. //
  1178. #if HAS_EXTRUDERS
  1179. {
  1180. #if DISABLED(ADVANCED_PAUSE_FEATURE)
  1181. const fil_change_settings_t fc_settings[EXTRUDERS] = { 0, 0 };
  1182. #endif
  1183. _FIELD_TEST(fc_settings);
  1184. EEPROM_WRITE(fc_settings);
  1185. }
  1186. #endif
  1187. //
  1188. // Multiple Extruders
  1189. //
  1190. #if HAS_MULTI_EXTRUDER
  1191. _FIELD_TEST(toolchange_settings);
  1192. EEPROM_WRITE(toolchange_settings);
  1193. #endif
  1194. //
  1195. // Backlash Compensation
  1196. //
  1197. {
  1198. #if ENABLED(BACKLASH_GCODE)
  1199. const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
  1200. const uint8_t &backlash_correction = backlash.correction;
  1201. #else
  1202. const xyz_float_t backlash_distance_mm{0};
  1203. const uint8_t backlash_correction = 0;
  1204. #endif
  1205. #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
  1206. const float &backlash_smoothing_mm = backlash.smoothing_mm;
  1207. #else
  1208. const float backlash_smoothing_mm = 3;
  1209. #endif
  1210. _FIELD_TEST(backlash_distance_mm);
  1211. EEPROM_WRITE(backlash_distance_mm);
  1212. EEPROM_WRITE(backlash_correction);
  1213. EEPROM_WRITE(backlash_smoothing_mm);
  1214. }
  1215. //
  1216. // Extensible UI User Data
  1217. //
  1218. #if ENABLED(EXTENSIBLE_UI)
  1219. {
  1220. char extui_data[ExtUI::eeprom_data_size] = { 0 };
  1221. ExtUI::onStoreSettings(extui_data);
  1222. _FIELD_TEST(extui_data);
  1223. EEPROM_WRITE(extui_data);
  1224. }
  1225. #endif
  1226. //
  1227. // Creality DWIN User Data
  1228. //
  1229. #if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
  1230. {
  1231. char dwin_data[eeprom_data_size] = { 0 };
  1232. DWIN_StoreSettings(dwin_data);
  1233. _FIELD_TEST(dwin_data);
  1234. EEPROM_WRITE(dwin_data);
  1235. }
  1236. #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
  1237. {
  1238. char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 };
  1239. CrealityDWIN.Save_Settings(dwin_settings);
  1240. _FIELD_TEST(dwin_settings);
  1241. EEPROM_WRITE(dwin_settings);
  1242. }
  1243. #endif
  1244. //
  1245. // Case Light Brightness
  1246. //
  1247. #if CASELIGHT_USES_BRIGHTNESS
  1248. EEPROM_WRITE(caselight.brightness);
  1249. #endif
  1250. //
  1251. // Password feature
  1252. //
  1253. #if ENABLED(PASSWORD_FEATURE)
  1254. EEPROM_WRITE(password.is_set);
  1255. EEPROM_WRITE(password.value);
  1256. #endif
  1257. //
  1258. // TOUCH_SCREEN_CALIBRATION
  1259. //
  1260. #if ENABLED(TOUCH_SCREEN_CALIBRATION)
  1261. EEPROM_WRITE(touch_calibration.calibration);
  1262. #endif
  1263. //
  1264. // Ethernet network info
  1265. //
  1266. #if HAS_ETHERNET
  1267. {
  1268. _FIELD_TEST(ethernet_hardware_enabled);
  1269. const bool ethernet_hardware_enabled = ethernet.hardware_enabled;
  1270. const uint32_t ethernet_ip = ethernet.ip,
  1271. ethernet_dns = ethernet.myDns,
  1272. ethernet_gateway = ethernet.gateway,
  1273. ethernet_subnet = ethernet.subnet;
  1274. EEPROM_WRITE(ethernet_hardware_enabled);
  1275. EEPROM_WRITE(ethernet_ip);
  1276. EEPROM_WRITE(ethernet_dns);
  1277. EEPROM_WRITE(ethernet_gateway);
  1278. EEPROM_WRITE(ethernet_subnet);
  1279. }
  1280. #endif
  1281. //
  1282. // Buzzer enable/disable
  1283. //
  1284. #if ENABLED(SOUND_MENU_ITEM)
  1285. EEPROM_WRITE(ui.buzzer_enabled);
  1286. #endif
  1287. //
  1288. // Fan tachometer check
  1289. //
  1290. #if HAS_FANCHECK
  1291. EEPROM_WRITE(fan_check.enabled);
  1292. #endif
  1293. //
  1294. // MKS UI controller
  1295. //
  1296. #if ENABLED(DGUS_LCD_UI_MKS)
  1297. EEPROM_WRITE(mks_language_index);
  1298. EEPROM_WRITE(mks_corner_offsets);
  1299. EEPROM_WRITE(mks_park_pos);
  1300. EEPROM_WRITE(mks_min_extrusion_temp);
  1301. #endif
  1302. //
  1303. // Selected LCD language
  1304. //
  1305. #if HAS_MULTI_LANGUAGE
  1306. EEPROM_WRITE(ui.language);
  1307. #endif
  1308. //
  1309. // Report final CRC and Data Size
  1310. //
  1311. if (!eeprom_error) {
  1312. const uint16_t eeprom_size = eeprom_index - (EEPROM_OFFSET),
  1313. final_crc = working_crc;
  1314. // Write the EEPROM header
  1315. eeprom_index = EEPROM_OFFSET;
  1316. EEPROM_WRITE(version);
  1317. #if ENABLED(EEPROM_INIT_NOW)
  1318. EEPROM_WRITE(build_hash);
  1319. #endif
  1320. EEPROM_WRITE(final_crc);
  1321. // Report storage size
  1322. DEBUG_ECHO_MSG("Settings Stored (", eeprom_size, " bytes; crc ", (uint32_t)final_crc, ")");
  1323. eeprom_error |= size_error(eeprom_size);
  1324. }
  1325. EEPROM_FINISH();
  1326. //
  1327. // UBL Mesh
  1328. //
  1329. #if ENABLED(UBL_SAVE_ACTIVE_ON_M500)
  1330. if (ubl.storage_slot >= 0)
  1331. store_mesh(ubl.storage_slot);
  1332. #endif
  1333. if (!eeprom_error) LCD_MESSAGE(MSG_SETTINGS_STORED);
  1334. TERN_(EXTENSIBLE_UI, ExtUI::onConfigurationStoreWritten(!eeprom_error));
  1335. return !eeprom_error;
  1336. }
  1337. /**
  1338. * M501 - Retrieve Configuration
  1339. */
  1340. bool MarlinSettings::_load() {
  1341. if (!EEPROM_START(EEPROM_OFFSET)) return false;
  1342. char stored_ver[4];
  1343. EEPROM_READ_ALWAYS(stored_ver);
  1344. // Version has to match or defaults are used
  1345. if (strncmp(version, stored_ver, 3) != 0) {
  1346. if (stored_ver[3] != '\0') {
  1347. stored_ver[0] = '?';
  1348. stored_ver[1] = '\0';
  1349. }
  1350. DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")");
  1351. TERN_(DWIN_CREALITY_LCD_ENHANCED, LCD_MESSAGE(MSG_ERR_EEPROM_VERSION));
  1352. IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_version());
  1353. eeprom_error = true;
  1354. }
  1355. else {
  1356. // Optionally reset on the first boot after flashing
  1357. #if ENABLED(EEPROM_INIT_NOW)
  1358. uint32_t stored_hash;
  1359. EEPROM_READ_ALWAYS(stored_hash);
  1360. if (stored_hash != build_hash) { EEPROM_FINISH(); return false; }
  1361. #endif
  1362. uint16_t stored_crc;
  1363. EEPROM_READ_ALWAYS(stored_crc);
  1364. float dummyf = 0;
  1365. working_crc = 0; // Init to 0. Accumulated by EEPROM_READ
  1366. _FIELD_TEST(e_factors);
  1367. // Number of e_factors may change
  1368. uint8_t e_factors;
  1369. EEPROM_READ_ALWAYS(e_factors);
  1370. //
  1371. // Planner Motion
  1372. //
  1373. {
  1374. // Get only the number of E stepper parameters previously stored
  1375. // Any steppers added later are set to their defaults
  1376. uint32_t tmp1[LINEAR_AXES + e_factors];
  1377. float tmp2[LINEAR_AXES + e_factors];
  1378. feedRate_t tmp3[LINEAR_AXES + e_factors];
  1379. EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2
  1380. EEPROM_READ(planner.settings.min_segment_time_us);
  1381. EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm
  1382. EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s
  1383. if (!validating) LOOP_DISTINCT_AXES(i) {
  1384. const bool in = (i < e_factors + LINEAR_AXES);
  1385. planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
  1386. planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
  1387. planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
  1388. }
  1389. EEPROM_READ(planner.settings.acceleration);
  1390. EEPROM_READ(planner.settings.retract_acceleration);
  1391. EEPROM_READ(planner.settings.travel_acceleration);
  1392. EEPROM_READ(planner.settings.min_feedrate_mm_s);
  1393. EEPROM_READ(planner.settings.min_travel_feedrate_mm_s);
  1394. #if HAS_CLASSIC_JERK
  1395. EEPROM_READ(planner.max_jerk);
  1396. #if HAS_LINEAR_E_JERK
  1397. EEPROM_READ(dummyf);
  1398. #endif
  1399. #else
  1400. for (uint8_t q = LOGICAL_AXES; q--;) EEPROM_READ(dummyf);
  1401. #endif
  1402. EEPROM_READ(TERN(CLASSIC_JERK, dummyf, planner.junction_deviation_mm));
  1403. }
  1404. //
  1405. // Home Offset (M206 / M665)
  1406. //
  1407. {
  1408. _FIELD_TEST(home_offset);
  1409. #if HAS_SCARA_OFFSET
  1410. EEPROM_READ(scara_home_offset);
  1411. #else
  1412. #if !HAS_HOME_OFFSET
  1413. xyz_pos_t home_offset;
  1414. #endif
  1415. EEPROM_READ(home_offset);
  1416. #endif
  1417. }
  1418. //
  1419. // Hotend Offsets, if any
  1420. //
  1421. {
  1422. #if HAS_HOTEND_OFFSET
  1423. // Skip hotend 0 which must be 0
  1424. LOOP_S_L_N(e, 1, HOTENDS)
  1425. EEPROM_READ(hotend_offset[e]);
  1426. #endif
  1427. }
  1428. //
  1429. // Filament Runout Sensor
  1430. //
  1431. {
  1432. int8_t runout_sensor_enabled;
  1433. _FIELD_TEST(runout_sensor_enabled);
  1434. EEPROM_READ(runout_sensor_enabled);
  1435. #if HAS_FILAMENT_SENSOR
  1436. runout.enabled = runout_sensor_enabled < 0 ? FIL_RUNOUT_ENABLED_DEFAULT : runout_sensor_enabled;
  1437. #endif
  1438. TERN_(HAS_FILAMENT_SENSOR, if (runout.enabled) runout.reset());
  1439. float runout_distance_mm;
  1440. EEPROM_READ(runout_distance_mm);
  1441. #if HAS_FILAMENT_RUNOUT_DISTANCE
  1442. if (!validating) runout.set_runout_distance(runout_distance_mm);
  1443. #endif
  1444. }
  1445. //
  1446. // Global Leveling
  1447. //
  1448. EEPROM_READ(TERN(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height, dummyf));
  1449. //
  1450. // Mesh (Manual) Bed Leveling
  1451. //
  1452. {
  1453. uint8_t mesh_num_x, mesh_num_y;
  1454. EEPROM_READ(dummyf);
  1455. EEPROM_READ_ALWAYS(mesh_num_x);
  1456. EEPROM_READ_ALWAYS(mesh_num_y);
  1457. #if ENABLED(MESH_BED_LEVELING)
  1458. if (!validating) mbl.z_offset = dummyf;
  1459. if (mesh_num_x == (GRID_MAX_POINTS_X) && mesh_num_y == (GRID_MAX_POINTS_Y)) {
  1460. // EEPROM data fits the current mesh
  1461. EEPROM_READ(mbl.z_values);
  1462. }
  1463. else {
  1464. // EEPROM data is stale
  1465. if (!validating) mbl.reset();
  1466. for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummyf);
  1467. }
  1468. #else
  1469. // MBL is disabled - skip the stored data
  1470. for (uint16_t q = mesh_num_x * mesh_num_y; q--;) EEPROM_READ(dummyf);
  1471. #endif // MESH_BED_LEVELING
  1472. }
  1473. //
  1474. // Probe Z Offset
  1475. //
  1476. {
  1477. _FIELD_TEST(probe_offset);
  1478. #if HAS_BED_PROBE
  1479. const xyz_pos_t &zpo = probe.offset;
  1480. #else
  1481. xyz_pos_t zpo;
  1482. #endif
  1483. EEPROM_READ(zpo);
  1484. }
  1485. //
  1486. // Planar Bed Leveling matrix
  1487. //
  1488. {
  1489. #if ABL_PLANAR
  1490. EEPROM_READ(planner.bed_level_matrix);
  1491. #else
  1492. for (uint8_t q = 9; q--;) EEPROM_READ(dummyf);
  1493. #endif
  1494. }
  1495. //
  1496. // Bilinear Auto Bed Leveling
  1497. //
  1498. {
  1499. uint8_t grid_max_x, grid_max_y;
  1500. EEPROM_READ_ALWAYS(grid_max_x); // 1 byte
  1501. EEPROM_READ_ALWAYS(grid_max_y); // 1 byte
  1502. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1503. if (grid_max_x == (GRID_MAX_POINTS_X) && grid_max_y == (GRID_MAX_POINTS_Y)) {
  1504. if (!validating) set_bed_leveling_enabled(false);
  1505. EEPROM_READ(bilinear_grid_spacing); // 2 ints
  1506. EEPROM_READ(bilinear_start); // 2 ints
  1507. EEPROM_READ(z_values); // 9 to 256 floats
  1508. #if ENABLED(X_AXIS_TWIST_COMPENSATION)
  1509. EEPROM_READ(xatc);
  1510. #endif
  1511. }
  1512. else // EEPROM data is stale
  1513. #endif // AUTO_BED_LEVELING_BILINEAR
  1514. {
  1515. // Skip past disabled (or stale) Bilinear Grid data
  1516. xy_pos_t bgs, bs;
  1517. EEPROM_READ(bgs);
  1518. EEPROM_READ(bs);
  1519. for (uint16_t q = grid_max_x * grid_max_y; q--;) EEPROM_READ(dummyf);
  1520. }
  1521. }
  1522. //
  1523. // Unified Bed Leveling active state
  1524. //
  1525. {
  1526. _FIELD_TEST(planner_leveling_active);
  1527. #if ENABLED(AUTO_BED_LEVELING_UBL)
  1528. const bool &planner_leveling_active = planner.leveling_active;
  1529. const int8_t &ubl_storage_slot = ubl.storage_slot;
  1530. #else
  1531. bool planner_leveling_active;
  1532. int8_t ubl_storage_slot;
  1533. #endif
  1534. EEPROM_READ(planner_leveling_active);
  1535. EEPROM_READ(ubl_storage_slot);
  1536. }
  1537. //
  1538. // SERVO_ANGLES
  1539. //
  1540. {
  1541. _FIELD_TEST(servo_angles);
  1542. #if ENABLED(EDITABLE_SERVO_ANGLES)
  1543. uint16_t (&servo_angles_arr)[EEPROM_NUM_SERVOS][2] = servo_angles;
  1544. #else
  1545. uint16_t servo_angles_arr[EEPROM_NUM_SERVOS][2];
  1546. #endif
  1547. EEPROM_READ(servo_angles_arr);
  1548. }
  1549. //
  1550. // Thermal first layer compensation values
  1551. //
  1552. #if HAS_PTC
  1553. #if ENABLED(PTC_PROBE)
  1554. EEPROM_READ(ptc.z_offsets_probe);
  1555. #endif
  1556. # if ENABLED(PTC_BED)
  1557. EEPROM_READ(ptc.z_offsets_bed);
  1558. #endif
  1559. #if ENABLED(PTC_HOTEND)
  1560. EEPROM_READ(ptc.z_offsets_hotend);
  1561. #endif
  1562. ptc.reset_index();
  1563. #else
  1564. // No placeholder data for this feature
  1565. #endif
  1566. //
  1567. // BLTOUCH
  1568. //
  1569. {
  1570. _FIELD_TEST(bltouch_od_5v_mode);
  1571. #if ENABLED(BLTOUCH)
  1572. const bool &bltouch_od_5v_mode = bltouch.od_5v_mode;
  1573. #else
  1574. bool bltouch_od_5v_mode;
  1575. #endif
  1576. EEPROM_READ(bltouch_od_5v_mode);
  1577. #ifdef BLTOUCH_HS_MODE
  1578. _FIELD_TEST(bltouch_high_speed_mode);
  1579. #if ENABLED(BLTOUCH)
  1580. const bool &bltouch_high_speed_mode = bltouch.high_speed_mode;
  1581. #else
  1582. bool bltouch_high_speed_mode;
  1583. #endif
  1584. EEPROM_READ(bltouch_high_speed_mode);
  1585. #endif
  1586. }
  1587. //
  1588. // Kinematic Segments-per-second
  1589. //
  1590. #if IS_KINEMATIC
  1591. {
  1592. EEPROM_READ(segments_per_second);
  1593. #if ENABLED(DELTA)
  1594. _FIELD_TEST(delta_height);
  1595. EEPROM_READ(delta_height); // 1 float
  1596. EEPROM_READ(delta_endstop_adj); // 3 floats
  1597. EEPROM_READ(delta_radius); // 1 float
  1598. EEPROM_READ(delta_diagonal_rod); // 1 float
  1599. EEPROM_READ(delta_tower_angle_trim); // 3 floats
  1600. EEPROM_READ(delta_diagonal_rod_trim); // 3 floats
  1601. #endif
  1602. }
  1603. #endif
  1604. //
  1605. // Extra Endstops offsets
  1606. //
  1607. #if HAS_EXTRA_ENDSTOPS
  1608. {
  1609. _FIELD_TEST(x2_endstop_adj);
  1610. EEPROM_READ(TERN(X_DUAL_ENDSTOPS, endstops.x2_endstop_adj, dummyf)); // 1 float
  1611. EEPROM_READ(TERN(Y_DUAL_ENDSTOPS, endstops.y2_endstop_adj, dummyf)); // 1 float
  1612. EEPROM_READ(TERN(Z_MULTI_ENDSTOPS, endstops.z2_endstop_adj, dummyf)); // 1 float
  1613. #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3
  1614. EEPROM_READ(endstops.z3_endstop_adj); // 1 float
  1615. #else
  1616. EEPROM_READ(dummyf);
  1617. #endif
  1618. #if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
  1619. EEPROM_READ(endstops.z4_endstop_adj); // 1 float
  1620. #else
  1621. EEPROM_READ(dummyf);
  1622. #endif
  1623. }
  1624. #endif
  1625. #if ENABLED(Z_STEPPER_AUTO_ALIGN)
  1626. EEPROM_READ(z_stepper_align.xy);
  1627. #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
  1628. EEPROM_READ(z_stepper_align.stepper_xy);
  1629. #endif
  1630. #endif
  1631. //
  1632. // LCD Preheat settings
  1633. //
  1634. #if HAS_PREHEAT
  1635. _FIELD_TEST(ui_material_preset);
  1636. EEPROM_READ(ui.material_preset);
  1637. #endif
  1638. //
  1639. // Hotend PID
  1640. //
  1641. {
  1642. HOTEND_LOOP() {
  1643. PIDCF_t pidcf;
  1644. EEPROM_READ(pidcf);
  1645. #if ENABLED(PIDTEMP)
  1646. if (!validating && !isnan(pidcf.Kp)) {
  1647. // Scale PID values since EEPROM values are unscaled
  1648. PID_PARAM(Kp, e) = pidcf.Kp;
  1649. PID_PARAM(Ki, e) = scalePID_i(pidcf.Ki);
  1650. PID_PARAM(Kd, e) = scalePID_d(pidcf.Kd);
  1651. TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = pidcf.Kc);
  1652. TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = pidcf.Kf);
  1653. }
  1654. #endif
  1655. }
  1656. }
  1657. //
  1658. // PID Extrusion Scaling
  1659. //
  1660. {
  1661. _FIELD_TEST(lpq_len);
  1662. #if ENABLED(PID_EXTRUSION_SCALING)
  1663. const int16_t &lpq_len = thermalManager.lpq_len;
  1664. #else
  1665. int16_t lpq_len;
  1666. #endif
  1667. EEPROM_READ(lpq_len);
  1668. }
  1669. //
  1670. // Heated Bed PID
  1671. //
  1672. {
  1673. PID_t pid;
  1674. EEPROM_READ(pid);
  1675. #if ENABLED(PIDTEMPBED)
  1676. if (!validating && !isnan(pid.Kp)) {
  1677. // Scale PID values since EEPROM values are unscaled
  1678. thermalManager.temp_bed.pid.Kp = pid.Kp;
  1679. thermalManager.temp_bed.pid.Ki = scalePID_i(pid.Ki);
  1680. thermalManager.temp_bed.pid.Kd = scalePID_d(pid.Kd);
  1681. }
  1682. #endif
  1683. }
  1684. //
  1685. // Heated Chamber PID
  1686. //
  1687. {
  1688. PID_t pid;
  1689. EEPROM_READ(pid);
  1690. #if ENABLED(PIDTEMPCHAMBER)
  1691. if (!validating && !isnan(pid.Kp)) {
  1692. // Scale PID values since EEPROM values are unscaled
  1693. thermalManager.temp_chamber.pid.Kp = pid.Kp;
  1694. thermalManager.temp_chamber.pid.Ki = scalePID_i(pid.Ki);
  1695. thermalManager.temp_chamber.pid.Kd = scalePID_d(pid.Kd);
  1696. }
  1697. #endif
  1698. }
  1699. //
  1700. // User-defined Thermistors
  1701. //
  1702. #if HAS_USER_THERMISTORS
  1703. {
  1704. user_thermistor_t user_thermistor[USER_THERMISTORS];
  1705. _FIELD_TEST(user_thermistor);
  1706. EEPROM_READ(user_thermistor);
  1707. if (!validating) COPY(thermalManager.user_thermistor, user_thermistor);
  1708. }
  1709. #endif
  1710. //
  1711. // Power monitor
  1712. //
  1713. {
  1714. uint8_t power_monitor_flags;
  1715. _FIELD_TEST(power_monitor_flags);
  1716. EEPROM_READ(power_monitor_flags);
  1717. TERN_(HAS_POWER_MONITOR, if (!validating) power_monitor.flags = power_monitor_flags);
  1718. }
  1719. //
  1720. // LCD Contrast
  1721. //
  1722. {
  1723. _FIELD_TEST(lcd_contrast);
  1724. uint8_t lcd_contrast;
  1725. EEPROM_READ(lcd_contrast);
  1726. TERN_(HAS_LCD_CONTRAST, if (!validating) ui.set_contrast(lcd_contrast));
  1727. }
  1728. //
  1729. // LCD Brightness
  1730. //
  1731. {
  1732. uint8_t lcd_brightness;
  1733. EEPROM_READ(lcd_brightness);
  1734. TERN_(HAS_LCD_BRIGHTNESS, if (!validating) ui.set_brightness(lcd_brightness));
  1735. }
  1736. //
  1737. // Controller Fan
  1738. //
  1739. {
  1740. controllerFan_settings_t cfs = { 0 };
  1741. _FIELD_TEST(controllerFan_settings);
  1742. EEPROM_READ(cfs);
  1743. TERN_(CONTROLLER_FAN_EDITABLE, if (!validating) controllerFan.settings = cfs);
  1744. }
  1745. //
  1746. // Power-Loss Recovery
  1747. //
  1748. {
  1749. bool recovery_enabled;
  1750. _FIELD_TEST(recovery_enabled);
  1751. EEPROM_READ(recovery_enabled);
  1752. TERN_(POWER_LOSS_RECOVERY, if (!validating) recovery.enabled = recovery_enabled);
  1753. }
  1754. //
  1755. // Firmware Retraction
  1756. //
  1757. {
  1758. fwretract_settings_t fwretract_settings;
  1759. bool autoretract_enabled;
  1760. _FIELD_TEST(fwretract_settings);
  1761. EEPROM_READ(fwretract_settings);
  1762. EEPROM_READ(autoretract_enabled);
  1763. #if ENABLED(FWRETRACT)
  1764. if (!validating) {
  1765. fwretract.settings = fwretract_settings;
  1766. TERN_(FWRETRACT_AUTORETRACT, fwretract.autoretract_enabled = autoretract_enabled);
  1767. }
  1768. #endif
  1769. }
  1770. //
  1771. // Volumetric & Filament Size
  1772. //
  1773. {
  1774. struct {
  1775. bool volumetric_enabled;
  1776. float filament_size[EXTRUDERS];
  1777. float volumetric_extruder_limit[EXTRUDERS];
  1778. } storage;
  1779. _FIELD_TEST(parser_volumetric_enabled);
  1780. EEPROM_READ(storage);
  1781. #if DISABLED(NO_VOLUMETRICS)
  1782. if (!validating) {
  1783. parser.volumetric_enabled = storage.volumetric_enabled;
  1784. COPY(planner.filament_size, storage.filament_size);
  1785. #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
  1786. COPY(planner.volumetric_extruder_limit, storage.volumetric_extruder_limit);
  1787. #endif
  1788. }
  1789. #endif
  1790. }
  1791. //
  1792. // TMC Stepper Settings
  1793. //
  1794. if (!validating) reset_stepper_drivers();
  1795. // TMC Stepper Current
  1796. {
  1797. _FIELD_TEST(tmc_stepper_current);
  1798. tmc_stepper_current_t currents;
  1799. EEPROM_READ(currents);
  1800. #if HAS_TRINAMIC_CONFIG
  1801. #define SET_CURR(Q) stepper##Q.rms_current(currents.Q ? currents.Q : Q##_CURRENT)
  1802. if (!validating) {
  1803. #if AXIS_IS_TMC(X)
  1804. SET_CURR(X);
  1805. #endif
  1806. #if AXIS_IS_TMC(Y)
  1807. SET_CURR(Y);
  1808. #endif
  1809. #if AXIS_IS_TMC(Z)
  1810. SET_CURR(Z);
  1811. #endif
  1812. #if AXIS_IS_TMC(X2)
  1813. SET_CURR(X2);
  1814. #endif
  1815. #if AXIS_IS_TMC(Y2)
  1816. SET_CURR(Y2);
  1817. #endif
  1818. #if AXIS_IS_TMC(Z2)
  1819. SET_CURR(Z2);
  1820. #endif
  1821. #if AXIS_IS_TMC(Z3)
  1822. SET_CURR(Z3);
  1823. #endif
  1824. #if AXIS_IS_TMC(Z4)
  1825. SET_CURR(Z4);
  1826. #endif
  1827. #if AXIS_IS_TMC(I)
  1828. SET_CURR(I);
  1829. #endif
  1830. #if AXIS_IS_TMC(J)
  1831. SET_CURR(J);
  1832. #endif
  1833. #if AXIS_IS_TMC(K)
  1834. SET_CURR(K);
  1835. #endif
  1836. #if AXIS_IS_TMC(E0)
  1837. SET_CURR(E0);
  1838. #endif
  1839. #if AXIS_IS_TMC(E1)
  1840. SET_CURR(E1);
  1841. #endif
  1842. #if AXIS_IS_TMC(E2)
  1843. SET_CURR(E2);
  1844. #endif
  1845. #if AXIS_IS_TMC(E3)
  1846. SET_CURR(E3);
  1847. #endif
  1848. #if AXIS_IS_TMC(E4)
  1849. SET_CURR(E4);
  1850. #endif
  1851. #if AXIS_IS_TMC(E5)
  1852. SET_CURR(E5);
  1853. #endif
  1854. #if AXIS_IS_TMC(E6)
  1855. SET_CURR(E6);
  1856. #endif
  1857. #if AXIS_IS_TMC(E7)
  1858. SET_CURR(E7);
  1859. #endif
  1860. }
  1861. #endif
  1862. }
  1863. // TMC Hybrid Threshold
  1864. {
  1865. tmc_hybrid_threshold_t tmc_hybrid_threshold;
  1866. _FIELD_TEST(tmc_hybrid_threshold);
  1867. EEPROM_READ(tmc_hybrid_threshold);
  1868. #if ENABLED(HYBRID_THRESHOLD)
  1869. if (!validating) {
  1870. TERN_(X_HAS_STEALTHCHOP, stepperX.set_pwm_thrs(tmc_hybrid_threshold.X));
  1871. TERN_(Y_HAS_STEALTHCHOP, stepperY.set_pwm_thrs(tmc_hybrid_threshold.Y));
  1872. TERN_(Z_HAS_STEALTHCHOP, stepperZ.set_pwm_thrs(tmc_hybrid_threshold.Z));
  1873. TERN_(X2_HAS_STEALTHCHOP, stepperX2.set_pwm_thrs(tmc_hybrid_threshold.X2));
  1874. TERN_(Y2_HAS_STEALTHCHOP, stepperY2.set_pwm_thrs(tmc_hybrid_threshold.Y2));
  1875. TERN_(Z2_HAS_STEALTHCHOP, stepperZ2.set_pwm_thrs(tmc_hybrid_threshold.Z2));
  1876. TERN_(Z3_HAS_STEALTHCHOP, stepperZ3.set_pwm_thrs(tmc_hybrid_threshold.Z3));
  1877. TERN_(Z4_HAS_STEALTHCHOP, stepperZ4.set_pwm_thrs(tmc_hybrid_threshold.Z4));
  1878. TERN_(I_HAS_STEALTHCHOP, stepperI.set_pwm_thrs(tmc_hybrid_threshold.I));
  1879. TERN_(J_HAS_STEALTHCHOP, stepperJ.set_pwm_thrs(tmc_hybrid_threshold.J));
  1880. TERN_(K_HAS_STEALTHCHOP, stepperK.set_pwm_thrs(tmc_hybrid_threshold.K));
  1881. TERN_(E0_HAS_STEALTHCHOP, stepperE0.set_pwm_thrs(tmc_hybrid_threshold.E0));
  1882. TERN_(E1_HAS_STEALTHCHOP, stepperE1.set_pwm_thrs(tmc_hybrid_threshold.E1));
  1883. TERN_(E2_HAS_STEALTHCHOP, stepperE2.set_pwm_thrs(tmc_hybrid_threshold.E2));
  1884. TERN_(E3_HAS_STEALTHCHOP, stepperE3.set_pwm_thrs(tmc_hybrid_threshold.E3));
  1885. TERN_(E4_HAS_STEALTHCHOP, stepperE4.set_pwm_thrs(tmc_hybrid_threshold.E4));
  1886. TERN_(E5_HAS_STEALTHCHOP, stepperE5.set_pwm_thrs(tmc_hybrid_threshold.E5));
  1887. TERN_(E6_HAS_STEALTHCHOP, stepperE6.set_pwm_thrs(tmc_hybrid_threshold.E6));
  1888. TERN_(E7_HAS_STEALTHCHOP, stepperE7.set_pwm_thrs(tmc_hybrid_threshold.E7));
  1889. }
  1890. #endif
  1891. }
  1892. //
  1893. // TMC StallGuard threshold.
  1894. //
  1895. {
  1896. tmc_sgt_t tmc_sgt;
  1897. _FIELD_TEST(tmc_sgt);
  1898. EEPROM_READ(tmc_sgt);
  1899. #if USE_SENSORLESS
  1900. if (!validating) {
  1901. LINEAR_AXIS_CODE(
  1902. TERN_(X_SENSORLESS, stepperX.homing_threshold(tmc_sgt.X)),
  1903. TERN_(Y_SENSORLESS, stepperY.homing_threshold(tmc_sgt.Y)),
  1904. TERN_(Z_SENSORLESS, stepperZ.homing_threshold(tmc_sgt.Z)),
  1905. TERN_(I_SENSORLESS, stepperI.homing_threshold(tmc_sgt.I)),
  1906. TERN_(J_SENSORLESS, stepperJ.homing_threshold(tmc_sgt.J)),
  1907. TERN_(K_SENSORLESS, stepperK.homing_threshold(tmc_sgt.K))
  1908. );
  1909. TERN_(X2_SENSORLESS, stepperX2.homing_threshold(tmc_sgt.X2));
  1910. TERN_(Y2_SENSORLESS, stepperY2.homing_threshold(tmc_sgt.Y2));
  1911. TERN_(Z2_SENSORLESS, stepperZ2.homing_threshold(tmc_sgt.Z2));
  1912. TERN_(Z3_SENSORLESS, stepperZ3.homing_threshold(tmc_sgt.Z3));
  1913. TERN_(Z4_SENSORLESS, stepperZ4.homing_threshold(tmc_sgt.Z4));
  1914. }
  1915. #endif
  1916. }
  1917. // TMC stepping mode
  1918. {
  1919. _FIELD_TEST(tmc_stealth_enabled);
  1920. tmc_stealth_enabled_t tmc_stealth_enabled;
  1921. EEPROM_READ(tmc_stealth_enabled);
  1922. #if HAS_TRINAMIC_CONFIG
  1923. #define SET_STEPPING_MODE(ST) stepper##ST.stored.stealthChop_enabled = tmc_stealth_enabled.ST; stepper##ST.refresh_stepping_mode();
  1924. if (!validating) {
  1925. TERN_(X_HAS_STEALTHCHOP, SET_STEPPING_MODE(X));
  1926. TERN_(Y_HAS_STEALTHCHOP, SET_STEPPING_MODE(Y));
  1927. TERN_(Z_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z));
  1928. TERN_(I_HAS_STEALTHCHOP, SET_STEPPING_MODE(I));
  1929. TERN_(J_HAS_STEALTHCHOP, SET_STEPPING_MODE(J));
  1930. TERN_(K_HAS_STEALTHCHOP, SET_STEPPING_MODE(K));
  1931. TERN_(X2_HAS_STEALTHCHOP, SET_STEPPING_MODE(X2));
  1932. TERN_(Y2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Y2));
  1933. TERN_(Z2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z2));
  1934. TERN_(Z3_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z3));
  1935. TERN_(Z4_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z4));
  1936. TERN_(E0_HAS_STEALTHCHOP, SET_STEPPING_MODE(E0));
  1937. TERN_(E1_HAS_STEALTHCHOP, SET_STEPPING_MODE(E1));
  1938. TERN_(E2_HAS_STEALTHCHOP, SET_STEPPING_MODE(E2));
  1939. TERN_(E3_HAS_STEALTHCHOP, SET_STEPPING_MODE(E3));
  1940. TERN_(E4_HAS_STEALTHCHOP, SET_STEPPING_MODE(E4));
  1941. TERN_(E5_HAS_STEALTHCHOP, SET_STEPPING_MODE(E5));
  1942. TERN_(E6_HAS_STEALTHCHOP, SET_STEPPING_MODE(E6));
  1943. TERN_(E7_HAS_STEALTHCHOP, SET_STEPPING_MODE(E7));
  1944. }
  1945. #endif
  1946. }
  1947. //
  1948. // Linear Advance
  1949. //
  1950. {
  1951. float extruder_advance_K[_MAX(EXTRUDERS, 1)];
  1952. _FIELD_TEST(planner_extruder_advance_K);
  1953. EEPROM_READ(extruder_advance_K);
  1954. #if ENABLED(LIN_ADVANCE)
  1955. if (!validating)
  1956. COPY(planner.extruder_advance_K, extruder_advance_K);
  1957. #endif
  1958. }
  1959. //
  1960. // Motor Current PWM
  1961. //
  1962. {
  1963. _FIELD_TEST(motor_current_setting);
  1964. uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]
  1965. #if HAS_MOTOR_CURRENT_SPI
  1966. = DIGIPOT_MOTOR_CURRENT
  1967. #endif
  1968. ;
  1969. #if HAS_MOTOR_CURRENT_SPI
  1970. DEBUG_ECHO_MSG("DIGIPOTS Loading");
  1971. #endif
  1972. EEPROM_READ(motor_current_setting);
  1973. #if HAS_MOTOR_CURRENT_SPI
  1974. DEBUG_ECHO_MSG("DIGIPOTS Loaded");
  1975. #endif
  1976. #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
  1977. if (!validating)
  1978. COPY(stepper.motor_current_setting, motor_current_setting);
  1979. #endif
  1980. }
  1981. //
  1982. // CNC Coordinate System
  1983. //
  1984. {
  1985. _FIELD_TEST(coordinate_system);
  1986. #if ENABLED(CNC_COORDINATE_SYSTEMS)
  1987. if (!validating) (void)gcode.select_coordinate_system(-1); // Go back to machine space
  1988. EEPROM_READ(gcode.coordinate_system);
  1989. #else
  1990. xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS];
  1991. EEPROM_READ(coordinate_system);
  1992. #endif
  1993. }
  1994. //
  1995. // Skew correction factors
  1996. //
  1997. {
  1998. skew_factor_t skew_factor;
  1999. _FIELD_TEST(planner_skew_factor);
  2000. EEPROM_READ(skew_factor);
  2001. #if ENABLED(SKEW_CORRECTION_GCODE)
  2002. if (!validating) {
  2003. planner.skew_factor.xy = skew_factor.xy;
  2004. #if ENABLED(SKEW_CORRECTION_FOR_Z)
  2005. planner.skew_factor.xz = skew_factor.xz;
  2006. planner.skew_factor.yz = skew_factor.yz;
  2007. #endif
  2008. }
  2009. #endif
  2010. }
  2011. //
  2012. // Advanced Pause filament load & unload lengths
  2013. //
  2014. #if HAS_EXTRUDERS
  2015. {
  2016. #if DISABLED(ADVANCED_PAUSE_FEATURE)
  2017. fil_change_settings_t fc_settings[EXTRUDERS];
  2018. #endif
  2019. _FIELD_TEST(fc_settings);
  2020. EEPROM_READ(fc_settings);
  2021. }
  2022. #endif
  2023. //
  2024. // Tool-change settings
  2025. //
  2026. #if HAS_MULTI_EXTRUDER
  2027. _FIELD_TEST(toolchange_settings);
  2028. EEPROM_READ(toolchange_settings);
  2029. #endif
  2030. //
  2031. // Backlash Compensation
  2032. //
  2033. {
  2034. #if ENABLED(BACKLASH_GCODE)
  2035. const xyz_float_t &backlash_distance_mm = backlash.distance_mm;
  2036. const uint8_t &backlash_correction = backlash.correction;
  2037. #else
  2038. xyz_float_t backlash_distance_mm;
  2039. uint8_t backlash_correction;
  2040. #endif
  2041. #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
  2042. const float &backlash_smoothing_mm = backlash.smoothing_mm;
  2043. #else
  2044. float backlash_smoothing_mm;
  2045. #endif
  2046. _FIELD_TEST(backlash_distance_mm);
  2047. EEPROM_READ(backlash_distance_mm);
  2048. EEPROM_READ(backlash_correction);
  2049. EEPROM_READ(backlash_smoothing_mm);
  2050. }
  2051. //
  2052. // Extensible UI User Data
  2053. //
  2054. #if ENABLED(EXTENSIBLE_UI)
  2055. { // This is a significant hardware change; don't reserve EEPROM space when not present
  2056. const char extui_data[ExtUI::eeprom_data_size] = { 0 };
  2057. _FIELD_TEST(extui_data);
  2058. EEPROM_READ(extui_data);
  2059. if (!validating) ExtUI::onLoadSettings(extui_data);
  2060. }
  2061. #endif
  2062. //
  2063. // Creality DWIN User Data
  2064. //
  2065. #if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
  2066. {
  2067. const char dwin_data[eeprom_data_size] = { 0 };
  2068. _FIELD_TEST(dwin_data);
  2069. EEPROM_READ(dwin_data);
  2070. if (!validating) DWIN_LoadSettings(dwin_data);
  2071. }
  2072. #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
  2073. {
  2074. const char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 };
  2075. _FIELD_TEST(dwin_settings);
  2076. EEPROM_READ(dwin_settings);
  2077. if (!validating) CrealityDWIN.Load_Settings(dwin_settings);
  2078. }
  2079. #endif
  2080. //
  2081. // Case Light Brightness
  2082. //
  2083. #if CASELIGHT_USES_BRIGHTNESS
  2084. _FIELD_TEST(caselight_brightness);
  2085. EEPROM_READ(caselight.brightness);
  2086. #endif
  2087. //
  2088. // Password feature
  2089. //
  2090. #if ENABLED(PASSWORD_FEATURE)
  2091. _FIELD_TEST(password_is_set);
  2092. EEPROM_READ(password.is_set);
  2093. EEPROM_READ(password.value);
  2094. #endif
  2095. //
  2096. // TOUCH_SCREEN_CALIBRATION
  2097. //
  2098. #if ENABLED(TOUCH_SCREEN_CALIBRATION)
  2099. _FIELD_TEST(touch_calibration_data);
  2100. EEPROM_READ(touch_calibration.calibration);
  2101. #endif
  2102. //
  2103. // Ethernet network info
  2104. //
  2105. #if HAS_ETHERNET
  2106. _FIELD_TEST(ethernet_hardware_enabled);
  2107. uint32_t ethernet_ip, ethernet_dns, ethernet_gateway, ethernet_subnet;
  2108. EEPROM_READ(ethernet.hardware_enabled);
  2109. EEPROM_READ(ethernet_ip); ethernet.ip = ethernet_ip;
  2110. EEPROM_READ(ethernet_dns); ethernet.myDns = ethernet_dns;
  2111. EEPROM_READ(ethernet_gateway); ethernet.gateway = ethernet_gateway;
  2112. EEPROM_READ(ethernet_subnet); ethernet.subnet = ethernet_subnet;
  2113. #endif
  2114. //
  2115. // Buzzer enable/disable
  2116. //
  2117. #if ENABLED(SOUND_MENU_ITEM)
  2118. _FIELD_TEST(buzzer_enabled);
  2119. EEPROM_READ(ui.buzzer_enabled);
  2120. #endif
  2121. //
  2122. // Fan tachometer check
  2123. //
  2124. #if HAS_FANCHECK
  2125. _FIELD_TEST(fan_check_enabled);
  2126. EEPROM_READ(fan_check.enabled);
  2127. #endif
  2128. //
  2129. // MKS UI controller
  2130. //
  2131. #if ENABLED(DGUS_LCD_UI_MKS)
  2132. _FIELD_TEST(mks_language_index);
  2133. EEPROM_READ(mks_language_index);
  2134. EEPROM_READ(mks_corner_offsets);
  2135. EEPROM_READ(mks_park_pos);
  2136. EEPROM_READ(mks_min_extrusion_temp);
  2137. #endif
  2138. //
  2139. // Selected LCD language
  2140. //
  2141. #if HAS_MULTI_LANGUAGE
  2142. {
  2143. uint8_t ui_language;
  2144. EEPROM_READ(ui_language);
  2145. if (ui_language >= NUM_LANGUAGES) ui_language = 0;
  2146. ui.set_language(ui_language);
  2147. }
  2148. #endif
  2149. //
  2150. // Validate Final Size and CRC
  2151. //
  2152. eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
  2153. if (eeprom_error) {
  2154. DEBUG_ECHO_MSG("Index: ", eeprom_index - (EEPROM_OFFSET), " Size: ", datasize());
  2155. IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_index());
  2156. }
  2157. else if (working_crc != stored_crc) {
  2158. eeprom_error = true;
  2159. DEBUG_ERROR_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!");
  2160. TERN_(DWIN_CREALITY_LCD_ENHANCED, LCD_MESSAGE(MSG_ERR_EEPROM_CRC));
  2161. IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_crc());
  2162. }
  2163. else if (!validating) {
  2164. DEBUG_ECHO_START();
  2165. DEBUG_ECHO(version);
  2166. DEBUG_ECHOLNPGM(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET), " bytes; crc ", (uint32_t)working_crc, ")");
  2167. }
  2168. if (!validating && !eeprom_error) postprocess();
  2169. #if ENABLED(AUTO_BED_LEVELING_UBL)
  2170. if (!validating) {
  2171. ubl.report_state();
  2172. if (!ubl.sanity_check()) {
  2173. #if BOTH(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE)
  2174. ubl.echo_name();
  2175. DEBUG_ECHOLNPGM(" initialized.\n");
  2176. #endif
  2177. }
  2178. else {
  2179. eeprom_error = true;
  2180. #if BOTH(EEPROM_CHITCHAT, DEBUG_LEVELING_FEATURE)
  2181. DEBUG_ECHOPGM("?Can't enable ");
  2182. ubl.echo_name();
  2183. DEBUG_ECHOLNPGM(".");
  2184. #endif
  2185. ubl.reset();
  2186. }
  2187. if (ubl.storage_slot >= 0) {
  2188. load_mesh(ubl.storage_slot);
  2189. DEBUG_ECHOLNPGM("Mesh ", ubl.storage_slot, " loaded from storage.");
  2190. }
  2191. else {
  2192. ubl.reset();
  2193. DEBUG_ECHOLNPGM("UBL reset");
  2194. }
  2195. }
  2196. #endif
  2197. }
  2198. #if ENABLED(EEPROM_CHITCHAT) && DISABLED(DISABLE_M503)
  2199. // Report the EEPROM settings
  2200. if (!validating && TERN1(EEPROM_BOOT_SILENT, IsRunning())) report();
  2201. #endif
  2202. EEPROM_FINISH();
  2203. return !eeprom_error;
  2204. }
  2205. #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
  2206. extern bool restoreEEPROM();
  2207. #endif
  2208. bool MarlinSettings::validate() {
  2209. validating = true;
  2210. #ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
  2211. bool success = _load();
  2212. if (!success && restoreEEPROM()) {
  2213. SERIAL_ECHOLNPGM("Recovered backup EEPROM settings from SPI Flash");
  2214. success = _load();
  2215. }
  2216. #else
  2217. const bool success = _load();
  2218. #endif
  2219. validating = false;
  2220. return success;
  2221. }
  2222. bool MarlinSettings::load() {
  2223. if (validate()) {
  2224. const bool success = _load();
  2225. TERN_(EXTENSIBLE_UI, ExtUI::onConfigurationStoreRead(success));
  2226. return success;
  2227. }
  2228. reset();
  2229. #if EITHER(EEPROM_AUTO_INIT, EEPROM_INIT_NOW)
  2230. (void)save();
  2231. SERIAL_ECHO_MSG("EEPROM Initialized");
  2232. #endif
  2233. return false;
  2234. }
  2235. #if ENABLED(AUTO_BED_LEVELING_UBL)
  2236. inline void ubl_invalid_slot(const int s) {
  2237. DEBUG_ECHOLNPGM("?Invalid slot.\n", s, " mesh slots available.");
  2238. UNUSED(s);
  2239. }
  2240. // 128 (+1 because of the change to capacity rather than last valid address)
  2241. // is a placeholder for the size of the MAT; the MAT will always
  2242. // live at the very end of the eeprom
  2243. const uint16_t MarlinSettings::meshes_end = persistentStore.capacity() - 129;
  2244. uint16_t MarlinSettings::meshes_start_index() {
  2245. // Pad the end of configuration data so it can float up
  2246. // or down a little bit without disrupting the mesh data
  2247. return (datasize() + EEPROM_OFFSET + 32) & 0xFFF8;
  2248. }
  2249. #define MESH_STORE_SIZE sizeof(TERN(OPTIMIZED_MESH_STORAGE, mesh_store_t, ubl.z_values))
  2250. uint16_t MarlinSettings::calc_num_meshes() {
  2251. return (meshes_end - meshes_start_index()) / MESH_STORE_SIZE;
  2252. }
  2253. int MarlinSettings::mesh_slot_offset(const int8_t slot) {
  2254. return meshes_end - (slot + 1) * MESH_STORE_SIZE;
  2255. }
  2256. void MarlinSettings::store_mesh(const int8_t slot) {
  2257. #if ENABLED(AUTO_BED_LEVELING_UBL)
  2258. const int16_t a = calc_num_meshes();
  2259. if (!WITHIN(slot, 0, a - 1)) {
  2260. ubl_invalid_slot(a);
  2261. DEBUG_ECHOLNPGM("E2END=", persistentStore.capacity() - 1, " meshes_end=", meshes_end, " slot=", slot);
  2262. DEBUG_EOL();
  2263. return;
  2264. }
  2265. int pos = mesh_slot_offset(slot);
  2266. uint16_t crc = 0;
  2267. #if ENABLED(OPTIMIZED_MESH_STORAGE)
  2268. int16_t z_mesh_store[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
  2269. ubl.set_store_from_mesh(ubl.z_values, z_mesh_store);
  2270. uint8_t * const src = (uint8_t*)&z_mesh_store;
  2271. #else
  2272. uint8_t * const src = (uint8_t*)&ubl.z_values;
  2273. #endif
  2274. // Write crc to MAT along with other data, or just tack on to the beginning or end
  2275. persistentStore.access_start();
  2276. const bool status = persistentStore.write_data(pos, src, MESH_STORE_SIZE, &crc);
  2277. persistentStore.access_finish();
  2278. if (status) SERIAL_ECHOLNPGM("?Unable to save mesh data.");
  2279. else DEBUG_ECHOLNPGM("Mesh saved in slot ", slot);
  2280. #else
  2281. // Other mesh types
  2282. #endif
  2283. }
  2284. void MarlinSettings::load_mesh(const int8_t slot, void * const into/*=nullptr*/) {
  2285. #if ENABLED(AUTO_BED_LEVELING_UBL)
  2286. const int16_t a = settings.calc_num_meshes();
  2287. if (!WITHIN(slot, 0, a - 1)) {
  2288. ubl_invalid_slot(a);
  2289. return;
  2290. }
  2291. int pos = mesh_slot_offset(slot);
  2292. uint16_t crc = 0;
  2293. #if ENABLED(OPTIMIZED_MESH_STORAGE)
  2294. int16_t z_mesh_store[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
  2295. uint8_t * const dest = (uint8_t*)&z_mesh_store;
  2296. #else
  2297. uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values;
  2298. #endif
  2299. persistentStore.access_start();
  2300. const uint16_t status = persistentStore.read_data(pos, dest, MESH_STORE_SIZE, &crc);
  2301. persistentStore.access_finish();
  2302. #if ENABLED(OPTIMIZED_MESH_STORAGE)
  2303. if (into) {
  2304. float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
  2305. ubl.set_mesh_from_store(z_mesh_store, z_values);
  2306. memcpy(into, z_values, sizeof(z_values));
  2307. }
  2308. else
  2309. ubl.set_mesh_from_store(z_mesh_store, ubl.z_values);
  2310. #endif
  2311. if (status) SERIAL_ECHOLNPGM("?Unable to load mesh data.");
  2312. else DEBUG_ECHOLNPGM("Mesh loaded from slot ", slot);
  2313. EEPROM_FINISH();
  2314. #else
  2315. // Other mesh types
  2316. #endif
  2317. }
  2318. //void MarlinSettings::delete_mesh() { return; }
  2319. //void MarlinSettings::defrag_meshes() { return; }
  2320. #endif // AUTO_BED_LEVELING_UBL
  2321. #else // !EEPROM_SETTINGS
  2322. bool MarlinSettings::save() {
  2323. DEBUG_ERROR_MSG("EEPROM disabled");
  2324. return false;
  2325. }
  2326. #endif // !EEPROM_SETTINGS
  2327. /**
  2328. * M502 - Reset Configuration
  2329. */
  2330. void MarlinSettings::reset() {
  2331. LOOP_DISTINCT_AXES(i) {
  2332. planner.settings.max_acceleration_mm_per_s2[i] = pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
  2333. planner.settings.axis_steps_per_mm[i] = pgm_read_float(&_DASU[ALIM(i, _DASU)]);
  2334. planner.settings.max_feedrate_mm_s[i] = pgm_read_float(&_DMF[ALIM(i, _DMF)]);
  2335. }
  2336. planner.settings.min_segment_time_us = DEFAULT_MINSEGMENTTIME;
  2337. planner.settings.acceleration = DEFAULT_ACCELERATION;
  2338. planner.settings.retract_acceleration = DEFAULT_RETRACT_ACCELERATION;
  2339. planner.settings.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION;
  2340. planner.settings.min_feedrate_mm_s = feedRate_t(DEFAULT_MINIMUMFEEDRATE);
  2341. planner.settings.min_travel_feedrate_mm_s = feedRate_t(DEFAULT_MINTRAVELFEEDRATE);
  2342. #if HAS_CLASSIC_JERK
  2343. #ifndef DEFAULT_XJERK
  2344. #define DEFAULT_XJERK 0
  2345. #endif
  2346. #if HAS_Y_AXIS && !defined(DEFAULT_YJERK)
  2347. #define DEFAULT_YJERK 0
  2348. #endif
  2349. #if HAS_Z_AXIS && !defined(DEFAULT_ZJERK)
  2350. #define DEFAULT_ZJERK 0
  2351. #endif
  2352. #if HAS_I_AXIS && !defined(DEFAULT_IJERK)
  2353. #define DEFAULT_IJERK 0
  2354. #endif
  2355. #if HAS_J_AXIS && !defined(DEFAULT_JJERK)
  2356. #define DEFAULT_JJERK 0
  2357. #endif
  2358. #if HAS_K_AXIS && !defined(DEFAULT_KJERK)
  2359. #define DEFAULT_KJERK 0
  2360. #endif
  2361. planner.max_jerk.set(
  2362. LINEAR_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_IJERK, DEFAULT_JJERK, DEFAULT_KJERK)
  2363. );
  2364. TERN_(HAS_CLASSIC_E_JERK, planner.max_jerk.e = DEFAULT_EJERK);
  2365. #endif
  2366. TERN_(HAS_JUNCTION_DEVIATION, planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM));
  2367. #if HAS_SCARA_OFFSET
  2368. scara_home_offset.reset();
  2369. #elif HAS_HOME_OFFSET
  2370. home_offset.reset();
  2371. #endif
  2372. TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets());
  2373. //
  2374. // Filament Runout Sensor
  2375. //
  2376. #if HAS_FILAMENT_SENSOR
  2377. runout.enabled = FIL_RUNOUT_ENABLED_DEFAULT;
  2378. runout.reset();
  2379. TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM));
  2380. #endif
  2381. //
  2382. // Tool-change Settings
  2383. //
  2384. #if HAS_MULTI_EXTRUDER
  2385. #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
  2386. toolchange_settings.swap_length = TOOLCHANGE_FS_LENGTH;
  2387. toolchange_settings.extra_resume = TOOLCHANGE_FS_EXTRA_RESUME_LENGTH;
  2388. toolchange_settings.retract_speed = TOOLCHANGE_FS_RETRACT_SPEED;
  2389. toolchange_settings.unretract_speed = TOOLCHANGE_FS_UNRETRACT_SPEED;
  2390. toolchange_settings.extra_prime = TOOLCHANGE_FS_EXTRA_PRIME;
  2391. toolchange_settings.prime_speed = TOOLCHANGE_FS_PRIME_SPEED;
  2392. toolchange_settings.fan_speed = TOOLCHANGE_FS_FAN_SPEED;
  2393. toolchange_settings.fan_time = TOOLCHANGE_FS_FAN_TIME;
  2394. #endif
  2395. #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
  2396. enable_first_prime = false;
  2397. #endif
  2398. #if ENABLED(TOOLCHANGE_PARK)
  2399. constexpr xyz_pos_t tpxy = TOOLCHANGE_PARK_XY;
  2400. toolchange_settings.enable_park = true;
  2401. toolchange_settings.change_point = tpxy;
  2402. #endif
  2403. toolchange_settings.z_raise = TOOLCHANGE_ZRAISE;
  2404. #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
  2405. migration = migration_defaults;
  2406. #endif
  2407. #endif
  2408. #if ENABLED(BACKLASH_GCODE)
  2409. backlash.correction = (BACKLASH_CORRECTION) * 255;
  2410. constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
  2411. backlash.distance_mm = tmp;
  2412. #ifdef BACKLASH_SMOOTHING_MM
  2413. backlash.smoothing_mm = BACKLASH_SMOOTHING_MM;
  2414. #endif
  2415. #endif
  2416. TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset());
  2417. TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_SetDataDefaults());
  2418. TERN_(DWIN_CREALITY_LCD_JYERSUI, CrealityDWIN.Reset_Settings());
  2419. //
  2420. // Case Light Brightness
  2421. //
  2422. TERN_(CASELIGHT_USES_BRIGHTNESS, caselight.brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS);
  2423. //
  2424. // TOUCH_SCREEN_CALIBRATION
  2425. //
  2426. TERN_(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration_reset());
  2427. //
  2428. // Buzzer enable/disable
  2429. //
  2430. TERN_(SOUND_MENU_ITEM, ui.buzzer_enabled = true);
  2431. //
  2432. // Magnetic Parking Extruder
  2433. //
  2434. TERN_(MAGNETIC_PARKING_EXTRUDER, mpe_settings_init());
  2435. //
  2436. // Global Leveling
  2437. //
  2438. TERN_(ENABLE_LEVELING_FADE_HEIGHT, new_z_fade_height = (DEFAULT_LEVELING_FADE_HEIGHT));
  2439. TERN_(HAS_LEVELING, reset_bed_level());
  2440. #if HAS_BED_PROBE
  2441. constexpr float dpo[] = NOZZLE_TO_PROBE_OFFSET;
  2442. static_assert(COUNT(dpo) == LINEAR_AXES, "NOZZLE_TO_PROBE_OFFSET must contain offsets for each linear axis X, Y, Z....");
  2443. #if HAS_PROBE_XY_OFFSET
  2444. LOOP_LINEAR_AXES(a) probe.offset[a] = dpo[a];
  2445. #else
  2446. probe.offset.set(LINEAR_AXIS_LIST(0, 0, dpo[Z_AXIS], 0, 0, 0));
  2447. #endif
  2448. #endif
  2449. //
  2450. // Z Stepper Auto-alignment points
  2451. //
  2452. TERN_(Z_STEPPER_AUTO_ALIGN, z_stepper_align.reset_to_default());
  2453. //
  2454. // Servo Angles
  2455. //
  2456. TERN_(EDITABLE_SERVO_ANGLES, COPY(servo_angles, base_servo_angles)); // When not editable only one copy of servo angles exists
  2457. //
  2458. // Probe Temperature Compensation
  2459. //
  2460. TERN_(HAS_PTC, ptc.reset());
  2461. //
  2462. // BLTouch
  2463. //
  2464. #ifdef BLTOUCH_HS_MODE
  2465. bltouch.high_speed_mode = ENABLED(BLTOUCH_HS_MODE);
  2466. #endif
  2467. //
  2468. // Kinematic settings
  2469. //
  2470. #if IS_KINEMATIC
  2471. segments_per_second = (
  2472. TERN_(DELTA, DELTA_SEGMENTS_PER_SECOND)
  2473. TERN_(IS_SCARA, SCARA_SEGMENTS_PER_SECOND)
  2474. TERN_(POLARGRAPH, POLAR_SEGMENTS_PER_SECOND)
  2475. );
  2476. #if ENABLED(DELTA)
  2477. const abc_float_t adj = DELTA_ENDSTOP_ADJ, dta = DELTA_TOWER_ANGLE_TRIM, ddr = DELTA_DIAGONAL_ROD_TRIM_TOWER;
  2478. delta_height = DELTA_HEIGHT;
  2479. delta_endstop_adj = adj;
  2480. delta_radius = DELTA_RADIUS;
  2481. delta_diagonal_rod = DELTA_DIAGONAL_ROD;
  2482. delta_tower_angle_trim = dta;
  2483. delta_diagonal_rod_trim = ddr;
  2484. #endif
  2485. #endif
  2486. //
  2487. // Endstop Adjustments
  2488. //
  2489. #if ENABLED(X_DUAL_ENDSTOPS)
  2490. #ifndef X2_ENDSTOP_ADJUSTMENT
  2491. #define X2_ENDSTOP_ADJUSTMENT 0
  2492. #endif
  2493. endstops.x2_endstop_adj = X2_ENDSTOP_ADJUSTMENT;
  2494. #endif
  2495. #if ENABLED(Y_DUAL_ENDSTOPS)
  2496. #ifndef Y2_ENDSTOP_ADJUSTMENT
  2497. #define Y2_ENDSTOP_ADJUSTMENT 0
  2498. #endif
  2499. endstops.y2_endstop_adj = Y2_ENDSTOP_ADJUSTMENT;
  2500. #endif
  2501. #if ENABLED(Z_MULTI_ENDSTOPS)
  2502. #ifndef Z2_ENDSTOP_ADJUSTMENT
  2503. #define Z2_ENDSTOP_ADJUSTMENT 0
  2504. #endif
  2505. endstops.z2_endstop_adj = Z2_ENDSTOP_ADJUSTMENT;
  2506. #if NUM_Z_STEPPER_DRIVERS >= 3
  2507. #ifndef Z3_ENDSTOP_ADJUSTMENT
  2508. #define Z3_ENDSTOP_ADJUSTMENT 0
  2509. #endif
  2510. endstops.z3_endstop_adj = Z3_ENDSTOP_ADJUSTMENT;
  2511. #endif
  2512. #if NUM_Z_STEPPER_DRIVERS >= 4
  2513. #ifndef Z4_ENDSTOP_ADJUSTMENT
  2514. #define Z4_ENDSTOP_ADJUSTMENT 0
  2515. #endif
  2516. endstops.z4_endstop_adj = Z4_ENDSTOP_ADJUSTMENT;
  2517. #endif
  2518. #endif
  2519. //
  2520. // Preheat parameters
  2521. //
  2522. #if HAS_PREHEAT
  2523. #define _PITEM(N,T) PREHEAT_##N##_##T,
  2524. #if HAS_HOTEND
  2525. constexpr uint16_t hpre[] = { REPEAT2_S(1, INCREMENT(PREHEAT_COUNT), _PITEM, TEMP_HOTEND) };
  2526. #endif
  2527. #if HAS_HEATED_BED
  2528. constexpr uint16_t bpre[] = { REPEAT2_S(1, INCREMENT(PREHEAT_COUNT), _PITEM, TEMP_BED) };
  2529. #endif
  2530. #if HAS_FAN
  2531. constexpr uint8_t fpre[] = { REPEAT2_S(1, INCREMENT(PREHEAT_COUNT), _PITEM, FAN_SPEED) };
  2532. #endif
  2533. LOOP_L_N(i, PREHEAT_COUNT) {
  2534. TERN_(HAS_HOTEND, ui.material_preset[i].hotend_temp = hpre[i]);
  2535. TERN_(HAS_HEATED_BED, ui.material_preset[i].bed_temp = bpre[i]);
  2536. TERN_(HAS_FAN, ui.material_preset[i].fan_speed = fpre[i]);
  2537. }
  2538. #endif
  2539. //
  2540. // Hotend PID
  2541. //
  2542. #if ENABLED(PIDTEMP)
  2543. #if ENABLED(PID_PARAMS_PER_HOTEND)
  2544. constexpr float defKp[] =
  2545. #ifdef DEFAULT_Kp_LIST
  2546. DEFAULT_Kp_LIST
  2547. #else
  2548. ARRAY_BY_HOTENDS1(DEFAULT_Kp)
  2549. #endif
  2550. , defKi[] =
  2551. #ifdef DEFAULT_Ki_LIST
  2552. DEFAULT_Ki_LIST
  2553. #else
  2554. ARRAY_BY_HOTENDS1(DEFAULT_Ki)
  2555. #endif
  2556. , defKd[] =
  2557. #ifdef DEFAULT_Kd_LIST
  2558. DEFAULT_Kd_LIST
  2559. #else
  2560. ARRAY_BY_HOTENDS1(DEFAULT_Kd)
  2561. #endif
  2562. ;
  2563. static_assert(WITHIN(COUNT(defKp), 1, HOTENDS), "DEFAULT_Kp_LIST must have between 1 and HOTENDS items.");
  2564. static_assert(WITHIN(COUNT(defKi), 1, HOTENDS), "DEFAULT_Ki_LIST must have between 1 and HOTENDS items.");
  2565. static_assert(WITHIN(COUNT(defKd), 1, HOTENDS), "DEFAULT_Kd_LIST must have between 1 and HOTENDS items.");
  2566. #if ENABLED(PID_EXTRUSION_SCALING)
  2567. constexpr float defKc[] =
  2568. #ifdef DEFAULT_Kc_LIST
  2569. DEFAULT_Kc_LIST
  2570. #else
  2571. ARRAY_BY_HOTENDS1(DEFAULT_Kc)
  2572. #endif
  2573. ;
  2574. static_assert(WITHIN(COUNT(defKc), 1, HOTENDS), "DEFAULT_Kc_LIST must have between 1 and HOTENDS items.");
  2575. #endif
  2576. #if ENABLED(PID_FAN_SCALING)
  2577. constexpr float defKf[] =
  2578. #ifdef DEFAULT_Kf_LIST
  2579. DEFAULT_Kf_LIST
  2580. #else
  2581. ARRAY_BY_HOTENDS1(DEFAULT_Kf)
  2582. #endif
  2583. ;
  2584. static_assert(WITHIN(COUNT(defKf), 1, HOTENDS), "DEFAULT_Kf_LIST must have between 1 and HOTENDS items.");
  2585. #endif
  2586. #define PID_DEFAULT(N,E) def##N[E]
  2587. #else
  2588. #define PID_DEFAULT(N,E) DEFAULT_##N
  2589. #endif
  2590. HOTEND_LOOP() {
  2591. PID_PARAM(Kp, e) = float(PID_DEFAULT(Kp, ALIM(e, defKp)));
  2592. PID_PARAM(Ki, e) = scalePID_i(PID_DEFAULT(Ki, ALIM(e, defKi)));
  2593. PID_PARAM(Kd, e) = scalePID_d(PID_DEFAULT(Kd, ALIM(e, defKd)));
  2594. TERN_(PID_EXTRUSION_SCALING, PID_PARAM(Kc, e) = float(PID_DEFAULT(Kc, ALIM(e, defKc))));
  2595. TERN_(PID_FAN_SCALING, PID_PARAM(Kf, e) = float(PID_DEFAULT(Kf, ALIM(e, defKf))));
  2596. }
  2597. #endif
  2598. //
  2599. // PID Extrusion Scaling
  2600. //
  2601. TERN_(PID_EXTRUSION_SCALING, thermalManager.lpq_len = 20); // Default last-position-queue size
  2602. //
  2603. // Heated Bed PID
  2604. //
  2605. #if ENABLED(PIDTEMPBED)
  2606. thermalManager.temp_bed.pid.Kp = DEFAULT_bedKp;
  2607. thermalManager.temp_bed.pid.Ki = scalePID_i(DEFAULT_bedKi);
  2608. thermalManager.temp_bed.pid.Kd = scalePID_d(DEFAULT_bedKd);
  2609. #endif
  2610. //
  2611. // Heated Chamber PID
  2612. //
  2613. #if ENABLED(PIDTEMPCHAMBER)
  2614. thermalManager.temp_chamber.pid.Kp = DEFAULT_chamberKp;
  2615. thermalManager.temp_chamber.pid.Ki = scalePID_i(DEFAULT_chamberKi);
  2616. thermalManager.temp_chamber.pid.Kd = scalePID_d(DEFAULT_chamberKd);
  2617. #endif
  2618. //
  2619. // User-Defined Thermistors
  2620. //
  2621. TERN_(HAS_USER_THERMISTORS, thermalManager.reset_user_thermistors());
  2622. //
  2623. // Power Monitor
  2624. //
  2625. TERN_(POWER_MONITOR, power_monitor.reset());
  2626. //
  2627. // LCD Contrast
  2628. //
  2629. TERN_(HAS_LCD_CONTRAST, ui.set_contrast(DEFAULT_LCD_CONTRAST));
  2630. //
  2631. // LCD Brightness
  2632. //
  2633. TERN_(HAS_LCD_BRIGHTNESS, ui.set_brightness(DEFAULT_LCD_BRIGHTNESS));
  2634. //
  2635. // Controller Fan
  2636. //
  2637. TERN_(USE_CONTROLLER_FAN, controllerFan.reset());
  2638. //
  2639. // Power-Loss Recovery
  2640. //
  2641. TERN_(POWER_LOSS_RECOVERY, recovery.enable(ENABLED(PLR_ENABLED_DEFAULT)));
  2642. //
  2643. // Firmware Retraction
  2644. //
  2645. TERN_(FWRETRACT, fwretract.reset());
  2646. //
  2647. // Volumetric & Filament Size
  2648. //
  2649. #if DISABLED(NO_VOLUMETRICS)
  2650. parser.volumetric_enabled = ENABLED(VOLUMETRIC_DEFAULT_ON);
  2651. LOOP_L_N(q, COUNT(planner.filament_size))
  2652. planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA;
  2653. #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
  2654. LOOP_L_N(q, COUNT(planner.volumetric_extruder_limit))
  2655. planner.volumetric_extruder_limit[q] = DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT;
  2656. #endif
  2657. #endif
  2658. endstops.enable_globally(ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT));
  2659. reset_stepper_drivers();
  2660. //
  2661. // Linear Advance
  2662. //
  2663. #if ENABLED(LIN_ADVANCE)
  2664. LOOP_L_N(i, EXTRUDERS) {
  2665. planner.extruder_advance_K[i] = LIN_ADVANCE_K;
  2666. TERN_(EXTRA_LIN_ADVANCE_K, other_extruder_advance_K[i] = LIN_ADVANCE_K);
  2667. }
  2668. #endif
  2669. //
  2670. // Motor Current PWM
  2671. //
  2672. #if HAS_MOTOR_CURRENT_PWM
  2673. constexpr uint32_t tmp_motor_current_setting[MOTOR_CURRENT_COUNT] = PWM_MOTOR_CURRENT;
  2674. LOOP_L_N(q, MOTOR_CURRENT_COUNT)
  2675. stepper.set_digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q]));
  2676. #endif
  2677. //
  2678. // DIGIPOTS
  2679. //
  2680. #if HAS_MOTOR_CURRENT_SPI
  2681. static constexpr uint32_t tmp_motor_current_setting[] = DIGIPOT_MOTOR_CURRENT;
  2682. DEBUG_ECHOLNPGM("Writing Digipot");
  2683. LOOP_L_N(q, COUNT(tmp_motor_current_setting))
  2684. stepper.set_digipot_current(q, tmp_motor_current_setting[q]);
  2685. DEBUG_ECHOLNPGM("Digipot Written");
  2686. #endif
  2687. //
  2688. // CNC Coordinate System
  2689. //
  2690. TERN_(CNC_COORDINATE_SYSTEMS, (void)gcode.select_coordinate_system(-1)); // Go back to machine space
  2691. //
  2692. // Skew Correction
  2693. //
  2694. #if ENABLED(SKEW_CORRECTION_GCODE)
  2695. planner.skew_factor.xy = XY_SKEW_FACTOR;
  2696. #if ENABLED(SKEW_CORRECTION_FOR_Z)
  2697. planner.skew_factor.xz = XZ_SKEW_FACTOR;
  2698. planner.skew_factor.yz = YZ_SKEW_FACTOR;
  2699. #endif
  2700. #endif
  2701. //
  2702. // Advanced Pause filament load & unload lengths
  2703. //
  2704. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  2705. LOOP_L_N(e, EXTRUDERS) {
  2706. fc_settings[e].unload_length = FILAMENT_CHANGE_UNLOAD_LENGTH;
  2707. fc_settings[e].load_length = FILAMENT_CHANGE_FAST_LOAD_LENGTH;
  2708. }
  2709. #endif
  2710. #if ENABLED(PASSWORD_FEATURE)
  2711. #ifdef PASSWORD_DEFAULT_VALUE
  2712. password.is_set = true;
  2713. password.value = PASSWORD_DEFAULT_VALUE;
  2714. #else
  2715. password.is_set = false;
  2716. #endif
  2717. #endif
  2718. //
  2719. // Fan tachometer check
  2720. //
  2721. TERN_(HAS_FANCHECK, fan_check.enabled = true);
  2722. //
  2723. // MKS UI controller
  2724. //
  2725. TERN_(DGUS_LCD_UI_MKS, MKS_reset_settings());
  2726. postprocess();
  2727. DEBUG_ECHO_MSG("Hardcoded Default Settings Loaded");
  2728. }
  2729. #if DISABLED(DISABLE_M503)
  2730. #define CONFIG_ECHO_START() gcode.report_echo_start(forReplay)
  2731. #define CONFIG_ECHO_MSG(V...) do{ CONFIG_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0)
  2732. #define CONFIG_ECHO_MSG_P(V...) do{ CONFIG_ECHO_START(); SERIAL_ECHOLNPGM_P(V); }while(0)
  2733. #define CONFIG_ECHO_HEADING(STR) gcode.report_heading(forReplay, F(STR))
  2734. void M92_report(const bool echo=true, const int8_t e=-1);
  2735. /**
  2736. * M503 - Report current settings in RAM
  2737. *
  2738. * Unless specifically disabled, M503 is available even without EEPROM
  2739. */
  2740. void MarlinSettings::report(const bool forReplay) {
  2741. //
  2742. // Announce current units, in case inches are being displayed
  2743. //
  2744. CONFIG_ECHO_HEADING("Linear Units");
  2745. CONFIG_ECHO_START();
  2746. #if ENABLED(INCH_MODE_SUPPORT)
  2747. SERIAL_ECHOPGM(" G2", AS_DIGIT(parser.linear_unit_factor == 1.0), " ;");
  2748. #else
  2749. SERIAL_ECHOPGM(" G21 ;");
  2750. #endif
  2751. gcode.say_units(); // " (in/mm)"
  2752. //
  2753. // M149 Temperature units
  2754. //
  2755. #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
  2756. gcode.M149_report(forReplay);
  2757. #else
  2758. CONFIG_ECHO_HEADING(STR_TEMPERATURE_UNITS);
  2759. CONFIG_ECHO_MSG(" M149 C ; Units in Celsius");
  2760. #endif
  2761. //
  2762. // M200 Volumetric Extrusion
  2763. //
  2764. IF_DISABLED(NO_VOLUMETRICS, gcode.M200_report(forReplay));
  2765. //
  2766. // M92 Steps per Unit
  2767. //
  2768. gcode.M92_report(forReplay);
  2769. //
  2770. // M203 Maximum feedrates (units/s)
  2771. //
  2772. gcode.M203_report(forReplay);
  2773. //
  2774. // M201 Maximum Acceleration (units/s2)
  2775. //
  2776. gcode.M201_report(forReplay);
  2777. //
  2778. // M204 Acceleration (units/s2)
  2779. //
  2780. gcode.M204_report(forReplay);
  2781. //
  2782. // M205 "Advanced" Settings
  2783. //
  2784. gcode.M205_report(forReplay);
  2785. //
  2786. // M206 Home Offset
  2787. //
  2788. TERN_(HAS_M206_COMMAND, gcode.M206_report(forReplay));
  2789. //
  2790. // M218 Hotend offsets
  2791. //
  2792. TERN_(HAS_HOTEND_OFFSET, gcode.M218_report(forReplay));
  2793. //
  2794. // Bed Leveling
  2795. //
  2796. #if HAS_LEVELING
  2797. gcode.M420_report(forReplay);
  2798. #if ENABLED(MESH_BED_LEVELING)
  2799. if (leveling_is_valid()) {
  2800. LOOP_L_N(py, GRID_MAX_POINTS_Y) {
  2801. LOOP_L_N(px, GRID_MAX_POINTS_X) {
  2802. CONFIG_ECHO_START();
  2803. SERIAL_ECHOPGM(" G29 S3 I", px, " J", py);
  2804. SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(mbl.z_values[px][py]), 5);
  2805. }
  2806. }
  2807. CONFIG_ECHO_START();
  2808. SERIAL_ECHOLNPAIR_F(" G29 S4 Z", LINEAR_UNIT(mbl.z_offset), 5);
  2809. }
  2810. #elif ENABLED(AUTO_BED_LEVELING_UBL)
  2811. if (!forReplay) {
  2812. SERIAL_EOL();
  2813. ubl.report_state();
  2814. SERIAL_ECHO_MSG("Active Mesh Slot ", ubl.storage_slot);
  2815. SERIAL_ECHO_MSG("EEPROM can hold ", calc_num_meshes(), " meshes.\n");
  2816. }
  2817. //ubl.report_current_mesh(); // This is too verbose for large meshes. A better (more terse)
  2818. // solution needs to be found.
  2819. #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
  2820. if (leveling_is_valid()) {
  2821. LOOP_L_N(py, GRID_MAX_POINTS_Y) {
  2822. LOOP_L_N(px, GRID_MAX_POINTS_X) {
  2823. CONFIG_ECHO_START();
  2824. SERIAL_ECHOPGM(" G29 W I", px, " J", py);
  2825. SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(z_values[px][py]), 5);
  2826. }
  2827. }
  2828. }
  2829. // TODO: Create G-code for settings
  2830. //#if ENABLED(X_AXIS_TWIST_COMPENSATION)
  2831. // CONFIG_ECHO_START();
  2832. // xatc.print_points();
  2833. //#endif
  2834. #endif
  2835. #endif // HAS_LEVELING
  2836. //
  2837. // Editable Servo Angles
  2838. //
  2839. TERN_(EDITABLE_SERVO_ANGLES, gcode.M281_report(forReplay));
  2840. //
  2841. // Kinematic Settings
  2842. //
  2843. TERN_(IS_KINEMATIC, gcode.M665_report(forReplay));
  2844. //
  2845. // M666 Endstops Adjustment
  2846. //
  2847. #if EITHER(DELTA, HAS_EXTRA_ENDSTOPS)
  2848. gcode.M666_report(forReplay);
  2849. #endif
  2850. //
  2851. // Z Auto-Align
  2852. //
  2853. TERN_(Z_STEPPER_AUTO_ALIGN, gcode.M422_report(forReplay));
  2854. //
  2855. // LCD Preheat Settings
  2856. //
  2857. #if HAS_PREHEAT
  2858. gcode.M145_report(forReplay);
  2859. #endif
  2860. //
  2861. // PID
  2862. //
  2863. TERN_(PIDTEMP, gcode.M301_report(forReplay));
  2864. TERN_(PIDTEMPBED, gcode.M304_report(forReplay));
  2865. TERN_(PIDTEMPCHAMBER, gcode.M309_report(forReplay));
  2866. #if HAS_USER_THERMISTORS
  2867. LOOP_L_N(i, USER_THERMISTORS)
  2868. thermalManager.M305_report(i, forReplay);
  2869. #endif
  2870. //
  2871. // LCD Contrast
  2872. //
  2873. TERN_(HAS_LCD_CONTRAST, gcode.M250_report(forReplay));
  2874. //
  2875. // LCD Brightness
  2876. //
  2877. TERN_(HAS_LCD_BRIGHTNESS, gcode.M256_report(forReplay));
  2878. //
  2879. // Controller Fan
  2880. //
  2881. TERN_(CONTROLLER_FAN_EDITABLE, gcode.M710_report(forReplay));
  2882. //
  2883. // Power-Loss Recovery
  2884. //
  2885. TERN_(POWER_LOSS_RECOVERY, gcode.M413_report(forReplay));
  2886. //
  2887. // Firmware Retraction
  2888. //
  2889. #if ENABLED(FWRETRACT)
  2890. gcode.M207_report(forReplay);
  2891. gcode.M208_report(forReplay);
  2892. TERN_(FWRETRACT_AUTORETRACT, gcode.M209_report(forReplay));
  2893. #endif
  2894. //
  2895. // Probe Offset
  2896. //
  2897. TERN_(HAS_BED_PROBE, gcode.M851_report(forReplay));
  2898. //
  2899. // Bed Skew Correction
  2900. //
  2901. TERN_(SKEW_CORRECTION_GCODE, gcode.M852_report(forReplay));
  2902. #if HAS_TRINAMIC_CONFIG
  2903. //
  2904. // TMC Stepper driver current
  2905. //
  2906. gcode.M906_report(forReplay);
  2907. //
  2908. // TMC Hybrid Threshold
  2909. //
  2910. TERN_(HYBRID_THRESHOLD, gcode.M913_report(forReplay));
  2911. //
  2912. // TMC Sensorless homing thresholds
  2913. //
  2914. TERN_(USE_SENSORLESS, gcode.M914_report(forReplay));
  2915. #endif
  2916. //
  2917. // TMC stepping mode
  2918. //
  2919. TERN_(HAS_STEALTHCHOP, gcode.M569_report(forReplay));
  2920. //
  2921. // Linear Advance
  2922. //
  2923. TERN_(LIN_ADVANCE, gcode.M900_report(forReplay));
  2924. //
  2925. // Motor Current (SPI or PWM)
  2926. //
  2927. #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
  2928. gcode.M907_report(forReplay);
  2929. #endif
  2930. //
  2931. // Advanced Pause filament load & unload lengths
  2932. //
  2933. TERN_(ADVANCED_PAUSE_FEATURE, gcode.M603_report(forReplay));
  2934. //
  2935. // Tool-changing Parameters
  2936. //
  2937. E_TERN_(gcode.M217_report(forReplay));
  2938. //
  2939. // Backlash Compensation
  2940. //
  2941. TERN_(BACKLASH_GCODE, gcode.M425_report(forReplay));
  2942. //
  2943. // Filament Runout Sensor
  2944. //
  2945. TERN_(HAS_FILAMENT_SENSOR, gcode.M412_report(forReplay));
  2946. #if HAS_ETHERNET
  2947. CONFIG_ECHO_HEADING("Ethernet");
  2948. if (!forReplay) ETH0_report();
  2949. CONFIG_ECHO_START(); SERIAL_ECHO_SP(2); MAC_report();
  2950. CONFIG_ECHO_START(); SERIAL_ECHO_SP(2); gcode.M552_report();
  2951. CONFIG_ECHO_START(); SERIAL_ECHO_SP(2); gcode.M553_report();
  2952. CONFIG_ECHO_START(); SERIAL_ECHO_SP(2); gcode.M554_report();
  2953. #endif
  2954. TERN_(HAS_MULTI_LANGUAGE, gcode.M414_report(forReplay));
  2955. }
  2956. #endif // !DISABLE_M503
  2957. #pragma pack(pop)