Przeglądaj źródła

Corrections (#7231)

20x4 map integration.    Also some minor changes to the UBL Menu layout.     Both 20x4 LCD's and Graphical LCD panels should have similar functionality now.
Tannoo 6 lat temu
rodzic
commit
aaacef9441

+ 0
- 6
Marlin/Conditionals_LCD.h Wyświetl plik

@@ -273,12 +273,6 @@
273 273
     #define LCD_FEEDRATE_CHAR    0x06
274 274
     #define LCD_CLOCK_CHAR       0x07
275 275
     #define LCD_STR_ARROW_RIGHT ">"  /* from the default character set */
276
-
277
-    #if ENABLED(AUTO_BED_LEVELING_UBL)
278
-      #define LCD_UBL_BOXTOP_CHAR 0x01
279
-      #define LCD_UBL_BOXBOT_CHAR 0x02
280
-    #endif
281
-
282 276
   #endif
283 277
 
284 278
   /**

+ 3
- 0
Marlin/language_en.h Wyświetl plik

@@ -208,6 +208,9 @@
208 208
 #ifndef MSG_UBL_CUSTOM_HOTEND_TEMP
209 209
   #define MSG_UBL_CUSTOM_HOTEND_TEMP          MSG_UBL_SET_HOTEND_TEMP
210 210
 #endif
211
+#ifndef MSG_UBL_MESH_EDIT
212
+  #define MSG_UBL_MESH_EDIT                   _UxGT("Mesh Edit")
213
+#endif
211 214
 #ifndef MSG_UBL_EDIT_CUSTOM_MESH
212 215
   #define MSG_UBL_EDIT_CUSTOM_MESH            _UxGT("Edit Custom Mesh")
213 216
 #endif

+ 10
- 1
Marlin/stepper.cpp Wyświetl plik

@@ -62,6 +62,10 @@ Stepper stepper; // Singleton
62 62
 
63 63
 // public:
64 64
 
65
+#if ENABLED(AUTO_BED_LEVELING_UBL)
66
+  extern bool ubl_lcd_map_control;
67
+#endif
68
+
65 69
 block_t* Stepper::current_block = NULL;  // A pointer to the block currently being traced
66 70
 
67 71
 #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@@ -1281,7 +1285,12 @@ void Stepper::finish_and_disable() {
1281 1285
 }
1282 1286
 
1283 1287
 void Stepper::quick_stop() {
1284
-  cleaning_buffer_counter = 5000;
1288
+  #if ENABLED(AUTO_BED_LEVELING_UBL)
1289
+    if (!ubl_lcd_map_control)
1290
+      cleaning_buffer_counter = 5000;
1291
+  #else
1292
+    cleaning_buffer_counter = 5000;
1293
+  #endif
1285 1294
   DISABLE_STEPPER_DRIVER_INTERRUPT();
1286 1295
   while (planner.blocks_queued()) planner.discard_current_block();
1287 1296
   current_block = NULL;

+ 0
- 1
Marlin/ubl_G29.cpp Wyświetl plik

@@ -1533,7 +1533,6 @@
1533 1533
         while (ubl_lcd_clicked()) { // debounce and watch for abort
1534 1534
           idle();
1535 1535
           if (ELAPSED(millis(), nxt)) {
1536
-            ubl_lcd_map_control = false;
1537 1536
             lcd_return_to_status();
1538 1537
             do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
1539 1538
             LCD_MESSAGEPGM(MSG_EDITING_STOPPED);

+ 16
- 11
Marlin/ultralcd.cpp Wyświetl plik

@@ -467,6 +467,9 @@ uint16_t max_display_update_time = 0;
467 467
       encoderPosition = encoder;
468 468
       if (screen == lcd_status_screen) {
469 469
         defer_return_to_status = false;
470
+        #if ENABLED(AUTO_BED_LEVELING_UBL)
471
+          ubl_lcd_map_control = false;
472
+        #endif
470 473
         screen_history_depth = 0;
471 474
       }
472 475
       lcd_implementation_clear();
@@ -2149,14 +2152,11 @@ void kill_screen(const char* lcd_msg) {
2149 2152
 
2150 2153
     void _lcd_ubl_map_homing() {
2151 2154
       defer_return_to_status = true;
2152
-      if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL);
2155
+      ubl_lcd_map_control = true; // Return to the map screen
2156
+      if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT < 3 ? 0 : (LCD_HEIGHT > 4 ? 2 : 1), PSTR(MSG_LEVEL_BED_HOMING));
2153 2157
       lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW;
2154
-      if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) {
2155
-        #if DISABLED(DOGLCD)
2156
-          lcd_set_ubl_map_plot_chars();
2157
-        #endif
2158
+      if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
2158 2159
         lcd_goto_screen(_lcd_ubl_output_map_lcd);
2159
-      }
2160 2160
     }
2161 2161
 
2162 2162
     /**
@@ -2232,9 +2232,12 @@ void kill_screen(const char* lcd_msg) {
2232 2232
 
2233 2233
         ubl_map_move_to_xy(); // Move to current location
2234 2234
 
2235
-        if (planner.movesplanned() > 1) { // if the nozzle is moving, cancel the move. There is a new location
2236
-          quickstop_stepper();
2235
+        if (planner.movesplanned() > 1) { // if the nozzle is moving, cancel the move.  There is a new location
2236
+          stepper.quick_stop();
2237
+          set_current_from_steppers_for_axis(ALL_AXES);
2238
+          sync_plan_position();
2237 2239
           ubl_map_move_to_xy(); // Move to new location
2240
+          refresh_cmd_timeout();
2238 2241
         }
2239 2242
       }
2240 2243
     }
@@ -2243,9 +2246,10 @@ void kill_screen(const char* lcd_msg) {
2243 2246
      * UBL Homing before LCD map
2244 2247
      */
2245 2248
     void _lcd_ubl_output_map_lcd_cmd() {
2246
-      ubl_lcd_map_control = true; // Return to the map screen (and don't restore the character set)
2247
-      if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]))
2249
+      if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
2250
+        axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false;
2248 2251
         enqueue_and_echo_commands_P(PSTR("G28"));
