Explorar el Código

Support new style Anycubic Chiron TFT (#21597)

Nick hace 4 años
padre
commit
d5143c2c15
No account linked to committer's email address

+ 25
- 0
Marlin/Configuration_adv.h Ver fichero

1618
 #endif // HAS_DGUS_LCD
1618
 #endif // HAS_DGUS_LCD
1619
 
1619
 
1620
 //
1620
 //
1621
+// Additional options for AnyCubic Chiron TFT displays
1622
+//
1623
+#if ENABLED(ANYCUBIC_LCD_CHIRON)
1624
+  // By default the type of panel is automatically detected.
1625
+  // Enable one of these options if you know the panel type.
1626
+  //#define CHIRON_TFT_STANDARD
1627
+  //#define CHIRON_TFT_NEW
1628
+
1629
+  // Enable the longer Anycubic powerup startup tune
1630
+  //#define AC_DEFAULT_STARTUP_TUNE
1631
+
1632
+  /**
1633
+   * Display Folders
1634
+   * By default the file browser lists all G-code files (including those in subfolders) in a flat list.
1635
+   * Enable this option to display a hierarchical file browser.
1636
+   *
1637
+   * NOTES:
1638
+   * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders.
1639
+   * - When used with the "new" panel, folder names will also have '.gcode' appended to their names.
1640
+   *   This hack is currently required to force the panel to show folders.
1641
+   */
1642
+  #define AC_SD_FOLDER_VIEW
1643
+#endif
1644
+
1645
+//
1621
 // Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
1646
 // Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
1622
 //
1647
 //
1623
 #if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE)
1648
 #if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE)

+ 4
- 0
Marlin/src/inc/SanityCheck.h Ver fichero

2443
   #error "GRAPHICAL_TFT_UPSCALE must be 2, 3, or 4."
2443
   #error "GRAPHICAL_TFT_UPSCALE must be 2, 3, or 4."
2444
 #endif
2444
 #endif
2445
 
2445
 
2446
+#if BOTH(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW)
2447
+  #error "Please select only one of CHIRON_TFT_STANDARD or CHIRON_TFT_NEW."
2448
+#endif
2449
+
2446
 /**
2450
 /**
2447
  * Some boards forbid the use of -1 Native USB
2451
  * Some boards forbid the use of -1 Native USB
2448
  */
2452
  */

+ 183
- 89
Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp Ver fichero

26
  * Extensible_UI implementation for Anycubic Chiron
26
  * Extensible_UI implementation for Anycubic Chiron
27
  * Written By Nick Wells, 2020 [https://github.com/SwiftNick]
27
  * Written By Nick Wells, 2020 [https://github.com/SwiftNick]
28
  *  (not affiliated with Anycubic, Ltd.)
28
  *  (not affiliated with Anycubic, Ltd.)
29
+ *
30
+ * The AC panel wants files in block of 4 and can only display a flat list
31
+ * This library allows full folder traversal or flat file display and supports both standerd and new style panels.
32
+ *
33
+ * ## Old Style TFT panel
34
+ * Supported chars	{}[]-+=_"$%^&*()~<>|
35
+ * Max display length 22 chars
36
+ * Max path len 29 chars
37
+ * (DOS 8.3 filepath max 29chars)
38
+ * (long filepath Max 22)
39
+ *
40
+ * ## New TFT Panel Format file display format
41
+ * Supported chars	{}[]-+=_!"$%^&*()~<>\|
42
+ * Max display length 26 chars
43
+ * Max path len 29 chars
44
+ * (DOS 8.3 filepath must end '.GCO')
45
+ * (long filepath must end '.gcode')
46
+ *
29
  */
47
  */
30
 
48
 
31
-/***************************************************************************
32
- * The AC panel wants files in block of 4 and can only display a flat list *
33
- * This library allows full folder traversal.                              *
34
- ***************************************************************************/
35
-
36
 #include "../../../../inc/MarlinConfigPre.h"
49
 #include "../../../../inc/MarlinConfigPre.h"
37
 
50
 
38
 #if ENABLED(ANYCUBIC_LCD_CHIRON)
51
 #if ENABLED(ANYCUBIC_LCD_CHIRON)
39
-
40
 #include "FileNavigator.h"
52
 #include "FileNavigator.h"
41
 #include "chiron_tft.h"
53
 #include "chiron_tft.h"
42
 
54
 
43
 using namespace ExtUI;
55
 using namespace ExtUI;
44
 
56
 
57
+#define DEBUG_OUT ACDEBUG(AC_FILE)
58
+#include "../../../../core/debug_out.h"
59
+
45
 namespace Anycubic {
60
 namespace Anycubic {
46
 
61
 
47
-  FileNavigator filenavigator;
62
+FileNavigator filenavigator;
63
+FileList  FileNavigator::filelist;                          // Instance of the Marlin file API
64
+uint16_t  FileNavigator::lastpanelindex;
65
+uint16_t  FileNavigator::currentindex;                      // override the panel request
66
+uint8_t   FileNavigator::currentfolderdepth;
67
+uint16_t  FileNavigator::currentfolderindex[MAX_FOLDER_DEPTH];   // track folder pos for iteration
68
+char      FileNavigator::currentfoldername[MAX_PATH_LEN + 1];   // Current folder path
69
+
70
+FileNavigator::FileNavigator() { reset(); }
71
+
72
+void FileNavigator::reset() {
73
+  DEBUG_ECHOLNPGM("reset()");
74
+  currentfoldername[0] = '\0';
75
+  currentfolderdepth = 0;
76
+  currentindex = 0;
77
+  lastpanelindex = 0;
78
+  ZERO(currentfolderindex)
79
+
80
+  // Start at root folder
81
+  while (!filelist.isAtRootDir()) filelist.upDir();
82
+  refresh();
83
+}
84
+
85
+void FileNavigator::refresh() { filelist.refresh(); }
48
 
86
 
49
-  FileList  FileNavigator::filelist;                          // Instance of the Marlin file API
50
-  char      FileNavigator::currentfoldername[MAX_PATH_LEN];   // Current folder path
51
-  uint16_t  FileNavigator::lastindex;
52
-  uint8_t   FileNavigator::folderdepth;
53
-  uint16_t  FileNavigator::currentindex;                      // override the panel request
87
+void FileNavigator::changeDIR(const char *folder) {
88
+  if (currentfolderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
89
+  DEBUG_ECHOLNPAIR("FD:" , folderdepth, " FP:",currentindex, " currentfolder:", currentfoldername, " enter:", folder);
90
+  currentfolderindex[currentfolderdepth] = currentindex;
91
+  strcat(currentfoldername, folder);
92
+  strcat(currentfoldername, "/");
93
+  filelist.changeDir(folder);
94
+  currentfolderdepth++;
95
+  currentindex = 0;
96
+}
54
 
97
 
55
-  FileNavigator::FileNavigator() { reset(); }
98
+void FileNavigator::upDIR() {
99
+  DEBUG_ECHOLNPAIR("upDIR() from D:", currentfolderdepth, " N:", currentfoldername);
100
+  if (!filelist.isAtRootDir()) {
101
+    filelist.upDir();
102
+    currentfolderdepth--;
103
+    currentindex = currentfolderindex[currentfolderdepth]; // restore last position in the folder
104
+    filelist.seek(currentindex); // restore file information
105
+  }
56
 
106
 
57
-  void FileNavigator::reset() {
107
+  // Remove the child folder from the stored path
108
+  if (currentfolderdepth == 0)
58
     currentfoldername[0] = '\0';
109
     currentfoldername[0] = '\0';
59
-    folderdepth  = 0;
60
-    currentindex = 0;
61
-    lastindex    = 0;
62
-    // Start at root folder
63
-    while (!filelist.isAtRootDir()) filelist.upDir();
64
-    refresh();
110
+  else {
111
+    const char *pos = strchr(currentfoldername, '/');
112
+    *(pos + 1) = '\0';
65
   }
113
   }
114
+}
66
 
115
 
67
-  void FileNavigator::refresh() { filelist.refresh(); }
116
+void FileNavigator::skiptofileindex(uint16_t skip) {
117
+  if (skip == 0) return;
118
+  while (skip > 0) {
119
+    if (filelist.seek(currentindex)) {
120
+      DEBUG_ECHOLNPAIR("CI:", currentindex, " FD:", currentfolderdepth, " N:", skip, " ", filelist.longFilename());
121
+      if (!filelist.isDir()) {
122
+        skip--;
123
+        currentindex++;
124
+      }
125
+      else
126
+        changeDIR(filelist.shortFilename());
127
+    } // valid file
128
+    if (currentindex == filelist.count()) {
129
+      if (currentfolderdepth > 0) {
130
+        upDIR();
131
+        currentindex++;
132
+      }
133
+      else break; // end of root folder
134
+    } // end of folder
135
+  } // files needed
136
+  // No more files available.
137
+}
68
 
138
 
69
-  void FileNavigator::getFiles(uint16_t index) {
70
-    uint8_t files = 4;
71
-    if (index == 0) currentindex = 0;
139
+#if ENABLED(AC_SD_FOLDER_VIEW) // SD Folder navigation
72
 
140
 
141
+  void FileNavigator::getFiles(uint16_t index, panel_type_t paneltype, uint8_t filesneeded) {
142
+    if (index == 0) currentindex = 0;
73
     // Each time we change folder we reset the file index to 0 and keep track
143
     // Each time we change folder we reset the file index to 0 and keep track
74
-    // of the current position as the TFT panel isnt aware of folders trees.
144
+    // of the current position, since the TFT panel isn't aware of folder trees.
75
     if (index > 0) {
145
     if (index > 0) {
76
-      --currentindex; // go back a file to take account of the .. added to the root.
77
-      if (index > lastindex)
78
-        currentindex += files;
146
+      --currentindex; // go back a file to take account of the .. we added to the root.
147
+      if (index > lastpanelindex)
148
+        currentindex += filesneeded;
79
       else
149
       else
80
-        currentindex = currentindex < 4 ? 0 : currentindex - files;
150
+        currentindex = currentindex < 4 ? 0 : currentindex - filesneeded;
81
     }
151
     }
82
-    lastindex = index;
152
+    lastpanelindex = index;
83
 
153
 
84
-    #if ACDEBUG(AC_FILE)
85
-      SERIAL_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
86
-    #endif
154
+    DEBUG_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
87
 
155
 
88
-    if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
89
-      TFTSer.println("<<");
90
-      TFTSer.println("..");
91
-      files--;
156
+    if (currentindex == 0 && currentfolderdepth > 0) { // Add a link to go up a folder
157
+      // The new panel ignores entries that don't end in .GCO or .gcode so add and pad them.
158
+      if (paneltype == AC_panel_new) {
159
+        TFTSer.println("<<.GCO");
160
+        Chiron.SendtoTFTLN(PSTR("..                  .gcode"));
161
+      }
162
+      else {
163
+        TFTSer.println("<<");
164
+        TFTSer.println("..");
165
+      }
166
+      filesneeded--;
92
     }
167
     }
93
 
168
 
94
-    for (uint16_t seek = currentindex; seek < currentindex + files; seek++) {
169
+    for (uint16_t seek = currentindex; seek < currentindex + filesneeded; seek++) {
95
       if (filelist.seek(seek)) {
170
       if (filelist.seek(seek)) {
96
-        sendFile();
97
-        #if ACDEBUG(AC_FILE)
98
-          SERIAL_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n");
99
-        #endif
171
+        sendFile(paneltype);
172
+        DEBUG_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'");
100
       }
173
       }
101
     }
174
     }
102
   }
175
   }
103
 
176
 
104
-  void FileNavigator::sendFile() {
105
-    // send the file and folder info to the panel
106
-    // this info will be returned when the file is selected
107
-    // Permitted special characters in file name -_*#~
108
-    // Panel can display 22 characters per line
177
+  void FileNavigator::sendFile(panel_type_t paneltype) {
109
     if (filelist.isDir()) {
178
     if (filelist.isDir()) {
110
-      //TFTSer.print(currentfoldername);
111
-      TFTSer.println(filelist.shortFilename());
112
-      TFTSer.print(filelist.shortFilename());
113
-      TFTSer.println("/");
179
+      // Add mandatory tags for new panel otherwise lines are ignored.
180
+      if (paneltype == AC_panel_new) {
181
+        TFTSer.print(filelist.shortFilename());
182
+        TFTSer.println(".GCO");
183
+        TFTSer.print(filelist.shortFilename());
184
+        TFTSer.write('/');
185
+        // Make sure we fill all 29 chars of the display line to clear the text buffer otherwise the last line is still visible
186
+        for (int8_t i = strlen(filelist.shortFilename()); i < 19; i++)
187
+          TFTSer.write(' ');
188
+        TFTSer.println(".gcode");
189
+      }
190
+      else {
191
+        TFTSer.println(filelist.shortFilename());
192
+        TFTSer.print(filelist.shortFilename());
193
+        TFTSer.write('/');
194
+        TFTSer.println();
195
+      }
114
     }
196
     }
115
-    else {
116
-      // Logical Name
197
+    else { // Not DIR
117
       TFTSer.write('/');
198
       TFTSer.write('/');
118
-      if (folderdepth > 0) TFTSer.print(currentfoldername);
119
-
199
+      if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
120
       TFTSer.println(filelist.shortFilename());
200
       TFTSer.println(filelist.shortFilename());
201
+      TFTSer.print(filelist.longFilename());
121
 
202
 
122
-      // Display Name
123
-      TFTSer.println(filelist.longFilename());
203
+      // Make sure we fill all 29 chars of the display line to clear the text buffer otherwise the last line is still visible
204
+      if (paneltype == AC_panel_new)
205
+        for (int8_t i = strlen(filelist.longFilename()); i < 26; i++)
206
+          TFTSer.write(' ');
207
+
208
+      TFTSer.println();
124
     }
209
     }
125
-  }
126
-  void FileNavigator::changeDIR(char *folder) {
127
-    #if ACDEBUG(AC_FILE)
128
-      SERIAL_ECHOLNPAIR("currentfolder: ", currentfoldername, "  New: ", folder);
129
-    #endif
130
-    if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
131
-    strcat(currentfoldername, folder);
132
-    strcat(currentfoldername, "/");
133
-    filelist.changeDir(folder);
134
-    refresh();
135
-    folderdepth++;
136
-    currentindex = 0;
137
-  }
210
+  }  // AC_SD_FOLDER_VIEW
138
 
211
 
139
-  void FileNavigator::upDIR() {
140
-    filelist.upDir();
141
-    refresh();
142
-    folderdepth--;
143
-    currentindex = 0;
144
-    // Remove the last child folder from the stored path
145
-    if (folderdepth == 0) {
146
-      currentfoldername[0] = '\0';
212
+#else // Flat file list
213
+
214
+  void FileNavigator::getFiles(uint16_t index, panel_type_t paneltype, uint8_t filesneeded) {
215
+    DEBUG_ECHOLNPAIR("getFiles() I:", index," L:", lastpanelindex);
216
+    // if we're searching backwards, jump back to start and search forward
217
+    if (index < lastpanelindex) {
147
       reset();
218
       reset();
219
+      skiptofileindex(index);
148
     }
220
     }
149
-    else {
150
-      char *pos = nullptr;
151
-      for (uint8_t f = 0; f < folderdepth; f++)
152
-        pos = strchr(currentfoldername, '/');
221
+    lastpanelindex = index;
153
 
222
 
154
-      *(pos + 1) = '\0';
155
-    }
156
-    #if ACDEBUG(AC_FILE)
157
-      SERIAL_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername);
158
-    #endif
223
+    while (filesneeded > 0) {
224
+      if (filelist.seek(currentindex)) {
225
+        if (!filelist.isDir()) {
226
+          sendFile(paneltype);
227
+          filesneeded--;
228
+          currentindex++;
229
+        }
230
+        else
231
+          changeDIR(filelist.shortFilename());
232
+      } // valid file
233
+
234
+      if (currentindex == filelist.count()) {
235
+        if (currentfolderdepth > 0) {
236
+          upDIR();
237
+          currentindex++;
238
+        }
239
+        else break; // end of root folder
240
+      } // end of folder
241
+    } // files needed
242
+    // No more files available.
159
   }
243
   }
160
 
244
 
161
-  char* FileNavigator::getCurrentFolderName() { return currentfoldername; }
162
-}
245
+  void FileNavigator::sendFile(panel_type_t paneltype) {
246
+    TFTSer.write('/');
247
+    if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
248
+    TFTSer.println(filelist.shortFilename());
249
+    if (currentfolderdepth > 0) TFTSer.print(currentfoldername);
250
+    TFTSer.println(filelist.longFilename());
251
+    DEBUG_ECHOLNPAIR("/", currentfoldername, "", filelist.shortFilename(), " ", filelist.longFilename());
252
+  }
253
+
254
+#endif // Flat file list
255
+
256
+} // Anycubic namespace
163
 
257
 
164
 #endif // ANYCUBIC_LCD_CHIRON
258
 #endif // ANYCUBIC_LCD_CHIRON

+ 8
- 9
Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.h Ver fichero

38
 
38
 
39
 class FileNavigator {
39
 class FileNavigator {
40
   public:
40
   public:
41
-    FileNavigator();
42
-    void reset();
43
-    void getFiles(uint16_t, panel_type_t, uint8_t filesneeded=4);
44
-    void upDIR();
45
-    void changeDIR(const char *);
46
-    void sendFile(panel_type_t);
47
-    void refresh();
48
-    void skiptofileindex(uint16_t);
41
+    static void reset();
42
+    static void getFiles(uint16_t, panel_type_t, uint8_t filesneeded=4);
43
+    static void upDIR();
44
+    static void changeDIR(const char *);
45
+    static void sendFile(panel_type_t);
46
+    static void refresh();
47
+    static void skiptofileindex(uint16_t);
49
 
48
 
50
     static FileList filelist;
49
     static FileList filelist;
51
   private:
50
   private:
53
     static uint16_t currentindex;
52
     static uint16_t currentindex;
54
     static uint8_t  currentfolderdepth;
53
     static uint8_t  currentfolderdepth;
55
     static uint16_t currentfolderindex[MAX_FOLDER_DEPTH];
54
     static uint16_t currentfolderindex[MAX_FOLDER_DEPTH];
56
-    static char     currentfoldername[MAX_PATH_LEN];
55
+    static char     currentfoldername[MAX_PATH_LEN + 1];
57
 };
56
 };
58
 
57
 
59
 extern FileNavigator filenavigator;
58
 extern FileNavigator filenavigator;

+ 199
- 109
Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.cpp Ver fichero

43
 
43
 
44
 namespace Anycubic {
44
 namespace Anycubic {
45
 
45
 
46
+ChironTFT Chiron;
47
+#if AUTO_DETECT_CHIRON_TFT
48
+  panel_type_t   ChironTFT::panel_type = AC_panel_unknown;
49
+#endif
50
+last_error_t     ChironTFT::last_error;
46
 printer_state_t  ChironTFT::printer_state;
51
 printer_state_t  ChironTFT::printer_state;
47
 paused_state_t   ChironTFT::pause_state;
52
 paused_state_t   ChironTFT::pause_state;
48
 heater_state_t   ChironTFT::hotend_state;
53
 heater_state_t   ChironTFT::hotend_state;
49
 heater_state_t   ChironTFT::hotbed_state;
54
 heater_state_t   ChironTFT::hotbed_state;
50
 xy_uint8_t       ChironTFT::selectedmeshpoint;
55
 xy_uint8_t       ChironTFT::selectedmeshpoint;
51
-char             ChironTFT::selectedfile[MAX_PATH_LEN];
52
-char             ChironTFT::panel_command[MAX_CMND_LEN];
56
+char             ChironTFT::selectedfile[MAX_PATH_LEN + 1];
57
+char             ChironTFT::panel_command[MAX_CMND_LEN + 1];
53
 uint8_t          ChironTFT::command_len;
58
 uint8_t          ChironTFT::command_len;
54
 float            ChironTFT::live_Zoffset;
59
 float            ChironTFT::live_Zoffset;
55
 file_menu_t      ChironTFT::file_menu;
60
 file_menu_t      ChironTFT::file_menu;
56
 
61
 
57
-ChironTFT Chiron;
58
-
59
-ChironTFT::ChironTFT(){}
60
-
61
 void ChironTFT::Startup() {
62
 void ChironTFT::Startup() {
62
   selectedfile[0]   = '\0';
63
   selectedfile[0]   = '\0';
63
   panel_command[0]  = '\0';
64
   panel_command[0]  = '\0';
64
   command_len       = 0;
65
   command_len       = 0;
66
+  last_error        = AC_error_none;
65
   printer_state     = AC_printer_idle;
67
   printer_state     = AC_printer_idle;
66
   pause_state       = AC_paused_idle;
68
   pause_state       = AC_paused_idle;
67
   hotend_state      = AC_heater_off;
69
   hotend_state      = AC_heater_off;
80
   // Filament runout is handled by Marlin settings in Configuration.h
82
   // Filament runout is handled by Marlin settings in Configuration.h
81
   // opt_set    FIL_RUNOUT_STATE HIGH  // Pin state indicating that filament is NOT present.
83
   // opt_set    FIL_RUNOUT_STATE HIGH  // Pin state indicating that filament is NOT present.
82
   // opt_enable FIL_RUNOUT_PULLUP
84
   // opt_enable FIL_RUNOUT_PULLUP
83
-
84
   TFTSer.begin(115200);
85
   TFTSer.begin(115200);
85
 
86
 
87
+  // wait for the TFT panel to initialise and finish the animation
88
+  delay_ms(250);
89
+
90
+  // There are different panels for the Chiron with slightly different commands
91
+  // So we need to know what we are working with.
92
+
93
+  // Panel type can be defined otherwise detect it automatically
94
+  if (panel_type == AC_panel_unknown) DetectPanelType();
95
+
86
   // Signal Board has reset
96
   // Signal Board has reset
87
   SendtoTFTLN(AC_msg_main_board_has_reset);
97
   SendtoTFTLN(AC_msg_main_board_has_reset);
88
 
98
 
89
-  safe_delay(200);
90
-
91
   // Enable leveling and Disable end stops during print
99
   // Enable leveling and Disable end stops during print
92
   // as Z home places nozzle above the bed so we need to allow it past the end stops
100
   // as Z home places nozzle above the bed so we need to allow it past the end stops
93
   injectCommands_P(AC_cmnd_enable_leveling);
101
   injectCommands_P(AC_cmnd_enable_leveling);
94
 
102
 
95
   // Startup tunes are defined in Tunes.h
103
   // Startup tunes are defined in Tunes.h
96
-  //PlayTune(BEEPER_PIN, Anycubic_PowerOn, 1);
97
-  PlayTune(BEEPER_PIN, GB_PowerOn, 1);
104
+  PlayTune(BEEPER_PIN, TERN(AC_DEFAULT_STARTUP_TUNE, Anycubic_PowerOn, GB_PowerOn), 1);
105
+
98
   #if ACDEBUGLEVEL
106
   #if ACDEBUGLEVEL
99
     SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL);
107
     SERIAL_ECHOLNPAIR("AC Debug Level ", ACDEBUGLEVEL);
100
   #endif
108
   #endif
101
   SendtoTFTLN(AC_msg_ready);
109
   SendtoTFTLN(AC_msg_ready);
102
 }
110
 }
103
 
111
 
112
+void ChironTFT::DetectPanelType() {
113
+  #if AUTO_DETECT_CHIRON_TFT
114
+    // Send a query to the TFT
115
+    SendtoTFTLN(AC_Test_for_OldPanel); // The panel will respond with 'SXY 480 320'
116
+    SendtoTFTLN(AC_Test_for_NewPanel); // the panel will respond with '[0]=0   ' to '[19]=0   '
117
+  #endif
118
+}
119
+
104
 void ChironTFT::IdleLoop()  {
120
 void ChironTFT::IdleLoop()  {
105
   if (ReadTFTCommand()) {
121
   if (ReadTFTCommand()) {
106
     ProcessPanelRequest();
122
     ProcessPanelRequest();
123
   switch (event) {
139
   switch (event) {
124
     case AC_media_inserted:
140
     case AC_media_inserted:
125
       SendtoTFTLN(AC_msg_sd_card_inserted);
141
       SendtoTFTLN(AC_msg_sd_card_inserted);
126
-    break;
142
+      break;
127
 
143
 
128
     case AC_media_removed:
144
     case AC_media_removed:
129
       SendtoTFTLN(AC_msg_sd_card_removed);
145
       SendtoTFTLN(AC_msg_sd_card_removed);
130
-    break;
146
+      break;
131
 
147
 
132
     case AC_media_error:
148
     case AC_media_error:
149
+      last_error = AC_error_noSD;
133
       SendtoTFTLN(AC_msg_no_sd_card);
150
       SendtoTFTLN(AC_msg_no_sd_card);
134
-    break;
151
+      break;
135
   }
152
   }
136
 }
153
 }
137
 
154
 
170
     SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state);
187
     SERIAL_ECHOLNPAIR("FilamentRunout() printer_state ", printer_state);
171
   #endif
188
   #endif
172
   // 1 Signal filament out
189
   // 1 Signal filament out
190
+  last_error = AC_error_filament_runout;
173
   SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block);
191
   SendtoTFTLN(isPrintingFromMedia() ? AC_msg_filament_out_alert : AC_msg_filament_out_block);
174
-  //printer_state = AC_printer_filament_out;
175
   PlayTune(BEEPER_PIN, FilamentOut, 1);
192
   PlayTune(BEEPER_PIN, FilamentOut, 1);
176
 }
193
 }
177
 
194
 
278
       SendtoTFTLN(AC_msg_bed_heating);
295
       SendtoTFTLN(AC_msg_bed_heating);
279
       hotbed_state = AC_heater_temp_set;
296
       hotbed_state = AC_heater_temp_set;
280
     }
