ソースを参照

Sub-file calls.

by overloading M32 it is now possible to execute gcode files from other gcode files, with a fixed recursion level.
This can be used e.g. for having a real start.g and end.g somewhere on the sd card, which are then called from the normal print file.
Another usecase would be to have macro-files for nozzle-change and layerchange.
I have not tested the speedwise performance. The testing was done with pronterface.

syntax:
normal call from sd card will open the new file and continue executing there.
M32 !/path/filename#
this however will call the new file and return to the caller file.
M32 P !/path/filename#
with the optional "S<position>" the  file starting position can be set.
this is for continuing prints from a previous location.
bkubicek 11年前
コミット
ab965376ff
3個のファイルの変更121行の追加20行の削除
  1. 34
    9
      Marlin/Marlin_main.cpp
  2. 79
    10
      Marlin/cardreader.cpp
  3. 8
    1
      Marlin/cardreader.h

+ 34
- 9
Marlin/Marlin_main.cpp ファイルの表示

@@ -90,7 +90,10 @@
90 90
 // M29  - Stop SD write
91 91
 // M30  - Delete file from SD (M30 filename.g)
92 92
 // M31  - Output time since last M109 or SD card start to serial
93
-// M32  - Select file and start SD print (Can be used when printing from SD card)
93
+// M32  - Select file and start SD print (Can be used _while_ printing from SD card files): 
94
+//        syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#"
95
+//        Call gcode file : "M32 P !filename#" and return to caller file after finishing (simiarl to #include).
96
+//        The '#' is necessary when calling from within sd files, as it stops buffer prereading
94 97
 // M42  - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
95 98
 // M80  - Turn on Power Supply
96 99
 // M81  - Turn off Power Supply
@@ -1467,19 +1470,41 @@ void process_commands()
1467 1470
         card.removeFile(strchr_pointer + 4);
1468 1471
       }
1469 1472
       break;
1470
-    case 32: //M32 - Select file and start SD print
1473
+    case 32: //M32 - Select file and start SD print 
1474
+    {
1471 1475
       if(card.sdprinting) {
1472 1476
         st_synchronize();
1473
-        card.closefile();
1474
-        card.sdprinting = false;
1477
+
1475 1478
       }
1476
-      starpos = (strchr(strchr_pointer + 4,'*'));
1479
+      starpos = (strchr(strchr_pointer + 4,'*')); 
1480
+      
1481
+      char* namestartpos = (strchr(strchr_pointer + 4,'!'));   //find ! to indicate filename string start.
1482
+      if(namestartpos==NULL)
1483
+      {
1484
+        namestartpos=strchr_pointer + 4; //default name position, 4 letters after the M
1485
+      }
1486
+      else
1487
+        namestartpos++; //to skip the '!'
1488
+        
1477 1489
       if(starpos!=NULL)
1478 1490
         *(starpos-1)='\0';
1479
-      card.openFile(strchr_pointer + 4,true);
1480
-      card.startFileprint();
1481
-      starttime=millis();
1482
-      break;
1491
+            
1492
+      bool call_procedure=(code_seen('P'));
1493
+      
1494
+      if(strchr_pointer>namestartpos) 
1495
+        call_procedure=false;  //false alert, 'P' found within filename
1496
+      
1497
+      if( card.cardOK ) 
1498
+      {
1499
+        card.openFile(namestartpos,true,!call_procedure);
1500
+        if(code_seen('S'))
1501
+          if(strchr_pointer<namestartpos) //only if "S" is occuring _before_ the filename
1502
+            card.setIndex(code_value_long());
1503
+        card.startFileprint();
1504
+        if(!call_procedure)
1505
+          starttime=millis(); //procedure calls count as normal print time.
1506
+      }
1507
+    } break;
1483 1508
     case 928: //M928 - Start SD write
1484 1509
       starpos = (strchr(strchr_pointer + 5,'*'));
1485 1510
       if(starpos != NULL){

+ 79
- 10
Marlin/cardreader.cpp ファイルの表示

@@ -19,6 +19,7 @@ CardReader::CardReader()
19 19
    logging = false;
20 20
    autostart_atmillis=0;
21 21
    workDirDepth = 0;
22
+   file_subcall_ctr=0;
22 23
    memset(workDirParents, 0, sizeof(workDirParents));
23 24
 
24 25
    autostart_stilltocheck=true; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
@@ -224,14 +225,71 @@ void CardReader::openLogFile(char* name)
224 225
   openFile(name, false);
225 226
 }
226 227
 