2252
+      }
2249 2253
       lcd_goto_screen(_lcd_ubl_map_homing);
2250 2254
     }
2251 2255
 
@@ -2281,6 +2285,7 @@ void kill_screen(const char* lcd_msg) {
2281 2285
       START_MENU();
2282 2286
       MENU_BACK(MSG_UBL_LEVEL_BED);
2283 2287
       MENU_ITEM(submenu, MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh);
2288
+      MENU_ITEM(gcode, MSG_UBL_MANUAL_MESH, PSTR("G29 I999\nG29 P2 B T0"));
2284 2289
       MENU_ITEM(submenu, MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh);
2285 2290
       MENU_ITEM(submenu, MSG_UBL_EDIT_MESH_MENU, _lcd_ubl_edit_mesh);
2286 2291
       MENU_ITEM(submenu, MSG_UBL_MESH_LEVELING, _lcd_ubl_mesh_leveling);
@@ -2329,10 +2334,10 @@ void kill_screen(const char* lcd_msg) {
2329 2334
     void _lcd_ubl_level_bed() {
2330 2335
       START_MENU();
2331 2336
       MENU_BACK(MSG_PREPARE);
2332
-      MENU_ITEM(gcode, MSG_UBL_MANUAL_MESH, PSTR("G29 I999\nG29 P2 B T0"));
2333 2337
       MENU_ITEM(gcode, MSG_UBL_ACTIVATE_MESH, PSTR("G29 A"));
2334 2338
       MENU_ITEM(gcode, MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D"));
2335 2339
       MENU_ITEM(submenu, MSG_UBL_STEP_BY_STEP_MENU, _lcd_ubl_step_by_step);
2340
+      MENU_ITEM(function, MSG_UBL_MESH_EDIT, _lcd_ubl_output_map_lcd_cmd);
2336 2341
       MENU_ITEM(submenu, MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh);
2337 2342
       MENU_ITEM(submenu, MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map);
2338 2343
       MENU_ITEM(submenu, MSG_UBL_TOOLS, _lcd_ubl_tools_menu);

+ 453
- 74
Marlin/ultralcd_impl_HD44780.h Wyświetl plik

@@ -33,6 +33,20 @@
33 33
 
34 34
 #if ENABLED(AUTO_BED_LEVELING_UBL)
35 35
   #include "ubl.h"
36
+
37
+  #if ENABLED(ULTIPANEL)
38
+    #define ULTRA_X_PIXELS_PER_CHAR    5
39
+    #define ULTRA_Y_PIXELS_PER_CHAR    8
40
+    #define ULTRA_COLUMNS_FOR_MESH_MAP 7
41
+    #define ULTRA_ROWS_FOR_MESH_MAP    4
42
+
43
+    #define N_USER_CHARS    8
44
+
45
+    #define TOP_LEFT      0x01
46
+    #define TOP_RIGHT     0x02
47
+    #define LOWER_LEFT    0x04
48
+    #define LOWER_RIGHT   0x08
49
+  #endif
36 50
 #endif
37 51
 
38 52
 extern volatile uint8_t buttons;  //an extended version of the last checked buttons in a bit array.
@@ -1078,68 +1092,68 @@ static void lcd_implementation_status_screen() {
1078 1092
       lcd.setBacklight(leds);
1079 1093
       ledsprev = leds;
1080 1094
     }
1081
-
1082 1095
   }
1083 1096
 
1084 1097
 #endif // LCD_HAS_STATUS_INDICATORS
1085 1098
 
1086 1099
 #if ENABLED(AUTO_BED_LEVELING_UBL)
1087 1100
 
1088
-  /**
1089
-   * These are just basic data for the 20x4 LCD work that
1090
-   * is coming up very soon.
1091
-   * Soon this will morph into a map code.
1092
-   */
1101
+   /**
1102
+    Possible map screens:
1093 1103
 
1094
-  /**
1095
-  Possible map screens:
1104
+    16x2   |X000.00  Y000.00|
1105
+           |(00,00)  Z00.000|
1096 1106
 
1097
-  16x2   |X000.00  Y000.00|
1098
-         |(00,00)  Z00.000|
1107
+    20x2   | X:000.00  Y:000.00 |
1108
+           | (00,00)   Z:00.000 |
1099 1109
 
1100
-  20x2   | X:000.00  Y:000.00 |
1101
-         | (00,00)   Z:00.000 |
1110
+    16x4   |+-------+(00,00)|
1111
+           ||       |X000.00|
1112
+           ||       |Y000.00|
1113
+           |+-------+Z00.000|
1102 1114
 
1103
-  16x4   |+-------+(00,00)|
1104
-         ||       |X000.00|
1105
-         ||       |Y000.00|
1106
-         |+-------+Z00.000|
1115
+    20x4   | +-------+  (00,00) |
1116
+           | |       |  X:000.00|
1117
+           | |       |  Y:000.00|
1118
+           | +-------+  Z:00.000|
1119
+    */
1107 1120
 
1108
-  20x4   | +-------+  (00,00) |
1109
-         | |       |  X:000.00|
1110
-         | |       |  Y:000.00|
1111
-         | +-------+  Z:00.000|
1112
-  */
1121
+  struct custom_char {
1122
+    uint8_t custom_char_bits[ULTRA_Y_PIXELS_PER_CHAR];
1123
+  };
1113 1124
 
1114
-  void lcd_set_ubl_map_plot_chars() {
1115
-    #if LCD_HEIGHT > 3
1116
-      //#include "_ubl_lcd_map_characters.h"
1117
-      const static byte _lcd_box_top[8] PROGMEM = {
1118
-        B11111,
1119
-        B00000,
1120
-        B00000,
1121
-        B00000,
1122
-        B00000,
1123
-        B00000,
1124
-        B00000,
1125
-        B00000
1126
-      };
1127
-      const static byte _lcd_box_bottom[8] PROGMEM = {
1128
-        B00000,
1129
-        B00000,
1130
-        B00000,
1131
-        B00000,
1132
-        B00000,
1133
-        B00000,
1134
-        B00000,
1135
-        B11111
1136
-      };
1137
-      createChar_P(LCD_UBL_BOXTOP_CHAR, _lcd_box_top);
1138
-      createChar_P(LCD_UBL_BOXBOT_CHAR, _lcd_box_bottom);
1139
-    #endif
1125
+  struct coordinate pixel_location(uint8_t x, uint8_t y);
1126
+
1127
+  struct coordinate {
1128
+          uint8_t column;
1129
+          uint8_t row;
1130
+          uint8_t y_pixel_offset;
1131
+          uint8_t x_pixel_offset;
1132
+          uint8_t x_pixel_mask;
1133
+  };
1134
+
1135
+  void add_edges_to_custom_char(struct custom_char *custom, struct coordinate *ul, struct coordinate *lr, struct coordinate *brc, uint8_t cell_location);
1136
+  extern custom_char user_defined_chars[N_USER_CHARS];
1137
+  inline static void CLEAR_CUSTOM_CHAR(struct custom_char *cc) { uint8_t j; for (j = 0; j < ULTRA_Y_PIXELS_PER_CHAR; j++) cc->custom_char_bits[j] = 0; }
1138
+
1139
+  /*
1140
+  void dump_custom_char(char *title, struct custom_char *c) {   // This debug routine should be deleted by anybody that sees it.  It doesn't belong here
1141
+    int i, j;                                                     // But I'm leaving it for now until we know the 20x4 Radar Map is working right.
1142
+    SERIAL_PROTOCOLLN(title);                                   // We will need it again if any funny lines show up on the mesh points.
1143
+    for(j=0; j<8; j++) {
1144
+      for(i=7; i>=0; i--) {
1145
+        if (c->custom_char_bits[j] & (0x01 << i))
1146
+          SERIAL_PROTOCOL("1");
1147
+        else
1148
+          SERIAL_PROTOCOL("0");
1149
+      }
1150
+      SERIAL_PROTOCOL("\n");
1151
+    }
1152
+    SERIAL_PROTOCOL("\n");
1140 1153
   }
1154
+  */
1141 1155
 
1142
-  void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) {
1156
+  void lcd_implementation_ubl_plot(uint8_t x, uint8_t inverted_y) {
1143 1157
 
1144 1158
     #if LCD_WIDTH >= 20
1145 1159
       #define _LCD_W_POS 12
@@ -1165,38 +1179,233 @@ static void lcd_implementation_status_screen() {
1165 1179
        * Show X and Y positions
1166 1180
        */
1167 1181
       _XLABEL(_PLOT_X, 0);
1168
-      lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
1182
+      lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x]))));
1169 1183
 
1170 1184
       _YLABEL(_LCD_W_POS, 0);
1171
-      lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
1185
+      lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y]))));
1172 1186
 
