Browse Source

Merge pull request #6738 from thinkyhead/bf_config_crc_rebase

Implement CRC16, develop mesh allocation table
Scott Lahteine 7 years ago
parent
commit
ffb5353294
10 changed files with 365 additions and 257 deletions
  1. 4
    4
      .travis.yml
  2. 22
    15
      Marlin/Marlin_main.cpp
  3. 170
    64
      Marlin/configuration_store.cpp
  4. 24
    4
      Marlin/configuration_store.h
  5. 14
    50
      Marlin/ubl.cpp
  6. 5
    11
      Marlin/ubl.h
  7. 105
    105
      Marlin/ubl_G29.cpp
  8. 4
    4
      Marlin/ultralcd.cpp
  9. 13
    0
      Marlin/utility.cpp
  10. 4
    0
      Marlin/utility.h

+ 4
- 4
.travis.yml View File

@@ -375,17 +375,17 @@ script:
375 375
   - use_example_configs Hephestos_2
376 376
   - build_marlin
377 377
   #
378
-  # Delta Config (generic)
378
+  # Delta Config (generic) + ABL bilinear + PROBE_MANUALLY
379 379
   - restore_configs
380 380
   - use_example_configs delta/generic
381
-  - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU
381
+  - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU AUTO_BED_LEVELING_BILINEAR PROBE_MANUALLY
382 382
   - build_marlin
383 383
   #
384
-  # Delta Config (generic) + ABL + ALLEN_KEY
384
+  # Delta Config (generic) + UBL + ALLEN_KEY + OLED_PANEL_TINYBOY2 + EEPROM_SETTINGS
385 385
   #
386 386
   - use_example_configs delta/generic
387 387
   - opt_disable DISABLE_MIN_ENDSTOPS
388
-  - opt_enable AUTO_BED_LEVELING_BILINEAR Z_PROBE_ALLEN_KEY
388
+  - opt_enable AUTO_BED_LEVELING_UBL Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT OLED_PANEL_TINYBOY2
389 389
   - build_marlin
390 390
   #
391 391
   # Delta Config (FLSUN AC because it's complex)

+ 22
- 15
Marlin/Marlin_main.cpp View File

@@ -3943,7 +3943,7 @@ void home_all_axes() { gcode_G28(true); }
3943 3943
 #if ENABLED(MESH_BED_LEVELING)
3944 3944
 
3945 3945
   // Save 130 bytes with non-duplication of PSTR
3946
-  void say_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); }
3946
+  void echo_not_entered() { SERIAL_PROTOCOLLNPGM(" not entered."); }
3947 3947
 
3948 3948
   void mbl_mesh_report() {
3949 3949
     SERIAL_PROTOCOLLNPGM("Num X,Y: " STRINGIFY(GRID_MAX_POINTS_X) "," STRINGIFY(GRID_MAX_POINTS_Y));
@@ -4074,7 +4074,7 @@ void home_all_axes() { gcode_G28(true); }
4074 4074
           }
4075 4075
         }
4076 4076
         else {
4077
-          SERIAL_CHAR('X'); say_not_entered();
4077
+          SERIAL_CHAR('X'); echo_not_entered();
4078 4078
           return;
4079 4079
         }
4080 4080
 
@@ -4086,7 +4086,7 @@ void home_all_axes() { gcode_G28(true); }
4086 4086
           }
4087 4087
         }
4088 4088
         else {
4089
-          SERIAL_CHAR('Y'); say_not_entered();
4089
+          SERIAL_CHAR('Y'); echo_not_entered();
4090 4090
           return;
4091 4091
         }
4092 4092
 
@@ -4094,7 +4094,7 @@ void home_all_axes() { gcode_G28(true); }
4094 4094
           mbl.z_values[px][py] = code_value_linear_units();
4095 4095
         }
4096 4096
         else {
4097
-          SERIAL_CHAR('Z'); say_not_entered();
4097
+          SERIAL_CHAR('Z'); echo_not_entered();
4098 4098
           return;
4099 4099
         }
4100 4100
         break;
@@ -4104,7 +4104,7 @@ void home_all_axes() { gcode_G28(true); }
4104 4104
           mbl.z_offset = code_value_linear_units();
4105 4105
         }
4106 4106
         else {
4107
-          SERIAL_CHAR('Z'); say_not_entered();
4107
+          SERIAL_CHAR('Z'); echo_not_entered();
4108 4108
           return;
4109 4109
         }
4110 4110
         break;
@@ -5123,7 +5123,7 @@ void home_all_axes() { gcode_G28(true); }
5123 5123
       SERIAL_PROTOCOLPGM("Checking... AC");
5124 5124
       if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)");
5125 5125
       SERIAL_EOL;
5126
-      LCD_MESSAGEPGM("Checking... AC");
5126
+      LCD_MESSAGEPGM("Checking... AC"); // TODO: Make translatable string
5127 5127
 
5128 5128
       SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
5129 5129
       if (!do_height_only) {
@@ -5343,7 +5343,7 @@ void home_all_axes() { gcode_G28(true); }
5343 5343
             SERIAL_PROTOCOL_SP(36);
5344 5344
             SERIAL_PROTOCOLPGM("rolling back.");
5345 5345
             SERIAL_EOL;
5346
-            LCD_MESSAGEPGM("Calibration OK");
5346
+            LCD_MESSAGEPGM("Calibration OK"); // TODO: Make translatable string
5347 5347
           }
5348 5348
           else {                                                     // !end iterations
5349 5349
             char mess[15] = "No convergence";
@@ -5394,7 +5394,7 @@ void home_all_axes() { gcode_G28(true); }
5394 5394
           }