297
     }
298
+    else if (strcmp_P(msg, MARLIN_msg_EEPROM_version) == 0) {
299
+      last_error = AC_error_EEPROM;
300
+    }
281
   }
301
   }
282
 }
302
 }
283
 
303
 
284
 void ChironTFT::PowerLossRecovery()  {
304
 void ChironTFT::PowerLossRecovery()  {
285
   printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover.
305
   printer_state = AC_printer_resuming_from_power_outage; // Play tune to notify user we can recover.
306
+  last_error = AC_error_powerloss;
286
   PlayTune(BEEPER_PIN, SOS, 1);
307
   PlayTune(BEEPER_PIN, SOS, 1);
287
-  SERIAL_ECHOLNPGM("Resuming from power outage...");
288
-  SERIAL_ECHOLNPGM("Select SD file then press resume");
308
+  SERIAL_ECHOLNPGM_P(AC_msg_powerloss_recovery);
309
+}
310
+
311
+void ChironTFT::PrintComplete() {
312
+  SendtoTFT(AC_msg_print_complete);
313
+  printer_state = AC_printer_idle;
314
+  setSoftEndstopState(true); // enable endstops
289
 }
315
 }
290
 
316
 
291
 void ChironTFT::SendtoTFT(PGM_P str) {  // A helper to print PROGMEM string to the panel
317
 void ChironTFT::SendtoTFT(PGM_P str) {  // A helper to print PROGMEM string to the panel
319
     command_len++;
345
     command_len++;
320
   }
346
   }