1173 1187
       lcd.setCursor(_PLOT_X, 0);
1174 1188
 
1175
-    #else                 // 16x4 or 20x4 display
1189
+    #else // 16x4 or 20x4 display
1176 1190
 
1177
-      /**
1178
-       * Draw the Mesh Map Box
1191
+      struct coordinate upper_left, lower_right, bottom_right_corner;
1192
+      struct custom_char new_char;
1193
+      uint8_t i, j, k, l, m, n, n_rows, n_cols, y;
1194
+      uint8_t bottom_line, right_edge;
1195
+      uint8_t x_map_pixels, y_map_pixels;
1196
+      uint8_t pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt;
1197
+      uint8_t suppress_x_offset=0, suppress_y_offset=0;
1198
+
1199
+      //  ********************************************************
1200
+      //  ************ Clear and setup everything        *********
1201
+      //  ********************************************************
1202
+
1203
+      y = GRID_MAX_POINTS_Y - inverted_y - 1;
1204
+
1205
+      upper_left.column  = 0;
1206
+      upper_left.row     = 0;
1207
+      lower_right.column = 0;
1208
+      lower_right.row    = 0;
1209
+
1210
+      lcd_implementation_clear();
1211
+
1212
+      x_map_pixels = ULTRA_X_PIXELS_PER_CHAR * ULTRA_COLUMNS_FOR_MESH_MAP - 2;  // minus 2 because we are drawing a box around the map
1213
+      y_map_pixels = ULTRA_Y_PIXELS_PER_CHAR * ULTRA_ROWS_FOR_MESH_MAP - 2;
1214
+
1215
+      pixels_per_X_mesh_pnt = x_map_pixels / GRID_MAX_POINTS_X;
1216
+      pixels_per_Y_mesh_pnt = y_map_pixels / GRID_MAX_POINTS_Y;
1217
+
1218
+      if (pixels_per_X_mesh_pnt >= ULTRA_X_PIXELS_PER_CHAR)  {                  // There are only 2 custom characters available, so the X
1219
+        pixels_per_X_mesh_pnt = ULTRA_X_PIXELS_PER_CHAR;                        // size of the mesh point needs to fit within them independent
1220
+        suppress_x_offset = 1;                                                  // of where the starting pixel is located.
1221
+      }
1222
+
1223
+      if (pixels_per_Y_mesh_pnt >= ULTRA_Y_PIXELS_PER_CHAR) {                   // There are only 2 custom characters available, so the Y
1224
+        pixels_per_Y_mesh_pnt = ULTRA_Y_PIXELS_PER_CHAR;                        // size of the mesh point needs to fit within them independent
1225
+        suppress_y_offset = 1;                                                  // of where the starting pixel is located.
1226
+      }
1227
+
1228
+      x_map_pixels = pixels_per_X_mesh_pnt * GRID_MAX_POINTS_X;                 // now we have the right number of pixels to make both
1229
+      y_map_pixels = pixels_per_Y_mesh_pnt * GRID_MAX_POINTS_Y;                 // directions fit nicely
1230
+
1231
+      right_edge = pixels_per_X_mesh_pnt * GRID_MAX_POINTS_X + 1;               // find location of right edge within the character cell
1232
+      bottom_line= pixels_per_Y_mesh_pnt * GRID_MAX_POINTS_Y + 1;               // find location of bottome line within the character cell
1233
+
1234
+      n_rows = (bottom_line / ULTRA_Y_PIXELS_PER_CHAR) + 1;
1235
+      n_cols = (right_edge / ULTRA_X_PIXELS_PER_CHAR) + 1;
1236
+
1237
+      for (i = 0; i < n_cols; i++) {
1238
+        lcd.setCursor(i, 0);
1239
+        lcd.print((char) 0x00);                    // top line of the box
1240
+
1241
+        lcd.setCursor(i, n_rows-1);
1242
+        lcd.write(0x01);                           // bottom line of the box
1243
+      }
1244
+
1245
+      for (j = 0; j < n_rows; j++) {
1246
+        lcd.setCursor(0, j);
1247
+        lcd.write(0x02);                           // Left edge of the box
1248
+        lcd.setCursor(n_cols-1, j);
1249
+        lcd.write(0x03);                           // right edge of the box
1250
+      }
1251
+
1252
+      //
1253
+      /* if the entire 4th row is not in use, do not put vertical bars all the way down to the bottom of the display */
1254
+      //
1255
+
1256
+      k = pixels_per_Y_mesh_pnt * GRID_MAX_POINTS_Y + 2;
1257
+      l = ULTRA_Y_PIXELS_PER_CHAR * n_rows;
1258
+      if ((k != l) && ((l-k)>=ULTRA_Y_PIXELS_PER_CHAR/2)) {
1259
+        lcd.setCursor(0, n_rows-1);            // left edge of the box
1260
+        lcd.write(' ');
1261
+        lcd.setCursor(n_cols-1, n_rows-1);     // right edge of the box
1262
+        lcd.write(' ');
1263
+      }
1264
+
1265
+      CLEAR_CUSTOM_CHAR(&new_char);
1266
+      new_char.custom_char_bits[0] = (unsigned char) 0B11111;                // char #0 is used for the top line of the box
1267
+      lcd.createChar(0, (uint8_t *) &new_char);
1268
+
1269
+      CLEAR_CUSTOM_CHAR(&new_char);
1270
+      k = GRID_MAX_POINTS_Y * pixels_per_Y_mesh_pnt + 1;                     // row of pixels for the bottom box line
1271
+      l = k % ULTRA_Y_PIXELS_PER_CHAR;                                       // row within relivant character cell
1272
+      new_char.custom_char_bits[l] = (unsigned char) 0B11111;                // char #1 is used for the bottom line of the box
1273
+      lcd.createChar(1, (uint8_t *) &new_char);
1274
+
1275
+      CLEAR_CUSTOM_CHAR(&new_char);
1276
+      for (j = 0; j < ULTRA_Y_PIXELS_PER_CHAR; j++)
1277
+        new_char.custom_char_bits[j] = (unsigned char) 0B10000;              // char #2 is used for the left edge of the box
1278
+      lcd.createChar(2, (uint8_t *) &new_char);
1279
+
1280
+      CLEAR_CUSTOM_CHAR(&new_char);
1281
+      m = GRID_MAX_POINTS_X * pixels_per_X_mesh_pnt + 1;                     // column of pixels for the right box line
1282
+      n = m % ULTRA_X_PIXELS_PER_CHAR;                                       // column within relivant character cell
1283
+      i = ULTRA_X_PIXELS_PER_CHAR - 1 - n;                                   // column within relivant character cell (0 on the right)
1284
+      for (j = 0; j < ULTRA_Y_PIXELS_PER_CHAR; j++)
1285
+        new_char.custom_char_bits[j] = (unsigned char) 0B00001 << i;         // char #3 is used for the right edge of the box
1286
+      lcd.createChar(3, (uint8_t *) &new_char);
1287
+
1288
+      i = x*pixels_per_X_mesh_pnt - suppress_x_offset;
1289
+      j = y*pixels_per_Y_mesh_pnt - suppress_y_offset;
1290
+      upper_left = pixel_location(i, j);
1291
+
1292
+      k = (x+1)*pixels_per_X_mesh_pnt-1-suppress_x_offset;
1293
+      l = (y+1)*pixels_per_Y_mesh_pnt-1-suppress_y_offset;
1294
+      lower_right = pixel_location(k, l);
1295
+
1296
+      bottom_right_corner = pixel_location(x_map_pixels, y_map_pixels);
1297
+
1298
+      /*
1299
+       * First, handle the simple case where everything is within a single character cell.
1300
+       * If part of the Mesh Plot is outside of this character cell, we will follow up
1301
+       * and deal with that next.
1179 1302
        */
