SDCard.cpp
1 /* 2 This file is part of Repetier-Firmware. 3 4 Repetier-Firmware is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 Repetier-Firmware is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with Foobar. If not, see <http://www.gnu.org/licenses/>. 16 17 This firmware is a nearly complete rewrite of the sprinter firmware 18 by kliment (https://github.com/kliment/Sprinter) 19 which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. 20 */ 21 22 #include "Reptier.h" 23 #include "ui.h" 24 25 #if SDSUPPORT 26 27 #ifndef SD_ALLOW_LONG_NAMES 28 #define SD_ALLOW_LONG_NAMES false 29 #endif 30 31 SDCard sd; 32 33 SDCard::SDCard() { 34 sdmode = false; 35 sdactive = false; 36 savetosd = false; 37 //power to SD reader 38 #if SDPOWER > -1 39 SET_OUTPUT(SDPOWER); 40 WRITE(SDPOWER,HIGH); 41 #endif 42 #if defined(SDCARDDETECT) && SDCARDDETECT>-1 43 SET_INPUT(SDCARDDETECT); 44 WRITE(SDCARDDETECT,HIGH); 45 #endif 46 } 47 void SDCard::automount() { 48 #if defined(SDCARDDETECT) && SDCARDDETECT>-1 49 if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) { 50 if(sdactive) { // Card removed 51 sdactive = false; 52 savetosd = false; 53 sdmode = false; 54 UI_STATUS(UI_TEXT_SD_REMOVED); 55 OUT_P_LN(UI_TEXT_SD_REMOVED); 56 } 57 } else { 58 if(!sdactive) { 59 UI_STATUS(UI_TEXT_SD_INSERTED); 60 OUT_P_LN(UI_TEXT_SD_INSERTED); 61 initsd(); 62 } 63 } 64 #endif 65 } 66 void SDCard::initsd() { 67 sdactive = false; 68 #if SDSS >- 1 69 /*if(dir[0].isOpen()) 70 dir[0].close();*/ 71 if(!fat.begin(SDSS,SPI_FULL_SPEED)) { 72 OUT_P_LN("SD init fail"); 73 return; 74 } 75 fat.setStdOut(&out); 76 sdactive = true; 77 #endif 78 } 79 80 void SDCard::write_command(GCode *code) { 81 unsigned int sum1=0,sum2=0; // for fletcher-16 checksum 82 byte buf[100]; 83 byte p=2; 84 file.writeError = false; 85 int params = 128 | (code->params & ~1); 86 *(int*)buf = params; 87 if(GCODE_IS_V2(code)) { // Read G,M as 16 bit value 88 *(int*)&buf[p] = code->params2;p+=2; 89 if(GCODE_HAS_STRING(code)) 90 buf[p++] = strlen(code->text); 91 if(code->params & 2) {*(int*)&buf[p] = code->M;p+=2;} 92 if(code->params & 4) {*(int*)&buf[p]= code->G;p+=2;} 93 } else { 94 if(code->params & 2) {buf[p++] = (byte)code->M;} 95 if(code->params & 4) {buf[p++] = (byte)code->G;} 96 } 97 if(code->params & 8) {*(float*)&buf[p] = code->X;p+=4;} 98 if(code->params & 16) {*(float*)&buf[p] = code->Y;p+=4;} 99 if(code->params & 32) {*(float*)&buf[p] = code->Z;p+=4;} 100 if(code->params & 64) {*(float*)&buf[p] = code->E;p+=4;} 101 if(code->params & 256) {*(float*)&buf[p] = code->F;p+=4;} 102 if(code->params & 512) {buf[p++] = code->T;} 103 if(code->params & 1024) {*(long int*)&buf[p] = code->S;p+=4;} 104 if(code->params & 2048) {*(long int*)&buf[p] = code->P;p+=4;} 105 if(code->params2 & 1) {*(float*)&buf[p] = code->I;p+=4;} 106 if(code->params2 & 2) {*(float*)&buf[p] = code->J;p+=4;} 107 if(GCODE_HAS_STRING(code)) { // read 16 byte into string 108 char *sp = code->text; 109 if(GCODE_IS_V2(code)) { 110 byte i = strlen(code->text); 111 for(;i;i--) buf[p++] = *sp++; 112 } else { 113 for(byte i=0;i<16;++i) buf[p++] = *sp++; 114 } 115 } 116 byte *ptr = buf; 117 byte len = p; 118 while (len) { 119 byte tlen = len > 21 ? 21 : len; 120 len -= tlen; 121 do { 122 sum1 += *ptr++; 123 if(sum1>=255) sum1-=255; 124 sum2 += sum1; 125 if(sum2>=255) sum2-=255; 126 } while (--tlen); 127 } 128 buf[p++] = sum1; 129 buf[p++] = sum2; 130 file.write(buf,p); 131 if (file.writeError){ 132 OUT_P_LN("error writing to file"); 133 } 134 } 135 char *SDCard::createFilename(char *buffer,const dir_t &p) 136 { 137 char *pos = buffer,*src = (char*)p.name; 138 for (byte i = 0; i < 11; i++,src++) 139 { 140 if (*src == ' ') continue; 141 if (i == 8) 142 *pos++ = '.'; 143 *pos++ = *src; 144 } 145 *pos = 0; 146 return pos; 147 } 148 bool SDCard::showFilename(const uint8_t *name) { 149 if (*name == DIR_NAME_DELETED || *name == '.') return false; 150 #if !SD_ALLOW_LONG_NAMES 151 byte i=11; 152 while(i--) { 153 if(*name=='~') return false; 154 name++; 155 } 156 #endif 157 return true; 158 } 159 void SDCard::lsRecursive(SdBaseFile *parent,byte level) 160 { 161 dir_t *p; 162 uint8_t cnt=0; 163 char *oldpathend = pathend; 164 char filename[13]; 165 parent->rewind(); 166 while ((p= parent->readDirCache())) 167 { 168 if (p->name[0] == DIR_NAME_FREE) break; 169 if (!showFilename(p->name)) continue; 170 if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; 171 if( DIR_IS_SUBDIR(p)) 172 { 173 if(level>=SD_MAX_FOLDER_DEPTH) continue; // can't go deeper 174 if(level<SD_MAX_FOLDER_DEPTH) { 175 createFilename(filename,*p); 176 if(level) { 177 out.print(fullName); 178 out.print('/'); 179 } 180 out.print(filename); 181 out.println('/'); //End with / to mark it as directory entry, so we can see empty directories. 182 } 183 char *tmp = oldpathend; 184 if(level) *tmp++ = '/'; 185 char *dirname = tmp; 186 pathend = createFilename(tmp,*p); 187 SdBaseFile next; 188 uint16_t index = parent->curPosition()/32 - 1; 189 if(next.open(parent,dirname, O_READ)) 190 lsRecursive(&next,level+1); 191 parent->seekSet(32 * (index + 1)); 192 *oldpathend = 0; 193 } else { 194 createFilename(filename,*p); 195 if(level) { 196 out.print(fullName); 197 out.print('/'); 198 } 199 out.print(filename); 200 #ifdef SD_EXTENDED_DIR 201 out.write(' '); 202 out.print(p->fileSize); 203 #endif 204 out.println(); 205 } 206 } 207 } 208 void SDCard::ls() { 209 OUT_P_LN("Begin file list"); 210 *fullName = 0; 211 pathend = fullName; 212 fat.chdir(); 213 lsRecursive(fat.vwd(),0); 214 OUT_P_LN("End file list"); 215 } 216 217 void SDCard::selectFile(char *filename) { 218 if(!sdactive) return; 219 sdmode = false; 220 file.close(); 221 fat.chdir(); 222 if (file.open(fat.vwd(),filename, O_READ)) { 223 OUT_P("File opened:"); 224 out.print(filename); 225 OUT_P_L_LN(" Size:",file.fileSize()); 226 sdpos = 0; 227 filesize = file.fileSize(); 228 OUT_P_LN("File selected"); 229 } else { 230 OUT_P_LN("file.open failed"); 231 } 232 } 233 void SDCard::printStatus() { 234 if(sdactive){ 235 OUT_P_L("SD printing byte ",sdpos); 236 OUT_P_L_LN("/",filesize); 237 } else { 238 OUT_P_LN("Not SD printing"); 239 } 240 } 241 void SDCard::startWrite(char *filename) { 242 if(!sdactive) return; 243 file.close(); 244 sdmode = false; 245 fat.chdir(); 246 if(!file.open(filename, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { 247 OUT_P("open failed, File: "); 248 out.print(filename); 249 out.print('.'); 250 } else { 251 UI_STATUS(UI_TEXT_UPLOADING); 252 savetosd = true; 253 OUT_P("Writing to file: "); 254 out.println(filename); 255 } 256 } 257 void SDCard::finishWrite() { 258 if(!savetosd) return; // already closed or never opened 259 file.sync(); 260 file.close(); 261 savetosd = false; 262 OUT_P_LN("Done saving file."); 263 UI_CLEAR_STATUS; 264 } 265 void SDCard::deleteFile(char *filename) { 266 if(!sdactive) return; 267 sdmode = false; 268 file.close(); 269 if(fat.remove(filename)) { 270 OUT_P_LN("File deleted"); 271 } else { 272 if(fat.rmdir(filename)) 273 OUT_P_LN("File deleted"); 274 else 275 OUT_P_LN("Deletion failed"); 276 } 277 } 278 void SDCard::makeDirectory(char *filename) { 279 if(!sdactive) return; 280 sdmode = false; 281 file.close(); 282 if(fat.mkdir(filename)) { 283 OUT_P_LN("Directory created"); 284 } else { 285 OUT_P_LN("Creation failed"); 286 } 287 } 288 #endif 289