321
 
347
 
322
-  if (command_ready) {
323
-    panel_command[command_len] = 0x00;
348
+  if (command_ready || command_len == MAX_CMND_LEN) {
349
+    panel_command[command_len] = '\0';
324
     #if ACDEBUG(AC_ALL)
350
     #if ACDEBUG(AC_ALL)
325
-      SERIAL_ECHOLNPAIR("< ", panel_command);
326
-    #endif
327
-    #if ACDEBUG(AC_SOME)
328
-      // Ignore status request commands
329
-      uint8_t req = atoi(&panel_command[1]);
330
-      if (req > 7 && req != 20) {
331
-        SERIAL_ECHOLNPAIR("> ", panel_command);
332
-        SERIAL_ECHOLNPAIR("printer_state:", printer_state);
333
-      }
351
+      SERIAL_ECHOLNPAIR("len(",command_len,") < ", panel_command);
334
     #endif
352
     #endif
353
+    command_ready = true;
335
   }
354
   }
336
   return command_ready;
355
   return command_ready;
337
 }
356
 }
338
 
357
 
339
-int8_t ChironTFT::Findcmndpos(const char * buff, char q) {
358
+int8_t ChironTFT::FindToken(char c) {
340
   int8_t pos = 0;
359
   int8_t pos = 0;
341
-  do { if (buff[pos] == q) return pos; } while (++pos < MAX_CMND_LEN);
360
+  do {
361
+    if (panel_command[pos] == c) {
362
+      #if ACDEBUG(AC_INFO)
363
+        SERIAL_ECHOLNPAIR("Tpos:", pos, " ", c);
364
+      #endif
365
+      return pos;
366
+    }
367
+  } while(++pos < command_len);
368
+  #if ACDEBUG(AC_INFO)
369
+    SERIAL_ECHOLNPAIR("Not found: ", c);
370
+  #endif
342
   return -1;
371
   return -1;
343
 }
372
 }