1180
-      uint8_t m;
1181
-      lcd.setCursor(_MAP_X, 0); for (m = 0; m < 5; m++) lcd.write(LCD_UBL_BOXTOP_CHAR); // Top
1182
-      lcd.setCursor(_MAP_X, 3); for (m = 0; m < 5; m++) lcd.write(LCD_UBL_BOXBOT_CHAR); // Bottom
1183
-      for (m = 0; m <= 3; m++) {
1184
-        lcd.setCursor(2, m); lcd.write('|'); // Left
1185
-        lcd.setCursor(8, m); lcd.write('|'); // Right
1303
+
1304
+  //dump_custom_char("at entry:", &new_char);
1305
+
1306
+      CLEAR_CUSTOM_CHAR(&new_char);
1307
+      for(j=upper_left.y_pixel_offset; j<upper_left.y_pixel_offset+pixels_per_Y_mesh_pnt; j++) {
1308
+        if (j >= ULTRA_Y_PIXELS_PER_CHAR)
1309
+          break;
1310
+        i=upper_left.x_pixel_mask;
1311
+        for(k=0; k<pixels_per_X_mesh_pnt; k++)  {
1312
+          new_char.custom_char_bits[j] |= i;
1313
+          i = i >> 1;
1314
+        }
1186 1315
       }
1316
+  //dump_custom_char("after loops:", &new_char);
1187 1317
 
1188
-      lcd.setCursor(_LCD_W_POS, 0);
1318
+      add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, TOP_LEFT);
1319
+  //dump_custom_char("after add edges", &new_char);
1320
+      lcd.createChar(4, (uint8_t *) &new_char);
1321
+
1322
+      lcd.setCursor(upper_left.column, upper_left.row);
1323
+      lcd.write(0x04);
1324
+  //dump_custom_char("after lcd update:", &new_char);
1325
+
1326
+      /*
1327
+       * Next, check for two side by side character cells being used to display the Mesh Point
1328
+       * If found...  do the right hand character cell next.
1329
+       */
1330
+      if (upper_left.column+1 == lower_right.column) {
1331
+        l = upper_left.x_pixel_offset;
1332
+        CLEAR_CUSTOM_CHAR(&new_char);
1333
+        for (j = upper_left.y_pixel_offset; j < upper_left.y_pixel_offset + pixels_per_Y_mesh_pnt; j++) {
1334
+          if (j >= ULTRA_Y_PIXELS_PER_CHAR)
1335
+            break;
1336
+          i=0x01 << (ULTRA_X_PIXELS_PER_CHAR-1);                  // fill in the left side of the right character cell
1337
+          for(k=0; k<pixels_per_X_mesh_pnt-1-l; k++)  {
1338
+            new_char.custom_char_bits[j] |= i;
1339
+            i = i >> 1;
1340
+          }
1341
+        }
1342
+        add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, TOP_RIGHT);
1343
+
1344
+        lcd.createChar(5, (uint8_t *) &new_char);
1345
+
1346
+        lcd.setCursor(lower_right.column, upper_left.row);
1347
+        lcd.write(0x05);
1348
+      }
1349
+
1350
+      /*
1351
+       * Next, check for two character cells stacked on top of each other being used to display the Mesh Point
1352
+       */
1353
+      if (upper_left.row+1 == lower_right.row) {
1354
+        l = ULTRA_Y_PIXELS_PER_CHAR - upper_left.y_pixel_offset;        // number of pixel rows in top character cell
1355
+        k = pixels_per_Y_mesh_pnt - l;                                  // number of pixel rows in bottom character cell
1356
+        CLEAR_CUSTOM_CHAR(&new_char);
1357
+        for(j=0; j<k; j++) {
1358
+          i=upper_left.x_pixel_mask;
1359
+          for(m=0; m<pixels_per_X_mesh_pnt; m++)  {                     // fill in the top side of the bottom character cell
1360
+            new_char.custom_char_bits[j] |= i;
1361
+            i = i >> 1;
1362
+            if (!i)
1363
+              break;
1364
+          }
1365
+        }
1366
+        add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, LOWER_LEFT);
1367
+        lcd.createChar(6, (uint8_t *) &new_char);
1368
+
1369
+        lcd.setCursor(upper_left.column, lower_right.row);
1370
+        lcd.write(0x06);
1371
+      }
1372
+
1373
+      /*
1374
+       * Next, check for four character cells being used to display the Mesh Point.  If that is
1375
+       * what is here, we work to fill in the character cell that is down one and to the right one
1376
+       * from the upper_left character cell.
1377
+       */
1378
+
1379
+      if (upper_left.column+1 == lower_right.column && upper_left.row+1 == lower_right.row) {
1380
+        l = ULTRA_Y_PIXELS_PER_CHAR - upper_left.y_pixel_offset;        // number of pixel rows in top character cell
1381
+        k = pixels_per_Y_mesh_pnt - l;                                  // number of pixel rows in bottom character cell
1382
+        CLEAR_CUSTOM_CHAR(&new_char);
1383
+        for (j = 0; j<k; j++) {
1384
+          l = upper_left.x_pixel_offset;
1385
+          i = 0x01 << (ULTRA_X_PIXELS_PER_CHAR - 1);                    // fill in the left side of the right character cell
1386
+          for (m = 0; m<pixels_per_X_mesh_pnt - 1 - l; m++) {           // fill in the top side of the bottom character cell
1387
+            new_char.custom_char_bits[j] |= i;
1388
+            i = i >> 1;
1389
+          }
1390
+        }
1391
+        add_edges_to_custom_char(&new_char, &upper_left, &lower_right, &bottom_right_corner, LOWER_RIGHT);
1392
+        lcd.createChar(7, (uint8_t *) &new_char);
1393
+
1394
+        lcd.setCursor(lower_right.column, lower_right.row);
1395
+        lcd.write(0x07);
1396
+      }
1189 1397
 
