Add SD library (not optimised).
This commit is contained in:
parent
0603b384d8
commit
2c954a58e4
21 changed files with 6016 additions and 0 deletions
150
xmega/libraries/SD/File.cpp
Normal file
150
xmega/libraries/SD/File.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
|
||||
SD - a slightly more friendly wrapper for sdfatlib
|
||||
|
||||
This library aims to expose a subset of SD card functionality
|
||||
in the form of a higher level "wrapper" object.
|
||||
|
||||
License: GNU General Public License V3
|
||||
(Because sdfatlib is licensed with this.)
|
||||
|
||||
(C) Copyright 2010 SparkFun Electronics
|
||||
|
||||
*/
|
||||
|
||||
#include <SD.h>
|
||||
|
||||
/* for debugging file open/close leaks
|
||||
uint8_t nfilecount=0;
|
||||
*/
|
||||
|
||||
File::File(SdFile f, const char *n) {
|
||||
// oh man you are kidding me, new() doesnt exist? Ok we do it by hand!
|
||||
_file = (SdFile *)malloc(sizeof(SdFile));
|
||||
if (_file) {
|
||||
memcpy(_file, &f, sizeof(SdFile));
|
||||
|
||||
strncpy(_name, n, 12);
|
||||
_name[12] = 0;
|
||||
|
||||
/* for debugging file open/close leaks
|
||||
nfilecount++;
|
||||
Serial.print("Created \"");
|
||||
Serial.print(n);
|
||||
Serial.print("\": ");
|
||||
Serial.println(nfilecount, DEC);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
File::File(void) {
|
||||
_file = 0;
|
||||
_name[0] = 0;
|
||||
//Serial.print("Created empty file object");
|
||||
}
|
||||
|
||||
File::~File(void) {
|
||||
// Serial.print("Deleted file object");
|
||||
}
|
||||
|
||||
// returns a pointer to the file name
|
||||
char *File::name(void) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
// a directory is a special type of file
|
||||
boolean File::isDirectory(void) {
|
||||
return (_file && _file->isDir());
|
||||
}
|
||||
|
||||
|
||||
size_t File::write(uint8_t val) {
|
||||
return write(&val, 1);
|
||||
}
|
||||
|
||||
size_t File::write(const uint8_t *buf, size_t size) {
|
||||
size_t t;
|
||||
if (!_file) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
_file->clearWriteError();
|
||||
t = _file->write(buf, size);
|
||||
if (_file->getWriteError()) {
|
||||
setWriteError();
|
||||
return 0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int File::peek() {
|
||||
if (! _file)
|
||||
return 0;
|
||||
|
||||
int c = _file->read();
|
||||
if (c != -1) _file->seekCur(-1);
|
||||
return c;
|
||||
}
|
||||
|
||||
int File::read() {
|
||||
if (_file)
|
||||
return _file->read();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// buffered read for more efficient, high speed reading
|
||||
int File::read(void *buf, uint16_t nbyte) {
|
||||
if (_file)
|
||||
return _file->read(buf, nbyte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int File::available() {
|
||||
if (! _file) return 0;
|
||||
|
||||
uint32_t n = size() - position();
|
||||
|
||||
return n > 0X7FFF ? 0X7FFF : n;
|
||||
}
|
||||
|
||||
void File::flush() {
|
||||
if (_file)
|
||||
_file->sync();
|
||||
}
|
||||
|
||||
boolean File::seek(uint32_t pos) {
|
||||
if (! _file) return false;
|
||||
|
||||
return _file->seekSet(pos);
|
||||
}
|
||||
|
||||
uint32_t File::position() {
|
||||
if (! _file) return -1;
|
||||
return _file->curPosition();
|
||||
}
|
||||
|
||||
uint32_t File::size() {
|
||||
if (! _file) return 0;
|
||||
return _file->fileSize();
|
||||
}
|
||||
|
||||
void File::close() {
|
||||
if (_file) {
|
||||
_file->close();
|
||||
free(_file);
|
||||
_file = 0;
|
||||
|
||||
/* for debugging file open/close leaks
|
||||
nfilecount--;
|
||||
Serial.print("Deleted ");
|
||||
Serial.println(nfilecount, DEC);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
File::operator bool() {
|
||||
if (_file)
|
||||
return _file->isOpen();
|
||||
return false;
|
||||
}
|
||||
|
15
xmega/libraries/SD/README.txt
Normal file
15
xmega/libraries/SD/README.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
** SD - a slightly more friendly wrapper for sdfatlib **
|
||||
|
||||
This library aims to expose a subset of SD card functionality in the
|
||||
form of a higher level "wrapper" object.
|
||||
|
||||
License: GNU General Public License V3
|
||||
(Because sdfatlib is licensed with this.)
|
||||
|
||||
(C) Copyright 2010 SparkFun Electronics
|
||||
|
||||
Now better than ever with optimization, multiple file support, directory handling, etc - ladyada!
|
||||
|
||||
Modifications for XMEGA (c) 2015 flabbergast - taken from Teensyduino 1.22.
|
||||
Not optimised in any way on XMEGAs.
|
||||
|
616
xmega/libraries/SD/SD.cpp
Normal file
616
xmega/libraries/SD/SD.cpp
Normal file
|
@ -0,0 +1,616 @@
|
|||
/*
|
||||
|
||||
SD - a slightly more friendly wrapper for sdfatlib
|
||||
|
||||
This library aims to expose a subset of SD card functionality
|
||||
in the form of a higher level "wrapper" object.
|
||||
|
||||
License: GNU General Public License V3
|
||||
(Because sdfatlib is licensed with this.)
|
||||
|
||||
(C) Copyright 2010 SparkFun Electronics
|
||||
|
||||
|
||||
This library provides four key benefits:
|
||||
|
||||
* Including `XSD.h` automatically creates a global
|
||||
`SD` object which can be interacted with in a similar
|
||||
manner to other standard global objects like `Serial` and `Ethernet`.
|
||||
|
||||
* Boilerplate initialisation code is contained in one method named
|
||||
`begin` and no further objects need to be created in order to access
|
||||
the SD card.
|
||||
|
||||
* Calls to `open` can supply a full path name including parent
|
||||
directories which simplifies interacting with files in subdirectories.
|
||||
|
||||
* Utility methods are provided to determine whether a file exists
|
||||
and to create a directory heirarchy.
|
||||
|
||||
|
||||
Note however that not all functionality provided by the underlying
|
||||
sdfatlib library is exposed.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Implementation Notes
|
||||
|
||||
In order to handle multi-directory path traversal, functionality that
|
||||
requires this ability is implemented as callback functions.
|
||||
|
||||
Individual methods call the `walkPath` function which performs the actual
|
||||
directory traversal (swapping between two different directory/file handles
|
||||
along the way) and at each level calls the supplied callback function.
|
||||
|
||||
Some types of functionality will take an action at each level (e.g. exists
|
||||
or make directory) which others will only take an action at the bottom
|
||||
level (e.g. open).
|
||||
|
||||
*/
|
||||
|
||||
#include "SD.h"
|
||||
|
||||
// Used by `getNextPathComponent`
|
||||
#define MAX_COMPONENT_LEN 12 // What is max length?
|
||||
#define PATH_COMPONENT_BUFFER_LEN MAX_COMPONENT_LEN+1
|
||||
|
||||
bool getNextPathComponent(char *path, unsigned int *p_offset,
|
||||
char *buffer) {
|
||||
/*
|
||||
|
||||
Parse individual path components from a path.
|
||||
|
||||
e.g. after repeated calls '/foo/bar/baz' will be split
|
||||
into 'foo', 'bar', 'baz'.
|
||||
|
||||
This is similar to `strtok()` but copies the component into the
|
||||
supplied buffer rather than modifying the original string.
|
||||
|
||||
|
||||
`buffer` needs to be PATH_COMPONENT_BUFFER_LEN in size.
|
||||
|
||||
`p_offset` needs to point to an integer of the offset at
|
||||
which the previous path component finished.
|
||||
|
||||
Returns `true` if more components remain.
|
||||
|
||||
Returns `false` if this is the last component.
|
||||
(This means path ended with 'foo' or 'foo/'.)
|
||||
|
||||
*/
|
||||
|
||||
// TODO: Have buffer local to this function, so we know it's the
|
||||
// correct length?
|
||||
|
||||
int bufferOffset = 0;
|
||||
|
||||
int offset = *p_offset;
|
||||
|
||||
// Skip root or other separator
|
||||
if (path[offset] == '/') {
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Copy the next next path segment
|
||||
while (bufferOffset < MAX_COMPONENT_LEN
|
||||
&& (path[offset] != '/')
|
||||
&& (path[offset] != '\0')) {
|
||||
buffer[bufferOffset++] = path[offset++];
|
||||
}
|
||||
|
||||
buffer[bufferOffset] = '\0';
|
||||
|
||||
// Skip trailing separator so we can determine if this
|
||||
// is the last component in the path or not.
|
||||
if (path[offset] == '/') {
|
||||
offset++;
|
||||
}
|
||||
|
||||
*p_offset = offset;
|
||||
|
||||
return (path[offset] != '\0');
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean walkPath(char *filepath, SdFile& parentDir,
|
||||
boolean (*callback)(SdFile& parentDir,
|
||||
char *filePathComponent,
|
||||
boolean isLastComponent,
|
||||
void *object),
|
||||
void *object = NULL) {
|
||||
/*
|
||||
|
||||
When given a file path (and parent directory--normally root),
|
||||
this function traverses the directories in the path and at each
|
||||
level calls the supplied callback function while also providing
|
||||
the supplied object for context if required.
|
||||
|
||||
e.g. given the path '/foo/bar/baz'
|
||||
the callback would be called at the equivalent of
|
||||
'/foo', '/foo/bar' and '/foo/bar/baz'.
|
||||
|
||||
The implementation swaps between two different directory/file
|
||||
handles as it traverses the directories and does not use recursion
|
||||
in an attempt to use memory efficiently.
|
||||
|
||||
If a callback wishes to stop the directory traversal it should
|
||||
return false--in this case the function will stop the traversal,
|
||||
tidy up and return false.
|
||||
|
||||
If a directory path doesn't exist at some point this function will
|
||||
also return false and not subsequently call the callback.
|
||||
|
||||
If a directory path specified is complete, valid and the callback
|
||||
did not indicate the traversal should be interrupted then this
|
||||
function will return true.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
SdFile subfile1;
|
||||
SdFile subfile2;
|
||||
|
||||
char buffer[PATH_COMPONENT_BUFFER_LEN];
|
||||
|
||||
unsigned int offset = 0;
|
||||
|
||||
SdFile *p_parent;
|
||||
SdFile *p_child;
|
||||
|
||||
SdFile *p_tmp_sdfile;
|
||||
|
||||
p_child = &subfile1;
|
||||
|
||||
p_parent = &parentDir;
|
||||
|
||||
while (true) {
|
||||
|
||||
boolean moreComponents = getNextPathComponent(filepath, &offset, buffer);
|
||||
|
||||
boolean shouldContinue = callback((*p_parent), buffer, !moreComponents, object);
|
||||
|
||||
if (!shouldContinue) {
|
||||
// TODO: Don't repeat this code?
|
||||
// If it's one we've created then we
|
||||
// don't need the parent handle anymore.
|
||||
if (p_parent != &parentDir) {
|
||||
(*p_parent).close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!moreComponents) {
|
||||
break;
|
||||
}
|
||||
|
||||
boolean exists = (*p_child).open(*p_parent, buffer, O_RDONLY);
|
||||
|
||||
// If it's one we've created then we
|
||||
// don't need the parent handle anymore.
|
||||
if (p_parent != &parentDir) {
|
||||
(*p_parent).close();
|
||||
}
|
||||
|
||||
// Handle case when it doesn't exist and we can't continue...
|
||||
if (exists) {
|
||||
// We alternate between two file handles as we go down
|
||||
// the path.
|
||||
if (p_parent == &parentDir) {
|
||||
p_parent = &subfile2;
|
||||
}
|
||||
|
||||
p_tmp_sdfile = p_parent;
|
||||
p_parent = p_child;
|
||||
p_child = p_tmp_sdfile;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_parent != &parentDir) {
|
||||
(*p_parent).close(); // TODO: Return/ handle different?
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
The callbacks used to implement various functionality follow.
|
||||
|
||||
Each callback is supplied with a parent directory handle,
|
||||
character string with the name of the current file path component,
|
||||
a flag indicating if this component is the last in the path and
|
||||
a pointer to an arbitrary object used for context.
|
||||
|
||||
*/
|
||||
|
||||
boolean callback_pathExists(SdFile& parentDir, char *filePathComponent,
|
||||
boolean isLastComponent, void *object) {
|
||||
/*
|
||||
|
||||
Callback used to determine if a file/directory exists in parent
|
||||
directory.
|
||||
|
||||
Returns true if file path exists.
|
||||
|
||||
*/
|
||||
SdFile child;
|
||||
|
||||
boolean exists = child.open(parentDir, filePathComponent, O_RDONLY);
|
||||
|
||||
if (exists) {
|
||||
child.close();
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean callback_makeDirPath(SdFile& parentDir, char *filePathComponent,
|
||||
boolean isLastComponent, void *object) {
|
||||
/*
|
||||
|
||||
Callback used to create a directory in the parent directory if
|
||||
it does not already exist.
|
||||
|
||||
Returns true if a directory was created or it already existed.
|
||||
|
||||
*/
|
||||
boolean result = false;
|
||||
SdFile child;
|
||||
|
||||
result = callback_pathExists(parentDir, filePathComponent, isLastComponent, object);
|
||||
if (!result) {
|
||||
result = child.makeDir(parentDir, filePathComponent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
boolean callback_openPath(SdFile& parentDir, char *filePathComponent,
|
||||
boolean isLastComponent, void *object) {
|
||||
|
||||
Callback used to open a file specified by a filepath that may
|
||||
specify one or more directories above it.
|
||||
|
||||
Expects the context object to be an instance of `SDClass` and
|
||||
will use the `file` property of the instance to open the requested
|
||||
file/directory with the associated file open mode property.
|
||||
|
||||
Always returns true if the directory traversal hasn't reached the
|
||||
bottom of the directory heirarchy.
|
||||
|
||||
Returns false once the file has been opened--to prevent the traversal
|
||||
from descending further. (This may be unnecessary.)
|
||||
|
||||
if (isLastComponent) {
|
||||
SDClass *p_SD = static_cast<SDClass*>(object);
|
||||
p_SD->file.open(parentDir, filePathComponent, p_SD->fileOpenMode);
|
||||
if (p_SD->fileOpenMode == FILE_WRITE) {
|
||||
p_SD->file.seekSet(p_SD->file.fileSize());
|
||||
}
|
||||
// TODO: Return file open result?
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
boolean callback_remove(SdFile& parentDir, char *filePathComponent,
|
||||
boolean isLastComponent, void *object) {
|
||||
if (isLastComponent) {
|
||||
return SdFile::remove(parentDir, filePathComponent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean callback_rmdir(SdFile& parentDir, char *filePathComponent,
|
||||
boolean isLastComponent, void *object) {
|
||||
if (isLastComponent) {
|
||||
SdFile f;
|
||||
if (!f.open(parentDir, filePathComponent, O_READ)) return false;
|
||||
return f.rmDir();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Implementation of class used to create `SDCard` object. */
|
||||
|
||||
|
||||
|
||||
boolean SDClass::begin(uint8_t csPin) {
|
||||
/*
|
||||
|
||||
Performs the initialisation required by the sdfatlib library.
|
||||
|
||||
Return true if initialization succeeds, false otherwise.
|
||||
|
||||
*/
|
||||
return card.init(SPI_HALF_SPEED, csPin) &&
|
||||
volume.init(card) &&
|
||||
root.openRoot(volume);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// this little helper is used to traverse paths
|
||||
SdFile SDClass::getParentDir(const char *filepath, int *index) {
|
||||
// get parent directory
|
||||
SdFile d1 = root; // start with the mostparent, root!
|
||||
SdFile d2;
|
||||
|
||||
// we'll use the pointers to swap between the two objects
|
||||
SdFile *parent = &d1;
|
||||
SdFile *subdir = &d2;
|
||||
|
||||
const char *origpath = filepath;
|
||||
|
||||
while (strchr(filepath, '/')) {
|
||||
|
||||
// get rid of leading /'s
|
||||
if (filepath[0] == '/') {
|
||||
filepath++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! strchr(filepath, '/')) {
|
||||
// it was in the root directory, so leave now
|
||||
break;
|
||||
}
|
||||
|
||||
// extract just the name of the next subdirectory
|
||||
uint8_t idx = strchr(filepath, '/') - filepath;
|
||||
if (idx > 12)
|
||||
idx = 12; // dont let them specify long names
|
||||
char subdirname[13];
|
||||
strncpy(subdirname, filepath, idx);
|
||||
subdirname[idx] = 0;
|
||||
|
||||
// close the subdir (we reuse them) if open
|
||||
subdir->close();
|
||||
if (! subdir->open(parent, subdirname, O_READ)) {
|
||||
// failed to open one of the subdirectories
|
||||
return SdFile();
|
||||
}
|
||||
// move forward to the next subdirectory
|
||||
filepath += idx;
|
||||
|
||||
// we reuse the objects, close it.
|
||||
parent->close();
|
||||
|
||||
// swap the pointers
|
||||
SdFile *t = parent;
|
||||
parent = subdir;
|
||||
subdir = t;
|
||||
}
|
||||
|
||||
*index = (int)(filepath - origpath);
|
||||
// parent is now the parent diretory of the file!
|
||||
return *parent;
|
||||
}
|
||||
|
||||
|
||||
File SDClass::open(const char *filepath, uint8_t mode) {
|
||||
/*
|
||||
|
||||
Open the supplied file path for reading or writing.
|
||||
|
||||
The file content can be accessed via the `file` property of
|
||||
the `SDClass` object--this property is currently
|
||||
a standard `SdFile` object from `sdfatlib`.
|
||||
|
||||
Defaults to read only.
|
||||
|
||||
If `write` is true, default action (when `append` is true) is to
|
||||
append data to the end of the file.
|
||||
|
||||
If `append` is false then the file will be truncated first.
|
||||
|
||||
If the file does not exist and it is opened for writing the file
|
||||
will be created.
|
||||
|
||||
An attempt to open a file for reading that does not exist is an
|
||||
error.
|
||||
|
||||
*/
|
||||
|
||||
int pathidx;
|
||||
|
||||
// do the interative search
|
||||
SdFile parentdir = getParentDir(filepath, &pathidx);
|
||||
// no more subdirs!
|
||||
|
||||
filepath += pathidx;
|
||||
|
||||
if (! filepath[0]) {
|
||||
// it was the directory itself!
|
||||
return File(parentdir, "/");
|
||||
}
|
||||
|
||||
// Open the file itself
|
||||
SdFile file;
|
||||
|
||||
// failed to open a subdir!
|
||||
if (!parentdir.isOpen())
|
||||
return File();
|
||||
|
||||
// there is a special case for the Root directory since its a static dir
|
||||
if (parentdir.isRoot()) {
|
||||
if ( ! file.open(SD.root, filepath, mode)) {
|
||||
// failed to open the file :(
|
||||
return File();
|
||||
}
|
||||
// dont close the root!
|
||||
} else {
|
||||
if ( ! file.open(parentdir, filepath, mode)) {
|
||||
return File();
|
||||
}
|
||||
// close the parent
|
||||
parentdir.close();
|
||||
}
|
||||
|
||||
if (mode & (O_APPEND | O_WRITE))
|
||||
file.seekSet(file.fileSize());
|
||||
return File(file, filepath);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
File SDClass::open(char *filepath, uint8_t mode) {
|
||||
//
|
||||
|
||||
Open the supplied file path for reading or writing.
|
||||
|
||||
The file content can be accessed via the `file` property of
|
||||
the `SDClass` object--this property is currently
|
||||
a standard `SdFile` object from `sdfatlib`.
|
||||
|
||||
Defaults to read only.
|
||||
|
||||
If `write` is true, default action (when `append` is true) is to
|
||||
append data to the end of the file.
|
||||
|
||||
If `append` is false then the file will be truncated first.
|
||||
|
||||
If the file does not exist and it is opened for writing the file
|
||||
will be created.
|
||||
|
||||
An attempt to open a file for reading that does not exist is an
|
||||
error.
|
||||
|
||||
//
|
||||
|
||||
// TODO: Allow for read&write? (Possibly not, as it requires seek.)
|
||||
|
||||
fileOpenMode = mode;
|
||||
walkPath(filepath, root, callback_openPath, this);
|
||||
|
||||
return File();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//boolean SDClass::close() {
|
||||
// /*
|
||||
//
|
||||
// Closes the file opened by the `open` method.
|
||||
//
|
||||
// */
|
||||
// file.close();
|
||||
//}
|
||||
|
||||
|
||||
boolean SDClass::exists(char *filepath) {
|
||||
/*
|
||||
|
||||
Returns true if the supplied file path exists.
|
||||
|
||||
*/
|
||||
return walkPath(filepath, root, callback_pathExists);
|
||||
}
|
||||
|
||||
|
||||
//boolean SDClass::exists(char *filepath, SdFile& parentDir) {
|
||||
// /*
|
||||
//
|
||||
// Returns true if the supplied file path rooted at `parentDir`
|
||||
// exists.
|
||||
//
|
||||
// */
|
||||
// return walkPath(filepath, parentDir, callback_pathExists);
|
||||
//}
|
||||
|
||||
|
||||
boolean SDClass::mkdir(char *filepath) {
|
||||
/*
|
||||
|
||||
Makes a single directory or a heirarchy of directories.
|
||||
|
||||
A rough equivalent to `mkdir -p`.
|
||||
|
||||
*/
|
||||
return walkPath(filepath, root, callback_makeDirPath);
|
||||
}
|
||||
|
||||
boolean SDClass::rmdir(char *filepath) {
|
||||
/*
|
||||
|
||||
Makes a single directory or a heirarchy of directories.
|
||||
|
||||
A rough equivalent to `mkdir -p`.
|
||||
|
||||
*/
|
||||
return walkPath(filepath, root, callback_rmdir);
|
||||
}
|
||||
|
||||
boolean SDClass::remove(char *filepath) {
|
||||
return walkPath(filepath, root, callback_remove);
|
||||
}
|
||||
|
||||
|
||||
// allows you to recurse into a directory
|
||||
File File::openNextFile(uint8_t mode) {
|
||||
dir_t p;
|
||||
|
||||
//Serial.print("\t\treading dir...");
|
||||
while (_file->readDir(&p) > 0) {
|
||||
|
||||
// done if past last used entry
|
||||
if (p.name[0] == DIR_NAME_FREE) {
|
||||
//Serial.println("end");
|
||||
return File();
|
||||
}
|
||||
|
||||
// skip deleted entry and entries for . and ..
|
||||
if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') {
|
||||
//Serial.println("dots");
|
||||
continue;
|
||||
}
|
||||
|
||||
// only list subdirectories and files
|
||||
if (!DIR_IS_FILE_OR_SUBDIR(&p)) {
|
||||
//Serial.println("notafile");
|
||||
continue;
|
||||
}
|
||||
|
||||
// print file name with possible blank fill
|
||||
SdFile f;
|
||||
char name[13];
|
||||
_file->dirName(p, name);
|
||||
//Serial.print("try to open file ");
|
||||
//Serial.println(name);
|
||||
|
||||
if (f.open(_file, name, mode)) {
|
||||
//Serial.println("OK!");
|
||||
return File(f, name);
|
||||
} else {
|
||||
//Serial.println("ugh");
|
||||
return File();
|
||||
}
|
||||
}
|
||||
|
||||
//Serial.println("nothing");
|
||||
return File();
|
||||
}
|
||||
|
||||
void File::rewindDirectory(void) {
|
||||
if (isDirectory())
|
||||
_file->rewind();
|
||||
}
|
||||
|
||||
SDClass SD;
|
103
xmega/libraries/SD/SD.h
Normal file
103
xmega/libraries/SD/SD.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
|
||||
SD - a slightly more friendly wrapper for sdfatlib
|
||||
|
||||
This library aims to expose a subset of SD card functionality
|
||||
in the form of a higher level "wrapper" object.
|
||||
|
||||
License: GNU General Public License V3
|
||||
(Because sdfatlib is licensed with this.)
|
||||
|
||||
(C) Copyright 2010 SparkFun Electronics
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __SD_H__
|
||||
#define __SD_H__
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <utility/SdFat.h>
|
||||
#include <utility/SdFatUtil.h>
|
||||
|
||||
#define FILE_READ O_READ
|
||||
#define FILE_WRITE (O_READ | O_WRITE | O_CREAT)
|
||||
|
||||
class File : public Stream {
|
||||
private:
|
||||
char _name[13]; // our name
|
||||
SdFile *_file; // underlying file pointer
|
||||
|
||||
public:
|
||||
File(SdFile f, const char *name); // wraps an underlying SdFile
|
||||
File(void); // 'empty' constructor
|
||||
~File(void); // destructor
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual int read();
|
||||
virtual int peek();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
int read(void *buf, uint16_t nbyte);
|
||||
boolean seek(uint32_t pos);
|
||||
uint32_t position();
|
||||
uint32_t size();
|
||||
void close();
|
||||
operator bool();
|
||||
char * name();
|
||||
|
||||
boolean isDirectory(void);
|
||||
File openNextFile(uint8_t mode = O_RDONLY);
|
||||
void rewindDirectory(void);
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
class SDClass {
|
||||
|
||||
private:
|
||||
// These are required for initialisation and use of sdfatlib
|
||||
Sd2Card card;
|
||||
SdVolume volume;
|
||||
SdFile root;
|
||||
|
||||
// my quick&dirty iterator, should be replaced
|
||||
SdFile getParentDir(const char *filepath, int *indx);
|
||||
public:
|
||||
// This needs to be called to set up the connection to the SD card
|
||||
// before other methods are used.
|
||||
boolean begin(uint8_t csPin = SD_CHIP_SELECT_PIN);
|
||||
|
||||
// Open the specified file/directory with the supplied mode (e.g. read or
|
||||
// write, etc). Returns a File object for interacting with the file.
|
||||
// Note that currently only one file can be open at a time.
|
||||
File open(const char *filename, uint8_t mode = FILE_READ);
|
||||
|
||||
// Methods to determine if the requested file path exists.
|
||||
boolean exists(char *filepath);
|
||||
|
||||
// Create the requested directory heirarchy--if intermediate directories
|
||||
// do not exist they will be created.
|
||||
boolean mkdir(char *filepath);
|
||||
|
||||
// Delete the file.
|
||||
boolean remove(char *filepath);
|
||||
|
||||
boolean rmdir(char *filepath);
|
||||
|
||||
private:
|
||||
|
||||
// This is used to determine the mode used to open a file
|
||||
// it's here because it's the easiest place to pass the
|
||||
// information through the directory walking function. But
|
||||
// it's probably not the best place for it.
|
||||
// It shouldn't be set directly--it is set via the parameters to `open`.
|
||||
int fileOpenMode;
|
||||
|
||||
friend class File;
|
||||
friend boolean callback_openPath(SdFile&, char *, boolean, void *);
|
||||
};
|
||||
|
||||
extern SDClass SD;
|
||||
|
||||
#endif
|
124
xmega/libraries/SD/examples/CardInfo/CardInfo.ino
Normal file
124
xmega/libraries/SD/examples/CardInfo/CardInfo.ino
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
SD card test
|
||||
|
||||
This example shows how use the utility libraries on which the'
|
||||
SD library is based in order to get info about your SD card.
|
||||
Very useful for testing a card when you're not sure whether its working or not.
|
||||
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
|
||||
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
|
||||
** CS - depends on your SD card shield or module.
|
||||
Pin 4 used here for consistency with other Arduino examples
|
||||
|
||||
|
||||
created 28 Mar 2011
|
||||
by Limor Fried
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
*/
|
||||
// include the SD library:
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// set up variables using the SD utility library functions:
|
||||
Sd2Card card;
|
||||
SdVolume volume;
|
||||
SdFile root;
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("\nInitializing SD card...");
|
||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT); // change this to 53 on a mega
|
||||
|
||||
|
||||
// we'll use the initialization code from the utility libraries
|
||||
// since we're just testing if the card is working!
|
||||
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
|
||||
Serial.println("initialization failed. Things to check:");
|
||||
Serial.println("* is a card is inserted?");
|
||||
Serial.println("* Is your wiring correct?");
|
||||
Serial.println("* did you change the chipSelect pin to match your shield or module?");
|
||||
return;
|
||||
} else {
|
||||
Serial.println("Wiring is correct and a card is present.");
|
||||
}
|
||||
|
||||
// print the type of card
|
||||
Serial.print("\nCard type: ");
|
||||
switch(card.type()) {
|
||||
case SD_CARD_TYPE_SD1:
|
||||
Serial.println("SD1");
|
||||
break;
|
||||
case SD_CARD_TYPE_SD2:
|
||||
Serial.println("SD2");
|
||||
break;
|
||||
case SD_CARD_TYPE_SDHC:
|
||||
Serial.println("SDHC");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
|
||||
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
|
||||
if (!volume.init(card)) {
|
||||
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// print the type and size of the first FAT-type volume
|
||||
uint32_t volumesize;
|
||||
Serial.print("\nVolume type is FAT");
|
||||
Serial.println(volume.fatType(), DEC);
|
||||
Serial.println();
|
||||
|
||||
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
|
||||
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
|
||||
volumesize *= 512; // SD card blocks are always 512 bytes
|
||||
Serial.print("Volume size (bytes): ");
|
||||
Serial.println(volumesize);
|
||||
Serial.print("Volume size (Kbytes): ");
|
||||
volumesize /= 1024;
|
||||
Serial.println(volumesize);
|
||||
Serial.print("Volume size (Mbytes): ");
|
||||
volumesize /= 1024;
|
||||
Serial.println(volumesize);
|
||||
|
||||
|
||||
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
|
||||
root.openRoot(volume);
|
||||
|
||||
// list all files in the card with date and size
|
||||
root.ls(LS_R | LS_DATE | LS_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void loop(void) {
|
||||
|
||||
}
|
104
xmega/libraries/SD/examples/Datalogger/Datalogger.ino
Normal file
104
xmega/libraries/SD/examples/Datalogger/Datalogger.ino
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
SD card datalogger
|
||||
|
||||
This example shows how to log data from three analog sensors
|
||||
to an SD card using the SD library.
|
||||
|
||||
The circuit:
|
||||
* analog sensors on analog ins 0, 1, and 2
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
created 24 Nov 2010
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
|
||||
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
|
||||
// 53 on the Mega) must be left as an output or the SD library
|
||||
// functions will not work.
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("Initializing SD card...");
|
||||
// make sure that the default chip select pin is set to
|
||||
// output, even if you don't use it:
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
// don't do anything more:
|
||||
return;
|
||||
}
|
||||
Serial.println("card initialized.");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// make a string for assembling the data to log:
|
||||
String dataString = "";
|
||||
|
||||
// read three sensors and append to the string:
|
||||
for (int analogPin = 0; analogPin < 3; analogPin++) {
|
||||
int sensor = analogRead(analogPin);
|
||||
dataString += String(sensor);
|
||||
if (analogPin < 2) {
|
||||
dataString += ",";
|
||||
}
|
||||
}
|
||||
|
||||
// open the file. note that only one file can be open at a time,
|
||||
// so you have to close this one before opening another.
|
||||
File dataFile = SD.open("datalog.txt", FILE_WRITE);
|
||||
|
||||
// if the file is available, write to it:
|
||||
if (dataFile) {
|
||||
dataFile.println(dataString);
|
||||
dataFile.close();
|
||||
// print to the serial port too:
|
||||
Serial.println(dataString);
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.println("error opening datalog.txt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
85
xmega/libraries/SD/examples/DumpFile/DumpFile.ino
Normal file
85
xmega/libraries/SD/examples/DumpFile/DumpFile.ino
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
SD card file dump
|
||||
|
||||
This example shows how to read a file from the SD card using the
|
||||
SD library and send it over the serial port.
|
||||
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
created 22 December 2010
|
||||
by Limor Fried
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
|
||||
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
|
||||
// 53 on the Mega) must be left as an output or the SD library
|
||||
// functions will not work.
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("Initializing SD card...");
|
||||
// make sure that the default chip select pin is set to
|
||||
// output, even if you don't use it:
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
// see if the card is present and can be initialized:
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("Card failed, or not present");
|
||||
// don't do anything more:
|
||||
return;
|
||||
}
|
||||
Serial.println("card initialized.");
|
||||
|
||||
// open the file. note that only one file can be open at a time,
|
||||
// so you have to close this one before opening another.
|
||||
File dataFile = SD.open("datalog.txt");
|
||||
|
||||
// if the file is available, write to it:
|
||||
if (dataFile) {
|
||||
while (dataFile.available()) {
|
||||
Serial.write(dataFile.read());
|
||||
}
|
||||
dataFile.close();
|
||||
}
|
||||
// if the file isn't open, pop up an error:
|
||||
else {
|
||||
Serial.println("error opening datalog.txt");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
97
xmega/libraries/SD/examples/Files/Files.ino
Normal file
97
xmega/libraries/SD/examples/Files/Files.ino
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
SD card basic file example
|
||||
|
||||
This example shows how to create and destroy an SD card file
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
File myFile;
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("Initializing SD card...");
|
||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("initialization failed!");
|
||||
return;
|
||||
}
|
||||
Serial.println("initialization done.");
|
||||
|
||||
if (SD.exists("example.txt")) {
|
||||
Serial.println("example.txt exists.");
|
||||
}
|
||||
else {
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
}
|
||||
|
||||
// open a new file and immediately close it:
|
||||
Serial.println("Creating example.txt...");
|
||||
myFile = SD.open("example.txt", FILE_WRITE);
|
||||
myFile.close();
|
||||
|
||||
// Check to see if the file exists:
|
||||
if (SD.exists("example.txt")) {
|
||||
Serial.println("example.txt exists.");
|
||||
}
|
||||
else {
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
}
|
||||
|
||||
// delete the file:
|
||||
Serial.println("Removing example.txt...");
|
||||
SD.remove("example.txt");
|
||||
|
||||
if (SD.exists("example.txt")){
|
||||
Serial.println("example.txt exists.");
|
||||
}
|
||||
else {
|
||||
Serial.println("example.txt doesn't exist.");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// nothing happens after setup finishes.
|
||||
}
|
||||
|
||||
|
||||
|
98
xmega/libraries/SD/examples/ReadWrite/ReadWrite.ino
Normal file
98
xmega/libraries/SD/examples/ReadWrite/ReadWrite.ino
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
SD card read/write
|
||||
|
||||
This example shows how to read and write data to and from an SD card file
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
File myFile;
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("Initializing SD card...");
|
||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("initialization failed!");
|
||||
return;
|
||||
}
|
||||
Serial.println("initialization done.");
|
||||
|
||||
// open the file. note that only one file can be open at a time,
|
||||
// so you have to close this one before opening another.
|
||||
myFile = SD.open("test.txt", FILE_WRITE);
|
||||
|
||||
// if the file opened okay, write to it:
|
||||
if (myFile) {
|
||||
Serial.print("Writing to test.txt...");
|
||||
myFile.println("testing 1, 2, 3.");
|
||||
// close the file:
|
||||
myFile.close();
|
||||
Serial.println("done.");
|
||||
} else {
|
||||
// if the file didn't open, print an error:
|
||||
Serial.println("error opening test.txt");
|
||||
}
|
||||
|
||||
// re-open the file for reading:
|
||||
myFile = SD.open("test.txt");
|
||||
if (myFile) {
|
||||
Serial.println("test.txt:");
|
||||
|
||||
// read from the file until there's nothing else in it:
|
||||
while (myFile.available()) {
|
||||
Serial.write(myFile.read());
|
||||
}
|
||||
// close the file:
|
||||
myFile.close();
|
||||
} else {
|
||||
// if the file didn't open, print an error:
|
||||
Serial.println("error opening test.txt");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// nothing happens after setup
|
||||
}
|
||||
|
||||
|
97
xmega/libraries/SD/examples/listfiles/listfiles.ino
Normal file
97
xmega/libraries/SD/examples/listfiles/listfiles.ino
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
SD card basic file example
|
||||
|
||||
This example shows how to create and destroy an SD card file
|
||||
The circuit:
|
||||
* SD card attached to SPI bus as follows:
|
||||
** MOSI - pin 11
|
||||
** MISO - pin 12
|
||||
** CLK - pin 13
|
||||
** CS - pin 4
|
||||
|
||||
created Nov 2010
|
||||
by David A. Mellis
|
||||
modified 9 Apr 2012
|
||||
by Tom Igoe
|
||||
|
||||
This example code is in the public domain.
|
||||
|
||||
*/
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
File root;
|
||||
|
||||
// change this to match your SD shield or module;
|
||||
// Arduino Ethernet shield: pin 4
|
||||
// Adafruit SD shields and modules: pin 10
|
||||
// Sparkfun SD shield: pin 8
|
||||
// Teensy 2.0: pin 0
|
||||
// Teensy++ 2.0: pin 20
|
||||
#if defined(XMEGA_XA4U)
|
||||
const int chipSelect = 22;
|
||||
#else
|
||||
const int chipSelect = 4;
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Open serial communications and wait for port to open:
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to connect. Needed for Leonardo only
|
||||
}
|
||||
|
||||
|
||||
Serial.print("Initializing SD card...");
|
||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
|
||||
// Note that even if it's not used as the CS pin, the hardware SS pin
|
||||
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
|
||||
// or the SD library functions will not work.
|
||||
pinMode(10, OUTPUT);
|
||||
|
||||
if (!SD.begin(chipSelect)) {
|
||||
Serial.println("initialization failed!");
|
||||
return;
|
||||
}
|
||||
Serial.println("initialization done.");
|
||||
|
||||
root = SD.open("/");
|
||||
|
||||
printDirectory(root, 0);
|
||||
|
||||
Serial.println("done!");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// nothing happens after setup finishes.
|
||||
}
|
||||
|
||||
void printDirectory(File dir, int numTabs) {
|
||||
while(true) {
|
||||
|
||||
File entry = dir.openNextFile();
|
||||
if (! entry) {
|
||||
// no more files
|
||||
//Serial.println("**nomorefiles**");
|
||||
break;
|
||||
}
|
||||
for (uint8_t i=0; i<numTabs; i++) {
|
||||
Serial.print('\t');
|
||||
}
|
||||
Serial.print(entry.name());
|
||||
if (entry.isDirectory()) {
|
||||
Serial.println("/");
|
||||
printDirectory(entry, numTabs+1);
|
||||
} else {
|
||||
// files have sizes, directories do not
|
||||
Serial.print("\t\t");
|
||||
Serial.println(entry.size(), DEC);
|
||||
}
|
||||
entry.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
30
xmega/libraries/SD/keywords.txt
Normal file
30
xmega/libraries/SD/keywords.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
#######################################
|
||||
# Syntax Coloring Map SD
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
SD KEYWORD1
|
||||
File KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
begin KEYWORD2
|
||||
exists KEYWORD2
|
||||
mkdir KEYWORD2
|
||||
remove KEYWORD2
|
||||
rmdir KEYWORD2
|
||||
open KEYWORD2
|
||||
close KEYWORD2
|
||||
seek KEYWORD2
|
||||
position KEYWORD2
|
||||
size KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
FILE_READ LITERAL1
|
||||
FILE_WRITE LITERAL1
|
418
xmega/libraries/SD/utility/FatStructs.h
Normal file
418
xmega/libraries/SD/utility/FatStructs.h
Normal file
|
@ -0,0 +1,418 @@
|
|||
/* 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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef FatStructs_h
|
||||
#define FatStructs_h
|
||||
/**
|
||||
* \file
|
||||
* FAT file structures
|
||||
*/
|
||||
/*
|
||||
* mostly from Microsoft document fatgen103.doc
|
||||
* http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
/** Value for byte 510 of boot block or MBR */
|
||||
uint8_t const BOOTSIG0 = 0X55;
|
||||
/** Value for byte 511 of boot block or MBR */
|
||||
uint8_t const BOOTSIG1 = 0XAA;
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \struct partitionTable
|
||||
* \brief MBR partition table entry
|
||||
*
|
||||
* A partition table entry for a MBR formatted storage device.
|
||||
* The MBR partition table has four entries.
|
||||
*/
|
||||
struct partitionTable {
|
||||