227
-void CardReader::openFile(char* name,bool read)
228
+void CardReader::getAbsFilename(char *t)
229
+{
230
+  uint8_t cnt=0;
231
+  *t='/';t++;cnt++;
232
+  for(uint8_t i=0;i<workDirDepth;i++)
233
+  {
234
+    workDirParents[i].getFilename(t); //SDBaseFile.getfilename!
235
+    while(*t!=0 && cnt< MAXPATHNAMELENGTH) 
236
+    {t++;cnt++;}  //crawl counter forward.
237
+  }
238
+  if(cnt<MAXPATHNAMELENGTH-13)
239
+    file.getFilename(t);
240
+  else
241
+    t[0]=0;
242
+}
243
+
244
+void CardReader::openFile(char* name,bool read, bool replace_current/*=true*/)
228 245
 {
229 246
   if(!cardOK)
230 247
     return;
231
-  file.close();
248
+  if(file.isOpen())  //replaceing current file by new file, or subfile call
249
+  {
250
+    if(!replace_current)
251
+    {
252
+     if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1)
253
+     {
254
+       SERIAL_ERROR_START;
255
+       SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
256
+       SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
257
+       kill();
258
+       return;
259
+     }
260
+     
261
+     SERIAL_ECHO_START;
262
+     SERIAL_ECHOPGM("SUBROUTINE CALL target:\"");
263
+     SERIAL_ECHO(name);
264
+     SERIAL_ECHOPGM("\" parent:\"");
265
+     
266
+     //store current filename and position
267
+     getAbsFilename(filenames[file_subcall_ctr]);
268
+     
269
+     SERIAL_ECHO(filenames[file_subcall_ctr]);
270
+     SERIAL_ECHOPGM("\" pos");
271
+     SERIAL_ECHOLN(sdpos);
272
+     filespos[file_subcall_ctr]=sdpos;
273
+     file_subcall_ctr++;
274
+    }
275
+    else
276
+    {
277
+     SERIAL_ECHO_START;
278
+     SERIAL_ECHOPGM("Now doing file: ");
279
+     SERIAL_ECHOLN(name);
280
+    }
281
+    file.close();
282
+  }
283
+  else //opening fresh file
284
+  {
285
+    file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure
286
+    SERIAL_ECHO_START;
287
+    SERIAL_ECHOPGM("Now fresh file: ");
288
+    SERIAL_ECHOLN(name);
289
+  }
232 290
   sdprinting = false;
233 291
   
234
-  
292
+ 
235 293
   SdFile myDir;
236 294
   curDir=&root;
237 295
   char *fname=name;
@@ -547,14 +605,25 @@ void CardReader::updir()
547 605
 void CardReader::printingHasFinished()
548 606
 {
549 607
     st_synchronize();
550
-    quickStop();
551
-    file.close();
552
-    sdprinting = false;
553
-    if(SD_FINISHED_STEPPERRELEASE)
608
+    if(file_subcall_ctr>0) //heading up to a parent file that called current as a procedure.
609
+    {
610
+      file.close();
611
+      file_subcall_ctr--;
612
+      openFile(filenames[file_subcall_ctr],true,true);
613
+      setIndex(filespos[file_subcall_ctr]);
614
+      startFileprint();
615
+    }
616
+    else
554 617
     {
555
-        //finishAndDisableSteppers();
556
-        enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
618
+      quickStop();
619
+      file.close();
620
+      sdprinting = false;
621
+      if(SD_FINISHED_STEPPERRELEASE)
622
+      {
623
+          //finishAndDisableSteppers();
624
+          enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
625
+      }
626
+      autotempShutdown();
557 627
     }
558
-    autotempShutdown();
559 628
 }
560 629
 #endif //SDSUPPORT

+ 8
- 1
Marlin/cardreader.h ファイルの表示

@@ -18,7 +18,7 @@ public:
18 18
   //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset
19 19
 
20 20
   void checkautostart(bool x); 
21
-  void openFile(char* name,bool read);
21
+  void openFile(char* name,bool read,bool replace_current=true);
22 22
   void openLogFile(char* name);
23 23
   void removeFile(char* name);
24 24
   void closefile();
@@ -31,6 +31,8 @@ public:
31 31
   void getfilename(const uint8_t nr);
32 32
   uint16_t getnrfilenames();
33 33
   
34
+  void getAbsFilename(char *t);
35
+  
34 36
 
35 37
   void ls();
36 38
   void chdir(const char * relpath);
@@ -60,6 +62,11 @@ private:
60 62
   Sd2Card card;
61 63
   SdVolume volume;
62 64
   SdFile file;
65
+  #define SD_PROCEDURE_DEPTH 1
66
+  #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
67
+  uint8_t file_subcall_ctr;
68
+  uint32_t filespos[SD_PROCEDURE_DEPTH];
69
+  char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
63 70
   uint32_t filesize;
64 71
   //int16_t n;
65 72
   unsigned long autostart_atmillis;

読み込み中…
キャンセル
保存