RepetierMAX/Repetier/SDCard.cpp
johnoly99 46729d116b Initial upload
Initial uploading of firmware to seemecnc git
2013-04-17 13:36:51 -04:00

289 lines
7.6 KiB
C++

/*
This file is part of Repetier-Firmware.
Repetier-Firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Repetier-Firmware is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
This firmware is a nearly complete rewrite of the sprinter firmware
by kliment (https://github.com/kliment/Sprinter)
which based on Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
*/
#include "Reptier.h"
#include "ui.h"
#if SDSUPPORT
#ifndef SD_ALLOW_LONG_NAMES
#define SD_ALLOW_LONG_NAMES false
#endif
SDCard sd;
SDCard::SDCard() {
sdmode = false;
sdactive = false;
savetosd = false;
//power to SD reader
#if SDPOWER > -1
SET_OUTPUT(SDPOWER);
WRITE(SDPOWER,HIGH);
#endif
#if defined(SDCARDDETECT) && SDCARDDETECT>-1
SET_INPUT(SDCARDDETECT);
WRITE(SDCARDDETECT,HIGH);
#endif
}
void SDCard::automount() {
#if defined(SDCARDDETECT) && SDCARDDETECT>-1
if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED) {
if(sdactive) { // Card removed
sdactive = false;
savetosd = false;
sdmode = false;
UI_STATUS(UI_TEXT_SD_REMOVED);
OUT_P_LN(UI_TEXT_SD_REMOVED);
}
} else {
if(!sdactive) {
UI_STATUS(UI_TEXT_SD_INSERTED);
OUT_P_LN(UI_TEXT_SD_INSERTED);
initsd();
}
}
#endif
}
void SDCard::initsd() {
sdactive = false;
#if SDSS >- 1
/*if(dir[0].isOpen())
dir[0].close();*/
if(!fat.begin(SDSS,SPI_FULL_SPEED)) {
OUT_P_LN("SD init fail");
return;
}
fat.setStdOut(&out);
sdactive = true;
#endif
}
void SDCard::write_command(GCode *code) {
unsigned int sum1=0,sum2=0; // for fletcher-16 checksum
byte buf[100];
byte p=2;
file.writeError = false;
int params = 128 | (code->params & ~1);
*(int*)buf = params;
if(GCODE_IS_V2(code)) { // Read G,M as 16 bit value
*(int*)&buf[p] = code->params2;p+=2;
if(GCODE_HAS_STRING(code))
buf[p++] = strlen(code->text);
if(code->params & 2) {*(int*)&buf[p] = code->M;p+=2;}
if(code->params & 4) {*(int*)&buf[p]= code->G;p+=2;}
} else {
if(code->params & 2) {buf[p++] = (byte)code->M;}
if(code->params & 4) {buf[p++] = (byte)code->G;}
}
if(code->params & 8) {*(float*)&buf[p] = code->X;p+=4;}
if(code->params & 16) {*(float*)&buf[p] = code->Y;p+=4;}
if(code->params & 32) {*(float*)&buf[p] = code->Z;p+=4;}
if(code->params & 64) {*(float*)&buf[p] = code->E;p+=4;}
if(code->params & 256) {*(float*)&buf[p] = code->F;p+=4;}
if(code->params & 512) {buf[p++] = code->T;}
if(code->params & 1024) {*(long int*)&buf[p] = code->S;p+=4;}
if(code->params & 2048) {*(long int*)&buf[p] = code->P;p+=4;}
if(code->params2 & 1) {*(float*)&buf[p] = code->I;p+=4;}
if(code->params2 & 2) {*(float*)&buf[p] = code->J;p+=4;}
if(GCODE_HAS_STRING(code)) { // read 16 byte into string
char *sp = code->text;
if(GCODE_IS_V2(code)) {
byte i = strlen(code->text);
for(;i;i--) buf[p++] = *sp++;
} else {
for(byte i=0;i<16;++i) buf[p++] = *sp++;
}
}
byte *ptr = buf;
byte len = p;
while (len) {
byte tlen = len > 21 ? 21 : len;
len -= tlen;
do {
sum1 += *ptr++;
if(sum1>=255) sum1-=255;
sum2 += sum1;
if(sum2>=255) sum2-=255;
} while (--tlen);
}
buf[p++] = sum1;
buf[p++] = sum2;
file.write(buf,p);
if (file.writeError){
OUT_P_LN("error writing to file");
}
}
char *SDCard::createFilename(char *buffer,const dir_t &p)
{
char *pos = buffer,*src = (char*)p.name;
for (byte i = 0; i < 11; i++,src++)
{
if (*src == ' ') continue;
if (i == 8)
*pos++ = '.';
*pos++ = *src;
}
*pos = 0;
return pos;
}
bool SDCard::showFilename(const uint8_t *name) {
if (*name == DIR_NAME_DELETED || *name == '.') return false;
#if !SD_ALLOW_LONG_NAMES
byte i=11;
while(i--) {
if(*name=='~') return false;
name++;
}
#endif
return true;
}
void SDCard::lsRecursive(SdBaseFile *parent,byte level)
{
dir_t *p;
uint8_t cnt=0;
char *oldpathend = pathend;
char filename[13];
parent->rewind();
while ((p= parent->readDirCache()))
{
if (p->name[0] == DIR_NAME_FREE) break;
if (!showFilename(p->name)) continue;
if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
if( DIR_IS_SUBDIR(p))
{
if(level>=SD_MAX_FOLDER_DEPTH) continue; // can't go deeper
if(level<SD_MAX_FOLDER_DEPTH) {
createFilename(filename,*p);
if(level) {
out.print(fullName);
out.print('/');
}
out.print(filename);
out.println('/'); //End with / to mark it as directory entry, so we can see empty directories.
}
char *tmp = oldpathend;
if(level) *tmp++ = '/';
char *dirname = tmp;
pathend = createFilename(tmp,*p);
SdBaseFile next;
uint16_t index = parent->curPosition()/32 - 1;
if(next.open(parent,dirname, O_READ))
lsRecursive(&next,level+1);
parent->seekSet(32 * (index + 1));
*oldpathend = 0;
} else {
createFilename(filename,*p);
if(level) {
out.print(fullName);
out.print('/');
}
out.print(filename);
#ifdef SD_EXTENDED_DIR
out.write(' ');
out.print(p->fileSize);
#endif
out.println();
}
}
}
void SDCard::ls() {
OUT_P_LN("Begin file list");
*fullName = 0;
pathend = fullName;
fat.chdir();
lsRecursive(fat.vwd(),0);
OUT_P_LN("End file list");
}
void SDCard::selectFile(char *filename) {
if(!sdactive) return;
sdmode = false;
file.close();
fat.chdir();
if (file.open(fat.vwd(),filename, O_READ)) {
OUT_P("File opened:");
out.print(filename);
OUT_P_L_LN(" Size:",file.fileSize());
sdpos = 0;
filesize = file.fileSize();
OUT_P_LN("File selected");
} else {
OUT_P_LN("file.open failed");
}
}
void SDCard::printStatus() {
if(sdactive){
OUT_P_L("SD printing byte ",sdpos);
OUT_P_L_LN("/",filesize);
} else {
OUT_P_LN("Not SD printing");
}
}
void SDCard::startWrite(char *filename) {
if(!sdactive) return;
file.close();
sdmode = false;
fat.chdir();
if(!file.open(filename, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
OUT_P("open failed, File: ");
out.print(filename);
out.print('.');
} else {
UI_STATUS(UI_TEXT_UPLOADING);
savetosd = true;
OUT_P("Writing to file: ");
out.println(filename);
}
}
void SDCard::finishWrite() {
if(!savetosd) return; // already closed or never opened
file.sync();
file.close();
savetosd = false;
OUT_P_LN("Done saving file.");
UI_CLEAR_STATUS;
}
void SDCard::deleteFile(char *filename) {
if(!sdactive) return;
sdmode = false;
file.close();
if(fat.remove(filename)) {
OUT_P_LN("File deleted");
} else {
if(fat.rmdir(filename))
OUT_P_LN("File deleted");
else
OUT_P_LN("Deletion failed");
}
}
void SDCard::makeDirectory(char *filename) {
if(!sdactive) return;
sdmode = false;
file.close();
if(fat.mkdir(filename)) {
OUT_P_LN("Directory created");
} else {
OUT_P_LN("Creation failed");
}
}
#endif