344
 
373
 
352
     faultDuration++;
381
     faultDuration++;
353
     if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
382
     if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
354
       SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
383
       SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
384
+      last_error = AC_error_abnormal_temp_t0;
355
       SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp);
385
       SERIAL_ECHOLNPAIR("Extruder temp abnormal! : ", temp);
356
       break;
386
       break;
357
     }
387
     }
366
     faultDuration++;
396
     faultDuration++;
367
     if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
397
     if (faultDuration >= AC_HEATER_FAULT_VALIDATION_TIME) {
368
       SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
398
       SendtoTFTLN(AC_msg_nozzle_temp_abnormal);
399
+      last_error = AC_error_abnormal_temp_bed;
369
       SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp);
400
       SERIAL_ECHOLNPAIR("Bed temp abnormal! : ", temp);
370
       break;
401
       break;
371
     }
402
     }
396
     SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex);
427
     SERIAL_ECHOLNPAIR("## SendFileList ## ", startindex);
397
   #endif
428
   #endif
398
   SendtoTFTLN(PSTR("FN "));
429
   SendtoTFTLN(PSTR("FN "));
399
-  filenavigator.getFiles(startindex);
430
+  filenavigator.getFiles(startindex, panel_type, 4);
400
   SendtoTFTLN(PSTR("END"));
