15Aug/150
Teensy 3.1 SdFat File Browser
I was working on making a test application for the SDFat library, but I eventually ended up creating was more of a Linux-style file browser.
All that I currently have implemented is "cd", "ls", and a SdFat-style "ls -l"...
/* * Print size, modify date/time, and name for all files in root. */ #include <SPI.h> #include <SdFat.h> #define LINUX_PROMPT_STYLE // SD chip select pin const uint8_t chipSelect = 4; // file system objects SdFat sd; SdFile file; SdBaseFile *cwd; String path; // ============================================================================= void printPrompt() { #ifdef LINUX_PROMPT_STYLE Serial.print("[root@localhost \""); Serial.print(path); Serial.println("\"]$ "); #else Serial.println("#"); #endif } void cmd_ll(SdBaseFile *d) { // cache the current d position FatPos_t p; d->getpos(&p); // open next file in root. The volume working directory, vwd, is root while (file.openNext(d, O_READ)) { file.printFileSize(&Serial); Serial.write(' '); file.printModifyDateTime(&Serial); Serial.write(' '); file.printName(&Serial); if (file.isDir()) { // Indicate a directory. Serial.write('/'); } Serial.println(); file.close(); } d->setpos(&p); printPrompt(); } void cmd_ls(SdBaseFile *d) { // cache the current d position FatPos_t p; d->getpos(&p); // open next file in root. The volume working directory, vwd, is root while (file.openNext(d, O_READ)) { if (file.isHidden()) { file.close(); continue; } file.printName(&Serial); if (file.isDir()) { // Indicate a directory. Serial.write('/'); } Serial.println(); file.close(); } d->setpos(&p); printPrompt(); } void cmd_cd(SdBaseFile *d, String *args) { if (*args == "") { if (sd.chdir()) path = "/"; } else if (*args == ".") { } else if (*args == "..") { int slash = path.lastIndexOf("/", path.length() - 1); String temp; if (slash == 0) temp = "/"; else temp = path.substring(0, slash); char pbuf[512]; memset(&pbuf, 0, sizeof(pbuf)); temp.toCharArray(pbuf, sizeof(pbuf)); if (sd.chdir(pbuf)) path = temp; } else if ((*args)[0] == '/') { int slash = path.lastIndexOf("/", path.length() - 1); String temp = path.substring(0, slash); char buf[64]; memset(&buf, 0, sizeof(buf)); args->toCharArray(buf, sizeof(buf)); if (sd.chdir(buf)) path = *args; } else { int slash = path.lastIndexOf("/", path.length() - 1); String temp = path.substring(0, slash); char buf[64]; memset(&buf, 0, sizeof(buf)); args->toCharArray(buf, sizeof(buf)); if (sd.chdir(buf)) { if (path == "/") { path.concat(buf); } else { path.concat("/"); path.concat(buf); } } } printPrompt(); return; } // ============================================================================= #define CMD_IS(x,y) (x.substring(0, strlen(y)) == y) //#define SAVE_ARGS(x,y) { Serial.println(x); Serial.println(y); }; #define SAVE_ARGS(x, y) { args = x.substring(strlen(y) + 1); } int getInputCommand() { String args; if (!Serial.available()) return -1; String i = Serial.readString(); // Flush while (Serial.available()) { Serial.read(); Serial.print("."); }; if CMD_IS(i, "ls -l") { cmd_ll(cwd); return 0; } else if CMD_IS(i, "ll") { cmd_ll(cwd); return 0; } else if CMD_IS(i, "ls") { cmd_ls(cwd); return 0; } else if CMD_IS(i, "cd") { SAVE_ARGS(i, "cd"); cmd_cd(cwd, &args); return 0; } return -1; } //------------------------------------------------------------------------------ void setup() { Serial.begin(9600); while (!Serial) {} // wait for Leonardo delay(400); // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with // breadboards. use SPI_FULL_SPEED for better performance. if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { sd.initErrorHalt(); } cwd = (SdBaseFile *)sd.vwd(); path = "/"; } //------------------------------------------------------------------------------ void loop() { getInputCommand(); }
Leave a comment
You must be logged in to post a comment.