5395 5395
           else {
5396 5396
             SERIAL_PROTOCOLLNPGM("Calibration OK");
5397
-            LCD_MESSAGEPGM("Calibration OK");
5397
+            LCD_MESSAGEPGM("Calibration OK"); // TODO: Make translatable string
5398 5398
             SERIAL_PROTOCOLPAIR(".Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
5399 5399
             SERIAL_EOL;
5400 5400
             serialprintPGM(save_message);
@@ -8460,15 +8460,22 @@ void quickstop_stepper() {
8460 8460
     #if ENABLED(AUTO_BED_LEVELING_UBL)
8461 8461
       // L to load a mesh from the EEPROM
8462 8462
       if (code_seen('L')) {
8463
-        const int8_t storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
8464
-        const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
8465
-        if (!WITHIN(storage_slot, 0, j - 1) || ubl.eeprom_start <= 0) {
8466
-          SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
8463
+        const int8_t storage_slot = code_has_value() ? code_value_int() : ubl.state.storage_slot;
8464
+        const int16_t a = settings.calc_num_meshes();
8465
+
8466
+        if (!a) {
8467
+          SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
8468
+          return;
8469
+        }
8470
+
8471
+        if (!WITHIN(storage_slot, 0, a - 1)) {
8472
+          SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
8473
+          SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
8467 8474
           return;
8468 8475
         }
8469 8476
 
8470
-        ubl.load_mesh(storage_slot);
8471
-        ubl.state.eeprom_storage_slot = storage_slot;
8477
+        settings.load_mesh(storage_slot);
8478
+        ubl.state.storage_slot = storage_slot;
8472 8479
       }
8473 8480
     #endif // AUTO_BED_LEVELING_UBL
8474 8481
 
@@ -8496,7 +8503,7 @@ void quickstop_stepper() {
8496 8503
       if (code_seen('L') || code_seen('V')) {
8497 8504
         ubl.display_map(0);  // Currently only supports one map type
8498 8505
         SERIAL_ECHOLNPAIR("UBL_MESH_VALID = ", UBL_MESH_VALID);
8499
-        SERIAL_ECHOLNPAIR("eeprom_storage_slot = ", ubl.state.eeprom_storage_slot);
8506
+        SERIAL_ECHOLNPAIR("ubl.state.storage_slot = ", ubl.state.storage_slot);
8500 8507
       }
8501 8508
     #endif
8502 8509
 

+ 170
- 64
Marlin/configuration_store.cpp View File

@@ -36,16 +36,16 @@
36 36
  *
37 37
  */
38 38
 
39
-#define EEPROM_VERSION "V37"
39
+#define EEPROM_VERSION "V38"
40 40
 
41 41
 // Change EEPROM version if these are changed:
42 42
 #define EEPROM_OFFSET 100
43 43
 
44 44
 /**
45
- * V37 EEPROM Layout:
45
+ * V38 EEPROM Layout:
46 46
  *
47 47
  *  100  Version                                    (char x4)
48
- *  104  EEPROM Checksum                            (uint16_t)
48
+ *  104  EEPROM CRC16                               (uint16_t)
49 49
  *
50 50
  *  106            E_STEPPERS                       (uint8_t)
51 51
  *  107  M92 XYZE  planner.axis_steps_per_mm        (float x4 ... x8)
@@ -90,7 +90,7 @@
90 90
  * AUTO_BED_LEVELING_UBL:                           6 bytes
91 91
  *  324  G29 A     ubl.state.active                 (bool)
92 92
  *  325  G29 Z     ubl.state.z_offset               (float)
93
- *  329  G29 S     ubl.state.eeprom_storage_slot    (int8_t)
93
+ *  329  G29 S     ubl.state.storage_slot           (int8_t)
94 94
  *
95 95
  * DELTA:                                           48 bytes
96 96
  *  348  M666 XYZ  endstop_adj                      (float x3)
@@ -158,6 +158,14 @@
158 158
  *
159 159
  *  588                                Minimum end-point
160 160
  * 1909 (588 + 36 + 9 + 288 + 988)     Maximum end-point
161
+ *
162
+ * ========================================================================
163
+ * meshes_begin (between max and min end-point, directly above)
164
+ * -- MESHES --
165
+ * meshes_end
166
+ * -- MAT (Mesh Allocation Table) --                128 bytes (placeholder size)
167
+ * mat_end = E2END (0xFFF)
168
+ *
161 169
  */
162 170
 #include "configuration_store.h"
163 171
 
@@ -230,18 +238,26 @@ void MarlinSettings::postprocess() {
230 238
 
231 239
 #if ENABLED(EEPROM_SETTINGS)
232 240
 
241
+  #define DUMMY_PID_VALUE 3000.0f
242
+  #define EEPROM_START() int eeprom_index = EEPROM_OFFSET
243
+  #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR)
244
+  #define EEPROM_WRITE(VAR) write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
245
+  #define EEPROM_READ(VAR) read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
246
+  #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START; SERIAL_ERRORLNPGM(ERR); eeprom_read_error = true; }while(0)
247
+
233 248
   const char version[4] = EEPROM_VERSION;
234 249
 
235
-  uint16_t MarlinSettings::eeprom_checksum;
250
+  bool MarlinSettings::eeprom_error;
236 251
 
237
-  bool MarlinSettings::eeprom_write_error,
238
-       MarlinSettings::eeprom_read_error;
252
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
253
+    int MarlinSettings::meshes_begin;
254
+  #endif
239 255
 
240
-  void MarlinSettings::write_data(int &pos, const uint8_t* value, uint16_t size) {
241
-    if (eeprom_write_error) return;
256
+  void MarlinSettings::write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc) {
257
+    if (eeprom_error) return;
242 258
     while (size--) {
243 259
       uint8_t * const p = (uint8_t * const)pos;
244
-      const uint8_t v = *value;
260
+      uint8_t v = *value;
245 261
       // EEPROM has only ~100,000 write cycles,
246 262
       // so only write bytes that have changed!
247 263
       if (v != eeprom_read_byte(p)) {
@@ -249,32 +265,27 @@ void MarlinSettings::postprocess() {
249 265
         if (eeprom_read_byte(p) != v) {
250 266
           SERIAL_ECHO_START;
251 267
           SERIAL_ECHOLNPGM(MSG_ERR_EEPROM_WRITE);
252
-          eeprom_write_error = true;
268
+          eeprom_error = true;
253 269
           return;
254 270
         }
255 271
       }
256
-      eeprom_checksum += v;
272
+      crc16(crc, &v, 1);
257 273
       pos++;
258 274
       value++;
259 275
     };
260 276
   }
261
-  void MarlinSettings::read_data(int &pos, uint8_t* value, uint16_t size) {
277
+
278
+  void MarlinSettings::read_data(int &pos, uint8_t* value, uint16_t size, uint16_t *crc) {
279
+    if (eeprom_error) return;
262 280
     do {
263 281
       uint8_t c = eeprom_read_byte((unsigned char*)pos);
264
-      if (!eeprom_read_error) *value = c;
265
-      eeprom_checksum += c;
282
+      *value = c;
283
+      crc16(crc, &c, 1);
266 284
       pos++;
267 285
       value++;
268 286
     } while (--size);
269 287
   }
270 288
 
271
-  #define DUMMY_PID_VALUE 3000.0f
272
-  #define EEPROM_START() int eeprom_index = EEPROM_OFFSET
273
-  #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR)
274
-  #define EEPROM_WRITE(VAR) write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR))
275
-  #define EEPROM_READ(VAR) read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR))
276
-  #define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START; SERIAL_ERRORLNPGM(ERR); eeprom_read_error = true; }while(0)
277
-
278 289
   /**
279 290
    * M500 - Store Configuration
280 291
    */
@@ -282,14 +293,16 @@ void MarlinSettings::postprocess() {
282 293
     float dummy = 0.0f;
283 294
     char ver[4] = "000";
284 295
 
296
+    uint16_t working_crc = 0;
297
+
285 298
     EEPROM_START();
286 299
 
287
-    eeprom_write_error = false;
300
+    eeprom_error = false;
288 301
 
289 302
     EEPROM_WRITE(ver);     // invalidate data first
290
-    EEPROM_SKIP(eeprom_checksum); // Skip the checksum slot
303
+    EEPROM_SKIP(working_crc); // Skip the checksum slot
291 304
 
292
-    eeprom_checksum = 0; // clear before first "real data"
305
+    working_crc = 0; // clear before first "real data"
293 306
 
294 307
     const uint8_t esteppers = COUNT(planner.axis_steps_per_mm) - XYZ;
295 308
     EEPROM_WRITE(esteppers);
@@ -410,14 +423,14 @@ void MarlinSettings::postprocess() {
410 423
     #if ENABLED(AUTO_BED_LEVELING_UBL)
411 424
       EEPROM_WRITE(ubl.state.active);
412 425
       EEPROM_WRITE(ubl.state.z_offset);
413
-      EEPROM_WRITE(ubl.state.eeprom_storage_slot);
426
+      EEPROM_WRITE(ubl.state.storage_slot);
414 427
     #else
415
-      const bool ubl_active = 0;
428
+      const bool ubl_active = false;
416 429
       dummy = 0.0f;
417
-      const int8_t eeprom_slot = -1;
430
+      const int8_t storage_slot = -1;
418 431
       EEPROM_WRITE(ubl_active);
419 432
       EEPROM_WRITE(dummy);
420
-      EEPROM_WRITE(eeprom_slot);
433
+      EEPROM_WRITE(storage_slot);
421 434
     #endif // AUTO_BED_LEVELING_UBL
422 435
 
423 436
     // 9 floats for DELTA / Z_DUAL_ENDSTOPS
@@ -609,43 +622,42 @@ void MarlinSettings::postprocess() {
609 622
       EEPROM_WRITE(dummy);
610 623
     #endif
611 624
 
612
-    if (!eeprom_write_error) {
613
-
614
-      const uint16_t final_checksum = eeprom_checksum,
615
-                     eeprom_size = eeprom_index;
625
+    if (!eeprom_error) {
626
+      const int eeprom_size = eeprom_index;
616 627
 
617 628
       // Write the EEPROM header
618 629
       eeprom_index = EEPROM_OFFSET;
619 630
       EEPROM_WRITE(version);
620
-      EEPROM_WRITE(final_checksum);
631
+      EEPROM_WRITE(working_crc);
621 632
 
622 633
       // Report storage size
623 634
       SERIAL_ECHO_START;
624 635
       SERIAL_ECHOPAIR("Settings Stored (", eeprom_size - (EEPROM_OFFSET));
625
-      SERIAL_ECHOLNPGM(" bytes)");
636
+      SERIAL_ECHOPAIR(" bytes; crc ", working_crc);
637
+      SERIAL_ECHOLNPGM(")");
626 638
     }
627 639
 
628 640
     #if ENABLED(UBL_SAVE_ACTIVE_ON_M500)
629
-      if (ubl.state.eeprom_storage_slot >= 0)
630
-        ubl.store_mesh(ubl.state.eeprom_storage_slot);
641
+      if (ubl.state.storage_slot >= 0)
642
+        store_mesh(ubl.state.storage_slot);
631 643
     #endif
632 644
 
633
-    return !eeprom_write_error;
645
+    return !eeprom_error;
634 646
   }
635 647
 
636 648
   /**
637 649
    * M501 - Retrieve Configuration
638 650
    */
639 651
   bool MarlinSettings::load() {
652
+    uint16_t working_crc = 0;
640 653
 
641 654
     EEPROM_START();
642
-    eeprom_read_error = false; // If set EEPROM_READ won't write into RAM
643 655
 
644 656
     char stored_ver[4];
645 657
     EEPROM_READ(stored_ver);
646 658
 
647
-    uint16_t stored_checksum;
648
-    EEPROM_READ(stored_checksum);
659
+    uint16_t stored_crc;
660
+    EEPROM_READ(stored_crc);
649 661
 
650 662
     // Version has to match or defaults are used
651 663
     if (strncmp(version, stored_ver, 3) != 0) {
@@ -662,7 +674,7 @@ void MarlinSettings::postprocess() {
662 674
     else {
663 675
       float dummy = 0;
664 676
 
665
-      eeprom_checksum = 0; // clear before reading first "real data"
677
+      working_crc = 0; //clear before reading first "real data"
666 678
 
667 679
       // Number of esteppers may change
668 680
       uint8_t esteppers;
@@ -788,7 +800,7 @@ void MarlinSettings::postprocess() {
788 800
       #if ENABLED(AUTO_BED_LEVELING_UBL)
789 801
         EEPROM_READ(ubl.state.active);
790 802
         EEPROM_READ(ubl.state.z_offset);
791
-        EEPROM_READ(ubl.state.eeprom_storage_slot);
803
+        EEPROM_READ(ubl.state.storage_slot);
792 804
       #else
793 805
         bool dummyb;
794 806
         uint8_t dummyui8;
@@ -960,42 +972,45 @@ void MarlinSettings::postprocess() {
960 972
         EEPROM_READ(dummy);
961 973
       #endif
962 974
 
963
-      if (eeprom_checksum == stored_checksum) {
964
-        if (eeprom_read_error)
965
-          reset();
966
-        else {
975
+      if (working_crc == stored_crc) {
967 976
           postprocess();
968 977
           SERIAL_ECHO_START;
969 978
           SERIAL_ECHO(version);
970 979
           SERIAL_ECHOPAIR(" stored settings retrieved (", eeprom_index - (EEPROM_OFFSET));
971
-          SERIAL_ECHOLNPGM(" bytes)");
972
-        }
980
+          SERIAL_ECHOPAIR(" bytes; crc ", working_crc);
981
+          SERIAL_ECHOLNPGM(")");
973 982
       }
974 983
       else {
975 984
         SERIAL_ERROR_START;
976
-        SERIAL_ERRORLNPGM("EEPROM checksum mismatch");
985
+        SERIAL_ERRORPGM("EEPROM checksum mismatch - (stored CRC)");
986
+        SERIAL_ERROR(stored_crc);
987
+        SERIAL_ERRORPGM(" != ");
988
+        SERIAL_ERROR(working_crc);
989
+        SERIAL_ERRORLNPGM(" (calculated CRC)!");
977 990
         reset();
978 991
       }
979 992
 
980 993
       #if ENABLED(AUTO_BED_LEVELING_UBL)
981
-        ubl.eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
982
-                                                         // can float up or down a little bit without
983
-                                                         // disrupting the Unified Bed Leveling data
984
-        SERIAL_ECHOPGM(" UBL ");
985
-        if (!ubl.state.active) SERIAL_ECHO("not ");
986
-        SERIAL_ECHOLNPGM("active!");
994
+        meshes_begin = (eeprom_index + 32) & 0xFFF8;  // Pad the end of configuration data so it
995
+                                                      // can float up or down a little bit without
996
+                                                      // disrupting the mesh data
997
+        ubl.report_state();
987 998
 
988 999
         if (!ubl.sanity_check()) {
989
-          SERIAL_ECHOLNPGM("\nUnified Bed Leveling system initialized.\n");
1000
+          SERIAL_EOL;
1001
+          ubl.echo_name();
1002
+          SERIAL_ECHOLNPGM(" initialized.\n");
990 1003
         }
991 1004
         else {
992
-          SERIAL_PROTOCOLPGM("?Unable to enable Unified Bed Leveling system.\n");
1005
+          SERIAL_PROTOCOLPGM("?Can't enable ");
1006
+          ubl.echo_name();
1007
+          SERIAL_PROTOCOLLNPGM(".");
993 1008
           ubl.reset();
994 1009
         }
995 1010
 
996
-        if (ubl.state.eeprom_storage_slot >= 0) {
997
-          ubl.load_mesh(ubl.state.eeprom_storage_slot);
998
-          SERIAL_ECHOPAIR("Mesh ", ubl.state.eeprom_storage_slot);
1011
+        if (ubl.state.storage_slot >= 0) {
1012
+          load_mesh(ubl.state.storage_slot);
1013
+          SERIAL_ECHOPAIR("Mesh ", ubl.state.storage_slot);
999 1014
           SERIAL_ECHOLNPGM(" loaded from storage.");
1000 1015
         }
1001 1016
         else {
@@ -1009,9 +1024,87 @@ void MarlinSettings::postprocess() {
1009 1024
       report();
1010 1025
     #endif
1011 1026
 
1012
-    return !eeprom_read_error;
1027
+    return !eeprom_error;
1013 1028
   }
1014 1029
 
1030
+
1031
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
1032
+
1033
+    void ubl_invalid_slot(const int s) {
1034
+      SERIAL_PROTOCOLLNPGM("?Invalid slot.");
1035
+      SERIAL_PROTOCOL(s);
1036
+      SERIAL_PROTOCOLLNPGM(" mesh slots available.");
1037
+    }
1038
+
1039
+    int MarlinSettings::calc_num_meshes() {
1040
+      //obviously this will get more sophisticated once we've added an actual MAT
1041
+
1042
+      if (meshes_begin <= 0) return 0;
1043
+
1044
+      return (meshes_end - meshes_begin) / sizeof(ubl.z_values);
1045
+    }
1046
+
1047
+    void MarlinSettings::store_mesh(int8_t slot) {
1048
+
1049
+      #if ENABLED(AUTO_BED_LEVELING_UBL)
1050
+        const int a = calc_num_meshes();
1051
+        if (!WITHIN(slot, 0, a - 1)) {
1052
+          ubl_invalid_slot(a);
1053
+          SERIAL_PROTOCOLPAIR("E2END=", E2END);
1054
+          SERIAL_PROTOCOLPAIR(" meshes_end=", (int)meshes_end);
1055
+          SERIAL_PROTOCOLLNPAIR(" slot=", slot);
1056
+          SERIAL_EOL;
1057
+          return;
1058
+        }
1059
+
1060
+        uint16_t crc = 0;
1061
+        int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values);
1062
+
1063
+        write_data(pos, (uint8_t *)&ubl.z_values, sizeof(ubl.z_values), &crc);
1064
+
1065
+        // Write crc to MAT along with other data, or just tack on to the beginning or end
1066
+
1067
+        SERIAL_PROTOCOLPAIR("Mesh saved in slot ", slot);
1068
+
1069
+      #else
1070
+
1071
+        // Other mesh types
1072
+
1073
+      #endif
1074
+    }
1075
+
1076
+    void MarlinSettings::load_mesh(int8_t slot, void *into /* = 0 */) {
1077
+
1078
+      #if ENABLED(AUTO_BED_LEVELING_UBL)
1079
+
1080
+        const int16_t a = settings.calc_num_meshes();
1081
+
1082
+        if (!WITHIN(slot, 0, a - 1)) {
1083
+          ubl_invalid_slot(a);
1084
+          return;
1085
+        }
1086
+
1087
+        uint16_t crc = 0;
1088
+        int pos = meshes_end - (slot + 1) * sizeof(ubl.z_values);
1089
+        uint8_t * const dest = into ? (uint8_t*)into : (uint8_t*)&ubl.z_values;
1090
+        read_data(pos, dest, sizeof(ubl.z_values), &crc);
1091
+
1092
+        // Compare crc with crc from MAT, or read from end
1093
+
1094
+        SERIAL_PROTOCOLPAIR("Mesh loaded from slot ", slot);
1095
+
1096
+      #else
1097
+
1098
+        // Other mesh types
1099
+
1100
+      #endif
1101
+    }
1102
+
1103
+    //void MarlinSettings::delete_mesh() { return; }
1104
+    //void MarlinSettings::defrag_meshes() { return; }
1105
+
1106
+  #endif // AUTO_BED_LEVELING_UBL
1107
+
1015 1108
 #else // !EEPROM_SETTINGS
1016 1109
 
1017 1110
   bool MarlinSettings::save() {
@@ -1449,7 +1542,8 @@ void MarlinSettings::reset() {
1449 1542
 
1450 1543
       if (!forReplay) {
1451 1544
         CONFIG_ECHO_START;
1452
-        SERIAL_ECHOLNPGM("Unified Bed Leveling:");
1545
+        ubl.echo_name();
1546
+        SERIAL_ECHOLNPGM(":");
1453 1547
       }
1454 1548
       CONFIG_ECHO_START;
1455 1549
       SERIAL_ECHOPAIR("  M420 S", ubl.state.active ? 1 : 0);
@@ -1458,7 +1552,19 @@ void MarlinSettings::reset() {
1458 1552
       #endif
1459 1553
       SERIAL_EOL;
1460 1554
 
1461
-      if (!forReplay) ubl.g29_what_command();
1555
+      if (!forReplay) {
1556
+        SERIAL_EOL;
1557
+        ubl.report_state();
1558
+
1559
+        SERIAL_ECHOLNPAIR("\nActive Mesh Slot: ", ubl.state.storage_slot);
1560
+
1561
+        SERIAL_ECHOPGM("z_offset: ");
1562
+        SERIAL_ECHO_F(ubl.state.z_offset, 6);
1563
+        SERIAL_EOL;
1564
+
1565
+        SERIAL_ECHOPAIR("EEPROM can hold ", calc_num_meshes());
1566
+        SERIAL_ECHOLNPGM(" meshes.\n");
1567
+      }
1462 1568
 
1463 1569
     #elif HAS_ABL
1464 1570
 

+ 24
- 4
Marlin/configuration_store.h View File

@@ -34,6 +34,18 @@ class MarlinSettings {
34 34
 
35 35
     #if ENABLED(EEPROM_SETTINGS)
36 36
       static bool load();
37
+
38
+      #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
39
+                                         // That can store is enabled
40
+        FORCE_INLINE static int get_start_of_meshes() { return meshes_begin; }
41
+        FORCE_INLINE static int get_end_of_meshes() { return meshes_end; }
42
+        static int calc_num_meshes();
43
+        static void store_mesh(int8_t slot);
44
+        static void load_mesh(int8_t slot, void *into = 0);
45
+
46
+        //static void delete_mesh();    // necessary if we have a MAT
47
+        //static void defrag_meshes();  // "
48
+      #endif
37 49
     #else
38 50
       FORCE_INLINE
39 51
       static bool load() { reset(); report(); return true; }
@@ -50,10 +62,18 @@ class MarlinSettings {
50 62
     static void postprocess();
51 63
 
52 64
     #if ENABLED(EEPROM_SETTINGS)
53
-      static uint16_t eeprom_checksum;
54
-      static bool eeprom_read_error, eeprom_write_error;
55
-      static void write_data(int &pos, const uint8_t* value, uint16_t size);
56
-      static void read_data(int &pos, uint8_t* value, uint16_t size);
65
+      static bool eeprom_error;
66
+
67
+      #if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
68
+                                         // That can store is enabled
69
+        static int meshes_begin;
70
+        const static int mat_end = E2END;            // Mesh allocation table; this may not end up being necessary
71
+        const static int meshes_end = mat_end - 128; // 128 is a placeholder for the size of the MAT
72
+
73
+      #endif
74
+
75
+      static void write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc);
76
+      static void read_data(int &pos, uint8_t *value, uint16_t size, uint16_t *crc);
57 77
     #endif
58 78
 };
59 79
 

+ 14
- 50
Marlin/ubl.cpp View File

@@ -41,6 +41,16 @@
41 41
 
42 42
   uint8_t ubl_cnt = 0;
43 43
 
44
+  void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); }
45
+
46
+  void unified_bed_leveling::report_state() {
47
+    echo_name();
48
+    SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " ");
49
+    if (!state.active) SERIAL_PROTOCOLPGM("in");
50
+    SERIAL_PROTOCOLLNPGM("active.");
51
+    safe_delay(50);
52
+  }
53
+
44 54
   static void serial_echo_xy(const int16_t x, const int16_t y) {
45 55
     SERIAL_CHAR('(');
46 56
     SERIAL_ECHO(x);
@@ -63,9 +73,6 @@
63 73
   bool unified_bed_leveling::g26_debug_flag = false,
64 74
        unified_bed_leveling::has_control_of_lcd_panel = false;
65 75
 
66
-  int16_t unified_bed_leveling::eeprom_start = -1;  // Please stop changing this to 8 bits in size
67
-                                                    // It needs to hold values bigger than this.
68
-
69 76
   volatile int unified_bed_leveling::encoder_diff;
70 77
 
71 78
   unified_bed_leveling::unified_bed_leveling() {
@@ -73,53 +80,10 @@
73 80
     reset();
74 81
   }
75 82
 
76
-  void unified_bed_leveling::load_mesh(const int16_t slot) {
77
-    int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
78
-
79
-    if (slot == -1) {
80
-      SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
81
-      reset();
82
-      return;
83
-    }
84
-
85
-    if (!WITHIN(slot, 0, j - 1) || eeprom_start <= 0) {
86
-      SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
87
-      return;
88
-    }
89
-
90
-    j = UBL_LAST_EEPROM_INDEX - (slot + 1) * sizeof(z_values);
91
-    eeprom_read_block((void *)&z_values, (void *)j, sizeof(z_values));
92
-
93
-    SERIAL_PROTOCOLPAIR("Mesh loaded from slot ", slot);
94
-    SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j));
95
-  }
96
-
97
-  void unified_bed_leveling::store_mesh(const int16_t slot) {
98
-    int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
99
-
100
-    if (!WITHIN(slot, 0, j - 1) || eeprom_start <= 0) {
101
-      SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
102
-      SERIAL_PROTOCOL(slot);
103
-      SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
104
-      SERIAL_PROTOCOLLNPAIR("E2END     : ", E2END);
105
-      SERIAL_PROTOCOLLNPAIR("k         : ", (int)UBL_LAST_EEPROM_INDEX);
106
-      SERIAL_PROTOCOLLNPAIR("j         : ", j);
107
-      SERIAL_PROTOCOLLNPAIR("m         : ", slot);
108
-      SERIAL_EOL;
109
-      return;
110
-    }
111
-
112
-    j = UBL_LAST_EEPROM_INDEX - (slot + 1) * sizeof(z_values);
113
-    eeprom_write_block((const void *)&z_values, (void *)j, sizeof(z_values));
114
-
115
-    SERIAL_PROTOCOLPAIR("Mesh saved in slot ", slot);
116
-    SERIAL_PROTOCOLLNPAIR(" at offset ", hex_address((void*)j));
117
-  }
118
-
119 83
   void unified_bed_leveling::reset() {
120 84
     state.active = false;
121 85
     state.z_offset = 0;
122
-    state.eeprom_storage_slot = -1;
86
+    state.storage_slot = -1;
123 87
 
124 88
     ZERO(z_values);
125 89
 
@@ -203,9 +167,9 @@
203 167
   bool unified_bed_leveling::sanity_check() {
204 168
     uint8_t error_flag = 0;
205 169
 
206
-    const int j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
207
-    if (j < 1) {
208
-      SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
170
+    const int a = settings.calc_num_meshes();
171
+    if (a < 1) {
172
+      SERIAL_PROTOCOLLNPGM("?Insufficient EEPROM storage for a mesh of this size.");
209 173
       error_flag++;
210 174
     }
211 175
 

+ 5
- 11
Marlin/ubl.h View File

@@ -30,8 +30,9 @@
30 30
   #include "planner.h"
31 31
   #include "math.h"
32 32
   #include "vector_3.h"
33
+  #include "configuration_store.h"
33 34
 
34
-  #define UBL_VERSION "1.00"
35
+  #define UBL_VERSION "1.01"
35 36
   #define UBL_OK false
36 37
   #define UBL_ERR true
37 38
 
@@ -92,7 +93,7 @@
92 93
   typedef struct {
93 94
     bool active = false;
94 95
     float z_offset = 0.0;
95
-    int8_t eeprom_storage_slot = -1;
96
+    int8_t storage_slot = -1;
96 97
   } ubl_state;
97 98
 
98 99
   class unified_bed_leveling {
@@ -102,6 +103,8 @@
102 103
 
103 104
     public:
104 105
 
106
+      void echo_name();
107
+      void report_state();
105 108
       void find_mean_mesh_height();
106 109
       void shift_mesh_height();
107 110
       void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
@@ -117,10 +120,6 @@
117 120
       void display_map(const int);
118 121
       void reset();
119 122
       void invalidate();
120
-      void store_state();
121
-      void load_state();
122
-      void store_mesh(const int16_t);
123
-      void load_mesh(const int16_t);
124 123
       bool sanity_check();
125 124
 
126 125
       static ubl_state state;
@@ -153,9 +152,6 @@
153 152
 
154 153
       static bool g26_debug_flag, has_control_of_lcd_panel;
155 154
 
156
-      static int16_t eeprom_start;    // Please do no change this to 8 bits in size
157
-                                      // It needs to hold values bigger than this.
158
-
159 155
       static volatile int encoder_diff; // Volatile because it's changed at interrupt time.
160 156
 
161 157
       unified_bed_leveling();
@@ -351,7 +347,5 @@
351 347
 
352 348
   extern unified_bed_leveling ubl;
353 349
 
354
-  #define UBL_LAST_EEPROM_INDEX E2END
355
-
356 350
 #endif // AUTO_BED_LEVELING_UBL
357 351
 #endif // UNIFIED_BED_LEVELING_H

+ 105
- 105
Marlin/ubl_G29.cpp View File

@@ -314,7 +314,7 @@
314 314
 
315 315
   void __attribute__((optimize("O0"))) gcode_G29() {
316 316
 
317
-    if (ubl.eeprom_start < 0) {
317
+    if (!settings.calc_num_meshes()) {
318 318
       SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it");
319 319
       SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n");
320 320
       return;
@@ -419,9 +419,9 @@
419 419
     }
420 420
 
421 421
     if (code_seen('P')) {
422
-      if (WITHIN(phase_value, 0, 1) && ubl.state.eeprom_storage_slot == -1) {
423
-        ubl.state.eeprom_storage_slot = 0;
424
-        SERIAL_PROTOCOLLNPGM("Default storage slot 0 selected.\n");
422
+      if (WITHIN(phase_value, 0, 1) && ubl.state.storage_slot == -1) {
423
+        ubl.state.storage_slot = 0;
424
+        SERIAL_PROTOCOLLNPGM("Default storage slot 0 selected.");
425 425
       }
426 426
 
427 427
       switch (phase_value) {
@@ -430,7 +430,7 @@
430 430
           // Zero Mesh Data
431 431
           //
432 432
           ubl.reset();
433
-          SERIAL_PROTOCOLLNPGM("Mesh zeroed.\n");
433
+          SERIAL_PROTOCOLLNPGM("Mesh zeroed.");
434 434
           break;
435 435
 
436 436
         case 1:
@@ -439,7 +439,7 @@
439 439
           //
440 440
           if (!code_seen('C')) {
441 441
             ubl.invalidate();
442
-            SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh.\n");
442
+            SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh.");
443 443
           }
444 444
           if (g29_verbose_level > 1) {
445 445
             SERIAL_PROTOCOLPAIR("Probing Mesh Points Closest to (", x_pos);
@@ -455,7 +455,7 @@
455 455
           //
456 456
           // Manually Probe Mesh in areas that can't be reached by the probe
457 457
           //
458
-          SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.\n");
458
+          SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.");
459 459
           do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
460 460
           if (!x_flag && !y_flag) {
461 461
             /**
@@ -485,7 +485,7 @@
485 485
             card_thickness = code_has_value() ? code_value_float() : measure_business_card_thickness(height);
486 486
 
487 487
             if (fabs(card_thickness) > 1.5) {
488
-              SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement.\n");
488
+              SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement.");
489 489
               return;
490 490
             }
491 491
           }
@@ -561,17 +561,25 @@
561 561
     //
562 562
 
563 563
     if (code_seen('L')) {     // Load Current Mesh Data
564
-      storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
564
+      storage_slot = code_has_value() ? code_value_int() : ubl.state.storage_slot;
565 565
 
566
-      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
566
+      int16_t a = settings.calc_num_meshes();
567 567
 
568
-      if (!WITHIN(storage_slot, 0, j - 1) || ubl.eeprom_start <= 0) {
569
-        SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
568
+      if (!a) {
569
+        SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
570 570
         return;
571 571
       }
572
-      ubl.load_mesh(storage_slot);
573
-      ubl.state.eeprom_storage_slot = storage_slot;
574
-      SERIAL_PROTOCOLLNPGM("Done.\n");
572
+
573
+      if (!WITHIN(storage_slot, 0, a - 1)) {
574
+        SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
575
+        SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
576
+        return;
577
+      }
578
+
579
+      settings.load_mesh(storage_slot);
580
+      ubl.state.storage_slot = storage_slot;
581
+
582
+      SERIAL_PROTOCOLLNPGM("Done.");
575 583
     }
576 584
 
577 585
     //
@@ -579,7 +587,7 @@
579 587
     //
580 588
 
581 589
     if (code_seen('S')) {     // Store (or Save) Current Mesh Data
582
-      storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
590
+      storage_slot = code_has_value() ? code_value_int() : ubl.state.storage_slot;
583 591
 
584 592
       if (storage_slot == -1) {                     // Special case, we are going to 'Export' the mesh to the
585 593
         SERIAL_ECHOLNPGM("G29 I 999");              // host in a form it can be reconstructed on a different machine
@@ -597,17 +605,23 @@
597 605
         return;
598 606
       }
599 607
 
600
-      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
608
+      int16_t a = settings.calc_num_meshes();
609
+
610
+      if (!a) {
611
+        SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
612
+        goto LEAVE;
613
+      }
601 614
 
602
-      if (!WITHIN(storage_slot, 0, j - 1) || ubl.eeprom_start <= 0) {
603
-        SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
604
-        SERIAL_PROTOCOLLNPAIR("?Use 0 to ", j - 1);
615
+      if (!WITHIN(storage_slot, 0, a - 1)) {
616
+        SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
617
+        SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
605 618
         goto LEAVE;
606 619
       }
607
-      ubl.store_mesh(storage_slot);
608
-      ubl.state.eeprom_storage_slot = storage_slot;
609 620
 
610
-      SERIAL_PROTOCOLLNPGM("Done.\n");
621
+      settings.store_mesh(storage_slot);
622
+      ubl.state.storage_slot = storage_slot;
623
+
624
+      SERIAL_PROTOCOLLNPGM("Done.");
611 625
     }
612 626
 
613 627
     if (code_seen('T'))
@@ -654,7 +668,7 @@
654 668
           if (ELAPSED(millis(), nxt)) {
655 669
             SERIAL_PROTOCOLLNPGM("\nZ-Offset Adjustment Stopped.");
656 670
             do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
657
-            LCD_MESSAGEPGM("Z-Offset Stopped");
671
+            LCD_MESSAGEPGM("Z-Offset Stopped"); // TODO: Make translatable string
658 672
             ubl.restore_ubl_active_state_and_leave();
659 673
             goto LEAVE;
660 674
           }
@@ -892,7 +906,7 @@
892 906
     return current_position[Z_AXIS];
893 907
   }
894 908
 
895
-  static void say_and_take_a_measurement() {
909
+  static void echo_and_take_a_measurement() {
896 910
     SERIAL_PROTOCOLLNPGM(" and take a measurement.");
897 911
   }
898 912
 
@@ -906,17 +920,17 @@
906 920
     stepper.synchronize();
907 921
 
908 922
     SERIAL_PROTOCOLPGM("Place shim under nozzle");
909
-    LCD_MESSAGEPGM("Place shim & measure");
923
+    LCD_MESSAGEPGM("Place shim & measure"); // TODO: Make translatable string
910 924
     lcd_goto_screen(lcd_status_screen);
911
-    say_and_take_a_measurement();
925
+    echo_and_take_a_measurement();
912 926
 
913 927
     const float z1 = use_encoder_wheel_to_measure_point();
914 928
     do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
915 929
     stepper.synchronize();
916 930
 
917 931
     SERIAL_PROTOCOLPGM("Remove shim");
918
-    LCD_MESSAGEPGM("Remove & measure bed");
919
-    say_and_take_a_measurement();
932
+    LCD_MESSAGEPGM("Remove & measure bed"); // TODO: Make translatable string
933
+    echo_and_take_a_measurement();
920 934
 
921 935
     const float z2 = use_encoder_wheel_to_measure_point();
922 936
 
@@ -962,7 +976,7 @@
962 976
 
963 977
       do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
964 978
 
965
-      LCD_MESSAGEPGM("Moving to next");
979
+      LCD_MESSAGEPGM("Moving to next"); // TODO: Make translatable string
966 980
 
967 981
       do_blocking_move_to_xy(xProbe, yProbe);
968 982
       do_blocking_move_to_z(z_clearance);
@@ -972,8 +986,10 @@
972 986
 
973 987
       if (do_ubl_mesh_map) ubl.display_map(map_type);  // show user where we're probing
974 988
 
975
-      if (code_seen('B')) {LCD_MESSAGEPGM("Place shim & measure");}
976
-      else {LCD_MESSAGEPGM("Measure");}
989
+      if (code_seen('B'))
990
+        LCD_MESSAGEPGM("Place shim & measure"); // TODO: Make translatable string
991
+      else
992
+        LCD_MESSAGEPGM("Measure"); // TODO: Make translatable string
977 993
 
978 994
       while (ubl_lcd_clicked()) delay(50);             // wait for user to release encoder wheel
979 995
       delay(50);                                       // debounce
@@ -1017,21 +1033,10 @@
1017 1033
     do_blocking_move_to_xy(lx, ly);
1018 1034
   }
1019 1035
 
1020
-  static void say_ubl_name() {
1021
-    SERIAL_PROTOCOLPGM("Unified Bed Leveling ");
1022
-  }
1023
-
1024
-  static void report_ubl_state() {
1025
-    say_ubl_name();
1026
-    SERIAL_PROTOCOLPGM("System ");
1027
-    if (!ubl.state.active) SERIAL_PROTOCOLPGM("de");
1028
-    SERIAL_PROTOCOLLNPGM("activated.\n");
1029
-  }
1030
-
1031 1036
   bool g29_parameter_parsing() {
1032 1037
     bool err_flag = false;
1033 1038
 
1034
-    LCD_MESSAGEPGM("Doing G29 UBL!");
1039
+    LCD_MESSAGEPGM("Doing G29 UBL!"); // TODO: Make translatable string
1035 1040
     lcd_quick_feedback();
1036 1041
 
1037 1042
     ubl_constant = 0.0;
@@ -1096,12 +1101,12 @@
1096 1101
         SERIAL_PROTOCOLLNPGM("?Can't activate and deactivate at the same time.\n");
1097 1102
         return UBL_ERR;
1098 1103
       }
1099
-      ubl.state.active = 1;
1100
-      report_ubl_state();
1104
+      ubl.state.active = true;
1105
+      ubl.report_state();
1101 1106
     }
1102 1107
     else if (code_seen('D')) {
1103
-      ubl.state.active = 0;
1104
-      report_ubl_state();
1108
+      ubl.state.active = false;
1109
+      ubl.report_state();
1105 1110
     }
1106 1111
 
1107 1112
     // Set global 'C' flag and its value
@@ -1134,7 +1139,7 @@
1134 1139
     ubl_state_recursion_chk++;
1135 1140
     if (ubl_state_recursion_chk != 1) {
1136 1141
       SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
1137
-      LCD_MESSAGEPGM("save_UBL_active() error");
1142
+      LCD_MESSAGEPGM("save_UBL_active() error"); // TODO: Make translatable string
1138 1143
       lcd_quick_feedback();
1139 1144
       return;
1140 1145
     }
@@ -1145,7 +1150,7 @@
1145 1150
   void unified_bed_leveling::restore_ubl_active_state_and_leave() {
1146 1151
     if (--ubl_state_recursion_chk) {
1147 1152
       SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
1148
-      LCD_MESSAGEPGM("restore_UBL_active() error");
1153
+      LCD_MESSAGEPGM("restore_UBL_active() error"); // TODO: Make translatable string
1149 1154
       lcd_quick_feedback();
1150 1155
       return;
1151 1156
     }
@@ -1157,21 +1162,12 @@
1157 1162
    * good to have the extra information. Soon... we prune this to just a few items
1158 1163
    */
1159 1164
   void unified_bed_leveling::g29_what_command() {
1160
-    const uint16_t k = E2END - ubl.eeprom_start;
1161
-
1162
-    say_ubl_name();
1163
-    SERIAL_PROTOCOLPGM("System Version " UBL_VERSION " ");
1164
-    if (state.active)
1165
-      SERIAL_PROTOCOLCHAR('A');
1166
-    else
1167
-      SERIAL_PROTOCOLPGM("Ina");
1168
-    SERIAL_PROTOCOLLNPGM("ctive.\n");
1169
-    safe_delay(50);
1165
+    report_state();
1170 1166
 
1171
-    if (state.eeprom_storage_slot == -1)
1167
+    if (state.storage_slot == -1)
1172 1168
       SERIAL_PROTOCOLPGM("No Mesh Loaded.");
1173 1169
     else {
1174
-      SERIAL_PROTOCOLPAIR("Mesh ", state.eeprom_storage_slot);
1170
+      SERIAL_PROTOCOLPAIR("Mesh ", state.storage_slot);
1175 1171
       SERIAL_PROTOCOLPGM(" Loaded.");
1176 1172
     }
1177 1173
     SERIAL_EOL;
@@ -1188,12 +1184,15 @@
1188 1184
     SERIAL_PROTOCOL_F(zprobe_zoffset, 7);
1189 1185
     SERIAL_EOL;
1190 1186
 
1191
-    SERIAL_PROTOCOLLNPAIR("ubl.eeprom_start=", hex_address((void*)eeprom_start));
1192
-
1187
+    SERIAL_ECHOLNPAIR("UBL_MESH_MIN_X  " STRINGIFY(UBL_MESH_MIN_X) "=", UBL_MESH_MIN_X);
1188
+    SERIAL_ECHOLNPAIR("UBL_MESH_MIN_Y  " STRINGIFY(UBL_MESH_MIN_Y) "=", UBL_MESH_MIN_Y);
1189
+    safe_delay(25);
1190
+    SERIAL_ECHOLNPAIR("UBL_MESH_MAX_X  " STRINGIFY(UBL_MESH_MAX_X) "=", UBL_MESH_MAX_X);
1191
+    SERIAL_ECHOLNPAIR("UBL_MESH_MAX_Y  " STRINGIFY(UBL_MESH_MAX_Y) "=", UBL_MESH_MAX_Y);
1192
+    safe_delay(25);
1193 1193
     SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X  ", GRID_MAX_POINTS_X);
1194 1194
     SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y  ", GRID_MAX_POINTS_Y);
1195 1195
     safe_delay(25);
1196
-
1197 1196
     SERIAL_ECHOLNPAIR("MESH_X_DIST  ", MESH_X_DIST);
1198 1197
     SERIAL_ECHOLNPAIR("MESH_Y_DIST  ", MESH_Y_DIST);
1199 1198
     safe_delay(25);
@@ -1214,43 +1213,39 @@
1214 1213
     }
1215 1214
     SERIAL_EOL;
1216 1215
 
1217
-    SERIAL_PROTOCOLLNPAIR("Free EEPROM space starts at: ", hex_address((void*)eeprom_start));
1218
-    SERIAL_PROTOCOLLNPAIR("end of EEPROM: ", hex_address((void*)E2END));
1219
-    safe_delay(25);
1216
+    #if HAS_KILL
1217
+      SERIAL_PROTOCOLPAIR("Kill pin on :", KILL_PIN);
1218
+      SERIAL_PROTOCOLLNPAIR("  state:", READ(KILL_PIN));
1219
+    #endif
1220
+    SERIAL_EOL;
1221
+    safe_delay(50);
1220 1222
 
1221
-    SERIAL_PROTOCOLPAIR("sizeof(ubl.state) : ", (int)sizeof(state));
1223
+    SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation);
1222 1224
     SERIAL_EOL;
1223
-    SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values));
1225
+    SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk);
1224 1226
     SERIAL_EOL;
1225
-    safe_delay(25);
1226
-
1227
-    SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)k));
1228
-    safe_delay(25);
1227
+    safe_delay(50);
1229 1228
 
1230
-    SERIAL_PROTOCOLPAIR("EEPROM can hold ", k / sizeof(z_values));
1231
-    SERIAL_PROTOCOLLNPGM(" meshes.\n");
1232
-    safe_delay(25);
1229
+    SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes()));
1230
+    SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes()));
1231
+    safe_delay(50);
1233 1232
 
1234
-    SERIAL_PROTOCOLPAIR("\nGRID_MAX_POINTS_X  ", GRID_MAX_POINTS_X);
1235
-    SERIAL_PROTOCOLPAIR("\nGRID_MAX_POINTS_Y  ", GRID_MAX_POINTS_Y);
1236
-    safe_delay(25);
1233
+    SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1234
+    SERIAL_EOL;
1235
+    SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values));
1237 1236
     SERIAL_EOL;
1238
-
1239
-    SERIAL_ECHOPGM("UBL_MESH_MIN_X  " STRINGIFY(UBL_MESH_MIN_X));
1240
-    SERIAL_ECHOLNPAIR("=", UBL_MESH_MIN_X );
1241
-    SERIAL_ECHOPGM("UBL_MESH_MIN_Y  " STRINGIFY(UBL_MESH_MIN_Y));
1242
-    SERIAL_ECHOLNPAIR("=", UBL_MESH_MIN_Y );
1243 1237
     safe_delay(25);
1244 1238
 
1245
-    SERIAL_ECHOPGM("UBL_MESH_MAX_X  " STRINGIFY(UBL_MESH_MAX_X));
1246
-    SERIAL_ECHOLNPAIR("=", UBL_MESH_MAX_X);
1247
-    SERIAL_ECHOPGM("UBL_MESH_MAX_Y  " STRINGIFY(UBL_MESH_MAX_Y));
1248
-    SERIAL_ECHOLNPAIR("=", UBL_MESH_MAX_Y);
1239
+    SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes())));
1240
+    safe_delay(50);
1241
+
1242
+    SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes());
1243
+    SERIAL_PROTOCOLLNPGM(" meshes.\n");
1249 1244
     safe_delay(25);
1250 1245
 
1251 1246
     if (!sanity_check()) {
1252
-      say_ubl_name();
1253
-      SERIAL_PROTOCOLLNPGM("sanity checks passed.");
1247
+      echo_name();
1248
+      SERIAL_PROTOCOLLNPGM(" sanity checks passed.");
1254 1249
     }
1255 1250
   }
1256 1251
 
@@ -1284,27 +1279,32 @@
1284 1279
    * use cases for the users. So we can wait and see what to do with it.
1285 1280
    */
1286 1281
   void g29_compare_current_mesh_to_stored_mesh() {
1287
-    float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
1282
+    int16_t a = settings.calc_num_meshes();
1283
+
1284
+    if (!a) {
1285
+      SERIAL_PROTOCOLLNPGM("?EEPROM storage not available.");
1286
+      return;
1287
+    }
1288 1288
 
1289 1289
     if (!code_has_value()) {
1290
-      SERIAL_PROTOCOLLNPGM("?Mesh # required.\n");
1290
+      SERIAL_PROTOCOLLNPGM("?Storage slot # required.");
1291
+      SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
1291 1292
       return;
1292 1293
     }
1293
-    storage_slot = code_value_int();
1294 1294
 
1295
-    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(tmp_z_values);
1295
+    storage_slot = code_value_int();
1296 1296
 
1297
-    if (!WITHIN(storage_slot, 0, j - 1) || ubl.eeprom_start <= 0) {
1298
-      SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1297
+    if (!WITHIN(storage_slot, 0, a - 1)) {
1298
+      SERIAL_PROTOCOLLNPGM("?Invalid storage slot.");
1299
+      SERIAL_PROTOCOLLNPAIR("?Use 0 to ", a - 1);
1299 1300
       return;
1300 1301
     }
1301 1302
 
1302
-    j = UBL_LAST_EEPROM_INDEX - (storage_slot + 1) * sizeof(tmp_z_values);
1303
-    eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1303
+    float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
1304
+    settings.load_mesh(storage_slot, &tmp_z_values);
1304 1305
 
1305
-    SERIAL_ECHOPAIR("Subtracting Mesh ", storage_slot);
1306
-    SERIAL_PROTOCOLLNPAIR(" loaded from EEPROM address ", hex_address((void*)j)); // Soon, we can remove the extra clutter of printing
1307
-                                                                        // the address in the EEPROM where the Mesh is stored.
1306
+    SERIAL_PROTOCOLPAIR("Subtracting mesh in slot ", storage_slot);
1307
+    SERIAL_PROTOCOLLNPGM(" from current mesh.");
1308 1308
 
1309 1309
     for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
1310 1310
       for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
@@ -1396,7 +1396,7 @@
1396 1396
 
1397 1397
     memset(not_done, 0xFF, sizeof(not_done));
1398 1398
 
1399
-    LCD_MESSAGEPGM("Fine Tuning Mesh");
1399
+    LCD_MESSAGEPGM("Fine Tuning Mesh"); // TODO: Make translatable string
1400 1400
 
1401 1401
     do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1402 1402
     do_blocking_move_to_xy(lx, ly);
@@ -1454,7 +1454,7 @@
1454 1454
           lcd_return_to_status();
1455 1455
           //SERIAL_PROTOCOLLNPGM("\nFine Tuning of Mesh Stopped.");
1456 1456
           do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
1457
-          LCD_MESSAGEPGM("Mesh Editing Stopped");
1457
+          LCD_MESSAGEPGM("Mesh Editing Stopped"); // TODO: Make translatable string
1458 1458
 
1459 1459
           while (ubl_lcd_clicked()) idle();
1460 1460
 
@@ -1481,7 +1481,7 @@
1481 1481
 
1482 1482
     do_blocking_move_to_xy(lx, ly);
1483 1483
 
1484
-    LCD_MESSAGEPGM("Done Editing Mesh");
1484
+    LCD_MESSAGEPGM("Done Editing Mesh"); // TODO: Make translatable string
1485 1485
     SERIAL_ECHOLNPGM("Done Editing Mesh");
1486 1486
   }
1487 1487
 

+ 4
- 4
Marlin/ultralcd.cpp View File

@@ -1425,10 +1425,6 @@ void kill_screen(const char* lcd_msg) {
1425 1425
 
1426 1426
     static uint8_t manual_probe_index;
1427 1427
 
1428
-    #if ENABLED(PROBE_MANUALLY)
1429
-      extern bool g29_in_progress;
1430
-    #endif
1431
-
1432 1428
     // LCD probed points are from defaults
1433 1429
     constexpr uint8_t total_probe_points = (
1434 1430
       #if ENABLED(AUTO_BED_LEVELING_3POINT)
@@ -1645,6 +1641,10 @@ void kill_screen(const char* lcd_msg) {
1645 1641
 
1646 1642
   #if ENABLED(LCD_BED_LEVELING) || HAS_ABL
1647 1643
 
1644
+    #if ENABLED(PROBE_MANUALLY)
1645
+      extern bool g29_in_progress;
1646
+    #endif
1647
+
1648 1648
     /**
1649 1649
      * Step 2: Continue Bed Leveling...
1650 1650
      */

+ 13
- 0
Marlin/utility.cpp View File

@@ -34,6 +34,19 @@ void safe_delay(millis_t ms) {
34 34
   thermalManager.manage_heater(); // This keeps us safe if too many small safe_delay() calls are made
35 35
 }
36 36
 
37
+#if ENABLED(EEPROM_SETTINGS)
38
+
39
+  void crc16(uint16_t *crc, const void * const data, uint16_t cnt) {
40
+    uint8_t *ptr = (uint8_t*)data;
41
+    while (cnt-- > 0) {
42
+      *crc = (uint16_t)(*crc ^ (uint16_t)(((uint16_t)*ptr++) << 8));
43
+      for (uint8_t x = 0; x < 8; x++)
44
+        *crc = (uint16_t)((*crc & 0x8000) ? ((uint16_t)(*crc << 1) ^ 0x1021) : (*crc << 1));
45
+    }
46
+  }
47
+
48
+#endif // EEPROM_SETTINGS
49
+
37 50
 #if ENABLED(ULTRA_LCD)
38 51
 
39 52
   char conv[8] = { 0 };

+ 4
- 0
Marlin/utility.h View File

@@ -25,6 +25,10 @@
25 25
 
26 26
 void safe_delay(millis_t ms);
27 27
 
28
+#if ENABLED(EEPROM_SETTINGS)
29
+  void crc16(uint16_t *crc, const void * const data, uint16_t cnt);
30
+#endif
31
+
28 32
 #if ENABLED(ULTRA_LCD)
29 33
 
30 34
   // Convert unsigned int to string with 12 format

Loading…
Cancel
Save