431
   SendtoTFTLN(PSTR("END"));
401
 }
432
 }
402
 
433
 
403
 void ChironTFT::SelectFile() {
434
 void ChironTFT::SelectFile() {
404
-  strncpy(selectedfile, panel_command + 4, command_len - 4);
405
-  selectedfile[command_len - 5] = '\0';
435
+  if (panel_type == AC_panel_new) {
436
+    strncpy(selectedfile, panel_command + 4, command_len - 3);
437
+    selectedfile[command_len - 4] = '\0';
438
+  }
439
+  else {
440
+    strncpy(selectedfile, panel_command + 4, command_len - 4);
441
+    selectedfile[command_len - 5] = '\0';
442
+  }
406
   #if ACDEBUG(AC_FILE)
443
   #if ACDEBUG(AC_FILE)
407
-    SERIAL_ECHOLNPAIR_F(" Selected File: ",selectedfile);
444
+    SERIAL_ECHOLNPAIR(" Selected File: ",selectedfile);
408
   #endif
445
   #endif
409
   switch (selectedfile[0]) {
446
   switch (selectedfile[0]) {
410
     case '/':   // Valid file selected
447
     case '/':   // Valid file selected
417
       SendFileList( 0 );
454
       SendFileList( 0 );
418
       break;
455
       break;
419
     default:   // enter sub folder
456
     default:   // enter sub folder
457
+      // for new panel remove the '.GCO' tag that was added to the end of the path
458
+      if (panel_type == AC_panel_new)
459
+        selectedfile[strlen(selectedfile) - 4] = '\0';
420
       filenavigator.changeDIR(selectedfile);
460
       filenavigator.changeDIR(selectedfile);
421
       SendtoTFTLN(AC_msg_sd_file_open_failed);
461
       SendtoTFTLN(AC_msg_sd_file_open_failed);
422
       SendFileList( 0 );
462
       SendFileList( 0 );
424
   }
464
   }
425
 }
465
 }
426
 
466
 
427
-void ChironTFT::InjectCommandandWait(PGM_P cmd) {
428
-  //injectCommands_P(cmnd); queue.enqueue_now_P(cmd);
429
-  //SERIAL_ECHOLN(PSTR("Inject>"));
430
-}
431
-
432
 void ChironTFT::ProcessPanelRequest() {
467
 void ChironTFT::ProcessPanelRequest() {
433
   // Break these up into logical blocks // as its easier to navigate than one huge switch case!
468
   // Break these up into logical blocks // as its easier to navigate than one huge switch case!
434
-  int8_t req = atoi(&panel_command[1]);
469
+  const int8_t tpos = FindToken('A');
470
+  // Panel request are 'A0' - 'A36'
471
+  if (tpos != -1) {
472
+    const int8_t req = atoi(&panel_command[tpos+1]);
435
 
473
 
436
-  // Information requests A0 - A8 and A33
437
-  if (req <= 8 || req == 33) PanelInfo(req);
474
+    // Information requests A0 - A8 and A33
475
+    if (req <= 8 || req == 33) PanelInfo(req);
438
 
476
 
439
-  // Simple Actions A9 - A28
440
-  else if ( req <= 28) PanelAction(req);
477
+    // Simple Actions A9 - A28
478
+    else if (req <= 28) PanelAction(req);
441
 
479
 
442
-  // Process Initiation
443
-  else if (req <= 34) PanelProcess(req);
480
+    // Process Initiation
481
+    else if (req <= 36) PanelProcess(req);
482
+  }
483
+  else {
484
+    #if AUTO_DETECT_CHIRON_TFT
485
+      // This may be a response to a panel type detection query
486
+      if (panel_type == AC_panel_unknown) {
487
+        tpos = FindToken('S'); // old panel will respond to 'SIZE' with 'SXY 480 320'
488
+        if (tpos != -1) {
489
+          if (panel_command[tpos+1]== 'X' && panel_command[tpos+2]=='Y') {
490
+            panel_type = AC_panel_standard;
491
+            SERIAL_ECHOLNPGM_P(AC_msg_old_panel_detected);
492
+          }
493
+        }
494
+        else {
495
+          tpos = FindToken('['); // new panel will respond to 'J200' with '[0]=0'
496
+          if (tpos != -1) {
497
+            if (panel_command[tpos+1]== '0' && panel_command[tpos+2]==']') {
498
+              panel_type = AC_panel_new;
499
+              SERIAL_ECHOLNPGM_P(AC_msg_new_panel_detected);
500
+            }
501
+          }
502
+        }
503
+        return;
504
+      }
505
+    #endif
444
 
506
 
445
-  else SendtoTFTLN();
507
+    SendtoTFTLN(); // Ignore unknown requests
508
+  }
446
 }
509
 }
447
 
510
 
448
 void ChironTFT::PanelInfo(uint8_t req) {
511
 void ChironTFT::PanelInfo(uint8_t req) {
513
 
576
 
514
     case 33:   // A33 Get firmware info
577
     case 33:   // A33 Get firmware info
515
       SendtoTFT(PSTR("J33 "));
578
       SendtoTFT(PSTR("J33 "));
516
-      SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
579
+      // If there is an error recorded, show that instead of the FW version
580
+      if (!GetLastError()) SendtoTFTLN(PSTR(SHORT_BUILD_VERSION));
517
       break;
581
       break;
518
   }
582
   }
519
 }
583
 }
567
       #if ACDebugLevel >= 1
631
       #if ACDebugLevel >= 1
568
         SERIAL_ECHOLNPAIR_F("Print: ", selectedfile);
632
         SERIAL_ECHOLNPAIR_F("Print: ", selectedfile);
569
       #endif
633
       #endif
570
-      // the card library needs a path starting // but the File api doesn't...
571
-      char file[MAX_PATH_LEN];
572
-      file[0] = '/';
573
-      strcpy(file + 1, selectedfile);
574
-      printFile(file);
634
+      printFile(selectedfile);
575
       SendtoTFTLN(AC_msg_print_from_sd_card);
635
       SendtoTFTLN(AC_msg_print_from_sd_card);
