diff --git a/Marlin/Marlin.pde b/Marlin/Marlin.pde
index 8dc8d0822e..34d50e3c46 100644
--- a/Marlin/Marlin.pde
+++ b/Marlin/Marlin.pde
@@ -176,6 +176,7 @@ static unsigned long stoptime=0;
//=============================ROUTINES=============================
//===========================================================================
+void get_arc_coordinates();
extern "C"{
extern unsigned int __bss_end;
@@ -588,7 +589,7 @@ inline void process_commands()
starpos = (strchr(strchr_pointer + 4,'*'));
if(starpos!=NULL)
*(starpos-1)='\0';
- card.selectFile(strchr_pointer + 4);
+ card.openFile(strchr_pointer + 4,true);
break;
case 24: //M24 - Start SD print
card.startFileprint();
@@ -613,7 +614,7 @@ inline void process_commands()
strchr_pointer = strchr(npos,' ') + 1;
*(starpos-1) = '\0';
}
- card.startFilewrite(strchr_pointer+4);
+ card.openFile(strchr_pointer+4,false);
break;
case 29: //M29 - Stop SD write
diff --git a/Marlin/SdFat.cpp b/Marlin/SdFat.cpp
deleted file mode 100644
index 494fd48225..0000000000
--- a/Marlin/SdFat.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Arduino SdFat Library
- * Copyright (C) 2009 by William Greiman
- *
- * This file is part of the Arduino SdFat Library
- *
- * This Library 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.
- *
- * This Library 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 the Arduino SdFat Library. If not, see
- * .
- */
-#include "SdFat.h"
-#include "SdFatUtil.h"
-//------------------------------------------------------------------------------
-/** Change a volume's working directory to root
- *
- * Changes the volume's working directory to the SD's root directory.
- * Optionally set the current working directory to the volume's
- * working directory.
- *
- * \param[in] set_cwd Set the current working directory to this volume's
- * working directory if true.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::chdir(bool set_cwd) {
- if (set_cwd) SdBaseFile::cwd_ = &vwd_;
- vwd_.close();
- return vwd_.openRoot(&vol_);
-}
-//------------------------------------------------------------------------------
-/** Change a volume's working directory
- *
- * Changes the volume working directory to the \a path subdirectory.
- * Optionally set the current working directory to the volume's
- * working directory.
- *
- * Example: If the volume's working directory is "/DIR", chdir("SUB")
- * will change the volume's working directory from "/DIR" to "/DIR/SUB".
- *
- * If path is "/", the volume's working directory will be changed to the
- * root directory
- *
- * \param[in] path The name of the subdirectory.
- *
- * \param[in] set_cwd Set the current working directory to this volume's
- * working directory if true.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::chdir(const char *path, bool set_cwd) {
- SdBaseFile dir;
- if (path[0] == '/' && path[1] == '\0') return chdir(set_cwd);
- if (!dir.open(&vwd_, path, O_READ)) goto fail;
- if (!dir.isDir()) goto fail;
- vwd_ = dir;
- if (set_cwd) SdBaseFile::cwd_ = &vwd_;
- return true;
-
- fail:
- return false;
-}
-//------------------------------------------------------------------------------
-/** Set the current working directory to a volume's working directory.
- *
- * This is useful with multiple SD cards.
- *
- * The current working directory is changed to this volume's working directory.
- *
- * This is like the Windows/DOS \: command.
- */
-void SdFat::chvol() {
- SdBaseFile::cwd_ = &vwd_;
-}
-//------------------------------------------------------------------------------
-/** %Print any SD error code and halt. */
-void SdFat::errorHalt() {
- errorPrint();
- while (1);
-}
-//------------------------------------------------------------------------------
-/** %Print msg, any SD error code, and halt.
- *
- * \param[in] msg Message to print.
- */
-void SdFat::errorHalt(char const* msg) {
- errorPrint(msg);
- while (1);
-}
-//------------------------------------------------------------------------------
-/** %Print msg, any SD error code, and halt.
- *
- * \param[in] msg Message in program space (flash memory) to print.
- */
-void SdFat::errorHalt_P(PGM_P msg) {
- errorPrint_P(msg);
- while (1);
-}
-//------------------------------------------------------------------------------
-/** %Print any SD error code. */
-void SdFat::errorPrint() {
- if (!card_.errorCode()) return;
- PgmPrint("SD errorCode: 0X");
- Serial.println(card_.errorCode(), HEX);
-}
-//------------------------------------------------------------------------------
-/** %Print msg, any SD error code.
- *
- * \param[in] msg Message to print.
- */
-void SdFat::errorPrint(char const* msg) {
- PgmPrint("error: ");
- Serial.println(msg);
- errorPrint();
-}
-//------------------------------------------------------------------------------
-/** %Print msg, any SD error code.
- *
- * \param[in] msg Message in program space (flash memory) to print.
- */
-void SdFat::errorPrint_P(PGM_P msg) {
- PgmPrint("error: ");
- SerialPrintln_P(msg);
- errorPrint();
-}
-//------------------------------------------------------------------------------
-/**
- * Test for the existence of a file.
- *
- * \param[in] name Name of the file to be tested for.
- *
- * \return true if the file exists else false.
- */
-bool SdFat::exists(const char* name) {
- return vwd_.exists(name);
-}
-//------------------------------------------------------------------------------
-/**
- * Initialize an SdFat object.
- *
- * Initializes the SD card, SD volume, and root directory.
- *
- * \param[in] sckRateID value for SPI SCK rate. See Sd2Card::init().
- * \param[in] chipSelectPin SD chip select pin. See Sd2Card::init().
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::init(uint8_t sckRateID, uint8_t chipSelectPin) {
- return card_.init(sckRateID, chipSelectPin) && vol_.init(&card_) && chdir(1);
-}
-//------------------------------------------------------------------------------
-/** %Print error details and halt after SdFat::init() fails. */
-void SdFat::initErrorHalt() {
- initErrorPrint();
- while (1);
-}
-//------------------------------------------------------------------------------
-/**Print message, error details, and halt after SdFat::init() fails.
- *
- * \param[in] msg Message to print.
- */
-void SdFat::initErrorHalt(char const *msg) {
- Serial.println(msg);
- initErrorHalt();
-}
-//------------------------------------------------------------------------------
-/**Print message, error details, and halt after SdFat::init() fails.
- *
- * \param[in] msg Message in program space (flash memory) to print.
- */
-void SdFat::initErrorHalt_P(PGM_P msg) {
- SerialPrintln_P(msg);
- initErrorHalt();
-}
-//------------------------------------------------------------------------------
-/** Print error details after SdFat::init() fails. */
-void SdFat::initErrorPrint() {
- if (card_.errorCode()) {
- PgmPrintln("Can't access SD card. Do not reformat.");
- if (card_.errorCode() == SD_CARD_ERROR_CMD0) {
- PgmPrintln("No card, wrong chip select pin, or SPI problem?");
- }
- errorPrint();
- } else if (vol_.fatType() == 0) {
- PgmPrintln("Invalid format, reformat SD.");
- } else if (!vwd_.isOpen()) {
- PgmPrintln("Can't open root directory.");
- } else {
- PgmPrintln("No error found.");
- }
-}
-//------------------------------------------------------------------------------
-/**Print message and error details and halt after SdFat::init() fails.
- *
- * \param[in] msg Message to print.
- */
-void SdFat::initErrorPrint(char const *msg) {
- Serial.println(msg);
- initErrorPrint();
-}
-//------------------------------------------------------------------------------
-/**Print message and error details after SdFat::init() fails.
- *
- * \param[in] msg Message in program space (flash memory) to print.
- */
-void SdFat::initErrorPrint_P(PGM_P msg) {
- SerialPrintln_P(msg);
- initErrorHalt();
-}
-//------------------------------------------------------------------------------
-/** List the directory contents of the volume working directory to Serial.
- *
- * \param[in] flags The inclusive OR of
- *
- * LS_DATE - %Print file modification date
- *
- * LS_SIZE - %Print file size.
- *
- * LS_R - Recursive list of subdirectories.
- */
-void SdFat::ls(uint8_t flags) {
- vwd_.ls(&Serial, flags);
-}
-//------------------------------------------------------------------------------
-/** List the directory contents of the volume working directory to Serial.
- *
- * \param[in] pr Print stream for list.
- *
- * \param[in] flags The inclusive OR of
- *
- * LS_DATE - %Print file modification date
- *
- * LS_SIZE - %Print file size.
- *
- * LS_R - Recursive list of subdirectories.
- */
-void SdFat::ls(Print* pr, uint8_t flags) {
- vwd_.ls(pr, flags);
-}
-//------------------------------------------------------------------------------
-/** Make a subdirectory in the volume working directory.
- *
- * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
- *
- * \param[in] pFlag Create missing parent directories if true.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::mkdir(const char* path, bool pFlag) {
- SdBaseFile sub;
- return sub.mkdir(&vwd_, path, pFlag);
-}
-//------------------------------------------------------------------------------
-/** Remove a file from the volume working directory.
-*
-* \param[in] path A path with a valid 8.3 DOS name for the file.
-*
-* \return The value one, true, is returned for success and
-* the value zero, false, is returned for failure.
-*/
-bool SdFat::remove(const char* path) {
- return SdBaseFile::remove(&vwd_, path);
-}
-//------------------------------------------------------------------------------
-/** Rename a file or subdirectory.
- *
- * \param[in] oldPath Path name to the file or subdirectory to be renamed.
- *
- * \param[in] newPath New path name of the file or subdirectory.
- *
- * The \a newPath object must not exist before the rename call.
- *
- * The file to be renamed must not be open. The directory entry may be
- * moved and file system corruption could occur if the file is accessed by
- * a file object that was opened before the rename() call.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::rename(const char *oldPath, const char *newPath) {
- SdBaseFile file;
- if (!file.open(oldPath, O_READ)) return false;
- return file.rename(&vwd_, newPath);
-}
-//------------------------------------------------------------------------------
-/** Remove a subdirectory from the volume's working directory.
- *
- * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
- *
- * The subdirectory file will be removed only if it is empty.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- */
-bool SdFat::rmdir(const char* path) {
- SdBaseFile sub;
- if (!sub.open(path, O_READ)) return false;
- return sub.rmdir();
-}
-//------------------------------------------------------------------------------
-/** Truncate a file to a specified length. The current file position
- * will be maintained if it is less than or equal to \a length otherwise
- * it will be set to end of file.
- *
- * \param[in] path A path with a valid 8.3 DOS name for the file.
- * \param[in] length The desired length for the file.
- *
- * \return The value one, true, is returned for success and
- * the value zero, false, is returned for failure.
- * Reasons for failure include file is read only, file is a directory,
- * \a length is greater than the current file size or an I/O error occurs.
- */
-bool SdFat::truncate(const char* path, uint32_t length) {
- SdBaseFile file;
- if (!file.open(path, O_WRITE)) return false;
- return file.truncate(length);
-}
diff --git a/Marlin/SdFat.h b/Marlin/SdFat.h
deleted file mode 100644
index 1a184d0843..0000000000
--- a/Marlin/SdFat.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Arduino SdFat Library
- * Copyright (C) 2009 by William Greiman
- *
- * This file is part of the Arduino SdFat Library
- *
- * This Library 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.
- *
- * This Library 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 the Arduino SdFat Library. If not, see
- * .
- */
-#ifndef SdFat_h
-#define SdFat_h
-/**
- * \file
- * \brief SdFat class
- */
-#include "SdFile.h"
-//#include
-//#include
-//------------------------------------------------------------------------------
-/** SdFat version YYYYMMDD */
-#define SD_FAT_VERSION 20110902
-//------------------------------------------------------------------------------
-/**
- * \class SdFat
- * \brief Integration class for the %SdFat library.
- */
-class SdFat {
- public:
- SdFat() {}
- /** \return a pointer to the Sd2Card object. */
- Sd2Card* card() {return &card_;}
- bool chdir(bool set_cwd = false);
- bool chdir(const char* path, bool set_cwd = false);
- void chvol();
- void errorHalt();
- void errorHalt_P(PGM_P msg);
- void errorHalt(char const *msg);
- void errorPrint();
- void errorPrint_P(PGM_P msg);
- void errorPrint(char const *msg);
- bool exists(const char* name);
- bool init(uint8_t sckRateID = SPI_FULL_SPEED,
- uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
- void initErrorHalt();
- void initErrorHalt(char const *msg);
- void initErrorHalt_P(PGM_P msg);
- void initErrorPrint();
- void initErrorPrint(char const *msg);
- void initErrorPrint_P(PGM_P msg);
- void ls(uint8_t flags = 0);
- void ls(Print* pr, uint8_t flags = 0);
- bool mkdir(const char* path, bool pFlag = true);
- bool remove(const char* path);
- bool rename(const char *oldPath, const char *newPath);
- bool rmdir(const char* path);
- bool truncate(const char* path, uint32_t length);
- /** \return a pointer to the SdVolume object. */
- SdVolume* vol() {return &vol_;}
- /** \return a pointer to the volume working directory. */
- SdBaseFile* vwd() {return &vwd_;}
- private:
- Sd2Card card_;
- SdVolume vol_;
- SdBaseFile vwd_;
-};
-#endif // SdFat_h
diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h
index 04076bfda0..d96715807f 100644
--- a/Marlin/cardreader.h
+++ b/Marlin/cardreader.h
@@ -3,9 +3,8 @@
#ifdef SDSUPPORT
-
-#include "SdFat.h"
-
+#include "SdFile.h"
+enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
class CardReader
{
public:
@@ -17,20 +16,22 @@ public:
//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
void checkautostart(bool x);
-
+ void openFile(char* name,bool read);
void closefile();
void release();
void startFileprint();
- void startFilewrite(char *name);
+ //void startFilewrite(char *name);
void pauseSDPrint();
void getStatus();
-
- void selectFile(char* name);
+ void cd(char * absolutPath);
+ //void selectFile(char* name);
void getfilename(const uint8_t nr);
- uint8_t getnrfilenames();
+ uint16_t getnrfilenames();
- inline void ls() {root.ls();};
+ void ls();
+ void lsDive(char *prepend,SdFile parent);
+
inline bool eof() { return sdpos>=filesize ;};
inline int16_t get() { sdpos = file.curPosition();return (int16_t)file.read();};
inline void setIndex(long index) {sdpos = index;file.seekSet(index);};
@@ -42,7 +43,7 @@ public:
bool cardOK ;
char filename[11];
private:
- SdFile root;
+ SdFile root,*curDir;
Sd2Card card;
SdVolume volume;
SdFile file;
@@ -52,6 +53,10 @@ private:
uint32_t sdpos ;
bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
+
+ LsAction lsAction; //stored for recursion.
+ int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
+ char* diveDirName;
};
diff --git a/Marlin/cardreader.pde b/Marlin/cardreader.pde
index 605af11bf5..77a8f692bf 100644
--- a/Marlin/cardreader.pde
+++ b/Marlin/cardreader.pde
@@ -20,6 +20,106 @@ CardReader::CardReader()
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;
+}
+
+// bool SdFat::chdir(bool set_cwd) {
+// if (set_cwd) SdBaseFile::cwd_ = &vwd_;
+// vwd_.close();
+// return vwd_.openRoot(&vol_);
+// }
+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
+
+
+ }
+ if (p.name[0] == DIR_NAME_FREE) break;
+ if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
+ if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
+
+
+ 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;
@@ -48,6 +148,7 @@ void CardReader::initsd()
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("SD card ok");
}
+ curDir=&root;
#endif //SDSS
}
void CardReader::release()
@@ -73,13 +174,20 @@ void CardReader::pauseSDPrint()
}
}
-void CardReader::selectFile(char* name)
+
+
+void CardReader::openFile(char* name,bool read)
{
- if(cardOK){
- sdprinting = false;
- file.close();
-
- if (file.open(&root, name, O_READ)) {
+ if(!cardOK)
+ return;
+
+
+ file.close();
+ sdprinting = false;
+ if(read)
+ {
+ if (file.open(&root, name, O_READ))
+ {
filesize = file.fileSize();
SERIAL_PROTOCOLPGM("File opened:");
SERIAL_PROTOCOL(name);
@@ -89,32 +197,27 @@ void CardReader::selectFile(char* name)
SERIAL_PROTOCOLLNPGM("File selected");
}
- else{
+ else
+ {
SERIAL_PROTOCOLLNPGM("file.open failed");
}
}
-}
-
-void CardReader::startFilewrite(char *name)
-{
- if(cardOK)
- {
-
- file.close();
- sdprinting = false;
-
+ else
+ { //write
if (!file.open(&root, name, O_CREAT | O_APPEND | O_WRITE | O_TRUNC))
{
SERIAL_PROTOCOLPGM("open failed, File: ");
SERIAL_PROTOCOL(name);
SERIAL_PROTOCOLLNPGM(".");
}
- else{
+ else
+ {
saving = true;
SERIAL_PROTOCOLPGM("Writing to file: ");
SERIAL_PROTOCOLLN(name);
}
}
+
}
void CardReader::getStatus()
@@ -212,49 +315,25 @@ void CardReader::closefile()
void CardReader::getfilename(const uint8_t nr)
{
-
- dir_t p;
- root.rewind();
- uint8_t cnt=0;
- filename[0]='\0';
- while (root.readDir(p) > 0)
- {
- if (p.name[0] == DIR_NAME_FREE) break;
- if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
- if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
- if(p.name[8]!='G') continue;
- if(p.name[9]=='~') continue;
- if(cnt++!=nr) continue;
- //Serial.println((char*)p.name);
- uint8_t writepos=0;
- for (int8_t i = 0; i < 11; i++)
- {
- if (p.name[i] == ' ') continue;
- if (i == 8) {
- filename[writepos++]='.';
- }
- filename[writepos++]=p.name[i];
- }
- filename[writepos++]=0;
- }
+ lsAction=LS_GetFilename;
+ nrFiles=nr;
+ curDir->rewind();
+ lsDive("",*curDir);
+
}
-uint8_t CardReader::getnrfilenames()
+uint16_t CardReader::getnrfilenames()
{
- dir_t p;
- root.rewind();
- uint8_t cnt=0;
- while (root.readDir(p) > 0)
- {
- if (p.name[0] == DIR_NAME_FREE) break;
- if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
- if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
- if(p.name[8]!='G') continue;
- if(p.name[9]=='~') continue;
- cnt++;
- }
- return cnt;
+ lsAction=LS_Count;
+ nrFiles=0;
+ curDir->rewind();
+ lsDive("",*curDir);
+ return nrFiles;
}
+void CardReader::cd(char * absolutPath)
+{
+
+}
#endif //SDSUPPORT
\ No newline at end of file