1190 1398
     #endif
1191 1399
 
1192
-    /**
1193
-     * Print plot position
1194
-     */
1195
-    lcd.write('(');
1196
-    lcd.print(x_plot);
1197
-    lcd.write(',');
1198
-    lcd.print(y_plot);
1199
-    lcd.write(')');
1400
+      /**
1401
+       * Print plot position
1402
+       */
1403
+      lcd.setCursor(_LCD_W_POS, 0);
1404
+      lcd.write('(');
1405
+      lcd.print(x);
1406
+      lcd.write(',');
1407
+      lcd.print(inverted_y);
1408
+      lcd.write(')');
1200 1409
 
1201 1410
     #if LCD_HEIGHT <= 3   // 16x2 or 20x2 display
1202 1411
 
@@ -1204,8 +1413,8 @@ static void lcd_implementation_status_screen() {
1204 1413
        * Print Z values
1205 1414
        */
1206 1415
       _ZLABEL(_LCD_W_POS, 1);
1207
-      if (!isnan(ubl.z_values[x_plot][y_plot]))
1208
-        lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
1416
+      if (!isnan(ubl.z_values[x][inverted_y]))
1417
+        lcd.print(ftostr43sign(ubl.z_values[x][inverted_y]));
1209 1418
       else
1210 1419
         lcd_printPGM(PSTR(" -----"));
1211 1420
 
@@ -1215,20 +1424,190 @@ static void lcd_implementation_status_screen() {
1215 1424
        * Show all values at right of screen
1216 1425
        */
1217 1426
       _XLABEL(_LCD_W_POS, 1);
1218
-      lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
1427
+      lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x]))));
1219 1428
       _YLABEL(_LCD_W_POS, 2);