576
     } break;
636
     } break;
577
 
637
 
631
       }
691
       }
632
       break;
692
       break;
633
 
693
 
634
-    case 22:   // A22 Move Axis  A22 Y +10F3000
635
-      // Ignore request if printing
636
-      if (!isPrinting()) {
637
-        // setAxisPosition_mm() uses pre defined manual feedrates so ignore the feedrate from the panel
638
-        setSoftEndstopState(true);  // enable endstops
639
-        float newposition = atof(&panel_command[6]);
694
+    case 22: {   // A22 Move Axis
695
+      // The commands have changed on the new panel
696
+      // Old TFT A22 X -1F1500      A22 X +1F1500
697
+      // New TFT A22 X-1.0 F1500    A22 X1.0 F1500
640
 
698
 
699
+      // lets just wrap this in a gcode relative nonprint move and let the controller deal with it
700
+      // G91 G0 <panel command> G90
701
+
702
+      if (!isPrinting()) { // Ignore request if printing
703
+        char MoveCmnd[30];
704
+        sprintf_P(MoveCmnd, PSTR("G91\nG0 %s \nG90"), panel_command+3);
641
         #if ACDEBUG(AC_ACTION)
705
         #if ACDEBUG(AC_ACTION)
642
-          SERIAL_ECHOLNPAIR("Nudge ", AS_CHAR(panel_command[4]), " axis ", newposition);
706
+          SERIAL_ECHOLNPAIR("Move: ", MoveCmnd);
643
         #endif
707
         #endif
644
-
645
-        switch (panel_command[4]) {
646
-          case 'X': setAxisPosition_mm(getAxisPosition_mm(X) + newposition, X); break;
647
-          case 'Y': setAxisPosition_mm(getAxisPosition_mm(Y) + newposition, Y); break;
648
-          case 'Z': setAxisPosition_mm(getAxisPosition_mm(Z) + newposition, Z); break;
649
-          case 'E':   // The only time we get this command is from the filament load/unload menu
650
-                      // the standard movement is too slow so we will use the load unlod GCode to speed it up a bit
651
-            if (canMove(E0) && !commandsInQueue())
652
-              injectCommands_P(newposition > 0 ? AC_cmnd_manual_load_filament : AC_cmnd_manual_unload_filament);
653
-            break;
654
-        }
708
+        setSoftEndstopState(true);  // enable endstops
709
+        injectCommands(MoveCmnd);
655
       }
710
       }
656
-      break;
711
+    } break;
657
 
712
 
658
     case 23:   // A23 Preheat PLA
713
     case 23:   // A23 Preheat PLA
659
       // Ignore request if printing
714
       // Ignore request if printing
690
       break;
745
       break;
691
 
746
 
692
     case 26:   // A26 Refresh SD
747
     case 26:   // A26 Refresh SD
693
-      // M22 M21 maybe needed here to reset sd card
748
+      if (card.isMounted())card.release();
749
+      card.mount();
750
+      safe_delay(500);
694
       filenavigator.reset();
751
       filenavigator.reset();
695
       break;
752
       break;
696
 
753
 
710
     case 29: { // A29 Read Mesh Point A29 X1 Y1
767
     case 29: { // A29 Read Mesh Point A29 X1 Y1
711
       xy_uint8_t pos;
768
       xy_uint8_t pos;
712
       float pos_z;
769
       float pos_z;
713
-      pos.x = atoi(&panel_command[5]);
714
-      pos.y = atoi(&panel_command[8]);
770
+      pos.x = atoi(&panel_command[FindToken('X')+1]);
771
+      pos.y = atoi(&panel_command[FindToken('Y')+1]);
715
       pos_z = getMeshPoint(pos);
772
       pos_z = getMeshPoint(pos);
716
 
773
 
717
       SendtoTFT(PSTR("A29V "));
774
       SendtoTFT(PSTR("A29V "));
743
       }
800
       }
744
     } break;
801
     } break;
745
 
802
 
746
-    case 30: {  // A30 Auto leveling
747
-      if (panel_command[3] == 'S') { // Start probing
803
+    case 30: {   // A30 Auto leveling
804
+      if (FindToken('S') != -1) { // Start probing New panel adds spaces..
748
         // Ignore request if printing
805
         // Ignore request if printing
749
         if (isPrinting())
806
         if (isPrinting())
750
           SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling
807
           SendtoTFTLN(AC_msg_probing_not_allowed); // forbid auto leveling
751
         else {
808
         else {
752
-          injectCommands_P(PSTR("G28O\nG29"));
753
-          printer_state = AC_printer_probing;
809
+
810
+
754
           SendtoTFTLN(AC_msg_start_probing);
811
           SendtoTFTLN(AC_msg_start_probing);
812
+          injectCommands_P(PSTR("G28\nG29"));
813
+          printer_state = AC_printer_probing;
755
         }
814
         }
756
       }
815
       }
757
-      else SendtoTFTLN(AC_msg_start_probing);
758
-    }  break;
816
+      else {
817
+        SendtoTFTLN(AC_msg_start_probing); // Just enter levelling menu
818
+      }
819
+    } break;
759
 
820
 
760
     case 31: { // A31 Adjust all Probe Points
821
     case 31: { // A31 Adjust all Probe Points
761
-      switch (panel_command[3]) {
762
-        case 'C':   // Restore and apply original offsets
763
-          if (!isPrinting()) {
764
-            injectCommands_P(PSTR("M501\nM420 S1"));
765
-            selectedmeshpoint.x = selectedmeshpoint.y = 99;
766
-          }
767
-        break;
768
-        case 'D':   // Save Z Offset tables and restore leveling state
769
-          if (!isPrinting()) {
770
-            setAxisPosition_mm(1.0,Z);
771
-            injectCommands_P(PSTR("M500"));
772
-            selectedmeshpoint.x = selectedmeshpoint.y = 99;
773
-          }
774
-        break;
775
-        case 'G':   // Get current offset
776
-          SendtoTFT(PSTR("A31V "));
777
-          // When printing use the live z Offset position
778
-          // we will use babystepping to move the print head
779
-          if (isPrinting())
780
-            TFTSer.println(live_Zoffset);
781
-          else {
782
-            TFTSer.println(getZOffset_mm());
783
-            selectedmeshpoint.x = selectedmeshpoint.y = 99;
784
-          }
785
-        break;
786
-        case 'S': { // Set offset (adjusts all points by value)
787
-          float Zshift = atof(&panel_command[4]);
822
+      // The tokens can occur in different places on the new panel so we need to find it.
823
+
824
+      if (FindToken('C') != -1) { // Restore and apply original offsets
825
+        if (!isPrinting()) {
826
+          injectCommands_P(PSTR("M501\nM420 S1"));
827
+          selectedmeshpoint.x = selectedmeshpoint.y = 99;
828
+          SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_abandoned);
829
+        }
830
+      }
831
+
832
+      else if (FindToken('D') != -1) { // Save Z Offset tables and restore leveling state
833
+        if (!isPrinting()) {
834
+          setAxisPosition_mm(1.0,Z); // Lift nozzle before any further movements are made
835
+          injectCommands_P(PSTR("M500"));
836
+          SERIAL_ECHOLNPGM_P(AC_msg_mesh_changes_saved);
837
+          selectedmeshpoint.x = selectedmeshpoint.y = 99;
838
+        }
839
+      }
840
+
841
+      else if (FindToken('G') != -1) { // Get current offset
842
+        SendtoTFT(PSTR("A31V "));
843
+        // When printing use the live z Offset position
844
+        // we will use babystepping to move the print head
845
+        if (isPrinting())
846
+          TFTSer.println(live_Zoffset);
847
+        else {
848
+          TFTSer.println(getZOffset_mm());
849
+          selectedmeshpoint.x = selectedmeshpoint.y = 99;
850
+        }
851
+      }
852
+
853
+      else {
854
+        int8_t tokenpos = FindToken('S');
855
+        if (tokenpos != -1) { // Set offset (adjusts all points by value)
856
+          float Zshift = atof(&panel_command[tokenpos+1]);
788
           setSoftEndstopState(false);  // disable endstops
857
           setSoftEndstopState(false);  // disable endstops
789
           // Allow temporary Z position nudging during print
858
           // Allow temporary Z position nudging during print
790
           // From the leveling panel use the all points UI to adjust the print pos.
859
           // From the leveling panel use the all points UI to adjust the print pos.
813
               const xy_uint8_t pos { x, y };
882
               const xy_uint8_t pos { x, y };
814
               const float currval = getMeshPoint(pos);
883
               const float currval = getMeshPoint(pos);
815
               setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2));
884
               setMeshPoint(pos, constrain(currval + Zshift, AC_LOWEST_MESHPOINT_VAL, 2));
885
+              #if ACDEBUG(AC_INFO)
886
+                SERIAL_ECHOLNPAIR("Change mesh point X", x," Y",y ," from ", currval, " to ", getMeshPoint(pos) );
887
+              #endif
816
             }
888
             }
817
             const float currZOffset = getZOffset_mm();
889
             const float currZOffset = getZOffset_mm();
818
             #if ACDEBUG(AC_INFO)
890
             #if ACDEBUG(AC_INFO)
878
         }
