Add SD library (not optimised).

This commit is contained in:
flabbergast 2015-04-05 20:34:12 +01:00
parent 0603b384d8
commit 2c954a58e4
21 changed files with 6016 additions and 0 deletions

150
xmega/libraries/SD/File.cpp Normal file
View 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;
}

View 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
View 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
View 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

View 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) {
}

View 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");
}
}

View 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()
{
}

View 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.
}

View 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
}

View 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();
}
}

View 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

View 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 {