1220
-      lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
1429
+      lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[inverted_y]))));
1221 1430
 
1222 1431
       /**
1223 1432
        * Show the location value
1224 1433
        */
1225 1434
       _ZLABEL(_LCD_W_POS, 3);
1226
-      if (!isnan(ubl.z_values[x_plot][y_plot]))
1227
-        lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot]));
1435
+      if (!isnan(ubl.z_values[x][inverted_y]))
1436
+        lcd.print(ftostr43sign(ubl.z_values[x][inverted_y]));
1228 1437
       else
1229 1438
         lcd_printPGM(PSTR(" -----"));
1230 1439
 
1231 1440
     #endif // LCD_HEIGHT > 3
1441
+
1442
+    return;
1443
+  }
1444
+void add_edges_to_custom_char(struct custom_char *custom, struct coordinate *ul, struct coordinate *lr, struct coordinate *brc, unsigned char cell_location) {
1445
+  unsigned char i, k;
1446
+  int n_rows, n_cols;
1447
+
1448
+  n_rows = lr->row    - ul->row    + 1;
1449
+  n_cols = lr->column - ul->column + 1;
1450
+
1451
+  /*
1452
+   * Check if Top line of box needs to be filled in
1453
+   */
1454
+  if ((ul->row == 0) && ((cell_location&TOP_LEFT) || (cell_location&TOP_RIGHT))) {   // Only fill in the top line for the top character cells
1455
+
1456
+    if (n_cols == 1)  {
1457
+      if (ul->column != brc->column)
1458
+        custom->custom_char_bits[0] = 0xff;                              // single column in middle
1459
+      else {
1460
+        for (i = brc->x_pixel_offset; i<ULTRA_X_PIXELS_PER_CHAR; i++)    // single column on right side
1461
+          custom->custom_char_bits[0] |= 0x01 << i;
1462
+      }
1463
+    } 
1464
+    else {                                                            
1465
+      if (cell_location & TOP_LEFT)
1466
+        custom->custom_char_bits[0] = 0xff;                              // multiple column in the middle
1467
+      else
1468
+        if (lr->column != brc->column)                                     
1469
+          custom->custom_char_bits[0] = 0xff;                            // multiple column with right cell in middle
1470
+        else {
1471
+          for (i = brc->x_pixel_offset; i<ULTRA_X_PIXELS_PER_CHAR; i++)
1472
+            custom->custom_char_bits[0] |= 0x01 << i;
1473
+        }
1474
+    }
1475
+  }
1476
+
1477
+  /*
1478
+   * Check if left line of box needs to be filled in
1479
+   */
1480
+  if ((cell_location & TOP_LEFT) || (cell_location & LOWER_LEFT)) {
1481
+    if (ul->column == 0) {                          // Left column of characters on LCD Display
1482
+      if (ul->row != brc->row)
1483
+        k = ULTRA_Y_PIXELS_PER_CHAR;      // if it isn't the last row... do the full character cell
1484
+      else
1485
+        k = brc->y_pixel_offset;
1486
+
1487
+      for (i = 0; i < k; i++)
1488
+        custom->custom_char_bits[i] |= 0x01 << (ULTRA_X_PIXELS_PER_CHAR - 1);
1489
+    }
1490
+  }
1491
+
1492
+  /*
1493
+   * Check if bottom line of box needs to be filled in
1494
+   */
1495
+
1496
+   // Single row of mesh plot cells
1497
+   if ((n_rows==1) /* && ((cell_location == TOP_LEFT) || (cell_location==TOP_RIGHT)) */) {
1498
+     if (ul->row == brc->row)  {
1499
+       if (n_cols == 1) {                 // single row, single column case
1500
+          if (ul->column != brc->column) 
1501
+            k = 0x01;
1502
+          else 
1503
+            k = brc->x_pixel_mask;
1504
+       } else {
1505
+          if (cell_location & TOP_RIGHT) {  // single row, multiple column case
1506
+            if(lr->column != brc->column)   
1507
+              k = 0x01;
1508
+            else 
1509
+              k = brc->x_pixel_mask;
1510
+          } else                            // single row, left of multiple columns
1511
+            k = 0x01;
1512
+       }
1513
+       while (k < (0x01 << ULTRA_X_PIXELS_PER_CHAR)) {
1514
+         custom->custom_char_bits[brc->y_pixel_offset] |= k;
1515
+         k = k << 1;
1516
+       }
1517
+     }
1518
+   }
1519
+
1520
+
1521
+  // Double row of characters on LCD Display
1522
+  // And this is a bottom custom character
1523
+   if ((n_rows==2) && ((cell_location == LOWER_LEFT) || (cell_location==LOWER_RIGHT))) {
1524
+     if (lr->row == brc->row)  {
1525
+       if (n_cols == 1) {                 // double row, single column case
1526
+          if (ul->column != brc->column) 
1527
+            k = 0x01;
1528
+          else 
1529
+            k = brc->x_pixel_mask;
1530
+       } else {
1531
+          if (cell_location & LOWER_RIGHT) {  // double row, multiple column case
1532
+            if(lr->column != brc->column)   
1533
+              k = 0x01;
1534
+            else 
1535
+              k = brc->x_pixel_mask;
1536
+          } else                            // double row, left of multiple columns
1537
+            k = 0x01;
1538
+       }
1539
+       while (k < (0x01 << ULTRA_X_PIXELS_PER_CHAR)) {
1540
+         custom->custom_char_bits[brc->y_pixel_offset] |= k;
1541
+         k = k << 1;
1542
+       }
1543
+     }
1544
+   }
1545
+
1546
+   /*
1547
+    * Check if right line of box needs to be filled in
1548
+    */
1549
+
1550
+   if (lr->column == brc->column) {     // nothing to do if the lower right part of the mesh pnt isn't in the same column as the box line
1551
+     if ((ul->column == brc->column) ||
1552
+        ((lr->column == brc->column) && (cell_location&TOP_RIGHT)) ||
1553
+        ((lr->column == brc->column) && (cell_location&LOWER_RIGHT))) {   // This mesh point is in the same character cell as the right box line
1554
+
1555
+       if (ul->row != brc->row)
1556
+         k = ULTRA_Y_PIXELS_PER_CHAR;      // if it isn't the last row... do the full character cell
1557
+       else
1558
+         k = brc->y_pixel_offset;
1559
+
1560
+       for (i = 0; i < k; i++)
1561
+         custom->custom_char_bits[i] |= brc->x_pixel_mask;
1562
+     }
1563
+   }
1564
+ }
1565
+
1566
+  struct coordinate pixel_location(int x, int y) {
1567
+    struct coordinate ret_val;
1568
+    int xp, yp, r, c;
1569
+
1570
+    x++;  // +1 because there is a line on the left 
1571
+    y++;  // and a line at the top to make the box
1572
+
1573
+    c = x / ULTRA_X_PIXELS_PER_CHAR;
1574
+    r = y / ULTRA_Y_PIXELS_PER_CHAR;
1575
+
1576
+    ret_val.column = c;
1577
+    ret_val.row    = r;
1578
+
1579
+    xp = x - c * ULTRA_X_PIXELS_PER_CHAR;   // get the pixel offsets into the character cell
1580
+    xp = ULTRA_X_PIXELS_PER_CHAR - 1 - xp;  // column within relivant character cell (0 on the right)
1581
+    yp = y - r * ULTRA_Y_PIXELS_PER_CHAR;
1582
+
1583
+    ret_val.x_pixel_mask   = 0x01 << xp;
1584
+    ret_val.x_pixel_offset = xp;
1585
+    ret_val.y_pixel_offset = yp;
1586
+    return ret_val;
1587
+  }
1588
+
1589
+  struct coordinate pixel_location(uint8_t x, uint8_t y) {
1590
+    struct coordinate ret_val;
1591
+    uint8_t xp, yp, r, c;
1592
+
1593
+    x++;  // +1 because there is a line on the left
1594
+    y++;  // and a line at the top to make the box
1595
+
1596
+    c = x / ULTRA_X_PIXELS_PER_CHAR;
1597
+    r = y / ULTRA_Y_PIXELS_PER_CHAR;
1598
+
1599
+    ret_val.column = c;
1600
+    ret_val.row    = r;
1601
+
1602
+    xp = x - c * ULTRA_X_PIXELS_PER_CHAR;   // get the pixel offsets into the character cell
1603
+    xp = ULTRA_X_PIXELS_PER_CHAR - 1 - xp;  // column within relivant character cell (0 on the right)
1604
+    yp = y - r * ULTRA_Y_PIXELS_PER_CHAR;
1605
+
1606
+    ret_val.x_pixel_mask   = 0x01 << xp;
1607
+    ret_val.x_pixel_offset = xp;
1608
+    ret_val.y_pixel_offset = yp;
1609
+
1610
+    return ret_val;
1232 1611
   }
1233 1612
 
1234 1613
 #endif // AUTO_BED_LEVELING_UBL

Ładowanie…
Anuluj
Zapisz