950
         }
879
       }
951
       }
880
     }  break;
952
     }  break;
953
+
954
+    case 36:    // A36 Auto leveling for new TFT bet that was a typo in the panel code!
955
+      SendtoTFTLN(AC_msg_start_probing);
956
+      break;
957
+  }
958
+}
959
+
960
+bool ChironTFT::GetLastError() {
961
+  switch (last_error) {
962
+    case AC_error_abnormal_temp_bed: SendtoTFTLN(AC_msg_error_bed_temp);    break;
963
+    case AC_error_abnormal_temp_t0:  SendtoTFTLN(AC_msg_error_hotend_temp); break;
964
+    case AC_error_noSD:              SendtoTFTLN(AC_msg_error_sd_card);     break;
965
+    case AC_error_powerloss:         SendtoTFTLN(AC_msg_power_loss);        break;
966
+    case AC_error_EEPROM:            SendtoTFTLN(AC_msg_eeprom_version);    break;
967
+    case AC_error_filament_runout:   SendtoTFTLN(AC_msg_filament_out);      break;
968
+    default: return false;
881
   }
969
   }
970
+  last_error = AC_error_none;
971
+  return true;
882
 }
972
 }
883
 
973
 
884
-} // Anycubic
974
+} // Anycubic namespace
885
 
975
 
886
 #endif // ANYCUBIC_LCD_CHIRON
976
 #endif // ANYCUBIC_LCD_CHIRON

+ 26
- 17
Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft.h Ver fichero

33
 #include "../../../../inc/MarlinConfigPre.h"
33
 #include "../../../../inc/MarlinConfigPre.h"
34
 #include "../../ui_api.h"
34
 #include "../../ui_api.h"
35
 
35
 
36
+#if NONE(CHIRON_TFT_STANDARD, CHIRON_TFT_NEW)
37
+  #define AUTO_DETECT_CHIRON_TFT 1
38
+#endif
39
+
36
 namespace Anycubic {
40
 namespace Anycubic {
37
 
41
 
38
 class ChironTFT {
42
 class ChironTFT {
39
-  private:
40
-    static printer_state_t  printer_state;
41
-    static paused_state_t   pause_state;
42
-    static heater_state_t   hotend_state;
43
-    static heater_state_t   hotbed_state;
44
-    static xy_uint8_t       selectedmeshpoint;
45
-    static char             panel_command[MAX_CMND_LEN];
46
-    static uint8_t          command_len;
47
-    static char             selectedfile[MAX_PATH_LEN];
48
-    static float            live_Zoffset;
49
-    static file_menu_t      file_menu;
50
-
43
+  #if AUTO_DETECT_CHIRON_TFT
44
+    static panel_type_t panel_type;
45
+  #else
46
+    static constexpr panel_type_t panel_type = TERN(CHIRON_TFT_NEW, AC_panel_new, AC_panel_standard);
47
+  #endif
48
+  static last_error_t last_error;
49
+  static printer_state_t  printer_state;
50
+  static paused_state_t   pause_state;
51
+  static heater_state_t   hotend_state;
52
+  static heater_state_t   hotbed_state;
53
+  static xy_uint8_t       selectedmeshpoint;
54
+  static char             panel_command[MAX_CMND_LEN + 1];
55
+  static uint8_t          command_len;
56
+  static char             selectedfile[MAX_PATH_LEN + 1];
57
+  static float            live_Zoffset;
58
+  static file_menu_t      file_menu;
51
   public:
59
   public:
52
-    ChironTFT();
53
     static void Startup();
60
     static void Startup();
54
     static void IdleLoop();
61
     static void IdleLoop();
55
     static void PrinterKilled(PGM_P,PGM_P);
62
     static void PrinterKilled(PGM_P,PGM_P);
59
     static void ConfirmationRequest(const char * const );
66
     static void ConfirmationRequest(const char * const );
60
     static void StatusChange(const char * const );
67
     static void StatusChange(const char * const );
61
     static void PowerLossRecovery();
68
     static void PowerLossRecovery();
62
-
63
-  private:
69
+    static void PrintComplete();
64
     static void SendtoTFT(PGM_P);
70
     static void SendtoTFT(PGM_P);
65
     static void SendtoTFTLN(PGM_P);
71
     static void SendtoTFTLN(PGM_P);
72
+  private:
73
+    static void DetectPanelType();
66
     static bool ReadTFTCommand();
74
     static bool ReadTFTCommand();
67
-    static int8_t Findcmndpos(const char *, char);
75
+    static int8_t FindToken(char);
68
     static void CheckHeaters();
76
     static void CheckHeaters();
69
     static void SendFileList(int8_t);
77
     static void SendFileList(int8_t);
70
     static void SelectFile();
78
     static void SelectFile();
73
     static void PanelInfo(uint8_t);
81
     static void PanelInfo(uint8_t);
74
     static void PanelAction(uint8_t);
82
     static void PanelAction(uint8_t);
75
     static void PanelProcess(uint8_t);
83
     static void PanelProcess(uint8_t);
84
+    static bool GetLastError();
76
 };
85
 };
77
 
86
 
78
 extern ChironTFT Chiron;
87
 extern ChironTFT Chiron;
79
 
88
 
80
-} // Anycubic
89
+} // Anycubic namespace

+ 35
- 4
Marlin/src/lcd/extui/lib/anycubic_chiron/chiron_tft_defs.h Ver fichero

30
 
30
 
31
 #pragma once
31
 #pragma once
32
 #include "../../../../inc/MarlinConfigPre.h"
32
 #include "../../../../inc/MarlinConfigPre.h"
