#include "cardreader.h" //#include #ifdef SDSUPPORT #include "Configuration.h" CardReader::CardReader() { filesize = 0; sdpos = 0; sdprinting = false; cardOK = false; saving = false; autostart_atmillis=0; autostart_stilltocheck=true; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. //power to SD reader #if SDPOWER > -1 SET_OUTPUT(SDPOWER); WRITE(SDPOWER,HIGH); #endif //SDPOWER autostart_atmillis=millis()+5000; } char *createFilename(char *buffer,const dir_t &p) //buffer>12characters { char *pos=buffer; for (uint8_t i = 0; i < 11; i++) { if (p.name[i] == ' ')continue; if (i == 8) { *pos++='.'; } *pos++=p.name[i]; } *pos++=0; return buffer; } void CardReader::lsDive(char *prepend,SdFile parent) { dir_t p; uint8_t cnt=0; while (parent.readDir(p) > 0) { if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) { char path[13*2]; char lfilename[13]; createFilename(lfilename,p); path[0]=0; if(strlen(prepend)==0) //avoid leading / if already in prepend { strcat(path,"/"); } strcat(path,prepend); strcat(path,lfilename); strcat(path,"/"); //Serial.print(path); SdFile dir; if(!dir.open(parent,lfilename, O_READ)) { if(lsAction==LS_SerialPrint) { SERIAL_ECHO_START; SERIAL_ECHOLN("Cannot open subdir"); SERIAL_ECHOLN(lfilename); } } lsDive(path,dir); //close done automatically by destructor of SdFile } else { if (p.name[0] == DIR_NAME_FREE) break; if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue; if ( p.name[0] == '.') { if ( p.name[1] != '.') continue; } if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; filenameIsDir=DIR_IS_SUBDIR(&p); if(!filenameIsDir) { if(p.name[8]!='G') continue; if(p.name[9]=='~') continue; } //if(cnt++!=nr) continue; createFilename(filename,p); if(lsAction==LS_SerialPrint) { SERIAL_PROTOCOL(prepend); SERIAL_PROTOCOLLN(filename); } else if(lsAction==LS_Count) { nrFiles++; } else if(lsAction==LS_GetFilename) { if(cnt==nrFiles) return; cnt++; } } } } void CardReader::ls() { lsAction=LS_SerialPrint; if(lsAction==LS_Count) nrFiles=0; root.rewind(); lsDive("",root); } void CardReader::initsd() { cardOK = false; if(root.isOpen()) root.close(); if (!card.init(SPI_FULL_SPEED,SDSS)) { //if (!card.init(SPI_HALF_SPEED,SDSS)) SERIAL_ECHO_START; SERIAL_ECHOLNPGM("SD init fail"); } else if (!volume.init(&card)) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("volume.init failed"); } else if (!root.openRoot(&volume)) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("openRoot failed"); } else { cardOK = true; SERIAL_ECHO_START; SERIAL_ECHOLNPGM("SD card ok"); } curDir=&root; if(!workDir.openRoot(&volume)) { SERIAL_ECHOLNPGM("workDir open failed"); } } void CardReader::release() { sdprinting = false; cardOK = false; } void CardReader::startFileprint() { if(cardOK) { sdprinting = true; } } void CardReader::pauseSDPrint() { if(sdprinting) { sdprinting = false; } } void CardReader::openFile(char* name,bool read) { if(!cardOK) return; file.close(); sdprinting = false; SdFile myDir; curDir=&root; char *fname=name; char *dirname_start,*dirname_end; if(name[0]=='/') { dirname_start=strchr(name,'/')+1; while(dirname_start>0) { dirname_end=strchr(dirname_start,'/'); //SERIAL_ECHO("start:");SERIAL_ECHOLN((int)(dirname_start-name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name)); if(dirname_end>0 && dirname_end>dirname_start) { char subdirname[13]; strncpy(subdirname, dirname_start, dirname_end-dirname_start); subdirname[dirname_end-dirname_start]=0; SERIAL_ECHOLN(subdirname); if(!myDir.open(curDir,subdirname,O_READ)) { SERIAL_PROTOCOLPGM("open failed, File: "); SERIAL_PROTOCOL(subdirname); SERIAL_PROTOCOLLNPGM("."); return; } else ;//SERIAL_ECHOLN("dive ok"); curDir=&myDir; dirname_start=dirname_end+1; } else // the reminder after all /fsa/fdsa/ is the filename { fname=dirname_start; //SERIAL_ECHOLN("remaider"); //SERIAL_ECHOLN(fname); break; } } } else //relative path { curDir=&workDir; } if(read) { if (file.open(curDir, fname, O_READ)) { filesize = file.fileSize(); SERIAL_PROTOCOLPGM("File opened:"); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLPGM(" Size:"); SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNPGM("File selected"); LCD_MESSAGE(fname); } else { SERIAL_PROTOCOLPGM("open failed, File: "); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLLNPGM("."); } } else { //write if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { SERIAL_PROTOCOLPGM("open failed, File: "); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLLNPGM("."); } else { saving = true; SERIAL_PROTOCOLPGM("Writing to file: "); SERIAL_PROTOCOLLN(name); LCD_MESSAGE(fname); } } } void CardReader::getStatus() { if(cardOK){ SERIAL_PROTOCOLPGM("SD printing byte "); SERIAL_PROTOCOL(sdpos); SERIAL_PROTOCOLPGM("/"); SERIAL_PROTOCOLLN(filesize); } else{ SERIAL_PROTOCOLLNPGM("Not SD printing"); } } void CardReader::write_command(char *buf) { char* begin = buf; char* npos = 0; char* end = buf + strlen(buf) - 1; file.writeError = false; if((npos = strchr(buf, 'N')) != NULL) { begin = strchr(npos, ' ') + 1; end = strchr(npos, '*') - 1; } end[1] = '\r'; end[2] = '\n'; end[3] = '\0'; file.write(begin); if (file.writeError) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("error writing to file"); } } void CardReader::checkautostart(bool force) { if(!force) { if(!autostart_stilltocheck) return; if(autostart_atmillis 0) { for(int8_t i=0;i<(int)strlen((char*)p.name);i++) p.name[i]=tolower(p.name[i]); //Serial.print((char*)p.name); //Serial.print(" "); //Serial.println(autoname); if(p.name[9]!='~') //skip safety copies if(strncmp((char*)p.name,autoname,5)==0) { char cmd[30]; sprintf(cmd,"M23 %s",autoname); enquecommand(cmd); enquecommand("M24"); found=true; } } if(!found) lastnr=-1; else lastnr++; } void CardReader::closefile() { file.sync(); file.close(); saving = false; } void CardReader::getfilename(const uint8_t nr) { curDir=&workDir; lsAction=LS_GetFilename; nrFiles=nr; curDir->rewind(); lsDive("",*curDir); } uint16_t CardReader::getnrfilenames() { curDir=&workDir; lsAction=LS_Count; nrFiles=0; curDir->rewind(); lsDive("",*curDir); //SERIAL_ECHOLN(nrFiles); return nrFiles; } void CardReader::chdir(const char * relpath) { SdFile newfile; SdFile *parent=&root; if(workDir.isOpen()) parent=&workDir; if(!newfile.open(*parent,relpath, O_READ)) { SERIAL_ECHO_START; SERIAL_ECHOPGM("Cannot enter subdir:"); SERIAL_ECHOLN(relpath); } else { workDirParentParent=workDirParent; workDirParent=*parent; workDir=newfile; } } void CardReader::updir() { if(!workDir.isRoot()) { workDir=workDirParent; workDirParent=workDirParentParent; } } void CardReader::printingHasFinished() { sdprinting = false; if(SD_FINISHED_STEPPERRELEASE) { finishAndDisableSteppers(); } } #endif //SDSUPPORT