33
-//#define ACDEBUGLEVEL 255
33
+//#define ACDEBUGLEVEL 4
34
 
34
 
35
 #if ACDEBUGLEVEL
35
 #if ACDEBUGLEVEL
36
   // Bit-masks for selective debug:
36
   // Bit-masks for selective debug:
54
 #define MAX_PATH_LEN                   16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
54
 #define MAX_PATH_LEN                   16 * MAX_FOLDER_DEPTH // Maximum number of characters in a SD file path
55
 
55
 
56
 #define AC_HEATER_FAULT_VALIDATION_TIME 5    // number of 1/2 second loops before signalling a heater fault
56
 #define AC_HEATER_FAULT_VALIDATION_TIME 5    // number of 1/2 second loops before signalling a heater fault
57
-#define AC_LOWEST_MESHPOINT_VAL        Z_PROBE_LOW_POINT // The lowest value you can set for a single mesh point offset
57
+#define AC_LOWEST_MESHPOINT_VAL         -10  // The lowest value you can set for a single mesh point offset
58
 
58
 
59
  // TFT panel commands
59
  // TFT panel commands
60
 #define  AC_msg_sd_card_inserted       PSTR("J00")
60
 #define  AC_msg_sd_card_inserted       PSTR("J00")
85
 #define  AC_msg_probing_complete       PSTR("J25")
85
 #define  AC_msg_probing_complete       PSTR("J25")
86
 #define  AC_msg_start_probing          PSTR("J26")
86
 #define  AC_msg_start_probing          PSTR("J26")
87
 #define  AC_msg_version                PSTR("J27")
87
 #define  AC_msg_version                PSTR("J27")
88
+#define  AC_msg_mesh_changes_abandoned PSTR("Mesh changes abandoned, previous mesh restored.")
89
+#define  AC_msg_mesh_changes_saved     PSTR("Mesh changes saved.")
90
+#define  AC_msg_old_panel_detected     PSTR("Standard TFT panel detected!")
91
+#define  AC_msg_new_panel_detected     PSTR("New TFT panel detected!")
92
+#define  AC_msg_powerloss_recovery     PSTR("Resuming from power outage! select the same SD file then press resume")
93
+// Error messages must not contain spaces
94
+#define  AC_msg_error_bed_temp         PSTR("Abnormal_bed_temp")
95
+#define  AC_msg_error_hotend_temp      PSTR("Abnormal_hotend_temp")
96
+#define  AC_msg_error_sd_card          PSTR("SD_card_error")
97
+#define  AC_msg_filament_out           PSTR("Filament_runout")
98
+#define  AC_msg_power_loss             PSTR("Power_failure")
99
+#define  AC_msg_eeprom_version         PSTR("EEPROM_ver_wrong")
88
 
100
 
89
 #define MARLIN_msg_start_probing       PSTR("Probing Point 1/25")
101
 #define MARLIN_msg_start_probing       PSTR("Probing Point 1/25")
90
 #define MARLIN_msg_probing_failed      PSTR("Probing Failed")
102
 #define MARLIN_msg_probing_failed      PSTR("Probing Failed")
93
 #define MARLIN_msg_print_aborted       PSTR("Print Aborted")
105
 #define MARLIN_msg_print_aborted       PSTR("Print Aborted")
94
 #define MARLIN_msg_extruder_heating    PSTR("E Heating...")
106
 #define MARLIN_msg_extruder_heating    PSTR("E Heating...")
95
 #define MARLIN_msg_bed_heating         PSTR("Bed Heating...")
107
 #define MARLIN_msg_bed_heating         PSTR("Bed Heating...")
96
-
108
+#define MARLIN_msg_EEPROM_version      PSTR("EEPROM Version Error")
97
 #define MARLIN_msg_nozzle_parked       PSTR("Nozzle Parked")
109
 #define MARLIN_msg_nozzle_parked       PSTR("Nozzle Parked")
98
 #define MARLIN_msg_heater_timeout      PSTR("Heater Timeout")
110
 #define MARLIN_msg_heater_timeout      PSTR("Heater Timeout")
99
 #define MARLIN_msg_reheating           PSTR("Reheating...")
111
 #define MARLIN_msg_reheating           PSTR("Reheating...")
100
 #define MARLIN_msg_reheat_done         PSTR("Reheat finished.")
112
 #define MARLIN_msg_reheat_done         PSTR("Reheat finished.")
101
 #define MARLIN_msg_filament_purging    PSTR("Filament Purging...")
113
 #define MARLIN_msg_filament_purging    PSTR("Filament Purging...")
102
 #define MARLIN_msg_special_pause       PSTR("PB")
114
 #define MARLIN_msg_special_pause       PSTR("PB")
115
+
103
 #define AC_cmnd_auto_unload_filament   PSTR("M701")                    // Use Marlin unload routine
116
 #define AC_cmnd_auto_unload_filament   PSTR("M701")                    // Use Marlin unload routine
104
 #define AC_cmnd_auto_load_filament     PSTR("M702 M0 PB")              // Use Marlin load routing then pause for user to clean nozzle
117
 #define AC_cmnd_auto_load_filament     PSTR("M702 M0 PB")              // Use Marlin load routing then pause for user to clean nozzle
105
 
118
 
108
 #define AC_cmnd_enable_leveling        PSTR("M420SV")
121
 #define AC_cmnd_enable_leveling        PSTR("M420SV")
109
 #define AC_cmnd_power_loss_recovery    PSTR("G28XYR5\nG28Z")           // Lift, home X and Y then home Z when in 'safe' position
122
 #define AC_cmnd_power_loss_recovery    PSTR("G28XYR5\nG28Z")           // Lift, home X and Y then home Z when in 'safe' position
110
 
123
 
124
+#define AC_Test_for_OldPanel           PSTR("SIZE")                    // An old panel will respond with 'SXY 480 320' a new panel wont respond.
125
+#define AC_Test_for_NewPanel           PSTR("J200")                    // A new panel will respond with '[0]=0   [1]=0' to '[19]=0   '  an old panel wont respond
126
+
111
 namespace Anycubic {
127
 namespace Anycubic {
112
   enum heater_state_t : uint8_t {
128
   enum heater_state_t : uint8_t {
113
     AC_heater_off,
129
     AC_heater_off,
120
     AC_paused_idle
136
     AC_paused_idle
121
   };
137
   };
122
   enum printer_state_t : uint8_t {
138
   enum printer_state_t : uint8_t {
139
+    AC_printer_booting,
123
     AC_printer_idle,
140
     AC_printer_idle,
124
     AC_printer_probing,
141
     AC_printer_probing,
125
     AC_printer_printing,
142
     AC_printer_printing,
144
     AC_menu_change_to_file,
161
     AC_menu_change_to_file,
145
     AC_menu_change_to_command
162
     AC_menu_change_to_command
146
   };
163
   };
147
-} // Anycubic
164
+  enum panel_type_t : uint8_t {
165
+    AC_panel_unknown,
166
+    AC_panel_standard,
167
+    AC_panel_new
168
+  };
169
+  enum last_error_t : uint8_t {
170
+    AC_error_none,
171
+    AC_error_abnormal_temp_t0,
172
+    AC_error_abnormal_temp_bed,
173
+    AC_error_noSD,
174
+    AC_error_powerloss,
175
+    AC_error_filament_runout,
176
+    AC_error_EEPROM
177
+  };
178
+}  // Anycubic namespace

Loading…
Cancelar
Guardar