This is a beta version with major changes so bugs and compatibility | |||||
problems are likely. | |||||
This is a beta version so there may be bugs and compatibility | |||||
problems. | |||||
Please report problems to the email address listed in the | Please report problems to the email address listed in the | ||||
"Bugs and Comments" section of the html documentation. | "Bugs and Comments" section of the html documentation. | ||||
http://arduino.cc/en/Guide/Libraries | http://arduino.cc/en/Guide/Libraries | ||||
A number of configuration options can be set by editing SdFatConfig.h | A number of configuration options can be set by editing SdFatConfig.h | ||||
#define macros. See the html documentation for details | |||||
define macros. See the html documentation for details | |||||
Read changes.txt if you have used previous releases of this library. | Read changes.txt if you have used previous releases of this library. | ||||
Please continue by reading the html documentation. | Please continue by reading the html documentation. | ||||
Updated 19 Jul 2015 | |||||
Updated 23 Jan 2016 |
/** | /** | ||||
\mainpage Arduino %SdFat Library | \mainpage Arduino %SdFat Library | ||||
<CENTER>Copyright © 2012, 2013, 2014, 2015 by William Greiman | |||||
<CENTER>Copyright © 2012, 2013, 2014, 2015, 2016 by William Greiman | |||||
</CENTER> | </CENTER> | ||||
\section Intro Introduction | \section Intro Introduction | ||||
of the standard Arduino SPI library. You must include SPI.h in your | of the standard Arduino SPI library. You must include SPI.h in your | ||||
programs when ENABLE_SPI_TRANSACTIONS is nonzero. | programs when ENABLE_SPI_TRANSACTIONS is nonzero. | ||||
Set ENABLE_SPI_YIELD nonzero to enable release of the SPI bus during | |||||
SD card busy waits. ENABLE_SPI_TRANSACTIONS must be nonzero. | |||||
\section SDPath Paths and Working Directories | \section SDPath Paths and Working Directories | ||||
Relative paths in SdFat are resolved in a manner similar to Windows. | Relative paths in SdFat are resolved in a manner similar to Windows. | ||||
UPPER.TXT, and lower.txt. | UPPER.TXT, and lower.txt. | ||||
An application which writes to a file using print(), println() or | An application which writes to a file using print(), println() or | ||||
\link SdFile::write write() \endlink must close the file or call | |||||
\link SdFile::sync() sync() \endlink at the appropriate time to | |||||
write() must close the file or call sync() at the appropriate time to | |||||
force data and directory information to be written to the SD Card. | force data and directory information to be written to the SD Card. | ||||
Applications must use care calling \link SdFile::sync() sync() \endlink | |||||
Applications must use care calling sync() sync() | |||||
since 2048 bytes of I/O is required to update file and | since 2048 bytes of I/O is required to update file and | ||||
directory information. This includes writing the current data block, reading | directory information. This includes writing the current data block, reading | ||||
the block that contains the directory entry for update, writing the directory | the block that contains the directory entry for update, writing the directory | ||||
bench - A read/write benchmark. | bench - A read/write benchmark. | ||||
cin_cout - Demo of ArduinoInStream and ArduinoOutStream. | |||||
dataLogger - A simple modifiable data logger. | dataLogger - A simple modifiable data logger. | ||||
directoryFunctions - Demo of chdir(), ls(), mkdir(), and rmdir(). | |||||
DirectoryFunctions - Demo of chdir(), ls(), mkdir(), and rmdir(). | |||||
fgets - Demo of the fgets read line/string function. | fgets - Demo of the fgets read line/string function. | ||||
readCSV - Read a comma-separated value file using iostream extractors. | readCSV - Read a comma-separated value file using iostream extractors. | ||||
ReadCsvArray - Read a two dimensional array from a CSV file. | |||||
ReadCsvFields - Function to read a CSV text file one field at a time. | |||||
ReadWriteSdFat - SdFat version of Arduino SD ReadWrite example. | ReadWriteSdFat - SdFat version of Arduino SD ReadWrite example. | ||||
rename - A demo of SdFat::rename(old, new) and SdFile::rename(dirFile, newPath). | rename - A demo of SdFat::rename(old, new) and SdFile::rename(dirFile, newPath). | ||||
TwoCards - Example using two SD cards. | TwoCards - Example using two SD cards. | ||||
VolumeFreeSpace - Demonstrate the freeClusterCount() call. | VolumeFreeSpace - Demonstrate the freeClusterCount() call. | ||||
wipe - Example to wipe all data from an already formatted SD. | |||||
*/ | */ |
// A simple data logger for the Arduino analog pins with optional DS1307 | // A simple data logger for the Arduino analog pins with optional DS1307 | ||||
// uses RTClib from https://github.com/adafruit/RTClib | // uses RTClib from https://github.com/adafruit/RTClib | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
#define SD_CHIP_SELECT SS // SD chip select pin | #define SD_CHIP_SELECT SS // SD chip select pin | ||||
#define USE_DS1307 0 // set nonzero to use DS1307 RTC | #define USE_DS1307 0 // set nonzero to use DS1307 RTC |
* Program to test Short File Name character case flags. | * Program to test Short File Name character case flags. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat sd; | SdFat sd; | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// create a serial output stream | // create a serial output stream | ||||
ArduinoOutStream cout(Serial); | ArduinoOutStream cout(Serial); |
// Will not work on Due, Leonardo, or Teensy | // Will not work on Due, Leonardo, or Teensy | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
#ifdef UDR0 // Must be AVR with serial port zero. | #ifdef UDR0 // Must be AVR with serial port zero. | ||||
#include <MinimumSerial.h> | |||||
#include "MinimumSerial.h" | |||||
MinimumSerial MiniSerial; | MinimumSerial MiniSerial; | ||||
* | * | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat sd; | SdFat sd; | ||||
// Simple demo of the Stream parsInt() member function. | // Simple demo of the Stream parsInt() member function. | ||||
#include <SPI.h> | #include <SPI.h> | ||||
// The next two lines replace #include <SD.h>. | // The next two lines replace #include <SD.h>. | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat SD; | SdFat SD; | ||||
// SD card chip select pin - Modify the value of csPin for your SD module. | // SD card chip select pin - Modify the value of csPin for your SD module. |
* The program will open and close the file 100 times. | * The program will open and close the file 100 times. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* Calculate the sum and average of a list of floating point numbers | * Calculate the sum and average of a list of floating point numbers | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* Use of ibufsteam to parse a line and obufstream to format a line | * Use of ibufsteam to parse a line and obufstream to format a line | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// create a serial output stream | // create a serial output stream | ||||
ArduinoOutStream cout(Serial); | ArduinoOutStream cout(Serial); |
* Demo of ArduinoInStream and ArduinoOutStream | * Demo of ArduinoInStream and ArduinoOutStream | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// create serial output stream | // create serial output stream | ||||
ArduinoOutStream cout(Serial); | ArduinoOutStream cout(Serial); |
* Append a line to a file - demo of pathnames and streams | * Append a line to a file - demo of pathnames and streams | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
// Demo of rewriting a line read by fgets | // Demo of rewriting a line read by fgets | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD card chip select pin | // SD card chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* Demo of pathnames and working directories | * Demo of pathnames and working directories | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
average - A demonstration of parsing floating point numbers. | average - A demonstration of parsing floating point numbers. | ||||
BaseExtCaseTest - Long file name test. | |||||
benchSD - A read/write benchmark for the standard Arduino SD.h library. | benchSD - A read/write benchmark for the standard Arduino SD.h library. | ||||
bufstream - ibufsteam to parse a line and obufstream to format a line. | |||||
bufstream - ibufsteam to parse a line and obufstream to format a line. | |||||
cin_cout - Demo of ArduinoInStream and ArduinoOutStream. | |||||
eventlog - Append a line to a file - demo of pathnames and streams. | eventlog - Append a line to a file - demo of pathnames and streams. | ||||
SD_Size - Determine flash used by SD.h example. | SD_Size - Determine flash used by SD.h example. | ||||
SdFatSize - Determine flash used by SdFat. | SdFatSize - Determine flash used by SdFat. | ||||
StreamParseInt - Simple demo of the Stream parsInt() member function. |
*/ | */ | ||||
#ifdef __AVR__ | #ifdef __AVR__ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
#include "AnalogBinLogger.h" | #include "AnalogBinLogger.h" | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// Analog pin number list for a sample. Pins may be in any order and pin | // Analog pin number list for a sample. Pins may be in any order and pin |
// You can use test files located in | // You can use test files located in | ||||
// SdFat/examples/LongFileName/testFiles. | // SdFat/examples/LongFileName/testFiles. | ||||
#include<SPI.h> | #include<SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
// SD card chip select pin. | // SD card chip select pin. | ||||
const uint8_t SD_CS_PIN = SS; | const uint8_t SD_CS_PIN = SS; |
* Data is written to the file using a SD multiple block write command. | * Data is written to the file using a SD multiple block write command. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// User data functions. Modify these functions for your data items. | // User data functions. Modify these functions for your data items. | ||||
#include "UserDataType.h" // Edit this include file to change data_t. | #include "UserDataType.h" // Edit this include file to change data_t. |
* Print size, modify date/time, and name for all files in root. | * Print size, modify date/time, and name for all files in root. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
// Open next file in root. The volume working directory, vwd, is root. | // Open next file in root. The volume working directory, vwd, is root. | ||||
// Warning, openNext starts at the current position of sd.vwd() so a | // Warning, openNext starts at the current position of sd.vwd() so a | ||||
// rewind may be neccessary in your application. | // rewind may be neccessary in your application. | ||||
sd.vwd()->rewind(); | |||||
while (file.openNext(sd.vwd(), O_READ)) { | while (file.openNext(sd.vwd(), O_READ)) { | ||||
file.printFileSize(&Serial); | file.printFileSize(&Serial); | ||||
Serial.write(' '); | Serial.write(' '); |
* This program is a simple Print benchmark. | * This program is a simple Print benchmark. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
while (Serial.read() >= 0) { | while (Serial.read() >= 0) { | ||||
} | } | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) { | while (Serial.read() <= 0) { | ||||
} | } |
// Quick hardware test. | // Quick hardware test. | ||||
// | // | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// | // | ||||
// Set DISABLE_CHIP_SELECT to disable a second SPI device. | // Set DISABLE_CHIP_SELECT to disable a second SPI device. | ||||
// For example, with the Ethernet shield, set DISABLE_CHIP_SELECT | // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT |
* marks the blocks as erased; no data transfer is required. | * marks the blocks as erased; no data transfer is required. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop(void) { | void loop(void) { | ||||
while (Serial.read() >= 0) {} | while (Serial.read() >= 0) {} | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} | ||||
delay(400); // catch Due reset problem | delay(400); // catch Due reset problem |
// Read a two dimensional array from a CSV file. | |||||
// | |||||
#include <SPI.h> | |||||
#include <SdFat.h> | |||||
#define CS_PIN 10 | |||||
// 5 X 4 array | |||||
#define ROW_DIM 5 | |||||
#define COL_DIM 4 | |||||
SdFat SD; | |||||
File file; | |||||
/* | |||||
* Read a file one field at a time. | |||||
* | |||||
* file - File to read. | |||||
* | |||||
* str - Character array for the field. | |||||
* | |||||
* size - Size of str array. | |||||
* | |||||
* delim - String containing field delimiters. | |||||
* | |||||
* return - length of field including terminating delimiter. | |||||
* | |||||
* Note, the last character of str will not be a delimiter if | |||||
* a read error occurs, the field is too long, or the file | |||||
* does not end with a delimiter. Consider this an error | |||||
* if not at end-of-file. | |||||
* | |||||
*/ | |||||
size_t readField(File* file, char* str, size_t size, char* delim) { | |||||
char ch; | |||||
size_t n = 0; | |||||
while ((n + 1) < size && file->read(&ch, 1) == 1) { | |||||
// Delete CR. | |||||
if (ch == '\r') { | |||||
continue; | |||||
} | |||||
str[n++] = ch; | |||||
if (strchr(delim, ch)) { | |||||
break; | |||||
} | |||||
} | |||||
str[n] = '\0'; | |||||
return n; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
#define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||||
//------------------------------------------------------------------------------ | |||||
void setup() { | |||||
Serial.begin(9600); | |||||
// Initialize the SD. | |||||
if (!SD.begin(CS_PIN)) { | |||||
errorHalt("begin failed"); | |||||
} | |||||
// Create or open the file. | |||||
file = SD.open("READNUM.TXT", FILE_WRITE); | |||||
if (!file) { | |||||
errorHalt("open failed"); | |||||
} | |||||
// Rewind file so test data is not appended. | |||||
file.seek(0); | |||||
// Write test data. | |||||
file.print(F( | |||||
"11,12,13,14\r\n" | |||||
"21,22,23,24\r\n" | |||||
"31,32,33,34\r\n" | |||||
"41,42,43,44\r\n" | |||||
"51,52,53,54" // Allow missing endl at eof. | |||||
)); | |||||
// Rewind the file for read. | |||||
file.seek(0); | |||||
// Array for data. | |||||
int array[ROW_DIM][COL_DIM]; | |||||
int i = 0; // First array index. | |||||
int j = 0; // Second array index | |||||
size_t n; // Length of returned field with delimiter. | |||||
char str[20]; // Must hold longest field with delimiter and zero byte. | |||||
char *ptr; // Test for valid field. | |||||
// Read the file and store the data. | |||||
for (i = 0; i < ROW_DIM; i++) { | |||||
for (j = 0; j < COL_DIM; j++) { | |||||
n = readField(&file, str, sizeof(str), ",\n"); | |||||
if (n == 0) { | |||||
errorHalt("Too few lines"); | |||||
} | |||||
array[i][j] = strtol(str, &ptr, 10); | |||||
if (ptr == str) { | |||||
errorHalt("bad number"); | |||||
} | |||||
while (*ptr == ' ') { | |||||
ptr++; | |||||
} | |||||
if (*ptr != ',' && *ptr != '\n' && *ptr != '\0') { | |||||
errorHalt("extra characters in field"); | |||||
} | |||||
if (j < (COL_DIM-1) && str[n-1] != ',') { | |||||
errorHalt("line with too few fields"); | |||||
} | |||||
} | |||||
// Allow missing endl at eof. | |||||
if (str[n-1] != '\n' && file.available()) { | |||||
errorHalt("missing endl"); | |||||
} | |||||
} | |||||
// Print the array. | |||||
for (i = 0; i < ROW_DIM; i++) { | |||||
for (j = 0; j < COL_DIM; j++) { | |||||
if (j) { | |||||
Serial.print(' '); | |||||
} | |||||
Serial.print(array[i][j]); | |||||
} | |||||
Serial.println(); | |||||
} | |||||
Serial.println("Done"); | |||||
file.close(); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void loop() { | |||||
} | |||||
// Function to read a CSV text file one field at a time. | |||||
// | |||||
#include <SPI.h> | |||||
#include <SdFat.h> | |||||
#define CS_PIN 10 | |||||
SdFat SD; | |||||
File file; | |||||
/* | |||||
* Read a file one field at a time. | |||||
* | |||||
* file - File to read. | |||||
* | |||||
* str - Character array for the field. | |||||
* | |||||
* size - Size of str array. | |||||
* | |||||
* delim - String containing field delimiters. | |||||
* | |||||
* return - length of field including terminating delimiter. | |||||
* | |||||
* Note, the last character of str will not be a delimiter if | |||||
* a read error occurs, the field is too long, or the file | |||||
* does not end with a delimiter. Consider this an error | |||||
* if not at end-of-file. | |||||
* | |||||
*/ | |||||
size_t readField(File* file, char* str, size_t size, char* delim) { | |||||
char ch; | |||||
size_t n = 0; | |||||
while ((n + 1) < size && file->read(&ch, 1) == 1) { | |||||
// Delete CR. | |||||
if (ch == '\r') { | |||||
continue; | |||||
} | |||||
str[n++] = ch; | |||||
if (strchr(delim, ch)) { | |||||
break; | |||||
} | |||||
} | |||||
str[n] = '\0'; | |||||
return n; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
#define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||||
//------------------------------------------------------------------------------ | |||||
void setup() { | |||||
Serial.begin(9600); | |||||
// Initialize the SD. | |||||
if (!SD.begin(CS_PIN)) errorHalt("begin failed"); | |||||
// Create or open the file. | |||||
file = SD.open("READTEST.TXT", FILE_WRITE); | |||||
if (!file) errorHalt("open failed"); | |||||
// Rewind file so test data is not appended. | |||||
file.seek(0); | |||||
// Write test data. | |||||
file.print(F( | |||||
"field_1_1,field_1_2,field_1_3\r\n" | |||||
"field_2_1,field_2_2,field_2_3\r\n" | |||||
"field_3_1,field_3_2\r\n" // missing a field | |||||
"field_4_1,field_4_2,field_4_3\r\n" | |||||
"field_5_1,field_5_2,field_5_3" // no delimiter | |||||
)); | |||||
// Rewind the file for read. | |||||
file.seek(0); | |||||
size_t n; // Length of returned field with delimiter. | |||||
char str[20]; // Must hold longest field with delimiter and zero byte. | |||||
// Read the file and print fields. | |||||
while (true) { | |||||
n = readField(&file, str, sizeof(str), ",\n"); | |||||
// done if Error or at EOF. | |||||
if (n == 0) break; | |||||
// Print the type of delimiter. | |||||
if (str[n-1] == ',' || str[n-1] == '\n') { | |||||
Serial.print(str[n-1] == ',' ? F("comma: ") : F("endl: ")); | |||||
// Remove the delimiter. | |||||
str[n-1] = 0; | |||||
} else { | |||||
// At eof, too long, or read error. Too long is error. | |||||
Serial.print(file.available() ? F("error: ") : F("eof: ")); | |||||
} | |||||
// Print the field. | |||||
Serial.println(str); | |||||
} | |||||
file.close(); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void loop() { | |||||
} | |||||
#define SD_CS_PIN SS | #define SD_CS_PIN SS | ||||
#include <SPI.h> | #include <SPI.h> | ||||
//#include <SD.h> | //#include <SD.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat SD; | SdFat SD; | ||||
File myFile; | File myFile; |
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat sd; | SdFat sd; | ||||
SdFile myFile; | SdFile myFile; | ||||
// Print extra info for debug if DEBUG_PRINT is nonzero | // Print extra info for debug if DEBUG_PRINT is nonzero | ||||
#define DEBUG_PRINT 0 | #define DEBUG_PRINT 0 | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
#if DEBUG_PRINT | #if DEBUG_PRINT | ||||
#include <FreeStack.h> | |||||
#include "FreeStack.h" | |||||
#endif // DEBUG_PRINT | #endif // DEBUG_PRINT | ||||
// | // | ||||
// Change the value of chipSelect if your hardware does | // Change the value of chipSelect if your hardware does |
* This program attempts to initialize an SD card and analyze its structure. | * This program attempts to initialize an SD card and analyze its structure. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
/* | /* | ||||
* SD chip select pin. Common values are: | * SD chip select pin. Common values are: | ||||
* | * | ||||
cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl; | cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl; | ||||
if (sd.vol()->dataStartBlock() % eraseSize) { | if (sd.vol()->dataStartBlock() % eraseSize) { | ||||
cout << F("Data area is not aligned on flash erase boundaries!\n"); | cout << F("Data area is not aligned on flash erase boundaries!\n"); | ||||
cout << F("Download and use formatter from www.sdsd.card()->org/consumer!\n"); | |||||
cout << F("Download and use formatter from www.sdcard.org!\n"); | |||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// use uppercase in hex and use 0X base prefix | // use uppercase in hex and use 0X base prefix | ||||
cout << uppercase << showbase << endl; | cout << uppercase << showbase << endl; | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("SdFat version: ") << SD_FAT_VERSION << endl; | cout << F("SdFat version: ") << SD_FAT_VERSION << endl; | ||||
if (DISABLE_CHIP_SELECT < 0) { | if (DISABLE_CHIP_SELECT < 0) { | ||||
cout << F( | cout << F( | ||||
// read any existing Serial data | // read any existing Serial data | ||||
while (Serial.read() >= 0) {} | while (Serial.read() >= 0) {} | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("\ntype any character to start\n"); | cout << F("\ntype any character to start\n"); | ||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} | ||||
delay(400); // catch Due reset problem | delay(400); // catch Due reset problem |
// This example will also run on an Uno and other boards using software SPI. | // This example will also run on an Uno and other boards using software SPI. | ||||
// | // | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
#if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h | #if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h | ||||
// | // | ||||
// Pin numbers in templates must be constants. | // Pin numbers in templates must be constants. |
// Benchmark comparing SdFile and StdioStream. | // Benchmark comparing SdFile and StdioStream. | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// Define PRINT_FIELD nonzero to use printField. | // Define PRINT_FIELD nonzero to use printField. | ||||
#define PRINT_FIELD 0 | #define PRINT_FIELD 0 |
* Example use of three SD cards. | * Example use of three SD cards. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
#if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h | #if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h | ||||
// SD1 is a microSD on hardware SPI pins 50-52 | // SD1 is a microSD on hardware SPI pins 50-52 |
* and the timestamp() function. | * and the timestamp() function. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
SdFat sd; | SdFat sd; | ||||
* Example use of two SD cards. | * Example use of two SD cards. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
SdFat sd1; | SdFat sd1; | ||||
const uint8_t SD1_CS = 10; // chip select for sd1 | const uint8_t SD1_CS = 10; // chip select for sd1 |
* This program demonstrates the freeClusterCount() call. | * This program demonstrates the freeClusterCount() call. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
/* | /* | ||||
* SD chip select pin. Common values are: | * SD chip select pin. Common values are: | ||||
* | * | ||||
cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); | cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); | ||||
cout << F("maximum freeClusterCount() performance.\n\n"); | cout << F("maximum freeClusterCount() performance.\n\n"); | ||||
} | } | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} | ||||
delay(400); // catch Due reset problem | delay(400); // catch Due reset problem |
* This program is a simple binary write/read benchmark. | * This program is a simple binary write/read benchmark. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include <FreeStack.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* Simple data logger. | * Simple data logger. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin. Be sure to disable any other SPI devices such as Enet. | // SD chip select pin. Be sure to disable any other SPI devices such as Enet. | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
// The interval must be greater than the maximum SD write latency plus the | // The interval must be greater than the maximum SD write latency plus the | ||||
// time to acquire and write data to the SD to avoid overrun errors. | // time to acquire and write data to the SD to avoid overrun errors. | ||||
// Run the bench example to check the quality of your SD card. | // Run the bench example to check the quality of your SD card. | ||||
const uint32_t SAMPLE_INTERVAL_MS = 200; | |||||
const uint32_t SAMPLE_INTERVAL_MS = 1000; | |||||
// Log file base name. Must be six characters or less. | // Log file base name. Must be six characters or less. | ||||
#define FILE_BASE_NAME "Data" | #define FILE_BASE_NAME "Data" |
/* | /* | ||||
* Example use of chdir(), ls(), mkdir(), and rmdir(). | * Example use of chdir(), ls(), mkdir(), and rmdir(). | ||||
*/ | */ | ||||
#include <SPI.h> | |||||
#include <SdFat.h> | |||||
#include <SPI.h> | |||||
#include "SdFat.h" | |||||
// SD card chip select pin. | // SD card chip select pin. | ||||
const uint8_t SD_CHIP_SELECT = SS; | const uint8_t SD_CHIP_SELECT = SS; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// Permit SD to be wiped if ALLOW_WIPE is true. | |||||
const bool ALLOW_WIPE = false; | |||||
// File system object. | // File system object. | ||||
SdFat sd; | SdFat sd; | ||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
// Wait for input line and discard. | // Wait for input line and discard. | ||||
cin.readline(); | cin.readline(); | ||||
cout << endl; | |||||
// Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | ||||
// breadboards. use SPI_FULL_SPEED for better performance. | // breadboards. use SPI_FULL_SPEED for better performance. | ||||
if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) { | if (!sd.begin(SD_CHIP_SELECT, SPI_HALF_SPEED)) { | ||||
sd.initErrorHalt(); | sd.initErrorHalt(); | ||||
} | } | ||||
if (sd.exists("Folder1") | |||||
|| sd.exists("Folder1/file1.txt") | |||||
|| sd.exists("Folder1/File2.txt")) { | |||||
error("Please remove existing Folder1, file1.txt, and File2.txt"); | |||||
} | |||||
// Check for empty SD. | |||||
if (file.openNext(sd.vwd(), O_READ)) { | |||||
cout << F("Found files/folders in the root directory.\n"); | |||||
if (!ALLOW_WIPE) { | |||||
error("SD not empty, use a blank SD or set ALLOW_WIPE true."); | |||||
} else { | |||||
cout << F("Type: 'WIPE' to delete all SD files.\n"); | |||||
char buf[10]; | |||||
cin.readline(); | |||||
cin.get(buf, sizeof(buf)); | |||||
if (cin.fail() || strncmp(buf, "WIPE", 4) || buf[4] >= ' ') { | |||||
error("Invalid WIPE input"); | |||||
} | |||||
file.close(); | |||||
if (!sd.vwd()->rmRfStar()) { | |||||
error("wipe failed"); | |||||
} | |||||
cout << F("***SD wiped clean.***\n\n"); | |||||
int rootFileCount = 0; | |||||
sd.vwd()->rewind(); | |||||
while (file.openNext(sd.vwd(), O_READ)) { | |||||
if (!file.isHidden()) { | |||||
rootFileCount++; | |||||
} | |||||
file.close(); | |||||
if (rootFileCount > 10) { | |||||
error("Too many files in root. Please use an empty SD."); | |||||
} | } | ||||
} | } | ||||
if (rootFileCount) { | |||||
cout << F("\nPlease use an empty SD for best results.\n\n"); | |||||
delay(1000); | |||||
} | |||||
// Create a new folder. | // Create a new folder. | ||||
if (!sd.mkdir("Folder1")) { | if (!sd.mkdir("Folder1")) { | ||||
error("Create Folder1 failed"); | error("Create Folder1 failed"); | ||||
file.close(); | file.close(); | ||||
cout << F("Created File2.txt in current directory\n"); | cout << F("Created File2.txt in current directory\n"); | ||||
cout << F("List of files on the SD.\n"); | |||||
cout << F("\nList of files on the SD.\n"); | |||||
sd.ls("/", LS_R); | sd.ls("/", LS_R); | ||||
// Remove files from current directory. | // Remove files from current directory. | ||||
error("chdir to root failed.\n"); | error("chdir to root failed.\n"); | ||||
} | } | ||||
cout << F("List of files on the SD.\n"); | |||||
cout << F("\nList of files on the SD.\n"); | |||||
sd.ls(LS_R); | sd.ls(LS_R); | ||||
// Remove Folder1. | // Remove Folder1. | ||||
error("rmdir for Folder1 failed\n"); | error("rmdir for Folder1 failed\n"); | ||||
} | } | ||||
cout << F("\nFolder1 removed, SD empty.\n"); | |||||
cout << F("\nFolder1 removed.\n"); | |||||
cout << F("\nList of files on the SD.\n"); | |||||
sd.ls(LS_R); | |||||
cout << F("Done!\n"); | cout << F("Done!\n"); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
// Demo of fgets function to read lines from a file. | // Demo of fgets function to read lines from a file. | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* Format dates | * Format dates | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// create Serial stream | // create Serial stream | ||||
ArduinoOutStream cout(Serial); | ArduinoOutStream cout(Serial); |
* may not the best way to read a file. | * may not the best way to read a file. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | while (!Serial) {} // wait for Leonardo | ||||
// pstr stores strings in flash to save RAM | |||||
// F stores strings in flash to save RAM | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} | ||||
delay(400); // catch Due reset problem | delay(400); // catch Due reset problem |
* Each line of the file has a label and three values, a long and two floats. | * Each line of the file has a label and three values, a long and two floats. | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
* and SdFat::rename(). | * and SdFat::rename(). | ||||
*/ | */ | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | |||||
#include "SdFat.h" | |||||
// SD chip select pin | // SD chip select pin | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; |
// Example to wipe all data from an already formatted SD. | |||||
#include <SPI.h> | |||||
#include "SdFat.h" | |||||
const int chipSelect = SS; | |||||
SdFat sd; | |||||
void setup() { | |||||
int c; | |||||
Serial.begin(9600); | |||||
while (!Serial) {} // wait for Leonardo | |||||
Serial.println("Type 'Y' to wipe all data."); | |||||
while ((c = Serial.read()) <= 0) {} | |||||
if (c != 'Y') { | |||||
sd.errorHalt("Quitting, you did not type 'Y'."); | |||||
} | |||||
if (!sd.begin(chipSelect)) { | |||||
sd.initErrorHalt(); | |||||
} | |||||
// Use wipe() for no dot progress indicator. | |||||
if (!sd.wipe(&Serial)) { | |||||
sd.errorHalt("Wipe failed."); | |||||
} | |||||
// Must reinitialize after wipe. | |||||
if (!sd.begin(chipSelect)) { | |||||
sd.errorHalt("Second init failed."); | |||||
} | |||||
Serial.println("Done"); | |||||
} | |||||
void loop() { | |||||
} |
/* Arduino SdFat Library | |||||
* Copyright (C) 2012 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 SdVolume_h | |||||
#include "SdSpiCard.h" | |||||
#include "utility/FatLib.h" | |||||
#define SdVolume_h | |||||
#ifndef USE_SD_VOLUME | |||||
#error SdVolume is deperacated. Remove this line to continue using this class. | |||||
#endif // USE_SD_VOLUME | |||||
//============================================================================== | |||||
/** | |||||
* \class SdVolume | |||||
* \brief SdVolume Soon to be removed. | |||||
*/ | |||||
class SdVolume : public FatVolume { | |||||
public: | |||||
/** Initialize a FAT volume. Try partition one first then try super | |||||
* floppy format. | |||||
* | |||||
* \param[in] dev The Sd2Card where the volume is located. | |||||
* | |||||
* \return true for success else false. | |||||
*/ | |||||
bool init(Sd2Card* dev) { | |||||
return init(dev, 1) ? true : init(dev, 0); | |||||
} | |||||
/** Initialize a FAT volume. | |||||
* | |||||
* \param[in] dev The Sd2Card where the volume is located. | |||||
* \param[in] part the partition to use. Zero for super floppy or 1-4. | |||||
* \return true for success else false. | |||||
*/ | |||||
bool init(Sd2Card* dev, uint8_t part) { | |||||
m_sdCard = dev; | |||||
return FatVolume::init(part); | |||||
} | |||||
private: | |||||
// friend class FatFile; | |||||
bool readBlock(uint32_t block, uint8_t* dst) { | |||||
return m_sdCard->readBlock(block, dst); | |||||
} | |||||
bool writeBlock(uint32_t block, const uint8_t* src) { | |||||
return m_sdCard->writeBlock(block, src); | |||||
} | |||||
bool readBlocks(uint32_t block, uint8_t* dst, size_t n) { | |||||
return m_sdCard->readBlocks(block, dst, n); | |||||
} | |||||
bool writeBlocks(uint32_t block, const uint8_t* src, size_t n) { | |||||
return m_sdCard->writeBlocks(block, src, n); | |||||
} | |||||
Sd2Card* m_sdCard; // Sd2Card object for cache | |||||
}; | |||||
#endif // SdVolume_h |
*/ | */ | ||||
#include "FatLibConfig.h" | #include "FatLibConfig.h" | ||||
#if ENABLE_ARDUINO_FEATURES | #if ENABLE_ARDUINO_FEATURES | ||||
#include <Arduino.h> | |||||
#include "SystemInclude.h" | |||||
#include "bufstream.h" | #include "bufstream.h" | ||||
//============================================================================== | //============================================================================== | ||||
/** | /** |
} | } | ||||
goto fail; | goto fail; | ||||
} | } | ||||
// if (read(&b, 1) != 1) { | |||||
// DBG_FAIL_MACRO; | |||||
// goto fail; | |||||
// } | |||||
m_curPosition += 31; | m_curPosition += 31; | ||||
} else { | } else { | ||||
m_curPosition += 32; | m_curPosition += 32; | ||||
DBG_FAIL_MACRO; | DBG_FAIL_MACRO; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
// Optimize O_APPEND writes. | |||||
if (pos == m_curPosition) { | |||||
return true; | |||||
} | |||||
if (pos == 0) { | if (pos == 0) { | ||||
// set position to start of file | // set position to start of file | ||||
m_curCluster = 0; | m_curCluster = 0; |
#ifdef __AVR__ | #ifdef __AVR__ | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#else // __AVR__ | #else // __AVR__ | ||||
#ifndef PGM_P | |||||
/** pointer to flash for ARM */ | |||||
#define PGM_P const char* | |||||
#endif // PGM_P | |||||
#ifndef PSTR | #ifndef PSTR | ||||
/** store literal string in flash for ARM */ | /** store literal string in flash for ARM */ | ||||
#define PSTR(x) (x) | #define PSTR(x) (x) | ||||
#endif // pgm_read_word | #endif // pgm_read_word | ||||
#ifndef PROGMEM | #ifndef PROGMEM | ||||
/** store in flash for ARM */ | /** store in flash for ARM */ | ||||
#define PROGMEM const | |||||
#define PROGMEM | |||||
#endif // PROGMEM | #endif // PROGMEM | ||||
#endif // __AVR__ | #endif // __AVR__ | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
*/ | */ | ||||
bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); | bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock); | ||||
/** Create and open a new contiguous file of a specified size. | /** Create and open a new contiguous file of a specified size. | ||||
* | |||||
* \note This function only supports short DOS 8.3 names. | |||||
* See open() for more information. | |||||
* | * | ||||
* \param[in] dirFile The directory where the file will be created. | * \param[in] dirFile The directory where the file will be created. | ||||
* \param[in] path A path with a valid DOS 8.3 file name. | * \param[in] path A path with a valid DOS 8.3 file name. |
#define FatLibConfig_h | #define FatLibConfig_h | ||||
#include <stdint.h> | #include <stdint.h> | ||||
// Allow this file to override defaults. | // Allow this file to override defaults. | ||||
#include "../SdFatConfig.h" | |||||
#include "SdFatConfig.h" | |||||
#ifdef __AVR__ | #ifdef __AVR__ | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
* Enable Extra features for Arduino. | * Enable Extra features for Arduino. | ||||
*/ | */ | ||||
#ifndef ENABLE_ARDUINO_FEATURES | #ifndef ENABLE_ARDUINO_FEATURES | ||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
#if defined(ARDUINO) || defined(PLATFORM_ID) || defined(DOXYGEN) | |||||
#define ENABLE_ARDUINO_FEATURES 1 | #define ENABLE_ARDUINO_FEATURES 1 | ||||
#else // #if defined(ARDUINO) || defined(DOXYGEN) | #else // #if defined(ARDUINO) || defined(DOXYGEN) | ||||
#define ENABLE_ARDUINO_FEATURES 0 | #define ENABLE_ARDUINO_FEATURES 0 |
/** Type name for masterBootRecord */ | /** Type name for masterBootRecord */ | ||||
typedef struct masterBootRecord mbr_t; | typedef struct masterBootRecord mbr_t; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | |||||
* \struct biosParmBlock | |||||
* | |||||
* \brief BIOS parameter block | |||||
* | |||||
* The BIOS parameter block describes the physical layout of a FAT volume. | |||||
*/ | |||||
struct biosParmBlock{ | |||||
/** | |||||
* Count of bytes per sector. This value may take on only the | |||||
* following values: 512, 1024, 2048 or 4096 | |||||
*/ | |||||
uint16_t bytesPerSector; | |||||
/** | |||||
* Number of sectors per allocation unit. This value must be a | |||||
* power of 2 that is greater than 0. The legal values are | |||||
* 1, 2, 4, 8, 16, 32, 64, and 128. | |||||
*/ | |||||
uint8_t sectorsPerCluster; | |||||
/** | |||||
* Number of sectors before the first FAT. | |||||
* This value must not be zero. | |||||
*/ | |||||
uint16_t reservedSectorCount; | |||||
/** The count of FAT data structures on the volume. This field should | |||||
* always contain the value 2 for any FAT volume of any type. | |||||
*/ | |||||
uint8_t fatCount; | |||||
/** | |||||
* For FAT12 and FAT16 volumes, this field contains the count of | |||||
* 32-byte directory entries in the root directory. For FAT32 volumes, | |||||
* this field must be set to 0. For FAT12 and FAT16 volumes, this | |||||
* value should always specify a count that when multiplied by 32 | |||||
* results in a multiple of bytesPerSector. FAT16 volumes should | |||||
* use the value 512. | |||||
*/ | |||||
uint16_t rootDirEntryCount; | |||||
/** | |||||
* This field is the old 16-bit total count of sectors on the volume. | |||||
* This count includes the count of all sectors in all four regions | |||||
* of the volume. This field can be 0; if it is 0, then totalSectors32 | |||||
* must be nonzero. For FAT32 volumes, this field must be 0. For | |||||
* FAT12 and FAT16 volumes, this field contains the sector count, and | |||||
* totalSectors32 is 0 if the total sector count fits | |||||
* (is less than 0x10000). | |||||
*/ | |||||
uint16_t totalSectors16; | |||||
/** | |||||
* This dates back to the old MS-DOS 1.x media determination and is | |||||
* no longer usually used for anything. 0xF8 is the standard value | |||||
* for fixed (nonremovable) media. For removable media, 0xF0 is | |||||
* frequently used. Legal values are 0xF0 or 0xF8-0xFF. | |||||
*/ | |||||
uint8_t mediaType; | |||||
/** | |||||
* Count of sectors occupied by one FAT on FAT12/FAT16 volumes. | |||||
* On FAT32 volumes this field must be 0, and sectorsPerFat32 | |||||
* contains the FAT size count. | |||||
*/ | |||||
uint16_t sectorsPerFat16; | |||||
/** Sectors per track for interrupt 0x13. Not used otherwise. */ | |||||
uint16_t sectorsPerTrtack; | |||||
/** Number of heads for interrupt 0x13. Not used otherwise. */ | |||||
uint16_t headCount; | |||||
/** | |||||
* Count of hidden sectors preceding the partition that contains this | |||||
* FAT volume. This field is generally only relevant for media | |||||
* visible on interrupt 0x13. | |||||
*/ | |||||
uint32_t hidddenSectors; | |||||
/** | |||||
* This field is the new 32-bit total count of sectors on the volume. | |||||
* This count includes the count of all sectors in all four regions | |||||
* of the volume. This field can be 0; if it is 0, then | |||||
* totalSectors16 must be nonzero. | |||||
*/ | |||||
uint32_t totalSectors32; | |||||
/** | |||||
* Count of sectors occupied by one FAT on FAT32 volumes. | |||||
*/ | |||||
uint32_t sectorsPerFat32; | |||||
/** | |||||
* This field is only defined for FAT32 media and does not exist on | |||||
* FAT12 and FAT16 media. | |||||
* Bits 0-3 -- Zero-based number of active FAT. | |||||
* Only valid if mirroring is disabled. | |||||
* Bits 4-6 -- Reserved. | |||||
* Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. | |||||
* -- 1 means only one FAT is active; it is the one referenced in bits 0-3. | |||||
* Bits 8-15 -- Reserved. | |||||
*/ | |||||
uint16_t fat32Flags; | |||||
/** | |||||
* FAT32 version. High byte is major revision number. | |||||
* Low byte is minor revision number. Only 0.0 define. | |||||
*/ | |||||
uint16_t fat32Version; | |||||
/** | |||||
* Cluster number of the first cluster of the root directory for FAT32. | |||||
* This usually 2 but not required to be 2. | |||||
*/ | |||||
uint32_t fat32RootCluster; | |||||
/** | |||||
* Sector number of FSINFO structure in the reserved area of the | |||||
* FAT32 volume. Usually 1. | |||||
*/ | |||||
uint16_t fat32FSInfo; | |||||
/** | |||||
* If nonzero, indicates the sector number in the reserved area | |||||
* of the volume of a copy of the boot record. Usually 6. | |||||
* No value other than 6 is recommended. | |||||
*/ | |||||
uint16_t fat32BackBootBlock; | |||||
/** | |||||
* Reserved for future expansion. Code that formats FAT32 volumes | |||||
* should always set all of the bytes of this field to 0. | |||||
*/ | |||||
uint8_t fat32Reserved[12]; | |||||
} __attribute__((packed)); | |||||
/** Type name for biosParmBlock */ | |||||
typedef struct biosParmBlock bpb_t; | |||||
//------------------------------------------------------------------------------ | |||||
/** | /** | ||||
* \struct fat_boot | * \struct fat_boot | ||||
* | * |
* \brief FatVolume class | * \brief FatVolume class | ||||
*/ | */ | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include "SystemInclude.h" | |||||
#include "FatLibConfig.h" | #include "FatLibConfig.h" | ||||
#include "FatStructs.h" | #include "FatStructs.h" | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** Macro for debug. */ | /** Macro for debug. */ | ||||
#define DEBUG_MODE 0 | #define DEBUG_MODE 0 | ||||
#if DEBUG_MODE | #if DEBUG_MODE | ||||
#include <Arduino.h> | |||||
#define DBG_FAIL_MACRO Serial.print(F(__FILE__)); Serial.println(__LINE__) | #define DBG_FAIL_MACRO Serial.print(F(__FILE__)); Serial.println(__LINE__) | ||||
#define DBG_PRINT_IF(b) if (b) {Serial.println(F(#b)); DBG_FAIL_MACRO;} | #define DBG_PRINT_IF(b) if (b) {Serial.println(F(#b)); DBG_FAIL_MACRO;} | ||||
#define DBG_HALT_IF(b) if (b) {Serial.println(F(#b));\ | #define DBG_HALT_IF(b) if (b) {Serial.println(F(#b));\ | ||||
#endif // DOXYGEN_SHOULD_SKIP_THIS | #endif // DOXYGEN_SHOULD_SKIP_THIS | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#if ENABLE_ARDUINO_FEATURES | #if ENABLE_ARDUINO_FEATURES | ||||
#include <Arduino.h> | |||||
/** Use Print on Arduino */ | |||||
/** Use Print for Arduino */ | |||||
typedef Print print_t; | typedef Print print_t; | ||||
#else // ENABLE_ARDUINO_FEATURES | #else // ENABLE_ARDUINO_FEATURES | ||||
// Arduino type for flash string. | |||||
class __FlashStringHelper; | |||||
/** | /** | ||||
* \class CharWriter | * \class CharWriter | ||||
* \brief Character output - often serial port. | * \brief Character output - often serial port. |
return fwrite(str, 1, len) == len ? len : EOF; | return fwrite(str, 1, len) == len ? len : EOF; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
int StdioStream::fputs_P(PGM_P str) { | |||||
PGM_P bgn = str; | |||||
for (char c; (c = pgm_read_byte(str)); str++) { | |||||
if (putc(c) < 0) { | |||||
return EOF; | |||||
} | |||||
} | |||||
return str - bgn; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
size_t StdioStream::fread(void* ptr, size_t size, size_t count) { | size_t StdioStream::fread(void* ptr, size_t size, size_t count) { | ||||
uint8_t* dst = reinterpret_cast<uint8_t*>(ptr); | uint8_t* dst = reinterpret_cast<uint8_t*>(ptr); | ||||
size_t total = size*count; | size_t total = size*count; | ||||
return count; | return count; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
size_t StdioStream::print(const __FlashStringHelper *str) { | size_t StdioStream::print(const __FlashStringHelper *str) { | ||||
const char *p = (const char PROGMEM *)str; | |||||
const char *p = (const char*)str; | |||||
uint8_t c; | uint8_t c; | ||||
while ((c = pgm_read_byte(p))) { | while ((c = pgm_read_byte(p))) { | ||||
if (putc(c) < 0) { | if (putc(c) < 0) { | ||||
} | } | ||||
p++; | p++; | ||||
} | } | ||||
return p - (const char PROGMEM *)str; | |||||
return p - (const char*)str; | |||||
} | } | ||||
#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
int StdioStream::printDec(float value, uint8_t prec) { | int StdioStream::printDec(float value, uint8_t prec) { | ||||
#define FLOAT_NEW_WAY | |||||
#ifdef FLOAT_NEW_WAY | |||||
char buf[24]; | char buf[24]; | ||||
char *ptr = fmtFloat(value, buf + sizeof(buf), prec); | char *ptr = fmtFloat(value, buf + sizeof(buf), prec); | ||||
// return fputs(ptr); | |||||
// uint8_t len = buf + sizeof(buf) - ptr; | |||||
return write(ptr, buf + sizeof(buf) - ptr); | return write(ptr, buf + sizeof(buf) - ptr); | ||||
#else | |||||
char* ptr; | |||||
uint8_t rtn = 0; | |||||
uint8_t sign = 0; | |||||
if (value < 0) { | |||||
value = -value; | |||||
sign = '-'; | |||||
} | |||||
// check for NaN INF OVF | |||||
if (isnan(value)) { | |||||
if (fputs_P(PSTR("nan")) < 0) { | |||||
return -1; | |||||
} | |||||
rtn += 3; | |||||
} else if (isinf(value)) { | |||||
if (fputs_P(PSTR("inf")) < 0) { | |||||
return -1; | |||||
} | |||||
rtn += 3; | |||||
} else if (value > 4294967040.0) { | |||||
if (fputs_P(PSTR("ovf")) < 0) { | |||||
return -1; | |||||
} | |||||
rtn += 3; | |||||
} else { | |||||
if (sign) { | |||||
if (putc(sign) < 0) { | |||||
return -1; | |||||
} | |||||
rtn++; | |||||
} | |||||
if (prec > 9) { | |||||
prec = 9; | |||||
} | |||||
/* | |||||
uint32_t s = 1; | |||||
for (uint8_t i = 0; i < prec; i++) { | |||||
// s *= 10; | |||||
s = ((s << 2) + s) << 1; | |||||
} | |||||
// round value | |||||
value += 0.5/s; | |||||
*/ | |||||
value += scale10(0.5, -prec); | |||||
uint32_t whole = value; | |||||
int np; | |||||
if ((np = printDec(whole)) < 0) { | |||||
return -1; | |||||
} | |||||
rtn += np; | |||||
if (prec) { | |||||
if (putc('.') < 0) { | |||||
return -1; | |||||
} | |||||
char* str = fmtSpace(prec); | |||||
if (!str) { | |||||
return -1; | |||||
} | |||||
char* tmp = str - prec; | |||||
// uint32_t fraction = s*(value - whole); | |||||
uint32_t fraction = scale10(value - whole, prec); | |||||
ptr = fmtDec(fraction, str); | |||||
while (ptr > tmp) { | |||||
*--ptr = '0'; | |||||
} | |||||
rtn += prec + 1; | |||||
} | |||||
} | |||||
return rtn; | |||||
#endif | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
int StdioStream::printDec(signed char n) { | int StdioStream::printDec(signed char n) { |
*/ | */ | ||||
int fputs(const char* str); | int fputs(const char* str); | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** Write a string stored in flash. | |||||
* | |||||
* \param[in] str string to be written. | |||||
* | |||||
* \return for success, fputs() returns a non-negative | |||||
* number. Otherwise, it returns EOF and sets the error indicator for | |||||
* the stream. | |||||
*/ | |||||
int fputs_P(PGM_P str); | |||||
//---------------------------------------------------------------------------- | |||||
/** Binary input. | /** Binary input. | ||||
* | * | ||||
* Reads an array of up to count elements, each one with a size of size | * Reads an array of up to count elements, each one with a size of size | ||||
return n < 0 ? 0 : n; | return n < 0 ? 0 : n; | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
/** Print a string stored in flash memory. | /** Print a string stored in flash memory. | ||||
* | * | ||||
* \param[in] str the string to print. | * \param[in] str the string to print. | ||||
* \return the number of bytes written. | * \return the number of bytes written. | ||||
*/ | */ | ||||
size_t print(const __FlashStringHelper *str); | size_t print(const __FlashStringHelper *str); | ||||
#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** Print a floating point number. | /** Print a floating point number. | ||||
* | * |
getNumber(b); | getNumber(b); | ||||
return; | return; | ||||
} | } | ||||
#ifdef __AVR__ | |||||
PGM_P truePtr = PSTR("true"); | PGM_P truePtr = PSTR("true"); | ||||
PGM_P falsePtr = PSTR("false"); | PGM_P falsePtr = PSTR("false"); | ||||
#else // __AVR__ | |||||
const char* truePtr = "true"; | |||||
const char* falsePtr = "false"; | |||||
#endif // __AVR | |||||
const uint8_t true_len = 4; | const uint8_t true_len = 4; | ||||
const uint8_t false_len = 5; | const uint8_t false_len = 5; | ||||
bool trueOk = true; | bool trueOk = true; | ||||
uint8_t i = 0; | uint8_t i = 0; | ||||
int c = readSkip(); | int c = readSkip(); | ||||
while (1) { | while (1) { | ||||
#ifdef __AVR__ | |||||
falseOk = falseOk && c == pgm_read_byte(falsePtr + i); | falseOk = falseOk && c == pgm_read_byte(falsePtr + i); | ||||
trueOk = trueOk && c == pgm_read_byte(truePtr + i); | trueOk = trueOk && c == pgm_read_byte(truePtr + i); | ||||
#else // __AVR__ | |||||
falseOk = falseOk && c == falsePtr[i]; | |||||
trueOk = trueOk && c == truePtr[i]; | |||||
#endif // __AVR | |||||
if (trueOk == false && falseOk == false) { | if (trueOk == false && falseOk == false) { | ||||
break; | break; | ||||
} | } |
* \brief \ref ostream class | * \brief \ref ostream class | ||||
*/ | */ | ||||
#include "ios.h" | #include "ios.h" | ||||
//------------------------------------------------------------------------------ | |||||
/** macro for flash inserter */ | |||||
#define pstr(str) pgm(PSTR(str)) | |||||
/** \struct pgm | |||||
* \brief type for string in flash | |||||
*/ | |||||
struct pgm { | |||||
/** Pointer to flash string */ | |||||
char *ptr; | |||||
/** constructor | |||||
* \param[in] str initializer for pointer. | |||||
*/ | |||||
explicit pgm(char* str) : ptr(str) {} | |||||
/** constructor | |||||
* \param[in] str initializer for pointer. | |||||
*/ | |||||
explicit pgm(const char *str) : ptr(const_cast<char*>(str)) {} | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
* \class ostream | * \class ostream | ||||
putNum(reinterpret_cast<uint32_t>(arg)); | putNum(reinterpret_cast<uint32_t>(arg)); | ||||
return *this; | return *this; | ||||
} | } | ||||
/** Output a string from flash using the pstr() macro | |||||
* \param[in] arg pgm struct pointing to string | |||||
* \return the stream | |||||
*/ | |||||
ostream &operator<< (pgm arg) { | |||||
putPgm(arg.ptr); | |||||
return *this; | |||||
} | |||||
#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
/** Output a string from flash using the Arduino F() macro. | /** Output a string from flash using the Arduino F() macro. | ||||
* \param[in] arg pointing to flash string | * \param[in] arg pointing to flash string | ||||
* \return the stream | * \return the stream | ||||
putPgm(reinterpret_cast<const char*>(arg)); | putPgm(reinterpret_cast<const char*>(arg)); | ||||
return *this; | return *this; | ||||
} | } | ||||
#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
/** | /** | ||||
* Puts a character in a stream. | * Puts a character in a stream. | ||||
* | * |
char top; | char top; | ||||
return &top - reinterpret_cast<char*>(sbrk(0)); | return &top - reinterpret_cast<char*>(sbrk(0)); | ||||
} | } | ||||
#else // __arm__ | |||||
#elif __AVR__ // __arm__ | |||||
/** boundary between stack and heap. */ | /** boundary between stack and heap. */ | ||||
extern char *__brkval; | extern char *__brkval; | ||||
/** End of bss section.*/ | /** End of bss section.*/ | ||||
char top; | char top; | ||||
return __brkval ? &top - __brkval : &top - &__bss_end; | return __brkval ? &top - __brkval : &top - &__bss_end; | ||||
} | } | ||||
#elif defined(PLATFORM_ID) // Particle board | |||||
static int FreeStack() { | |||||
return System.freeMemory(); | |||||
} | |||||
#else | |||||
#warning FreeStack is not defined for this system. | |||||
#endif // __arm | #endif // __arm | ||||
#endif // FreeStack_h | #endif // FreeStack_h |
* along with the Arduino SdFat Library. If not, see | * along with the Arduino SdFat Library. If not, see | ||||
* <http://www.gnu.org/licenses/>. | * <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include <Arduino.h> | |||||
#include "SystemInclude.h" | |||||
#if defined(UDR0) || defined(DOXYGEN) | #if defined(UDR0) || defined(DOXYGEN) | ||||
#include "MinimumSerial.h" | #include "MinimumSerial.h" | ||||
const uint16_t MIN_2X_BAUD = F_CPU/(4*(2*0XFFF + 1)) + 1; | const uint16_t MIN_2X_BAUD = F_CPU/(4*(2*0XFFF + 1)) + 1; |
*/ | */ | ||||
#ifndef MinimumSerial_h | #ifndef MinimumSerial_h | ||||
#define MinimumSerial_h | #define MinimumSerial_h | ||||
#include <Arduino.h> | |||||
#include "SystemInclude.h" | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
* \class MinimumSerial | * \class MinimumSerial |
while (1) {} | while (1) {} | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { | |||||
errorPrint(pr, msg); | |||||
while (1) {} | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::errorPrint(Print* pr) { | void SdFatBase::errorPrint(Print* pr) { | ||||
if (!cardErrorCode()) { | if (!cardErrorCode()) { | ||||
return; | return; | ||||
errorPrint(pr); | errorPrint(pr); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | |||||
pr->print(F("error: ")); | |||||
pr->println(msg); | |||||
errorPrint(pr); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::initErrorHalt(Print* pr) { | void SdFatBase::initErrorHalt(Print* pr) { | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
while (1) {} | while (1) {} | ||||
initErrorHalt(pr); | initErrorHalt(pr); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { | |||||
pr->println(msg); | |||||
initErrorHalt(pr); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::initErrorPrint(Print* pr) { | void SdFatBase::initErrorPrint(Print* pr) { | ||||
if (cardErrorCode()) { | if (cardErrorCode()) { | ||||
pr->println(F("Can't access SD card. Do not reformat.")); | pr->println(F("Can't access SD card. Do not reformat.")); | ||||
pr->println(msg); | pr->println(msg); | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
} | } | ||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | |||||
pr->print(F("error: ")); | |||||
pr->println(msg); | |||||
errorPrint(pr); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { | |||||
errorPrint(pr, msg); | |||||
while (1) {} | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { | |||||
pr->println(msg); | |||||
initErrorHalt(pr); | |||||
} | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::initErrorPrint(Print* pr, const __FlashStringHelper* msg) { | void SdFatBase::initErrorPrint(Print* pr, const __FlashStringHelper* msg) { | ||||
pr->println(msg); | pr->println(msg); | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
} | } | ||||
#endif // defined(ARDUINO) || defined(DOXYGEN) |
* \file | * \file | ||||
* \brief SdFat class | * \brief SdFat class | ||||
*/ | */ | ||||
#ifdef ARDUINO | |||||
#include "SdSpiCard/SdSpiCard.h" | #include "SdSpiCard/SdSpiCard.h" | ||||
#include "FatLib/FatLib.h" | #include "FatLib/FatLib.h" | ||||
#else // ARDUINO | |||||
#include "SdSpiCard.h" | |||||
#include "FatLib.h" | |||||
#endif // ARDUINO | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** SdFat version YYYYMMDD */ | /** SdFat version YYYYMMDD */ | ||||
#define SD_FAT_VERSION 20150718 | |||||
#define SD_FAT_VERSION 20160123 | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
* \class SdBaseFile | * \class SdBaseFile | ||||
* \class SdFile | * \class SdFile | ||||
* \brief Class for backward compatibility. | * \brief Class for backward compatibility. | ||||
*/ | */ | ||||
class SdFile : public PrintFile { | class SdFile : public PrintFile { | ||||
public: | public: | ||||
SdFile() {} | SdFile() {} | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void errorHalt(Print* pr, char const* msg); | void errorHalt(Print* pr, char const* msg); | ||||
/** %Print msg, any SD error code, and halt. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorHalt(const __FlashStringHelper* msg) { | |||||
errorHalt(&Serial, msg); | |||||
} | |||||
/** %Print msg, any SD error code, and halt. | |||||
* | |||||
* \param[in] pr Print destination. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
/** %Print any SD error code to Serial */ | /** %Print any SD error code to Serial */ | ||||
void errorPrint() { | void errorPrint() { | ||||
errorPrint(&Serial); | errorPrint(&Serial); | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void errorPrint(Print* pr, char const* msg); | void errorPrint(Print* pr, char const* msg); | ||||
/** %Print msg, any SD error code. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorPrint(const __FlashStringHelper* msg) { | |||||
errorPrint(&Serial, msg); | |||||
} | |||||
/** %Print msg, any SD error code. | |||||
* | |||||
* \param[in] pr Print destination. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorPrint(Print* pr, const __FlashStringHelper* msg); | |||||
/** Diagnostic call to initialize FatFileSystem - use for | /** Diagnostic call to initialize FatFileSystem - use for | ||||
* diagnostic purposes only. | * diagnostic purposes only. | ||||
* \return true for success else false. | * \return true for success else false. | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void initErrorHalt(Print* pr, char const *msg); | void initErrorHalt(Print* pr, char const *msg); | ||||
/**Print message, error details, and halt after SdFat::init() fails. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void initErrorHalt(const __FlashStringHelper* msg) { | |||||
initErrorHalt(&Serial, msg); | |||||
} | |||||
/**Print message, error details, and halt after SdFatBase::init() fails. | |||||
* \param[in] pr Print device for message. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void initErrorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
/** Print error details after SdFat::init() fails. */ | /** Print error details after SdFat::init() fails. */ | ||||
void initErrorPrint() { | void initErrorPrint() { | ||||
initErrorPrint(&Serial); | initErrorPrint(&Serial); | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void initErrorPrint(Print* pr, char const *msg); | void initErrorPrint(Print* pr, char const *msg); | ||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
/** %Print msg, any SD error code, and halt. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorHalt(const __FlashStringHelper* msg) { | |||||
errorHalt(&Serial, msg); | |||||
} | |||||
/** %Print msg, any SD error code, and halt. | |||||
* | |||||
* \param[in] pr Print destination. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
/** %Print msg, any SD error code. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorPrint(const __FlashStringHelper* msg) { | |||||
errorPrint(&Serial, msg); | |||||
} | |||||
/** %Print msg, any SD error code. | |||||
* | |||||
* \param[in] pr Print destination. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void errorPrint(Print* pr, const __FlashStringHelper* msg); | |||||
/**Print message, error details, and halt after SdFat::init() fails. | |||||
* | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void initErrorHalt(const __FlashStringHelper* msg) { | |||||
initErrorHalt(&Serial, msg); | |||||
} | |||||
/**Print message, error details, and halt after SdFatBase::init() fails. | |||||
* \param[in] pr Print device for message. | |||||
* \param[in] msg Message to print. | |||||
*/ | |||||
void initErrorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
/**Print message and error details and halt after SdFat::init() fails. | /**Print message and error details and halt after SdFat::init() fails. | ||||
* | * | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void initErrorPrint(Print* pr, const __FlashStringHelper* msg); | void initErrorPrint(Print* pr, const __FlashStringHelper* msg); | ||||
#endif //defined(ARDUINO) || defined(DOXYGEN) | |||||
private: | private: | ||||
uint8_t cardErrorCode() { | uint8_t cardErrorCode() { | ||||
return m_sdCard.errorCode(); | return m_sdCard.errorCode(); | ||||
*/ | */ | ||||
class SdFat : public SdFatBase { | class SdFat : public SdFatBase { | ||||
public: | public: | ||||
#if IMPLEMENT_SPI_INTERFACE_SELECTION | |||||
SdFat() { | |||||
m_spi.setSpiIf(0); | |||||
} | |||||
SdFat(uint8_t spiIf) { | |||||
m_spi.setSpiIf(spiIf < SPI_INTERFACE_COUNT ? spiIf : 0); | |||||
} | |||||
#endif // IMPLEMENT_SPI_INTERFACE_SELECTION | |||||
/** Initialize SD card and file system. | /** Initialize SD card and file system. | ||||
* | * | ||||
* \param[in] csPin SD card chip select pin. | * \param[in] csPin SD card chip select pin. |
*/ | */ | ||||
#define ARDUINO_FILE_USES_STREAM 1 | #define ARDUINO_FILE_USES_STREAM 1 | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | |||||
* Determine the default SPI configuration. | |||||
*/ | |||||
#if defined(__AVR__)\ | |||||
|| defined(__SAM3X8E__) || defined(__SAM3X8H__)\ | |||||
|| (defined(__arm__) && defined(CORE_TEENSY))\ | |||||
|| defined(__STM32F1__)\ | |||||
|| defined(DOXYGEN) | |||||
// Use custom fast implementation. | |||||
#define SD_HAS_CUSTOM_SPI 1 | |||||
#else // SD_HAS_CUSTOM_SPI | |||||
// Use standard SPI library. | |||||
#define SD_HAS_CUSTOM_SPI 0 | |||||
#endif // SD_HAS_CUSTOM_SPI | |||||
//------------------------------------------------------------------------------ | |||||
/** | /** | ||||
* The symbol SD_SPI_CONFIGURATION defines SPI access to the SD card. | * The symbol SD_SPI_CONFIGURATION defines SPI access to the SD card. | ||||
* | * | ||||
*/ | */ | ||||
#define ENABLE_SPI_TRANSACTIONS 0 | #define ENABLE_SPI_TRANSACTIONS 0 | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | |||||
* Set ENABLE_SPI_YIELD nonzero to enable release of the SPI bus during | |||||
* SD card busy waits. | |||||
* | |||||
* This will allow interrupt routines to access the SPI bus if | |||||
* ENABLE_SPI_TRANSACTIONS is nonzero. | |||||
* | |||||
* Setting ENABLE_SPI_YIELD will introduce some extra overhead and will | |||||
* slightly slow transfer rates. A few older SD cards may fail when | |||||
* ENABLE_SPI_YIELD is nonzero. | |||||
*/ | |||||
#define ENABLE_SPI_YIELD 0 | |||||
//------------------------------------------------------------------------------ | |||||
/** | /** | ||||
* Set FAT12_SUPPORT nonzero to enable use if FAT12 volumes. | * Set FAT12_SUPPORT nonzero to enable use if FAT12 volumes. | ||||
* FAT12 has not been well tested and requires additional flash. | * FAT12 has not been well tested and requires additional flash. | ||||
#else // RAMEND | #else // RAMEND | ||||
#define USE_MULTI_BLOCK_IO 1 | #define USE_MULTI_BLOCK_IO 1 | ||||
#endif // RAMEND | #endif // RAMEND | ||||
//------------------------------------------------------------------------------ | |||||
/** | |||||
* Determine the default SPI configuration. | |||||
*/ | |||||
#if defined(__AVR__)\ | |||||
|| defined(__SAM3X8E__) || defined(__SAM3X8H__)\ | |||||
|| (defined(__arm__) && defined(CORE_TEENSY))\ | |||||
|| defined(__STM32F1__)\ | |||||
|| defined(PLATFORM_ID)\ | |||||
|| defined(DOXYGEN) | |||||
// Use custom fast implementation. | |||||
#define SD_HAS_CUSTOM_SPI 1 | |||||
#else // SD_HAS_CUSTOM_SPI | |||||
// Use standard SPI library. | |||||
#define SD_HAS_CUSTOM_SPI 0 | |||||
#endif // SD_HAS_CUSTOM_SPI | |||||
//----------------------------------------------------------------------------- | |||||
/** | |||||
* Number of hardware interfaces. | |||||
*/ | |||||
#if defined(PLATFORM_ID) | |||||
#if Wiring_SPI1 && Wiring_SPI2 | |||||
#define SPI_INTERFACE_COUNT 3 | |||||
#elif Wiring_SPI1 | |||||
#define SPI_INTERFACE_COUNT 2 | |||||
#endif // Wiring_SPI1 && Wiring_SPI2 | |||||
#endif // defined(PLATFORM_ID) | |||||
// default is one | |||||
#ifndef SPI_INTERFACE_COUNT | |||||
#define SPI_INTERFACE_COUNT 1 | |||||
#endif // SPI_INTERFACE_COUNT | |||||
//------------------------------------------------------------------------------ | |||||
/** | |||||
* Check if API to select HW SPI interface is needed. | |||||
*/ | |||||
#if SPI_INTERFACE_COUNT > 1 && SD_HAS_CUSTOM_SPI\ | |||||
&& SD_SPI_CONFIGURATION != 1 && SD_SPI_CONFIGURATION != 2 | |||||
#define IMPLEMENT_SPI_INTERFACE_SELECTION 1 | |||||
#else // SPI_INTERFACE_COUNT > 1 | |||||
#define IMPLEMENT_SPI_INTERFACE_SELECTION 0 | |||||
#endif // SPI_INTERFACE_COUNT > 1 | |||||
#endif // SdFatConfig_h | #endif // SdFatConfig_h |
return __brkval ? &top - __brkval : &top - &__bss_end; | return __brkval ? &top - __brkval : &top - &__bss_end; | ||||
} | } | ||||
#endif // __arm | #endif // __arm | ||||
//------------------------------------------------------------------------------ | |||||
void SdFatUtil::print_P(Print* pr, PGM_P str) { | |||||
for (uint8_t c; (c = pgm_read_byte(str)); str++) { | |||||
pr->write(c); | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdFatUtil::println_P(Print* pr, PGM_P str) { | |||||
print_P(pr, str); | |||||
pr->println(); | |||||
} | |||||
* \brief Useful utility functions. | * \brief Useful utility functions. | ||||
*/ | */ | ||||
#include "SdFat.h" | #include "SdFat.h" | ||||
/** Store and print a string in flash memory.*/ | |||||
#define PgmPrint(x) SerialPrint_P(PSTR(x)) | |||||
/** Store and print a string in flash memory followed by a CR/LF.*/ | |||||
#define PgmPrintln(x) SerialPrintln_P(PSTR(x)) | |||||
namespace SdFatUtil { | namespace SdFatUtil { | ||||
/** Amount of free RAM | /** Amount of free RAM | ||||
* \return The number of free bytes. | * \return The number of free bytes. | ||||
*/ | */ | ||||
int FreeRam(); | int FreeRam(); | ||||
/** %Print a string in flash memory. | |||||
* | |||||
* \param[in] pr Print object for output. | |||||
* \param[in] str Pointer to string stored in flash memory. | |||||
*/ | |||||
void print_P(Print* pr, PGM_P str); | |||||
/** %Print a string in flash memory followed by a CR/LF. | |||||
* | |||||
* \param[in] pr Print object for output. | |||||
* \param[in] str Pointer to string stored in flash memory. | |||||
*/ | |||||
void println_P(Print* pr, PGM_P str); | |||||
//---------------------------------------------------------------------------- | |||||
/** %Print a string in flash memory to Serial. | |||||
* | |||||
* \param[in] str Pointer to string stored in flash memory. | |||||
*/ | |||||
inline void SerialPrint_P(PGM_P str) { | |||||
print_P(&Serial, str); | |||||
} | |||||
//---------------------------------------------------------------------------- | |||||
/** %Print a string in flash memory to Serial followed by a CR/LF. | |||||
* | |||||
* \param[in] str Pointer to string stored in flash memory. | |||||
*/ | |||||
inline void SerialPrintln_P(PGM_P str) { | |||||
println_P(&Serial, str); | |||||
} | |||||
} // namespace SdFatUtil | } // namespace SdFatUtil | ||||
using namespace SdFatUtil; // NOLINT | using namespace SdFatUtil; // NOLINT | ||||
#endif // #define SdFatUtil_h | #endif // #define SdFatUtil_h |
*/ | */ | ||||
#ifndef DigitalPin_h | #ifndef DigitalPin_h | ||||
#define DigitalPin_h | #define DigitalPin_h | ||||
#include <Arduino.h> | |||||
#include "SystemInclude.h" | |||||
#ifdef __arm__ | #ifdef __arm__ | ||||
#ifdef CORE_TEENSY | #ifdef CORE_TEENSY | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastDigitalWrite(uint8_t pin, bool value) { | void fastDigitalWrite(uint8_t pin, bool value) { | ||||
if (value) { | |||||
*portSetRegister(pin) = 1; | |||||
} else { | |||||
*portClearRegister(pin) = 1; | |||||
} | |||||
if (value) { | |||||
*portSetRegister(pin) = 1; | |||||
} else { | |||||
*portClearRegister(pin) = 1; | |||||
} | |||||
} | } | ||||
#elif defined(__SAM3X8E__) || defined(__SAM3X8H__) // CORE_TEENSY | |||||
#else // CORE_TEENSY | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** read pin value | /** read pin value | ||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* @return value read | * @return value read | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
bool fastDigitalRead(uint8_t pin) { | |||||
bool fastDigitalRead(uint8_t pin){ | |||||
return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; | return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
* @param[in] level value to write | * @param[in] level value to write | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastDigitalWrite(uint8_t pin, bool value) { | |||||
if (value) { | |||||
void fastDigitalWrite(uint8_t pin, bool value){ | |||||
if(value) { | |||||
g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; | g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; | ||||
} else { | } else { | ||||
g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; | g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; | ||||
} | } | ||||
} | } | ||||
#else // CORE_TEENSY | |||||
//------------------------------------------------------------------------------ | |||||
/** read pin value | |||||
* @param[in] pin Arduino pin number | |||||
* @return value read | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
bool fastDigitalRead(uint8_t pin) { | |||||
return digitalRead(pin); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** Set pin value | |||||
* @param[in] pin Arduino pin number | |||||
* @param[in] level value to write | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
void fastDigitalWrite(uint8_t pin, bool value) { | |||||
digitalWrite(pin, value); | |||||
} | |||||
#endif // CORE_TEENSY | #endif // CORE_TEENSY | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
inline void fastDigitalToggle(uint8_t pin) { | inline void fastDigitalToggle(uint8_t pin) { | ||||
fastDigitalWrite(pin, !fastDigitalRead(pin)); | |||||
} | |||||
fastDigitalWrite(pin, !fastDigitalRead(pin)); | |||||
} | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
inline void fastPinMode(uint8_t pin, bool mode) { | |||||
pinMode(pin, mode); | |||||
} | |||||
inline void fastPinMode(uint8_t pin, uint8_t mode) {pinMode(pin, mode);} | |||||
#else // __arm__ | #else // __arm__ | ||||
//============================================================================== | |||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <util/atomic.h> | |||||
//------------------------------------------------------------------------------ | |||||
/** | |||||
* @class pin_map_t | |||||
* @brief struct for mapping digital pins | |||||
*/ | |||||
struct pin_map_t { | |||||
/** GpioPinMap type */ | |||||
struct GpioPinMap_t { | |||||
volatile uint8_t* pin; /**< address of PIN for this pin */ | |||||
volatile uint8_t* ddr; /**< address of DDR for this pin */ | volatile uint8_t* ddr; /**< address of DDR for this pin */ | ||||
volatile uint8_t* pin; /**< address of PIN for this pin */ | |||||
volatile uint8_t* port; /**< address of PORT for this pin */ | volatile uint8_t* port; /**< address of PORT for this pin */ | ||||
uint8_t bit; /**< bit number for this pin */ | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
#if defined(__AVR_ATmega168__)\ | |||||
||defined(__AVR_ATmega168P__)\ | |||||
||defined(__AVR_ATmega328P__) | |||||
// 168 and 328 Arduinos | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 0 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 1 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 2 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 3 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 4 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 5 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 6 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 7 | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 8 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 9 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 10 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 11 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 12 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 13 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 14 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 15 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 16 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 17 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 18 | |||||
{&DDRC, &PINC, &PORTC, 5} // C5 19 | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
#elif defined(__AVR_ATmega1280__)\ | |||||
|| defined(__AVR_ATmega2560__) | |||||
// Mega | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRE, &PINE, &PORTE, 0}, // E0 0 | |||||
{&DDRE, &PINE, &PORTE, 1}, // E1 1 | |||||
{&DDRE, &PINE, &PORTE, 4}, // E4 2 | |||||
{&DDRE, &PINE, &PORTE, 5}, // E5 3 | |||||
{&DDRG, &PING, &PORTG, 5}, // G5 4 | |||||
{&DDRE, &PINE, &PORTE, 3}, // E3 5 | |||||
{&DDRH, &PINH, &PORTH, 3}, // H3 6 | |||||
{&DDRH, &PINH, &PORTH, 4}, // H4 7 | |||||
{&DDRH, &PINH, &PORTH, 5}, // H5 8 | |||||
{&DDRH, &PINH, &PORTH, 6}, // H6 9 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 10 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 11 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 12 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 13 | |||||
{&DDRJ, &PINJ, &PORTJ, 1}, // J1 14 | |||||
{&DDRJ, &PINJ, &PORTJ, 0}, // J0 15 | |||||
{&DDRH, &PINH, &PORTH, 1}, // H1 16 | |||||
{&DDRH, &PINH, &PORTH, 0}, // H0 17 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 18 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 19 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 20 | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 21 | |||||
{&DDRA, &PINA, &PORTA, 0}, // A0 22 | |||||
{&DDRA, &PINA, &PORTA, 1}, // A1 23 | |||||
{&DDRA, &PINA, &PORTA, 2}, // A2 24 | |||||
{&DDRA, &PINA, &PORTA, 3}, // A3 25 | |||||
{&DDRA, &PINA, &PORTA, 4}, // A4 26 | |||||
{&DDRA, &PINA, &PORTA, 5}, // A5 27 | |||||
{&DDRA, &PINA, &PORTA, 6}, // A6 28 | |||||
{&DDRA, &PINA, &PORTA, 7}, // A7 29 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 30 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 31 | |||||
{&DDRC, &PINC, &PORTC, 5}, // C5 32 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 33 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 34 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 35 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 36 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 37 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 38 | |||||
{&DDRG, &PING, &PORTG, 2}, // G2 39 | |||||
{&DDRG, &PING, &PORTG, 1}, // G1 40 | |||||
{&DDRG, &PING, &PORTG, 0}, // G0 41 | |||||
{&DDRL, &PINL, &PORTL, 7}, // L7 42 | |||||
{&DDRL, &PINL, &PORTL, 6}, // L6 43 | |||||
{&DDRL, &PINL, &PORTL, 5}, // L5 44 | |||||
{&DDRL, &PINL, &PORTL, 4}, // L4 45 | |||||
{&DDRL, &PINL, &PORTL, 3}, // L3 46 | |||||
{&DDRL, &PINL, &PORTL, 2}, // L2 47 | |||||
{&DDRL, &PINL, &PORTL, 1}, // L1 48 | |||||
{&DDRL, &PINL, &PORTL, 0}, // L0 49 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 50 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 51 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 52 | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 53 | |||||
{&DDRF, &PINF, &PORTF, 0}, // F0 54 | |||||
{&DDRF, &PINF, &PORTF, 1}, // F1 55 | |||||
{&DDRF, &PINF, &PORTF, 2}, // F2 56 | |||||
{&DDRF, &PINF, &PORTF, 3}, // F3 57 | |||||
{&DDRF, &PINF, &PORTF, 4}, // F4 58 | |||||
{&DDRF, &PINF, &PORTF, 5}, // F5 59 | |||||
{&DDRF, &PINF, &PORTF, 6}, // F6 60 | |||||
{&DDRF, &PINF, &PORTF, 7}, // F7 61 | |||||
{&DDRK, &PINK, &PORTK, 0}, // K0 62 | |||||
{&DDRK, &PINK, &PORTK, 1}, // K1 63 | |||||
{&DDRK, &PINK, &PORTK, 2}, // K2 64 | |||||
{&DDRK, &PINK, &PORTK, 3}, // K3 65 | |||||
{&DDRK, &PINK, &PORTK, 4}, // K4 66 | |||||
{&DDRK, &PINK, &PORTK, 5}, // K5 67 | |||||
{&DDRK, &PINK, &PORTK, 6}, // K6 68 | |||||
{&DDRK, &PINK, &PORTK, 7} // K7 69 | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
#elif defined(__AVR_ATmega1284P__)\ | |||||
|| defined(__AVR_ATmega1284__)\ | |||||
|| defined(__AVR_ATmega644P__)\ | |||||
|| defined(__AVR_ATmega644__)\ | |||||
|| defined(__AVR_ATmega64__)\ | |||||
|| defined(__AVR_ATmega32__)\ | |||||
|| defined(__AVR_ATmega324__)\ | |||||
|| defined(__AVR_ATmega16__) | |||||
#ifdef PORT_D0 | |||||
// Newer version of 1284P | |||||
#define DPM(x) {PORT_TO_MODE(PORT_D##x), PORT_TO_INPUT(PORT_D##x), \ | |||||
PORT_TO_OUTPUT(PORT_D##x), BIT_D##x} | |||||
static const pin_map_t pinMap[] = { | |||||
DPM(0), | |||||
DPM(1), | |||||
DPM(2), | |||||
DPM(3), | |||||
DPM(4), | |||||
DPM(5), | |||||
DPM(6), | |||||
DPM(7), | |||||
DPM(8), | |||||
DPM(9), | |||||
DPM(10), | |||||
DPM(11), | |||||
DPM(12), | |||||
DPM(13), | |||||
DPM(14), | |||||
DPM(15), | |||||
DPM(16), | |||||
DPM(17), | |||||
DPM(18), | |||||
DPM(19), | |||||
DPM(20), | |||||
DPM(21), | |||||
DPM(22), | |||||
DPM(23), | |||||
DPM(24), | |||||
DPM(25), | |||||
DPM(26), | |||||
DPM(27), | |||||
DPM(28), | |||||
DPM(29), | |||||
DPM(30), | |||||
DPM(31) | |||||
uint8_t mask; /**< bit mask for this pin */ | |||||
}; | }; | ||||
#undef DPM | |||||
/** Initializer macro. */ | |||||
#define GPIO_PIN(reg, bit) {&PIN##reg, &DDR##reg, &PORT##reg, 1 << bit} | |||||
#elif analogInputToDigitalPin(0) == 24 | |||||
// Mighty Layout | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 0 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 1 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 2 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 3 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 4 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 5 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 6 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 7 | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 8 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 9 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 10 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 11 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 12 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 13 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 14 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 15 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 16 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 17 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 18 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 19 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 20 | |||||
{&DDRC, &PINC, &PORTC, 5}, // C5 21 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 22 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 23 | |||||
{&DDRA, &PINA, &PORTA, 0}, // A0 24 | |||||
{&DDRA, &PINA, &PORTA, 1}, // A1 25 | |||||
{&DDRA, &PINA, &PORTA, 2}, // A2 26 | |||||
{&DDRA, &PINA, &PORTA, 3}, // A3 27 | |||||
{&DDRA, &PINA, &PORTA, 4}, // A4 28 | |||||
{&DDRA, &PINA, &PORTA, 5}, // A5 29 | |||||
{&DDRA, &PINA, &PORTA, 6}, // A6 30 | |||||
{&DDRA, &PINA, &PORTA, 7} // A7 31 | |||||
}; | |||||
#elif analogInputToDigitalPin(0) == 21 | |||||
// Bobuino Layout | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 0 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 1 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 2 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 3 | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 4 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 5 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 6 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 7 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 8 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 9 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 10 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 11 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 12 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 13 | |||||
{&DDRA, &PINA, &PORTA, 7}, // A7 14 | |||||
{&DDRA, &PINA, &PORTA, 6}, // A6 15 | |||||
{&DDRA, &PINA, &PORTA, 5}, // A5 16 | |||||
{&DDRA, &PINA, &PORTA, 4}, // A4 17 | |||||
{&DDRA, &PINA, &PORTA, 3}, // A3 18 | |||||
{&DDRA, &PINA, &PORTA, 2}, // A2 19 | |||||
{&DDRA, &PINA, &PORTA, 1}, // A1 20 | |||||
{&DDRA, &PINA, &PORTA, 0}, // A0 21 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 22 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 23 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 24 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 25 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 26 | |||||
{&DDRC, &PINC, &PORTC, 5}, // C5 27 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 28 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 29 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 30 | |||||
{&DDRD, &PIND, &PORTD, 7} // D7 31 | |||||
}; | |||||
#elif analogInputToDigitalPin(0) == 31 | |||||
// Standard Layout | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 0 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 1 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 2 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 3 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 4 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 5 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 6 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 7 | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 8 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 9 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 10 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 11 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 12 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 13 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 14 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 15 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 16 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 17 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 18 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 19 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 20 | |||||
{&DDRC, &PINC, &PORTC, 5}, // C5 21 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 22 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 23 | |||||
{&DDRA, &PINA, &PORTA, 7}, // A7 24 | |||||
{&DDRA, &PINA, &PORTA, 6}, // A6 25 | |||||
{&DDRA, &PINA, &PORTA, 5}, // A5 26 | |||||
{&DDRA, &PINA, &PORTA, 4}, // A4 27 | |||||
{&DDRA, &PINA, &PORTA, 3}, // A3 28 | |||||
{&DDRA, &PINA, &PORTA, 2}, // A2 29 | |||||
{&DDRA, &PINA, &PORTA, 1}, // A1 30 | |||||
{&DDRA, &PINA, &PORTA, 0} // A0 31 | |||||
}; | |||||
#else // VARIANT_MIGHTY | |||||
#error Undefined variant 1284, 644, 324, 64, 32 | |||||
#endif // VARIANT_MIGHTY | |||||
//------------------------------------------------------------------------------ | |||||
#elif defined(__AVR_ATmega32U4__) | |||||
#ifdef CORE_TEENSY | |||||
// Teensy 2.0 | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 0 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 1 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 2 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 3 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 4 | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 5 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 6 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 7 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 8 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 9 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 10 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 11 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 12 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 13 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 14 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 15 | |||||
{&DDRF, &PINF, &PORTF, 7}, // F7 16 | |||||
{&DDRF, &PINF, &PORTF, 6}, // F6 17 | |||||
{&DDRF, &PINF, &PORTF, 5}, // F5 18 | |||||
{&DDRF, &PINF, &PORTF, 4}, // F4 19 | |||||
{&DDRF, &PINF, &PORTF, 1}, // F1 20 | |||||
{&DDRF, &PINF, &PORTF, 0}, // F0 21 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 22 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 23 | |||||
{&DDRE, &PINE, &PORTE, 6} // E6 24 | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
#else // CORE_TEENSY | |||||
// Leonardo | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 0 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 1 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 2 | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 3 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 4 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 5 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 6 | |||||
{&DDRE, &PINE, &PORTE, 6}, // E6 7 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 8 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 9 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 10 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 11 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 12 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 13 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 14 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 15 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 16 | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 17 | |||||
{&DDRF, &PINF, &PORTF, 7}, // F7 18 | |||||
{&DDRF, &PINF, &PORTF, 6}, // F6 19 | |||||
{&DDRF, &PINF, &PORTF, 5}, // F5 20 | |||||
{&DDRF, &PINF, &PORTF, 4}, // F4 21 | |||||
{&DDRF, &PINF, &PORTF, 1}, // F1 22 | |||||
{&DDRF, &PINF, &PORTF, 0}, // F0 23 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 24 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 25 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 26 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 27 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 28 | |||||
{&DDRD, &PIND, &PORTD, 6} // D6 29 | |||||
}; | |||||
#endif // CORE_TEENSY | |||||
//------------------------------------------------------------------------------ | |||||
#elif defined(__AVR_AT90USB646__)\ | |||||
|| defined(__AVR_AT90USB1286__) | |||||
// Teensy++ 1.0 & 2.0 | |||||
static const pin_map_t pinMap[] = { | |||||
{&DDRD, &PIND, &PORTD, 0}, // D0 0 | |||||
{&DDRD, &PIND, &PORTD, 1}, // D1 1 | |||||
{&DDRD, &PIND, &PORTD, 2}, // D2 2 | |||||
{&DDRD, &PIND, &PORTD, 3}, // D3 3 | |||||
{&DDRD, &PIND, &PORTD, 4}, // D4 4 | |||||
{&DDRD, &PIND, &PORTD, 5}, // D5 5 | |||||
{&DDRD, &PIND, &PORTD, 6}, // D6 6 | |||||
{&DDRD, &PIND, &PORTD, 7}, // D7 7 | |||||
{&DDRE, &PINE, &PORTE, 0}, // E0 8 | |||||
{&DDRE, &PINE, &PORTE, 1}, // E1 9 | |||||
{&DDRC, &PINC, &PORTC, 0}, // C0 10 | |||||
{&DDRC, &PINC, &PORTC, 1}, // C1 11 | |||||
{&DDRC, &PINC, &PORTC, 2}, // C2 12 | |||||
{&DDRC, &PINC, &PORTC, 3}, // C3 13 | |||||
{&DDRC, &PINC, &PORTC, 4}, // C4 14 | |||||
{&DDRC, &PINC, &PORTC, 5}, // C5 15 | |||||
{&DDRC, &PINC, &PORTC, 6}, // C6 16 | |||||
{&DDRC, &PINC, &PORTC, 7}, // C7 17 | |||||
{&DDRE, &PINE, &PORTE, 6}, // E6 18 | |||||
{&DDRE, &PINE, &PORTE, 7}, // E7 19 | |||||
{&DDRB, &PINB, &PORTB, 0}, // B0 20 | |||||
{&DDRB, &PINB, &PORTB, 1}, // B1 21 | |||||
{&DDRB, &PINB, &PORTB, 2}, // B2 22 | |||||
{&DDRB, &PINB, &PORTB, 3}, // B3 23 | |||||
{&DDRB, &PINB, &PORTB, 4}, // B4 24 | |||||
{&DDRB, &PINB, &PORTB, 5}, // B5 25 | |||||
{&DDRB, &PINB, &PORTB, 6}, // B6 26 | |||||
{&DDRB, &PINB, &PORTB, 7}, // B7 27 | |||||
{&DDRA, &PINA, &PORTA, 0}, // A0 28 | |||||
{&DDRA, &PINA, &PORTA, 1}, // A1 29 | |||||
{&DDRA, &PINA, &PORTA, 2}, // A2 30 | |||||
{&DDRA, &PINA, &PORTA, 3}, // A3 31 | |||||
{&DDRA, &PINA, &PORTA, 4}, // A4 32 | |||||
{&DDRA, &PINA, &PORTA, 5}, // A5 33 | |||||
{&DDRA, &PINA, &PORTA, 6}, // A6 34 | |||||
{&DDRA, &PINA, &PORTA, 7}, // A7 35 | |||||
{&DDRE, &PINE, &PORTE, 4}, // E4 36 | |||||
{&DDRE, &PINE, &PORTE, 5}, // E5 37 | |||||
{&DDRF, &PINF, &PORTF, 0}, // F0 38 | |||||
{&DDRF, &PINF, &PORTF, 1}, // F1 39 | |||||
{&DDRF, &PINF, &PORTF, 2}, // F2 40 | |||||
{&DDRF, &PINF, &PORTF, 3}, // F3 41 | |||||
{&DDRF, &PINF, &PORTF, 4}, // F4 42 | |||||
{&DDRF, &PINF, &PORTF, 5}, // F5 43 | |||||
{&DDRF, &PINF, &PORTF, 6}, // F6 44 | |||||
{&DDRF, &PINF, &PORTF, 7} // F7 45 | |||||
}; | |||||
//------------------------------------------------------------------------------ | |||||
#else // CPU type | |||||
#error unknown CPU type | |||||
#endif // CPU type | |||||
// Include pin map for current board. | |||||
#include "boards/GpioPinMap.h" | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** count of pins */ | |||||
static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t); | |||||
//============================================================================== | |||||
/** generate bad pin number error */ | /** generate bad pin number error */ | ||||
void badPinNumber(void) | void badPinNumber(void) | ||||
__attribute__((error("Pin number is too large or not a constant"))); | |||||
__attribute__((error("Pin number is too large or not a constant"))); | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** Check for valid pin number | /** Check for valid pin number | ||||
* @param[in] pin Number of pin to be checked. | * @param[in] pin Number of pin to be checked. | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void badPinCheck(uint8_t pin) { | void badPinCheck(uint8_t pin) { | ||||
if (!__builtin_constant_p(pin) || pin >= digitalPinCount) { | |||||
badPinNumber(); | |||||
if (!__builtin_constant_p(pin) || pin >= NUM_DIGITAL_PINS) { | |||||
badPinNumber(); | |||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** fast write helper | |||||
/** DDR register address | |||||
* @param[in] pin Arduino pin number | |||||
* @return register address | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
volatile uint8_t* ddrReg(uint8_t pin) { | |||||
badPinCheck(pin); | |||||
return GpioPinMap[pin].ddr; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** Bit mask for pin | |||||
* @param[in] pin Arduino pin number | |||||
* @return mask | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
uint8_t pinMask(uint8_t pin) { | |||||
badPinCheck(pin); | |||||
return GpioPinMap[pin].mask; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** PIN register address | |||||
* @param[in] pin Arduino pin number | |||||
* @return register address | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
volatile uint8_t* pinReg(uint8_t pin) { | |||||
badPinCheck(pin); | |||||
return GpioPinMap[pin].pin; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** PORT register address | |||||
* @param[in] pin Arduino pin number | |||||
* @return register address | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
volatile uint8_t* portReg(uint8_t pin) { | |||||
badPinCheck(pin); | |||||
return GpioPinMap[pin].port; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** Fast write helper. | |||||
* @param[in] address I/O register address | * @param[in] address I/O register address | ||||
* @param[in] bit bit number to write | |||||
* @param[in] mask bit mask for pin | |||||
* @param[in] level value for bit | * @param[in] level value for bit | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) { | |||||
uint8_t oldSREG; | |||||
if (address > reinterpret_cast<uint8_t*>(0X5F)) { | |||||
oldSREG = SREG; | |||||
void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { | |||||
uint8_t s; | |||||
if (address > (uint8_t*)0X3F) { | |||||
s = SREG; | |||||
cli(); | cli(); | ||||
} | } | ||||
if (level) { | if (level) { | ||||
*address |= 1 << bit; | |||||
*address |= mask; | |||||
} else { | } else { | ||||
*address &= ~(1 << bit); | |||||
*address &= ~mask; | |||||
} | } | ||||
if (address > reinterpret_cast<uint8_t*>(0X5F)) { | |||||
SREG = oldSREG; | |||||
if (address > (uint8_t*)0X3F) { | |||||
SREG = s; | |||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** read pin value | |||||
/** Read pin value. | |||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* @return value read | * @return value read | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
bool fastDigitalRead(uint8_t pin) { | bool fastDigitalRead(uint8_t pin) { | ||||
badPinCheck(pin); | |||||
return (*pinMap[pin].pin >> pinMap[pin].bit) & 1; | |||||
return *pinReg(pin) & pinMask(pin); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** toggle a pin | |||||
/** Toggle a pin. | |||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* | * | ||||
* If the pin is in output mode toggle the pin level. | * If the pin is in output mode toggle the pin level. | ||||
* If the pin is in input mode toggle the state of the 20K pull-up. | |||||
* If the pin is in input mode toggle the state of the 20K pullup. | |||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastDigitalToggle(uint8_t pin) { | void fastDigitalToggle(uint8_t pin) { | ||||
badPinCheck(pin); | |||||
if (pinMap[pin].pin > reinterpret_cast<uint8_t*>(0X5F)) { | |||||
// must write bit to high address port | |||||
*pinMap[pin].pin = 1 << pinMap[pin].bit; | |||||
} else { | |||||
// will compile to sbi and PIN register will not be read. | |||||
*pinMap[pin].pin |= 1 << pinMap[pin].bit; | |||||
} | |||||
if (pinReg(pin) > (uint8_t*)0X3F) { | |||||
// must write bit to high address port | |||||
*pinReg(pin) = pinMask(pin); | |||||
} else { | |||||
// will compile to sbi and PIN register will not be read. | |||||
*pinReg(pin) |= pinMask(pin); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** Set pin value | |||||
/** Set pin value. | |||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* @param[in] level value to write | * @param[in] level value to write | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastDigitalWrite(uint8_t pin, bool level) { | void fastDigitalWrite(uint8_t pin, bool level) { | ||||
badPinCheck(pin); | |||||
fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level); | |||||
fastBitWriteSafe(portReg(pin), pinMask(pin), level); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** Write the DDR register. | |||||
* @param[in] pin Arduino pin number | |||||
* @param[in] level value to write | |||||
*/ | |||||
static inline __attribute__((always_inline)) | |||||
void fastDdrWrite(uint8_t pin, bool level) { | |||||
fastBitWriteSafe(ddrReg(pin), pinMask(pin), level); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** set pin mode | |||||
/** Set pin mode. | |||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* @param[in] mode if true set output mode else input mode | |||||
* @param[in] mode INPUT, OUTPUT, or INPUT_PULLUP. | |||||
* | * | ||||
* fastPinMode does not enable or disable the 20K pull-up for input mode. | |||||
* The internal pullup resistors will be enabled if mode is INPUT_PULLUP | |||||
* and disabled if the mode is INPUT. | |||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastPinMode(uint8_t pin, bool mode) { | |||||
badPinCheck(pin); | |||||
fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode); | |||||
void fastPinMode(uint8_t pin, uint8_t mode) { | |||||
fastDdrWrite(pin, mode == OUTPUT); | |||||
if (mode != OUTPUT) { | |||||
fastDigitalWrite(pin, mode == INPUT_PULLUP); | |||||
} | |||||
} | } | ||||
#endif // __arm__ | #endif // __arm__ | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** set pin configuration | /** set pin configuration | ||||
* @param[in] pin Arduino pin number | * @param[in] pin Arduino pin number | ||||
* @param[in] mode If true set output mode else input mode | |||||
* @param[in] mode mode INPUT or OUTPUT. | |||||
* @param[in] level If mode is output, set level high/low. | * @param[in] level If mode is output, set level high/low. | ||||
* If mode is input, enable or disable the pin's 20K pull-up. | |||||
* If mode is input, enable or disable the pin's 20K pullup. | |||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastPinConfig(uint8_t pin, bool mode, bool level) { | |||||
void fastPinConfig(uint8_t pin, uint8_t mode, bool level) { | |||||
fastPinMode(pin, mode); | fastPinMode(pin, mode); | ||||
fastDigitalWrite(pin, level); | fastDigitalWrite(pin, level); | ||||
} | } | ||||
/** Constructor */ | /** Constructor */ | ||||
DigitalPin() {} | DigitalPin() {} | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** Constructor | |||||
* @param[in] pinMode if true set output mode else input mode. | |||||
*/ | |||||
explicit DigitalPin(bool pinMode) { | |||||
mode(pinMode); | |||||
} | |||||
//---------------------------------------------------------------------------- | |||||
/** Constructor | |||||
* @param[in] mode If true set output mode else input mode | |||||
* @param[in] level If mode is output, set level high/low. | |||||
* If mode is input, enable or disable the pin's 20K pull-up. | |||||
*/ | |||||
DigitalPin(bool mode, bool level) { | |||||
config(mode, level); | |||||
} | |||||
//---------------------------------------------------------------------------- | |||||
/** Asignment operator | |||||
/** Asignment operator. | |||||
* @param[in] value If true set the pin's level high else set the | * @param[in] value If true set the pin's level high else set the | ||||
* pin's level low. | * pin's level low. | ||||
* | * | ||||
return *this; | return *this; | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** Parenthesis operator | |||||
/** Parenthesis operator. | |||||
* @return Pin's level | * @return Pin's level | ||||
*/ | */ | ||||
inline operator bool() const __attribute__((always_inline)) { | |||||
inline operator bool () const __attribute__((always_inline)) { | |||||
return read(); | return read(); | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** set pin configuration | |||||
* @param[in] mode If true set output mode else input mode | |||||
* @param[in] level If mode is output, set level high/low. If mode | |||||
* is input, enable or disable the pin's 20K pull-up. | |||||
/** Set pin configuration. | |||||
* @param[in] mode: INPUT or OUTPUT. | |||||
* @param[in] level If mode is OUTPUT, set level high/low. | |||||
* If mode is INPUT, enable or disable the pin's 20K pullup. | |||||
*/ | */ | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void config(bool mode, bool level) { | |||||
void config(uint8_t mode, bool level) { | |||||
fastPinConfig(PinNumber, mode, level); | fastPinConfig(PinNumber, mode, level); | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** | /** | ||||
* Set pin level high if output mode or enable 20K pull-up if input mode. | |||||
* Set pin level high if output mode or enable 20K pullup if input mode. | |||||
*/ | */ | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void high() { | |||||
write(true); | |||||
} | |||||
void high() {write(true);} | |||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** | /** | ||||
* Set pin level low if output mode or disable 20K pull-up if input mode. | |||||
* Set pin level low if output mode or disable 20K pullup if input mode. | |||||
*/ | */ | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void low() { | |||||
write(false); | |||||
} | |||||
void low() {write(false);} | |||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** | /** | ||||
* Set pin mode | |||||
* @param[in] pinMode if true set output mode else input mode. | |||||
* Set pin mode. | |||||
* @param[in] mode: INPUT, OUTPUT, or INPUT_PULLUP. | |||||
* | * | ||||
* mode() does not enable or disable the 20K pull-up for input mode. | |||||
* The internal pullup resistors will be enabled if mode is INPUT_PULLUP | |||||
* and disabled if the mode is INPUT. | |||||
*/ | */ | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void mode(bool pinMode) { | |||||
fastPinMode(PinNumber, pinMode); | |||||
void mode(uint8_t mode) { | |||||
fastPinMode(PinNumber, mode); | |||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** @return Pin's level */ | |||||
/** @return Pin's level. */ | |||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
bool read() const { | bool read() const { | ||||
return fastDigitalRead(PinNumber); | return fastDigitalRead(PinNumber); | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
/** toggle a pin | |||||
/** Toggle a pin. | |||||
* | * | ||||
* If the pin is in output mode toggle the pin's level. | * If the pin is in output mode toggle the pin's level. | ||||
* If the pin is in input mode toggle the state of the 20K pull-up. | |||||
* If the pin is in input mode toggle the state of the 20K pullup. | |||||
*/ | */ | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void toggle() { | void toggle() { | ||||
} | } | ||||
}; | }; | ||||
#endif // DigitalPin_h | #endif // DigitalPin_h | ||||
/** @} */ | |||||
/** @} */ |
/** attempt to write protected block zero */ | /** attempt to write protected block zero */ | ||||
uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used | uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used | ||||
/** card did not go ready for a multiple block write */ | /** card did not go ready for a multiple block write */ | ||||
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15; | |||||
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15; // Not used | |||||
/** card returned an error to a CMD13 status check after a write */ | /** card returned an error to a CMD13 status check after a write */ | ||||
uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16; | uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16; | ||||
/** timeout occurred during write programming */ | /** timeout occurred during write programming */ |
*/ | */ | ||||
#ifndef SdSpi_h | #ifndef SdSpi_h | ||||
#define SdSpi_h | #define SdSpi_h | ||||
#include <Arduino.h> | |||||
#include <SPI.h> | |||||
#include "SystemInclude.h" | |||||
#include "SdFatConfig.h" | #include "SdFatConfig.h" | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | /** | ||||
* \class SdSpiBase | * \class SdSpiBase | ||||
*/ | */ | ||||
class SdSpiBase { | class SdSpiBase { | ||||
public: | public: | ||||
/** Initialize the SPI bus */ | |||||
virtual void begin() = 0; | |||||
/** Initialize the SPI bus. | |||||
* | |||||
* \param[in] chipSelectPin SD card chip select pin. | |||||
*/ | |||||
virtual void begin(uint8_t chipSelectPin) = 0; | |||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. | ||||
* | * | ||||
* \param[in] divisor SCK clock divider relative to the system clock. | * \param[in] divisor SCK clock divider relative to the system clock. | ||||
class SdSpi { | class SdSpi { | ||||
#endif // SD_SPI_CONFIGURATION >= 3 | #endif // SD_SPI_CONFIGURATION >= 3 | ||||
public: | public: | ||||
/** Initialize the SPI bus */ | |||||
void begin(); | |||||
/** Initialize the SPI bus. | |||||
* | |||||
* \param[in] chipSelectPin SD card chip select pin. | |||||
*/ | |||||
void begin(uint8_t chipSelectPin); | |||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. | ||||
* | * | ||||
* \param[in] divisor SCK clock divider relative to the system clock. | * \param[in] divisor SCK clock divider relative to the system clock. | ||||
*/ | */ | ||||
void send(const uint8_t* buf, size_t n); | void send(const uint8_t* buf, size_t n); | ||||
/** \return true - uses SPI transactions */ | /** \return true - uses SPI transactions */ | ||||
#if IMPLEMENT_SPI_INTERFACE_SELECTION | |||||
void setSpiIf(uint8_t spiIf) { | |||||
m_spiIf = spiIf; | |||||
} | |||||
private: | |||||
uint8_t m_spiIf; | |||||
#endif // IMPLEMENT_SPI_INTERFACE_SELECTION | |||||
}; | }; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | /** | ||||
class SdSpiLib { | class SdSpiLib { | ||||
#endif // SD_SPI_CONFIGURATION >= 3 | #endif // SD_SPI_CONFIGURATION >= 3 | ||||
public: | public: | ||||
/** | |||||
* Initialize SPI pins. | |||||
/** Initialize the SPI bus. | |||||
* | |||||
* \param[in] chipSelectPin SD card chip select pin. | |||||
*/ | */ | ||||
void begin() { | |||||
void begin(uint8_t chipSelectPin) { | |||||
SPI.begin(); | SPI.begin(); | ||||
} | } | ||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. | ||||
* | * | ||||
* \return Zero for no error or nonzero error code. | * \return Zero for no error or nonzero error code. | ||||
*/ | */ | ||||
#if defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
uint8_t receive(uint8_t* buf, size_t n); | |||||
#else // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
uint8_t receive(uint8_t* buf, size_t n) { | uint8_t receive(uint8_t* buf, size_t n) { | ||||
for (size_t i = 0; i < n; i++) { | for (size_t i = 0; i < n; i++) { | ||||
buf[i] = SPI.transfer(0XFF); | buf[i] = SPI.transfer(0XFF); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
#endif // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
/** Send a byte. | /** Send a byte. | ||||
* | * | ||||
* \param[in] b Byte to send | * \param[in] b Byte to send | ||||
* \param[in] buf Buffer for data to be sent. | * \param[in] buf Buffer for data to be sent. | ||||
* \param[in] n Number of bytes to send. | * \param[in] n Number of bytes to send. | ||||
*/ | */ | ||||
#if defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
void send(const uint8_t* buf , size_t n); | |||||
#else // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
void send(const uint8_t* buf , size_t n) { | void send(const uint8_t* buf , size_t n) { | ||||
for (size_t i = 0; i < n; i++) { | for (size_t i = 0; i < n; i++) { | ||||
SPI.transfer(buf[i]); | SPI.transfer(buf[i]); | ||||
} | } | ||||
} | } | ||||
#endif // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
}; | }; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#if SD_SPI_CONFIGURATION > 1 || defined(DOXYGEN) | #if SD_SPI_CONFIGURATION > 1 || defined(DOXYGEN) | ||||
#ifdef ARDUINO | |||||
#include "SoftSPI.h" | #include "SoftSPI.h" | ||||
#elif defined(PLATFORM_ID) //Only defined if a Particle device | |||||
#include "SoftSPIParticle.h" | |||||
#endif // ARDUINO | |||||
/** | /** | ||||
* \class SdSpiSoft | * \class SdSpiSoft | ||||
* \brief Software SPI class for access to SD and SDHC flash memory cards. | * \brief Software SPI class for access to SD and SDHC flash memory cards. | ||||
template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin> | template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin> | ||||
class SdSpiSoft : public SdSpiBase { | class SdSpiSoft : public SdSpiBase { | ||||
public: | public: | ||||
/** | |||||
* initialize SPI pins | |||||
/** Initialize the SPI bus. | |||||
* | |||||
* \param[in] chipSelectPin SD card chip select pin. | |||||
*/ | */ | ||||
void begin() { | |||||
void begin(uint8_t chipSelectPin) { | |||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
m_spi.begin(); | m_spi.begin(); | ||||
} | } | ||||
/** | /** | ||||
// Use of in-line for AVR to save flash. | // Use of in-line for AVR to save flash. | ||||
#ifdef __AVR__ | #ifdef __AVR__ | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
inline void SdSpi::begin() { | |||||
inline void SdSpi::begin(uint8_t chipSelectPin) { | |||||
#ifdef __AVR_ATmega328P__ | #ifdef __AVR_ATmega328P__ | ||||
// Save a few bytes for 328 CPU - gcc optimizes single bit '|' to sbi. | // Save a few bytes for 328 CPU - gcc optimizes single bit '|' to sbi. | ||||
PORTB |= 1 << 2; // SS high | PORTB |= 1 << 2; // SS high | ||||
pinMode(MOSI, OUTPUT); | pinMode(MOSI, OUTPUT); | ||||
pinMode(SCK, OUTPUT); | pinMode(SCK, OUTPUT); | ||||
#endif // __AVR_ATmega328P__ | #endif // __AVR_ATmega328P__ | ||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
inline void SdSpi::beginTransaction(uint8_t divisor) { | inline void SdSpi::beginTransaction(uint8_t divisor) { |
// debug trace macro | // debug trace macro | ||||
#define SD_TRACE(m, b) | #define SD_TRACE(m, b) | ||||
// #define SD_TRACE(m, b) Serial.print(m);Serial.println(b); | // #define SD_TRACE(m, b) Serial.print(m);Serial.println(b); | ||||
#define SD_CS_DBG(m) | |||||
// #define SD_CS_DBG(m) Serial.println(F(m)); | |||||
//============================================================================== | //============================================================================== | ||||
#if USE_SD_CRC | #if USE_SD_CRC | ||||
// CRC functions | // CRC functions | ||||
m_spi = spi; | m_spi = spi; | ||||
m_chipSelectPin = chipSelectPin; | m_chipSelectPin = chipSelectPin; | ||||
// 16-bit init start time allows over a minute | // 16-bit init start time allows over a minute | ||||
uint16_t t0 = (uint16_t)millis(); | |||||
unsigned t0 = (unsigned)millis(); | |||||
uint32_t arg; | uint32_t arg; | ||||
pinMode(m_chipSelectPin, OUTPUT); | |||||
digitalWrite(m_chipSelectPin, HIGH); | |||||
spiBegin(); | |||||
// initialize SPI bus and chip select pin. | |||||
spiBegin(m_chipSelectPin); | |||||
// set SCK rate for initialization commands | |||||
// set SCK rate for initialization commands. | |||||
m_sckDivisor = SPI_SCK_INIT_DIVISOR; | m_sckDivisor = SPI_SCK_INIT_DIVISOR; | ||||
spiBeginTransaction(m_sckDivisor); | spiBeginTransaction(m_sckDivisor); | ||||
spiEndTransaction(); | spiEndTransaction(); | ||||
// command to go idle in SPI mode | // command to go idle in SPI mode | ||||
while (cardCommand(CMD0, 0) != R1_IDLE_STATE) { | while (cardCommand(CMD0, 0) != R1_IDLE_STATE) { | ||||
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
if (((unsigned)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
error(SD_CARD_ERROR_CMD0); | error(SD_CARD_ERROR_CMD0); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
type(SD_CARD_TYPE_SD2); | type(SD_CARD_TYPE_SD2); | ||||
break; | break; | ||||
} | } | ||||
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
if (((unsigned)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
error(SD_CARD_ERROR_CMD8); | error(SD_CARD_ERROR_CMD8); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
while (cardAcmd(ACMD41, arg) != R1_READY_STATE) { | while (cardAcmd(ACMD41, arg) != R1_READY_STATE) { | ||||
// check for timeout | // check for timeout | ||||
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
if (((unsigned)millis() - t0) > SD_INIT_TIMEOUT) { | |||||
error(SD_CARD_ERROR_ACMD41); | error(SD_CARD_ERROR_ACMD41); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
// send command and return error code. Return zero for OK | // send command and return error code. Return zero for OK | ||||
uint8_t SdSpiCard::cardCommand(uint8_t cmd, uint32_t arg) { | uint8_t SdSpiCard::cardCommand(uint8_t cmd, uint32_t arg) { | ||||
// select card | // select card | ||||
chipSelectLow(); | |||||
if (!m_selected) { | |||||
chipSelectLow(); | |||||
} | |||||
// wait if busy | // wait if busy | ||||
waitNotBusy(SD_WRITE_TIMEOUT); | waitNotBusy(SD_WRITE_TIMEOUT); | ||||
#if USE_SD_CRC | #if USE_SD_CRC | ||||
// form message | // form message | ||||
uint8_t d[6] = {cmd | 0X40, pa[3], pa[2], pa[1], pa[0]}; | |||||
uint8_t d[6] = {cmd , pa[3], pa[2], pa[1], pa[0]}; | |||||
d[0] |= 0X40; | |||||
// add crc | // add crc | ||||
d[5] = CRC7(d, 5); | d[5] = CRC7(d, 5); | ||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdSpiCard::spiYield() { | |||||
#if ENABLE_SPI_TRANSACTIONS && ENABLE_SPI_YIELD | |||||
chipSelectHigh(); | |||||
chipSelectLow(); | |||||
#endif // ENABLE_SPI_TRANSACTIONS && ENABLE_SPI_YIELD | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdSpiCard::chipSelectHigh() { | void SdSpiCard::chipSelectHigh() { | ||||
if (!m_selected) { | |||||
SD_CS_DBG("chipSelectHigh error"); | |||||
return; | |||||
} | |||||
digitalWrite(m_chipSelectPin, HIGH); | digitalWrite(m_chipSelectPin, HIGH); | ||||
// insure MISO goes high impedance | // insure MISO goes high impedance | ||||
spiSend(0XFF); | spiSend(0XFF); | ||||
spiEndTransaction(); | spiEndTransaction(); | ||||
m_selected = false; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdSpiCard::chipSelectLow() { | void SdSpiCard::chipSelectLow() { | ||||
if (m_selected) { | |||||
SD_CS_DBG("chipSelectLow error"); | |||||
return; | |||||
} | |||||
spiBeginTransaction(m_sckDivisor); | spiBeginTransaction(m_sckDivisor); | ||||
digitalWrite(m_chipSelectPin, LOW); | digitalWrite(m_chipSelectPin, LOW); | ||||
m_selected = true; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::erase(uint32_t firstBlock, uint32_t lastBlock) { | bool SdSpiCard::erase(uint32_t firstBlock, uint32_t lastBlock) { | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::isBusy() { | bool SdSpiCard::isBusy() { | ||||
bool rtn; | |||||
chipSelectLow(); | |||||
for (uint8_t i = 0; i < 8; i++) { | for (uint8_t i = 0; i < 8; i++) { | ||||
rtn = spiReceive() != 0XFF; | |||||
if (!rtn) { | |||||
break; | |||||
if (0XFF == spiReceive()) { | |||||
return false; | |||||
} | } | ||||
} | } | ||||
chipSelectHigh(); | |||||
return rtn; | |||||
return true; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | ||||
error(SD_CARD_ERROR_CMD17); | error(SD_CARD_ERROR_CMD17); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
return readData(dst, 512); | |||||
if (!readData(dst, 512)) { | |||||
goto fail; | |||||
} | |||||
chipSelectHigh(); | |||||
return true; | |||||
fail: | fail: | ||||
chipSelectHigh(); | chipSelectHigh(); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::readData(uint8_t *dst) { | bool SdSpiCard::readData(uint8_t *dst) { | ||||
chipSelectLow(); | |||||
return readData(dst, 512); | return readData(dst, 512); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
uint16_t crc; | uint16_t crc; | ||||
#endif // USE_SD_CRC | #endif // USE_SD_CRC | ||||
// wait for start block token | // wait for start block token | ||||
uint16_t t0 = millis(); | |||||
unsigned t0 = millis(); | |||||
while ((m_status = spiReceive()) == 0XFF) { | while ((m_status = spiReceive()) == 0XFF) { | ||||
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) { | |||||
if (((unsigned)millis() - t0) > SD_READ_TIMEOUT) { | |||||
error(SD_CARD_ERROR_READ_TIMEOUT); | error(SD_CARD_ERROR_READ_TIMEOUT); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
spiReceive(); | spiReceive(); | ||||
spiReceive(); | spiReceive(); | ||||
#endif // USE_SD_CRC | #endif // USE_SD_CRC | ||||
chipSelectHigh(); | |||||
return true; | return true; | ||||
fail: | fail: | ||||
error(SD_CARD_ERROR_CMD18); | error(SD_CARD_ERROR_CMD18); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
chipSelectHigh(); | |||||
return true; | return true; | ||||
fail: | fail: | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// wait for card to go not busy | // wait for card to go not busy | ||||
bool SdSpiCard::waitNotBusy(uint16_t timeoutMillis) { | bool SdSpiCard::waitNotBusy(uint16_t timeoutMillis) { | ||||
uint16_t t0 = millis(); | |||||
unsigned t0 = millis(); | |||||
while (spiReceive() != 0XFF) { | while (spiReceive() != 0XFF) { | ||||
if (((uint16_t)millis() - t0) >= timeoutMillis) { | |||||
if (((unsigned)millis() - t0) >= timeoutMillis) { | |||||
goto fail; | goto fail; | ||||
} | } | ||||
spiYield(); | |||||
} | } | ||||
return true; | return true; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::writeBlocks(uint32_t block, const uint8_t* src, size_t count) { | bool SdSpiCard::writeBlocks(uint32_t block, const uint8_t* src, size_t count) { | ||||
if (!writeStart(block, count)) { | if (!writeStart(block, count)) { | ||||
return false; | |||||
goto fail; | |||||
} | } | ||||
for (size_t b = 0; b < count; b++, src += 512) { | for (size_t b = 0; b < count; b++, src += 512) { | ||||
if (!writeData(src)) { | if (!writeData(src)) { | ||||
return false; | |||||
goto fail; | |||||
} | } | ||||
} | } | ||||
return writeStop(); | return writeStop(); | ||||
fail: | |||||
chipSelectHigh(); | |||||
return false; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::writeData(const uint8_t* src) { | bool SdSpiCard::writeData(const uint8_t* src) { | ||||
chipSelectLow(); | |||||
// wait for previous write to finish | // wait for previous write to finish | ||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | ||||
error(SD_CARD_ERROR_WRITE_TIMEOUT); | |||||
goto fail; | goto fail; | ||||
} | } | ||||
if (!writeData(WRITE_MULTIPLE_TOKEN, src)) { | if (!writeData(WRITE_MULTIPLE_TOKEN, src)) { | ||||
goto fail; | goto fail; | ||||
} | } | ||||
chipSelectHigh(); | |||||
return true; | return true; | ||||
fail: | fail: | ||||
error(SD_CARD_ERROR_WRITE_MULTIPLE); | |||||
chipSelectHigh(); | chipSelectHigh(); | ||||
return false; | return false; | ||||
} | } | ||||
error(SD_CARD_ERROR_CMD25); | error(SD_CARD_ERROR_CMD25); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
chipSelectHigh(); | |||||
return true; | return true; | ||||
fail: | fail: | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::writeStop() { | bool SdSpiCard::writeStop() { | ||||
chipSelectLow(); | |||||
if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | ||||
goto fail; | goto fail; | ||||
} | } |
* \file | * \file | ||||
* \brief SdSpiCard class for V2 SD/SDHC cards | * \brief SdSpiCard class for V2 SD/SDHC cards | ||||
*/ | */ | ||||
#include <Arduino.h> | |||||
#include "SystemInclude.h" | |||||
#include "SdFatConfig.h" | #include "SdFatConfig.h" | ||||
#include "SdInfo.h" | #include "SdInfo.h" | ||||
#include "SdSpi.h" | #include "SdSpi.h" | ||||
typedef SdSpiBase m_spi_t; | typedef SdSpiBase m_spi_t; | ||||
#endif // SD_SPI_CONFIGURATION < 3 | #endif // SD_SPI_CONFIGURATION < 3 | ||||
/** Construct an instance of SdSpiCard. */ | /** Construct an instance of SdSpiCard. */ | ||||
SdSpiCard() : m_errorCode(SD_CARD_ERROR_INIT_NOT_CALLED), m_type(0) {} | |||||
SdSpiCard() : m_selected(false), m_errorCode(SD_CARD_ERROR_INIT_NOT_CALLED), m_type(0) {} | |||||
/** Initialize the SD card. | /** Initialize the SD card. | ||||
* \param[in] spi SPI object. | * \param[in] spi SPI object. | ||||
* \param[in] chipSelectPin SD chip select pin. | * \param[in] chipSelectPin SD chip select pin. | ||||
* or zero if an error occurs. | * or zero if an error occurs. | ||||
*/ | */ | ||||
uint32_t cardSize(); | uint32_t cardSize(); | ||||
/** Set the SD chip select pin high, send a dummy byte, and call SPI endTransaction. | |||||
* | |||||
* This function should only be called by programs doing raw I/O to the SD. | |||||
*/ | |||||
void chipSelectHigh(); | |||||
/** Set the SD chip select pin low and call SPI beginTransaction. | |||||
* | |||||
* This function should only be called by programs doing raw I/O to the SD. | |||||
*/ | |||||
void chipSelectLow(); | |||||
/** Erase a range of blocks. | /** Erase a range of blocks. | ||||
* | * | ||||
* \param[in] firstBlock The address of the first block in the range. | * \param[in] firstBlock The address of the first block in the range. | ||||
uint8_t sckDivisor() { | uint8_t sckDivisor() { | ||||
return m_sckDivisor; | return m_sckDivisor; | ||||
} | } | ||||
/** \return the SD chip select status, true if slected else false. */ | |||||
bool selected() {return m_selected;} | |||||
/** Return the card type: SD V1, SD V2 or SDHC | /** Return the card type: SD V1, SD V2 or SDHC | ||||
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. | * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. | ||||
*/ | */ | ||||
uint8_t cardCommand(uint8_t cmd, uint32_t arg); | uint8_t cardCommand(uint8_t cmd, uint32_t arg); | ||||
bool readData(uint8_t* dst, size_t count); | bool readData(uint8_t* dst, size_t count); | ||||
bool readRegister(uint8_t cmd, void* buf); | bool readRegister(uint8_t cmd, void* buf); | ||||
void chipSelectHigh(); | |||||
void chipSelectLow(); | |||||
void spiYield(); | |||||
void type(uint8_t value) { | void type(uint8_t value) { | ||||
m_type = value; | m_type = value; | ||||
} | } | ||||
bool waitNotBusy(uint16_t timeoutMillis); | bool waitNotBusy(uint16_t timeoutMillis); | ||||
bool writeData(uint8_t token, const uint8_t* src); | bool writeData(uint8_t token, const uint8_t* src); | ||||
void spiBegin() { | |||||
m_spi->begin(); | |||||
void spiBegin(uint8_t chipSelectPin) { | |||||
m_spi->begin(chipSelectPin); | |||||
} | } | ||||
void spiBeginTransaction(uint8_t spiDivisor) { | void spiBeginTransaction(uint8_t spiDivisor) { | ||||
m_spi->beginTransaction(spiDivisor); | m_spi->beginTransaction(spiDivisor); | ||||
m_spi->send(buf, n); | m_spi->send(buf, n); | ||||
} | } | ||||
m_spi_t* m_spi; | m_spi_t* m_spi; | ||||
bool m_selected; | |||||
uint8_t m_chipSelectPin; | uint8_t m_chipSelectPin; | ||||
uint8_t m_errorCode; | uint8_t m_errorCode; | ||||
uint8_t m_sckDivisor; | uint8_t m_sckDivisor; |
/* Arduino SdFat Library | |||||
* Copyright (C) 2012 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/>. | |||||
*/ | |||||
#include "SdSpi.h" | |||||
#if defined(PLATFORM_ID) | |||||
static uint32_t bugDelay = 0; // fix for SPI DMA bug. | |||||
static volatile bool SPI_DMA_TransferCompleted = false; | |||||
//static uint8_t m_spiIf = 1; | |||||
static SPIClass* const spiPtr[] = { | |||||
&SPI | |||||
#if Wiring_SPI1 | |||||
,&SPI1 | |||||
#if Wiring_SPI2 | |||||
,&SPI2 | |||||
#endif // Wiring_SPI2 | |||||
#endif // Wiring_SPI1 | |||||
}; | |||||
#if SPI_INTERFACE_COUNT == 1 | |||||
const uint8_t m_spiIf = 0; | |||||
#endif | |||||
//----------------------------------------------------------------------------- | |||||
void SD_SPI_DMA_TransferComplete_Callback(void) { | |||||
SPI_DMA_TransferCompleted = true; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdSpi::begin(uint8_t chipSelectPin) { | |||||
spiPtr[m_spiIf]->begin(chipSelectPin); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdSpi::beginTransaction(uint8_t divisor) { | |||||
spiPtr[m_spiIf]->setBitOrder(MSBFIRST); | |||||
spiPtr[m_spiIf]->setDataMode(SPI_MODE0); | |||||
#ifndef SPI_CLOCK_DIV128 | |||||
spiPtr[m_spiIf]->setClockDivider(divisor); | |||||
#else // SPI_CLOCK_DIV128 | |||||
int v; | |||||
if (divisor <= 2) { | |||||
v = SPI_CLOCK_DIV2; | |||||
} else if (divisor <= 4) { | |||||
v = SPI_CLOCK_DIV4; | |||||
} else if (divisor <= 8) { | |||||
v = SPI_CLOCK_DIV8; | |||||
} else if (divisor <= 16) { | |||||
v = SPI_CLOCK_DIV16; | |||||
} else if (divisor <= 32) { | |||||
v = SPI_CLOCK_DIV32; | |||||
} else if (divisor <= 64) { | |||||
v = SPI_CLOCK_DIV64; | |||||
} else { | |||||
v = SPI_CLOCK_DIV128; | |||||
} | |||||
spiPtr[m_spiIf]->setClockDivider(v); | |||||
#endif // SPI_CLOCK_DIV128 | |||||
// delay for SPI transfer done callback too soon bug. | |||||
bugDelay = 24*divisor*(1 + m_spiIf)/60; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void SdSpi::endTransaction() { | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** SPI receive a byte */ | |||||
uint8_t SdSpi::receive() { | |||||
return spiPtr[m_spiIf]->transfer(0xFF); | |||||
} | |||||
//----------------------------------------------------------------------------- | |||||
uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||||
SPI_DMA_TransferCompleted = false; | |||||
spiPtr[m_spiIf]->transfer(0, buf, n, SD_SPI_DMA_TransferComplete_Callback); | |||||
while(!SPI_DMA_TransferCompleted); | |||||
if (bugDelay) { | |||||
delayMicroseconds(bugDelay); | |||||
} | |||||
return 0; | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
/** SPI send a byte */ | |||||
void SdSpi::send(uint8_t b) { | |||||
spiPtr[m_spiIf]->transfer(b); | |||||
} | |||||
//----------------------------------------------------------------------------- | |||||
void SdSpi::send(const uint8_t* buf , size_t n) { | |||||
SPI_DMA_TransferCompleted = false; | |||||
spiPtr[m_spiIf]->transfer((void *)buf, 0, n, SD_SPI_DMA_TransferComplete_Callback); | |||||
while(!SPI_DMA_TransferCompleted); | |||||
if (bugDelay) { | |||||
delayMicroseconds(bugDelay); | |||||
} | |||||
} | |||||
#endif //defined(PLATFORM_ID) |
return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true; | return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdSpi::begin() { | |||||
void SdSpi::begin(uint8_t chipSelectPin) { | |||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
PIO_Configure( | PIO_Configure( | ||||
g_APinDescription[PIN_SPI_MOSI].pPort, | g_APinDescription[PIN_SPI_MOSI].pPort, | ||||
g_APinDescription[PIN_SPI_MOSI].ulPinType, | g_APinDescription[PIN_SPI_MOSI].ulPinType, |
dma_enable(DMA1, ul_num); | dma_enable(DMA1, ul_num); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdSpi::begin() { | |||||
void SdSpi::begin(uint8_t chipSelectPin) { | |||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
SPI.begin(); | SPI.begin(); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
/** | /** | ||||
* initialize SPI pins | * initialize SPI pins | ||||
*/ | */ | ||||
void SdSpi::begin() { | |||||
void SdSpi::begin(uint8_t chipSelectPin) { | |||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
SIM_SCGC6 |= SIM_SCGC6_SPI0; | SIM_SCGC6 |= SIM_SCGC6_SPI0; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** | /** | ||||
* Initialize SPI pins. | * Initialize SPI pins. | ||||
*/ | */ | ||||
void SdSpi::begin() { | |||||
void SdSpi::begin(uint8_t chipSelectPin) { | |||||
SPI.begin(); | SPI.begin(); | ||||
} | } | ||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. |
* <http://www.gnu.org/licenses/>. | * <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
/** | /** | ||||
* @file | |||||
* @file | |||||
* @brief Software SPI. | * @brief Software SPI. | ||||
* | * | ||||
* @defgroup softSPI Software SPI | * @defgroup softSPI Software SPI | ||||
private: | private: | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
bool MODE_CPHA(uint8_t mode) { | |||||
return (mode & 1) != 0; | |||||
} | |||||
bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} | |||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
bool MODE_CPOL(uint8_t mode) { | |||||
return (mode & 2) != 0; | |||||
} | |||||
bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} | |||||
inline __attribute__((always_inline)) | inline __attribute__((always_inline)) | ||||
void receiveBit(uint8_t bit, uint8_t* data) { | void receiveBit(uint8_t bit, uint8_t* data) { | ||||
if (MODE_CPHA(Mode)) { | if (MODE_CPHA(Mode)) { | ||||
nop; | nop; | ||||
nop; | nop; | ||||
fastDigitalWrite(SckPin, | fastDigitalWrite(SckPin, | ||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
if (fastDigitalRead(MisoPin)) { | |||||
*data |= 1 << bit; | |||||
} | |||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
if (fastDigitalRead(MisoPin)) *data |= 1 << bit; | |||||
if (!MODE_CPHA(Mode)) { | if (!MODE_CPHA(Mode)) { | ||||
fastDigitalWrite(SckPin, MODE_CPOL(Mode)); | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); | ||||
} | } | ||||
} | } | ||||
fastDigitalWrite(MosiPin, data & (1 << bit)); | fastDigitalWrite(MosiPin, data & (1 << bit)); | ||||
fastDigitalWrite(SckPin, | fastDigitalWrite(SckPin, | ||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
nop; | nop; | ||||
nop; | nop; | ||||
if (!MODE_CPHA(Mode)) { | if (!MODE_CPHA(Mode)) { | ||||
} | } | ||||
fastDigitalWrite(MosiPin, txData & (1 << bit)); | fastDigitalWrite(MosiPin, txData & (1 << bit)); | ||||
fastDigitalWrite(SckPin, | fastDigitalWrite(SckPin, | ||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
if (fastDigitalRead(MisoPin)) { | |||||
*rxData |= 1 << bit; | |||||
} | |||||
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); | |||||
if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; | |||||
if (!MODE_CPHA(Mode)) { | if (!MODE_CPHA(Mode)) { | ||||
fastDigitalWrite(SckPin, MODE_CPOL(Mode)); | fastDigitalWrite(SckPin, MODE_CPOL(Mode)); | ||||
} | } |
#ifndef AvrDevelopersGpioPinMap_h | |||||
#define AvrDevelopersGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(B, 0), // D0 | |||||
GPIO_PIN(B, 1), // D1 | |||||
GPIO_PIN(B, 2), // D2 | |||||
GPIO_PIN(B, 3), // D3 | |||||
GPIO_PIN(B, 4), // D4 | |||||
GPIO_PIN(B, 5), // D5 | |||||
GPIO_PIN(B, 6), // D6 | |||||
GPIO_PIN(B, 7), // D7 | |||||
GPIO_PIN(D, 0), // D8 | |||||
GPIO_PIN(D, 1), // D9 | |||||
GPIO_PIN(D, 2), // D10 | |||||
GPIO_PIN(D, 3), // D11 | |||||
GPIO_PIN(D, 4), // D12 | |||||
GPIO_PIN(D, 5), // D13 | |||||
GPIO_PIN(D, 6), // D14 | |||||
GPIO_PIN(D, 7), // D15 | |||||
GPIO_PIN(C, 0), // D16 | |||||
GPIO_PIN(C, 1), // D17 | |||||
GPIO_PIN(C, 2), // D18 | |||||
GPIO_PIN(C, 3), // D19 | |||||
GPIO_PIN(C, 4), // D20 | |||||
GPIO_PIN(C, 5), // D21 | |||||
GPIO_PIN(C, 6), // D22 | |||||
GPIO_PIN(C, 7), // D23 | |||||
GPIO_PIN(A, 7), // D24 | |||||
GPIO_PIN(A, 6), // D25 | |||||
GPIO_PIN(A, 5), // D26 | |||||
GPIO_PIN(A, 4), // D27 | |||||
GPIO_PIN(A, 3), // D28 | |||||
GPIO_PIN(A, 2), // D29 | |||||
GPIO_PIN(A, 1), // D30 | |||||
GPIO_PIN(A, 0) // D31 | |||||
}; | |||||
#endif // AvrDevelopersGpioPinMap_h |
#ifndef BobuinoGpioPinMap_h | |||||
#define BobuinoGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(B, 0), // D0 | |||||
GPIO_PIN(B, 1), // D1 | |||||
GPIO_PIN(B, 2), // D2 | |||||
GPIO_PIN(B, 3), // D3 | |||||
GPIO_PIN(B, 4), // D4 | |||||
GPIO_PIN(B, 5), // D5 | |||||
GPIO_PIN(B, 6), // D6 | |||||
GPIO_PIN(B, 7), // D7 | |||||
GPIO_PIN(D, 0), // D8 | |||||
GPIO_PIN(D, 1), // D9 | |||||
GPIO_PIN(D, 2), // D10 | |||||
GPIO_PIN(D, 3), // D11 | |||||
GPIO_PIN(D, 4), // D12 | |||||
GPIO_PIN(D, 5), // D13 | |||||
GPIO_PIN(D, 6), // D14 | |||||
GPIO_PIN(D, 7), // D15 | |||||
GPIO_PIN(C, 0), // D16 | |||||
GPIO_PIN(C, 1), // D17 | |||||
GPIO_PIN(C, 2), // D18 | |||||
GPIO_PIN(C, 3), // D19 | |||||
GPIO_PIN(C, 4), // D20 | |||||
GPIO_PIN(C, 5), // D21 | |||||
GPIO_PIN(C, 6), // D22 | |||||
GPIO_PIN(C, 7), // D23 | |||||
GPIO_PIN(A, 0), // D24 | |||||
GPIO_PIN(A, 1), // D25 | |||||
GPIO_PIN(A, 2), // D26 | |||||
GPIO_PIN(A, 3), // D27 | |||||
GPIO_PIN(A, 4), // D28 | |||||
GPIO_PIN(A, 5), // D29 | |||||
GPIO_PIN(A, 6), // D30 | |||||
GPIO_PIN(A, 7) // D31 | |||||
}; | |||||
#endif // BobuinoGpioPinMap_h |
#ifndef GpioPinMap_h | |||||
#define GpioPinMap_h | |||||
#if defined(__AVR_ATmega168__)\ | |||||
||defined(__AVR_ATmega168P__)\ | |||||
||defined(__AVR_ATmega328P__) | |||||
// 168 and 328 Arduinos | |||||
#include "UnoGpioPinMap.h" | |||||
#elif defined(__AVR_ATmega1280__)\ | |||||
|| defined(__AVR_ATmega2560__) | |||||
// Mega ADK | |||||
#include "MegaGpioPinMap.h" | |||||
#elif defined(__AVR_ATmega32U4__) | |||||
#ifdef CORE_TEENSY | |||||
#include "Teensy2GpioPinMap.h" | |||||
#else // CORE_TEENSY | |||||
// Leonardo or Yun | |||||
#include "LeonardoGpioPinMap.h" | |||||
#endif // CORE_TEENSY | |||||
#elif defined(__AVR_AT90USB646__)\ | |||||
|| defined(__AVR_AT90USB1286__) | |||||
// Teensy++ 1.0 & 2.0 | |||||
#include "Teensy2ppGpioPinMap.h" | |||||
#elif defined(__AVR_ATmega1284P__)\ | |||||
|| defined(__AVR_ATmega1284__)\ | |||||
|| defined(__AVR_ATmega644P__)\ | |||||
|| defined(__AVR_ATmega644__)\ | |||||
|| defined(__AVR_ATmega64__)\ | |||||
|| defined(__AVR_ATmega32__)\ | |||||
|| defined(__AVR_ATmega324__)\ | |||||
|| defined(__AVR_ATmega16__) | |||||
#ifdef ARDUINO_1284P_AVR_DEVELOPERS | |||||
#include "AvrDevelopersGpioPinMap.h" | |||||
#elif defined(ARDUINO_1284P_BOBUINO) | |||||
#include "BobuinoGpioPinMap.h" | |||||
#elif defined(ARDUINO_1284P_SLEEPINGBEAUTY) | |||||
#include "SleepingBeautyGpioPinMap.h" | |||||
#elif defined(ARDUINO_1284P_STANDARD) | |||||
#include "Standard1284GpioPinMap.h" | |||||
#else // ARDUINO_1284P_SLEEPINGBEAUTY | |||||
#error Undefined variant 1284, 644, 324 | |||||
#endif // ARDUINO_1284P_SLEEPINGBEAUTY | |||||
#else // 1284P, 1284, 644 | |||||
#error Unknown board type. | |||||
#endif // end all boards | |||||
#endif // GpioPinMap_h |
#ifndef LeonardoGpioPinMap_h | |||||
#define LeonardoGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(D, 2), // D0 | |||||
GPIO_PIN(D, 3), // D1 | |||||
GPIO_PIN(D, 1), // D2 | |||||
GPIO_PIN(D, 0), // D3 | |||||
GPIO_PIN(D, 4), // D4 | |||||
GPIO_PIN(C, 6), // D5 | |||||
GPIO_PIN(D, 7), // D6 | |||||
GPIO_PIN(E, 6), // D7 | |||||
GPIO_PIN(B, 4), // D8 | |||||
GPIO_PIN(B, 5), // D9 | |||||
GPIO_PIN(B, 6), // D10 | |||||
GPIO_PIN(B, 7), // D11 | |||||
GPIO_PIN(D, 6), // D12 | |||||
GPIO_PIN(C, 7), // D13 | |||||
GPIO_PIN(B, 3), // D14 | |||||
GPIO_PIN(B, 1), // D15 | |||||
GPIO_PIN(B, 2), // D16 | |||||
GPIO_PIN(B, 0), // D17 | |||||
GPIO_PIN(F, 7), // D18 | |||||
GPIO_PIN(F, 6), // D19 | |||||
GPIO_PIN(F, 5), // D20 | |||||
GPIO_PIN(F, 4), // D21 | |||||
GPIO_PIN(F, 1), // D22 | |||||
GPIO_PIN(F, 0), // D23 | |||||
GPIO_PIN(D, 4), // D24 | |||||
GPIO_PIN(D, 7), // D25 | |||||
GPIO_PIN(B, 4), // D26 | |||||
GPIO_PIN(B, 5), // D27 | |||||
GPIO_PIN(B, 6), // D28 | |||||
GPIO_PIN(D, 6) // D29 | |||||
}; | |||||
#endif // LeonardoGpioPinMap_h |
#ifndef MegaGpioPinMap_h | |||||
#define MegaGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(E, 0), // D0 | |||||
GPIO_PIN(E, 1), // D1 | |||||
GPIO_PIN(E, 4), // D2 | |||||
GPIO_PIN(E, 5), // D3 | |||||
GPIO_PIN(G, 5), // D4 | |||||
GPIO_PIN(E, 3), // D5 | |||||
GPIO_PIN(H, 3), // D6 | |||||
GPIO_PIN(H, 4), // D7 | |||||
GPIO_PIN(H, 5), // D8 | |||||
GPIO_PIN(H, 6), // D9 | |||||
GPIO_PIN(B, 4), // D10 | |||||
GPIO_PIN(B, 5), // D11 | |||||
GPIO_PIN(B, 6), // D12 | |||||
GPIO_PIN(B, 7), // D13 | |||||
GPIO_PIN(J, 1), // D14 | |||||
GPIO_PIN(J, 0), // D15 | |||||
GPIO_PIN(H, 1), // D16 | |||||
GPIO_PIN(H, 0), // D17 | |||||
GPIO_PIN(D, 3), // D18 | |||||
GPIO_PIN(D, 2), // D19 | |||||
GPIO_PIN(D, 1), // D20 | |||||
GPIO_PIN(D, 0), // D21 | |||||
GPIO_PIN(A, 0), // D22 | |||||
GPIO_PIN(A, 1), // D23 | |||||
GPIO_PIN(A, 2), // D24 | |||||
GPIO_PIN(A, 3), // D25 | |||||
GPIO_PIN(A, 4), // D26 | |||||
GPIO_PIN(A, 5), // D27 | |||||
GPIO_PIN(A, 6), // D28 | |||||
GPIO_PIN(A, 7), // D29 | |||||
GPIO_PIN(C, 7), // D30 | |||||
GPIO_PIN(C, 6), // D31 | |||||
GPIO_PIN(C, 5), // D32 | |||||
GPIO_PIN(C, 4), // D33 | |||||
GPIO_PIN(C, 3), // D34 | |||||
GPIO_PIN(C, 2), // D35 | |||||
GPIO_PIN(C, 1), // D36 | |||||
GPIO_PIN(C, 0), // D37 | |||||
GPIO_PIN(D, 7), // D38 | |||||
GPIO_PIN(G, 2), // D39 | |||||
GPIO_PIN(G, 1), // D40 | |||||
GPIO_PIN(G, 0), // D41 | |||||
GPIO_PIN(L, 7), // D42 | |||||
GPIO_PIN(L, 6), // D43 | |||||
GPIO_PIN(L, 5), // D44 | |||||
GPIO_PIN(L, 4), // D45 | |||||
GPIO_PIN(L, 3), // D46 | |||||
GPIO_PIN(L, 2), // D47 | |||||
GPIO_PIN(L, 1), // D48 | |||||
GPIO_PIN(L, 0), // D49 | |||||
GPIO_PIN(B, 3), // D50 | |||||
GPIO_PIN(B, 2), // D51 | |||||
GPIO_PIN(B, 1), // D52 | |||||
GPIO_PIN(B, 0), // D53 | |||||
GPIO_PIN(F, 0), // D54 | |||||
GPIO_PIN(F, 1), // D55 | |||||
GPIO_PIN(F, 2), // D56 | |||||
GPIO_PIN(F, 3), // D57 | |||||
GPIO_PIN(F, 4), // D58 | |||||
GPIO_PIN(F, 5), // D59 | |||||
GPIO_PIN(F, 6), // D60 | |||||
GPIO_PIN(F, 7), // D61 | |||||
GPIO_PIN(K, 0), // D62 | |||||
GPIO_PIN(K, 1), // D63 | |||||
GPIO_PIN(K, 2), // D64 | |||||
GPIO_PIN(K, 3), // D65 | |||||
GPIO_PIN(K, 4), // D66 | |||||
GPIO_PIN(K, 5), // D67 | |||||
GPIO_PIN(K, 6), // D68 | |||||
GPIO_PIN(K, 7) // D69 | |||||
}; | |||||
#endif // MegaGpioPinMap_h |
#ifndef SleepingBeautyGpioPinMap_h | |||||
#define SleepingBeautyGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(D, 0), // D0 | |||||
GPIO_PIN(D, 1), // D1 | |||||
GPIO_PIN(D, 2), // D2 | |||||
GPIO_PIN(D, 3), // D3 | |||||
GPIO_PIN(B, 0), // D4 | |||||
GPIO_PIN(B, 1), // D5 | |||||
GPIO_PIN(B, 2), // D6 | |||||
GPIO_PIN(B, 3), // D7 | |||||
GPIO_PIN(D, 6), // D8 | |||||
GPIO_PIN(D, 5), // D9 | |||||
GPIO_PIN(B, 4), // D10 | |||||
GPIO_PIN(B, 5), // D11 | |||||
GPIO_PIN(B, 6), // D12 | |||||
GPIO_PIN(B, 7), // D13 | |||||
GPIO_PIN(C, 7), // D14 | |||||
GPIO_PIN(C, 6), // D15 | |||||
GPIO_PIN(A, 5), // D16 | |||||
GPIO_PIN(A, 4), // D17 | |||||
GPIO_PIN(A, 3), // D18 | |||||
GPIO_PIN(A, 2), // D19 | |||||
GPIO_PIN(A, 1), // D20 | |||||
GPIO_PIN(A, 0), // D21 | |||||
GPIO_PIN(D, 4), // D22 | |||||
GPIO_PIN(D, 7), // D23 | |||||
GPIO_PIN(C, 2), // D24 | |||||
GPIO_PIN(C, 3), // D25 | |||||
GPIO_PIN(C, 4), // D26 | |||||
GPIO_PIN(C, 5), // D27 | |||||
GPIO_PIN(C, 1), // D28 | |||||
GPIO_PIN(C, 0), // D29 | |||||
GPIO_PIN(A, 6), // D30 | |||||
GPIO_PIN(A, 7) // D31 | |||||
}; | |||||
#endif // SleepingBeautyGpioPinMap_h |
#ifndef Standard1284GpioPinMap_h | |||||
#define Standard1284GpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(B, 0), // D0 | |||||
GPIO_PIN(B, 1), // D1 | |||||
GPIO_PIN(B, 2), // D2 | |||||
GPIO_PIN(B, 3), // D3 | |||||
GPIO_PIN(B, 4), // D4 | |||||
GPIO_PIN(B, 5), // D5 | |||||
GPIO_PIN(B, 6), // D6 | |||||
GPIO_PIN(B, 7), // D7 | |||||
GPIO_PIN(D, 0), // D8 | |||||
GPIO_PIN(D, 1), // D9 | |||||
GPIO_PIN(D, 2), // D10 | |||||
GPIO_PIN(D, 3), // D11 | |||||
GPIO_PIN(D, 4), // D12 | |||||
GPIO_PIN(D, 5), // D13 | |||||
GPIO_PIN(D, 6), // D14 | |||||
GPIO_PIN(D, 7), // D15 | |||||
GPIO_PIN(C, 0), // D16 | |||||
GPIO_PIN(C, 1), // D17 | |||||
GPIO_PIN(C, 2), // D18 | |||||
GPIO_PIN(C, 3), // D19 | |||||
GPIO_PIN(C, 4), // D20 | |||||
GPIO_PIN(C, 5), // D21 | |||||
GPIO_PIN(C, 6), // D22 | |||||
GPIO_PIN(C, 7), // D23 | |||||
GPIO_PIN(A, 0), // D24 | |||||
GPIO_PIN(A, 1), // D25 | |||||
GPIO_PIN(A, 2), // D26 | |||||
GPIO_PIN(A, 3), // D27 | |||||
GPIO_PIN(A, 4), // D28 | |||||
GPIO_PIN(A, 5), // D29 | |||||
GPIO_PIN(A, 6), // D30 | |||||
GPIO_PIN(A, 7) // D31 | |||||
}; | |||||
#endif // Standard1284GpioPinMap_h |
#ifndef Teensy2GpioPinMap_h | |||||
#define Teensy2GpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(B, 0), // D0 | |||||
GPIO_PIN(B, 1), // D1 | |||||
GPIO_PIN(B, 2), // D2 | |||||
GPIO_PIN(B, 3), // D3 | |||||
GPIO_PIN(B, 7), // D4 | |||||
GPIO_PIN(D, 0), // D5 | |||||
GPIO_PIN(D, 1), // D6 | |||||
GPIO_PIN(D, 2), // D7 | |||||
GPIO_PIN(D, 3), // D8 | |||||
GPIO_PIN(C, 6), // D9 | |||||
GPIO_PIN(C, 7), // D10 | |||||
GPIO_PIN(D, 6), // D11 | |||||
GPIO_PIN(D, 7), // D12 | |||||
GPIO_PIN(B, 4), // D13 | |||||
GPIO_PIN(B, 5), // D14 | |||||
GPIO_PIN(B, 6), // D15 | |||||
GPIO_PIN(F, 7), // D16 | |||||
GPIO_PIN(F, 6), // D17 | |||||
GPIO_PIN(F, 5), // D18 | |||||
GPIO_PIN(F, 4), // D19 | |||||
GPIO_PIN(F, 1), // D20 | |||||
GPIO_PIN(F, 0), // D21 | |||||
GPIO_PIN(D, 4), // D22 | |||||
GPIO_PIN(D, 5), // D23 | |||||
GPIO_PIN(E, 6), // D24 | |||||
}; | |||||
#endif // Teensy2GpioPinMap_h |
#ifndef Teensypp2GpioPinMap_h | |||||
#define Teensypp2GpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(D, 0), // D0 | |||||
GPIO_PIN(D, 1), // D1 | |||||
GPIO_PIN(D, 2), // D2 | |||||
GPIO_PIN(D, 3), // D3 | |||||
GPIO_PIN(D, 4), // D4 | |||||
GPIO_PIN(D, 5), // D5 | |||||
GPIO_PIN(D, 6), // D6 | |||||
GPIO_PIN(D, 7), // D7 | |||||
GPIO_PIN(E, 0), // D8 | |||||
GPIO_PIN(E, 1), // D9 | |||||
GPIO_PIN(C, 0), // D10 | |||||
GPIO_PIN(C, 1), // D11 | |||||
GPIO_PIN(C, 2), // D12 | |||||
GPIO_PIN(C, 3), // D13 | |||||
GPIO_PIN(C, 4), // D14 | |||||
GPIO_PIN(C, 5), // D15 | |||||
GPIO_PIN(C, 6), // D16 | |||||
GPIO_PIN(C, 7), // D17 | |||||
GPIO_PIN(E, 6), // D18 | |||||
GPIO_PIN(E, 7), // D19 | |||||
GPIO_PIN(B, 0), // D20 | |||||
GPIO_PIN(B, 1), // D21 | |||||
GPIO_PIN(B, 2), // D22 | |||||
GPIO_PIN(B, 3), // D23 | |||||
GPIO_PIN(B, 4), // D24 | |||||
GPIO_PIN(B, 5), // D25 | |||||
GPIO_PIN(B, 6), // D26 | |||||
GPIO_PIN(B, 7), // D27 | |||||
GPIO_PIN(A, 0), // D28 | |||||
GPIO_PIN(A, 1), // D29 | |||||
GPIO_PIN(A, 2), // D30 | |||||
GPIO_PIN(A, 3), // D31 | |||||
GPIO_PIN(A, 4), // D32 | |||||
GPIO_PIN(A, 5), // D33 | |||||
GPIO_PIN(A, 6), // D34 | |||||
GPIO_PIN(A, 7), // D35 | |||||
GPIO_PIN(E, 4), // D36 | |||||
GPIO_PIN(E, 5), // D37 | |||||
GPIO_PIN(F, 0), // D38 | |||||
GPIO_PIN(F, 1), // D39 | |||||
GPIO_PIN(F, 2), // D40 | |||||
GPIO_PIN(F, 3), // D41 | |||||
GPIO_PIN(F, 4), // D42 | |||||
GPIO_PIN(F, 5), // D43 | |||||
GPIO_PIN(F, 6), // D44 | |||||
GPIO_PIN(F, 7), // D45 | |||||
}; | |||||
#endif // Teensypp2GpioPinMap_h |
#ifndef UnoGpioPinMap_h | |||||
#define UnoGpioPinMap_h | |||||
static const GpioPinMap_t GpioPinMap[] = { | |||||
GPIO_PIN(D, 0), // D0 | |||||
GPIO_PIN(D, 1), // D1 | |||||
GPIO_PIN(D, 2), // D2 | |||||
GPIO_PIN(D, 3), // D3 | |||||
GPIO_PIN(D, 4), // D4 | |||||
GPIO_PIN(D, 5), // D5 | |||||
GPIO_PIN(D, 6), // D6 | |||||
GPIO_PIN(D, 7), // D7 | |||||
GPIO_PIN(B, 0), // D8 | |||||
GPIO_PIN(B, 1), // D9 | |||||
GPIO_PIN(B, 2), // D10 | |||||
GPIO_PIN(B, 3), // D11 | |||||
GPIO_PIN(B, 4), // D12 | |||||
GPIO_PIN(B, 5), // D13 | |||||
GPIO_PIN(C, 0), // D14 | |||||
GPIO_PIN(C, 1), // D15 | |||||
GPIO_PIN(C, 2), // D16 | |||||
GPIO_PIN(C, 3), // D17 | |||||
GPIO_PIN(C, 4), // D18 | |||||
GPIO_PIN(C, 5) // D19 | |||||
}; | |||||
#endif // UnoGpioPinMap_h |
#ifndef SystemInclude_h | |||||
#define SystemInclude_h | |||||
#if defined(ARDUINO) | |||||
#include <Arduino.h> | |||||
#include <SPI.h> | |||||
#elif defined(PLATFORM_ID) //Only defined if a Particle device | |||||
#include "application.h" | |||||
#else // | |||||
#error "Unknown system" | |||||
#endif // defined(ARDUINO) | |||||
#ifndef F | |||||
#define F(str) (str) | |||||
#endif // F | |||||
#endif // SystemInclude_h |
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for leonardo | while (!Serial) {} // wait for leonardo | ||||
testOut = &Serial; | testOut = &Serial; | ||||
SerialPrintln_P(PSTR("Type any character to begin.")); | |||||
Serial.println(F("Type any character to begin.")); | |||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} | ||||
delay(200); // Catch Due reset problem | delay(200); // Catch Due reset problem | ||||
const signed char* csc = (const signed char*)"CSC"; | const signed char* csc = (const signed char*)"CSC"; | ||||
unsigned char *uc = (unsigned char *)"uc"; | unsigned char *uc = (unsigned char *)"uc"; | ||||
const unsigned char *cuc = (const unsigned char *)"CUC"; | const unsigned char *cuc = (const unsigned char *)"CUC"; | ||||
ob << "lit" << c << cc << sc << csc << uc << cuc << pstr("pstr") << F("F"); | |||||
testVerifyStr(buf, "litcCCscCSCucCUCpstrF"); | |||||
ob << "lit" << c << cc << sc << csc << uc << cuc << F("F"); | |||||
testVerifyStr(buf, "litcCCscCSCucCUCF"); | |||||
ob.init(buf, sizeof(buf)); | ob.init(buf, sizeof(buf)); | ||||
ob << setfill('*') << "s" << setw(8) << "right"; | ob << setfill('*') << "s" << setw(8) << "right"; |
23 Jan 2016 | |||||
New Examples. | |||||
New SPI structure for ports to boards like the Particle Photon/Electron. | |||||
Several bug fixes. | |||||
19 Jul 2015 | 19 Jul 2015 | ||||
Converted to 1.5x library format. | Converted to 1.5x library format. |
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | <meta http-equiv="X-UA-Compatible" content="IE=9"/> | ||||
<meta name="generator" content="Doxygen 1.8.8"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoFiles.h File Reference</title> | <title>SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoFiles.h File Reference</title> | ||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="jquery.js"></script> | <script type="text/javascript" src="jquery.js"></script> | ||||
<script type="text/javascript" src="dynsections.js"></script> | <script type="text/javascript" src="dynsections.js"></script> | ||||
<link href="search/search.css" rel="stylesheet" type="text/css"/> | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="search/searchdata.js"></script> | |||||
<script type="text/javascript" src="search/search.js"></script> | <script type="text/javascript" src="search/search.js"></script> | ||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
$(document).ready(function() { searchBox.OnSelectItem(0); }); | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | </script> | ||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||||
</head> | </head> | ||||
<table cellspacing="0" cellpadding="0"> | <table cellspacing="0" cellpadding="0"> | ||||
<tbody> | <tbody> | ||||
<tr style="height: 56px;"> | <tr style="height: 56px;"> | ||||
<td style="padding-left: 0.5em;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | <div id="projectname">SdFat | ||||
</div> | </div> | ||||
</td> | </td> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
<!-- end header part --> | <!-- end header part --> | ||||
<!-- Generated by Doxygen 1.8.8 --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||||
</script> | </script> | ||||
onmouseover="return searchBox.OnSearchSelectShow()" | onmouseover="return searchBox.OnSearchSelectShow()" | ||||
onmouseout="return searchBox.OnSearchSelectHide()" | onmouseout="return searchBox.OnSearchSelectHide()" | ||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||||
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Modules</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Pages</a></div> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | <!-- iframe showing the search results (closed by default) --> | ||||
<div id="MSearchResultsWindow"> | <div id="MSearchResultsWindow"> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_arduino_files_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h" alt=""/></div> | <div class="center"><img src="_arduino_files_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8h"> | ||||
<area shape="rect" id="node3" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="323,245,428,272"/> <area shape="rect" id="node10" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="211,96,284,123"/> <area shape="rect" id="node7" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="366,320,481,347"/> <area shape="rect" id="node19" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="102,245,196,272"/> <area shape="rect" id="node21" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="200,171,296,197"/> </map> | |||||
<area shape="rect" id="node2" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="264,244,369,271"/> | |||||
<area shape="rect" id="node5" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="195,95,268,121"/> | |||||
<area shape="rect" id="node4" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="310,319,414,345"/> | |||||
<area shape="rect" id="node9" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="5,244,100,271"/> | |||||
<area shape="rect" id="node10" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="183,169,279,196"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
This graph shows which files directly or indirectly include this file:</div> | This graph shows which files directly or indirectly include this file:</div> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_arduino_files_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep" alt=""/></div> | <div class="center"><img src="_arduino_files_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_files_8hdep"> | ||||
<area shape="rect" id="node3" href="_fat_file_system_8h.html" title="FatFileSystem class. " alt="" coords="5,97,189,138"/> </map> | |||||
<area shape="rect" id="node2" href="_fat_file_system_8h.html" title="FatFileSystem class. " alt="" coords="5,95,189,136"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | ||||
</div><!-- contents --> | </div><!-- contents --> | ||||
<!-- start footer part --> | <!-- start footer part --> | ||||
<hr class="footer"/><address class="footer"><small> | <hr class="footer"/><address class="footer"><small> | ||||
Generated on Sun Jul 19 2015 10:15:53 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | <img class="footer" src="doxygen.png" alt="doxygen"/> | ||||
</a> 1.8.8 | |||||
</a> 1.8.10 | |||||
</small></address> | </small></address> | ||||
</body> | </body> | ||||
</html> | </html> |
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | <meta http-equiv="X-UA-Compatible" content="IE=9"/> | ||||
<meta name="generator" content="Doxygen 1.8.8"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoStream.h File Reference</title> | <title>SdFat: Arduino/libraries/SdFat/src/FatLib/ArduinoStream.h File Reference</title> | ||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="jquery.js"></script> | <script type="text/javascript" src="jquery.js"></script> | ||||
<script type="text/javascript" src="dynsections.js"></script> | <script type="text/javascript" src="dynsections.js"></script> | ||||
<link href="search/search.css" rel="stylesheet" type="text/css"/> | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="search/searchdata.js"></script> | |||||
<script type="text/javascript" src="search/search.js"></script> | <script type="text/javascript" src="search/search.js"></script> | ||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
$(document).ready(function() { searchBox.OnSelectItem(0); }); | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | </script> | ||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||||
</head> | </head> | ||||
<table cellspacing="0" cellpadding="0"> | <table cellspacing="0" cellpadding="0"> | ||||
<tbody> | <tbody> | ||||
<tr style="height: 56px;"> | <tr style="height: 56px;"> | ||||
<td style="padding-left: 0.5em;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | <div id="projectname">SdFat | ||||
</div> | </div> | ||||
</td> | </td> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
<!-- end header part --> | <!-- end header part --> | ||||
<!-- Generated by Doxygen 1.8.8 --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||||
</script> | </script> | ||||
onmouseover="return searchBox.OnSearchSelectShow()" | onmouseover="return searchBox.OnSearchSelectShow()" | ||||
onmouseout="return searchBox.OnSearchSelectHide()" | onmouseout="return searchBox.OnSearchSelectHide()" | ||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||||
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Modules</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Pages</a></div> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | <!-- iframe showing the search results (closed by default) --> | ||||
<div id="MSearchResultsWindow"> | <div id="MSearchResultsWindow"> | ||||
<p><a class="el" href="class_arduino_in_stream.html" title="Input stream for Arduino Stream objects. ">ArduinoInStream</a> and <a class="el" href="class_arduino_out_stream.html" title="Output stream for Arduino Print objects. ">ArduinoOutStream</a> classes. | <p><a class="el" href="class_arduino_in_stream.html" title="Input stream for Arduino Stream objects. ">ArduinoInStream</a> and <a class="el" href="class_arduino_out_stream.html" title="Output stream for Arduino Print objects. ">ArduinoOutStream</a> classes. | ||||
<a href="#details">More...</a></p> | <a href="#details">More...</a></p> | ||||
<div class="textblock"><code>#include "<a class="el" href="_fat_lib_config_8h.html">FatLibConfig.h</a>"</code><br /> | <div class="textblock"><code>#include "<a class="el" href="_fat_lib_config_8h.html">FatLibConfig.h</a>"</code><br /> | ||||
<code>#include <Arduino.h></code><br /> | |||||
<code>#include "SystemInclude.h"</code><br /> | |||||
<code>#include "<a class="el" href="bufstream_8h.html">bufstream.h</a>"</code><br /> | <code>#include "<a class="el" href="bufstream_8h.html">bufstream.h</a>"</code><br /> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
Include dependency graph for ArduinoStream.h:</div> | Include dependency graph for ArduinoStream.h:</div> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_arduino_stream_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h" alt=""/></div> | <div class="center"><img src="_arduino_stream_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_arduino_stream_8h"> | ||||
<area shape="rect" id="node3" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="5,544,109,571"/> <area shape="rect" id="node12" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="347,96,437,123"/> <area shape="rect" id="node7" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="47,619,163,645"/> <area shape="rect" id="node16" href="iostream_8h.html" title="iostream class " alt="" coords="317,171,400,197"/> <area shape="rect" id="node18" href="istream_8h.html" title="istream class " alt="" coords="219,245,295,272"/> <area shape="rect" id="node38" href="ostream_8h.html" title="ostream class " alt="" coords="320,245,400,272"/> <area shape="rect" id="node20" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="244,320,295,347"/> <area shape="rect" id="node22" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="233,395,305,421"/> <area shape="rect" id="node30" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="263,544,357,571"/> <area shape="rect" id="node32" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="233,469,329,496"/> </map> | |||||
<area shape="rect" id="node2" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="365,543,471,569"/> | |||||
<area shape="rect" id="node5" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="178,95,269,121"/> | |||||
<area shape="rect" id="node4" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="411,617,515,644"/> | |||||
<area shape="rect" id="node7" href="iostream_8h.html" title="iostream class " alt="" coords="182,169,265,196"/> | |||||
<area shape="rect" id="node8" href="istream_8h.html" title="istream class " alt="" coords="133,244,209,271"/> | |||||
<area shape="rect" id="node15" href="ostream_8h.html" title="ostream class " alt="" coords="234,244,314,271"/> | |||||
<area shape="rect" id="node9" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="197,319,247,345"/> | |||||
<area shape="rect" id="node10" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="185,393,259,420"/> | |||||
<area shape="rect" id="node13" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="151,543,245,569"/> | |||||
<area shape="rect" id="node14" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="285,468,381,495"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | ||||
</div></div><!-- contents --> | </div></div><!-- contents --> | ||||
<!-- start footer part --> | <!-- start footer part --> | ||||
<hr class="footer"/><address class="footer"><small> | <hr class="footer"/><address class="footer"><small> | ||||
Generated on Sun Jul 19 2015 10:15:53 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | <img class="footer" src="doxygen.png" alt="doxygen"/> | ||||
</a> 1.8.8 | |||||
</a> 1.8.10 | |||||
</small></address> | </small></address> | ||||
</body> | </body> | ||||
</html> | </html> |
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | <meta http-equiv="X-UA-Compatible" content="IE=9"/> | ||||
<meta name="generator" content="Doxygen 1.8.8"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/SdSpiCard/DigitalPin.h File Reference</title> | <title>SdFat: Arduino/libraries/SdFat/src/SdSpiCard/DigitalPin.h File Reference</title> | ||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="jquery.js"></script> | <script type="text/javascript" src="jquery.js"></script> | ||||
<script type="text/javascript" src="dynsections.js"></script> | <script type="text/javascript" src="dynsections.js"></script> | ||||
<link href="search/search.css" rel="stylesheet" type="text/css"/> | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="search/searchdata.js"></script> | |||||
<script type="text/javascript" src="search/search.js"></script> | <script type="text/javascript" src="search/search.js"></script> | ||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
$(document).ready(function() { searchBox.OnSelectItem(0); }); | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | </script> | ||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||||
</head> | </head> | ||||
<table cellspacing="0" cellpadding="0"> | <table cellspacing="0" cellpadding="0"> | ||||
<tbody> | <tbody> | ||||
<tr style="height: 56px;"> | <tr style="height: 56px;"> | ||||
<td style="padding-left: 0.5em;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | <div id="projectname">SdFat | ||||
</div> | </div> | ||||
</td> | </td> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
<!-- end header part --> | <!-- end header part --> | ||||
<!-- Generated by Doxygen 1.8.8 --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||||
</script> | </script> | ||||
onmouseover="return searchBox.OnSearchSelectShow()" | onmouseover="return searchBox.OnSearchSelectShow()" | ||||
onmouseout="return searchBox.OnSearchSelectHide()" | onmouseout="return searchBox.OnSearchSelectHide()" | ||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||||
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Modules</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Pages</a></div> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | <!-- iframe showing the search results (closed by default) --> | ||||
<div id="MSearchResultsWindow"> | <div id="MSearchResultsWindow"> | ||||
<div class="header"> | <div class="header"> | ||||
<div class="summary"> | <div class="summary"> | ||||
<a href="#nested-classes">Classes</a> | | <a href="#nested-classes">Classes</a> | | ||||
<a href="#func-members">Functions</a> | | |||||
<a href="#var-members">Variables</a> </div> | |||||
<a href="#define-members">Macros</a> | | |||||
<a href="#func-members">Functions</a> </div> | |||||
<div class="headertitle"> | <div class="headertitle"> | ||||
<div class="title">DigitalPin.h File Reference</div> </div> | <div class="title">DigitalPin.h File Reference</div> </div> | ||||
</div><!--header--> | </div><!--header--> | ||||
<p>Fast Digital Pin functions. | <p>Fast Digital Pin functions. | ||||
<a href="#details">More...</a></p> | <a href="#details">More...</a></p> | ||||
<div class="textblock"><code>#include <Arduino.h></code><br /> | |||||
<div class="textblock"><code>#include "SystemInclude.h"</code><br /> | |||||
<code>#include <avr/io.h></code><br /> | <code>#include <avr/io.h></code><br /> | ||||
<code>#include <util/atomic.h></code><br /> | |||||
<code>#include "boards/GpioPinMap.h"</code><br /> | |||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
Include dependency graph for DigitalPin.h:</div> | Include dependency graph for DigitalPin.h:</div> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_digital_pin_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep" alt=""/></div> | <div class="center"><img src="_digital_pin_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_sd_spi_card_2_digital_pin_8hdep"> | ||||
<area shape="rect" id="node3" href="_soft_s_p_i_8h.html" title="Software SPI. " alt="" coords="14,97,183,138"/> <area shape="rect" id="node5" href="_sd_spi_8h.html" title="SdSpi class for V2 SD/SDHC cards. " alt="" coords="19,187,179,229"/> <area shape="rect" id="node7" href="_sd_spi_card_8h.html" title="SdSpiCard class for V2 SD/SDHC cards. " alt="" coords="5,278,192,319"/> <area shape="rect" id="node9" href="_sd_fat_8h.html" title="SdFat class. " alt="" coords="21,369,176,410"/> <area shape="rect" id="node11" href="_sd_fat_util_8h.html" title="Useful utility functions. " alt="" coords="21,459,176,501"/> </map> | |||||
<area shape="rect" id="node2" href="_soft_s_p_i_8h.html" title="Software SPI. " alt="" coords="11,95,180,136"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | ||||
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_digital_pin.html">DigitalPin< PinNumber ></a></td></tr> | <tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_digital_pin.html">DigitalPin< PinNumber ></a></td></tr> | ||||
<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">Fast digital port I/O. <a href="class_digital_pin.html#details">More...</a><br /></td></tr> | <tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">Fast digital port I/O. <a href="class_digital_pin.html#details">More...</a><br /></td></tr> | ||||
<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="structpin__map__t.html">pin_map_t</a></td></tr> | |||||
<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight">struct for mapping digital pins <a href="structpin__map__t.html#details">More...</a><br /></td></tr> | |||||
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_gpio_pin_map__t.html">GpioPinMap_t</a></td></tr> | |||||
<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> | ||||
</table><table class="memberdecls"> | </table><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a> | |||||
Macros</h2></td></tr> | |||||
<tr class="memitem:gacf92f370944e233db04f7423bde1c164"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gacf92f370944e233db04f7423bde1c164">GPIO_PIN</a>(reg, bit)   {&PIN##reg, &DDR##reg, &PORT##reg, 1 << bit}</td></tr> | |||||
<tr class="separator:gacf92f370944e233db04f7423bde1c164"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</table><table class="memberdecls"> | |||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a> | ||||
Functions</h2></td></tr> | Functions</h2></td></tr> | ||||
<tr class="memitem:ga107992311bca47c7ebee5afdedc280e0"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga107992311bca47c7ebee5afdedc280e0">badPinCheck</a> (uint8_t pin)</td></tr> | <tr class="memitem:ga107992311bca47c7ebee5afdedc280e0"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga107992311bca47c7ebee5afdedc280e0">badPinCheck</a> (uint8_t pin)</td></tr> | ||||
<tr class="separator:ga107992311bca47c7ebee5afdedc280e0"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:ga107992311bca47c7ebee5afdedc280e0"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:ga2a50c39692fdc6a7be0f614f6d730bfe"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga2a50c39692fdc6a7be0f614f6d730bfe">badPinNumber</a> (void)</td></tr> | <tr class="memitem:ga2a50c39692fdc6a7be0f614f6d730bfe"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga2a50c39692fdc6a7be0f614f6d730bfe">badPinNumber</a> (void)</td></tr> | ||||
<tr class="separator:ga2a50c39692fdc6a7be0f614f6d730bfe"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:ga2a50c39692fdc6a7be0f614f6d730bfe"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:gac074e589cd04dca057b403dd3781ee45"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gac074e589cd04dca057b403dd3781ee45">fastBitWriteSafe</a> (volatile uint8_t *address, uint8_t bit, bool level)</td></tr> | |||||
<tr class="separator:gac074e589cd04dca057b403dd3781ee45"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:gaa28ed1bee40bd072ba33554ac6d36ed8"><td class="memItemLeft" align="right" valign="top">static volatile uint8_t * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gaa28ed1bee40bd072ba33554ac6d36ed8">ddrReg</a> (uint8_t pin)</td></tr> | |||||
<tr class="separator:gaa28ed1bee40bd072ba33554ac6d36ed8"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:gaff40f792e0b2aefb3ef6f11f32bae3dd"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gaff40f792e0b2aefb3ef6f11f32bae3dd">fastBitWriteSafe</a> (volatile uint8_t *address, uint8_t mask, bool level)</td></tr> | |||||
<tr class="separator:gaff40f792e0b2aefb3ef6f11f32bae3dd"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:gada03ef0d2522fe5639f5239991993409"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gada03ef0d2522fe5639f5239991993409">fastDdrWrite</a> (uint8_t pin, bool level)</td></tr> | |||||
<tr class="separator:gada03ef0d2522fe5639f5239991993409"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:ga618a9ee1c3d1b9fc5c8a2c6a43014b08"><td class="memItemLeft" align="right" valign="top">static bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga618a9ee1c3d1b9fc5c8a2c6a43014b08">fastDigitalRead</a> (uint8_t pin)</td></tr> | <tr class="memitem:ga618a9ee1c3d1b9fc5c8a2c6a43014b08"><td class="memItemLeft" align="right" valign="top">static bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga618a9ee1c3d1b9fc5c8a2c6a43014b08">fastDigitalRead</a> (uint8_t pin)</td></tr> | ||||
<tr class="separator:ga618a9ee1c3d1b9fc5c8a2c6a43014b08"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:ga618a9ee1c3d1b9fc5c8a2c6a43014b08"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:ga5314f1aaede89a4090b44779c8c551f1"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga5314f1aaede89a4090b44779c8c551f1">fastDigitalToggle</a> (uint8_t pin)</td></tr> | <tr class="memitem:ga5314f1aaede89a4090b44779c8c551f1"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga5314f1aaede89a4090b44779c8c551f1">fastDigitalToggle</a> (uint8_t pin)</td></tr> | ||||
<tr class="separator:ga5314f1aaede89a4090b44779c8c551f1"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:ga5314f1aaede89a4090b44779c8c551f1"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:gac4f52b5038c366dd4ac081b18709f19c"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gac4f52b5038c366dd4ac081b18709f19c">fastDigitalWrite</a> (uint8_t pin, bool level)</td></tr> | <tr class="memitem:gac4f52b5038c366dd4ac081b18709f19c"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gac4f52b5038c366dd4ac081b18709f19c">fastDigitalWrite</a> (uint8_t pin, bool level)</td></tr> | ||||
<tr class="separator:gac4f52b5038c366dd4ac081b18709f19c"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:gac4f52b5038c366dd4ac081b18709f19c"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:ga6d022f02ed0a7d69d56521346bb81457"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga6d022f02ed0a7d69d56521346bb81457">fastPinConfig</a> (uint8_t pin, bool mode, bool level)</td></tr> | |||||
<tr class="separator:ga6d022f02ed0a7d69d56521346bb81457"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:gac66bd0bc3332b7a08f257058034cdba8"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gac66bd0bc3332b7a08f257058034cdba8">fastPinMode</a> (uint8_t pin, bool mode)</td></tr> | |||||
<tr class="separator:gac66bd0bc3332b7a08f257058034cdba8"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</table><table class="memberdecls"> | |||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="var-members"></a> | |||||
Variables</h2></td></tr> | |||||
<tr class="memitem:ga3ba5f4d8ff10e60ec2d424722dd9fe92"><td class="memItemLeft" align="right" valign="top">static const uint8_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga3ba5f4d8ff10e60ec2d424722dd9fe92">digitalPinCount</a> = sizeof(pinMap)/sizeof(<a class="el" href="structpin__map__t.html">pin_map_t</a>)</td></tr> | |||||
<tr class="separator:ga3ba5f4d8ff10e60ec2d424722dd9fe92"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:gab5243728ddd84498e4eb59247f58e55d"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#gab5243728ddd84498e4eb59247f58e55d">fastPinConfig</a> (uint8_t pin, uint8_t mode, bool level)</td></tr> | |||||
<tr class="separator:gab5243728ddd84498e4eb59247f58e55d"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:ga5b9c17432f07f0eb39283c8b23665fe7"><td class="memItemLeft" align="right" valign="top">static void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga5b9c17432f07f0eb39283c8b23665fe7">fastPinMode</a> (uint8_t pin, uint8_t mode)</td></tr> | |||||
<tr class="separator:ga5b9c17432f07f0eb39283c8b23665fe7"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:ga99fe9f7aeaaae3764a7b7c40d9d9837b"><td class="memItemLeft" align="right" valign="top">static uint8_t </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga99fe9f7aeaaae3764a7b7c40d9d9837b">pinMask</a> (uint8_t pin)</td></tr> | |||||
<tr class="separator:ga99fe9f7aeaaae3764a7b7c40d9d9837b"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:ga213b72ce9a61eddce1e85fa057e9e3b6"><td class="memItemLeft" align="right" valign="top">static volatile uint8_t * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga213b72ce9a61eddce1e85fa057e9e3b6">pinReg</a> (uint8_t pin)</td></tr> | |||||
<tr class="separator:ga213b72ce9a61eddce1e85fa057e9e3b6"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:ga1e2ef44778ccf79ac2c02afe0633ef88"><td class="memItemLeft" align="right" valign="top">static volatile uint8_t * </td><td class="memItemRight" valign="bottom"><a class="el" href="group__digital_pin.html#ga1e2ef44778ccf79ac2c02afe0633ef88">portReg</a> (uint8_t pin)</td></tr> | |||||
<tr class="separator:ga1e2ef44778ccf79ac2c02afe0633ef88"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</table> | </table> | ||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> | <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> | ||||
<div class="textblock"><p>Fast Digital Pin functions. </p> | <div class="textblock"><p>Fast Digital Pin functions. </p> | ||||
</div></div><!-- contents --> | </div></div><!-- contents --> | ||||
<!-- start footer part --> | <!-- start footer part --> | ||||
<hr class="footer"/><address class="footer"><small> | <hr class="footer"/><address class="footer"><small> | ||||
Generated on Sun Jul 19 2015 10:15:53 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | <img class="footer" src="doxygen.png" alt="doxygen"/> | ||||
</a> 1.8.8 | |||||
</a> 1.8.10 | |||||
</small></address> | </small></address> | ||||
</body> | </body> | ||||
</html> | </html> |
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | <meta http-equiv="X-UA-Compatible" content="IE=9"/> | ||||
<meta name="generator" content="Doxygen 1.8.8"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/FatLib/FatFile.h File Reference</title> | <title>SdFat: Arduino/libraries/SdFat/src/FatLib/FatFile.h File Reference</title> | ||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="jquery.js"></script> | <script type="text/javascript" src="jquery.js"></script> | ||||
<script type="text/javascript" src="dynsections.js"></script> | <script type="text/javascript" src="dynsections.js"></script> | ||||
<link href="search/search.css" rel="stylesheet" type="text/css"/> | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="search/searchdata.js"></script> | |||||
<script type="text/javascript" src="search/search.js"></script> | <script type="text/javascript" src="search/search.js"></script> | ||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
$(document).ready(function() { searchBox.OnSelectItem(0); }); | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | </script> | ||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||||
</head> | </head> | ||||
<table cellspacing="0" cellpadding="0"> | <table cellspacing="0" cellpadding="0"> | ||||
<tbody> | <tbody> | ||||
<tr style="height: 56px;"> | <tr style="height: 56px;"> | ||||
<td style="padding-left: 0.5em;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | <div id="projectname">SdFat | ||||
</div> | </div> | ||||
</td> | </td> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
<!-- end header part --> | <!-- end header part --> | ||||
<!-- Generated by Doxygen 1.8.8 --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||||
</script> | </script> | ||||
onmouseover="return searchBox.OnSearchSelectShow()" | onmouseover="return searchBox.OnSearchSelectShow()" | ||||
onmouseout="return searchBox.OnSearchSelectHide()" | onmouseout="return searchBox.OnSearchSelectHide()" | ||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||||
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Modules</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Pages</a></div> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | <!-- iframe showing the search results (closed by default) --> | ||||
<div id="MSearchResultsWindow"> | <div id="MSearchResultsWindow"> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_fat_file_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h" alt=""/></div> | <div class="center"><img src="_fat_file_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8h"> | ||||
<area shape="rect" id="node9" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="106,171,211,197"/> <area shape="rect" id="node16" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="338,171,432,197"/> <area shape="rect" id="node18" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="196,96,292,123"/> <area shape="rect" id="node13" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="149,245,264,272"/> </map> | |||||
<area shape="rect" id="node5" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="160,169,265,196"/> | |||||
<area shape="rect" id="node8" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="289,169,384,196"/> | |||||
<area shape="rect" id="node9" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="146,95,242,121"/> | |||||
<area shape="rect" id="node7" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="205,244,309,271"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
This graph shows which files directly or indirectly include this file:</div> | This graph shows which files directly or indirectly include this file:</div> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_fat_file_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep" alt=""/></div> | <div class="center"><img src="_fat_file_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_8hdep"> | ||||
<area shape="rect" id="node3" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="29,97,200,138"/> <area shape="rect" id="node5" href="_fat_file_system_8h.html" title="FatFileSystem class. " alt="" coords="5,187,189,229"/> <area shape="rect" id="node7" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="375,97,529,138"/> <area shape="rect" id="node17" href="fstream_8h.html" title="fstream, ifstream, and ofstream classes " alt="" coords="507,369,661,410"/> <area shape="rect" id="node23" href="_stdio_stream_8h.html" title="StdioStream class. " alt="" coords="621,97,792,138"/> <area shape="rect" id="node9" href="istream_8h.html" title="istream class " alt="" coords="213,187,368,229"/> <area shape="rect" id="node19" href="ostream_8h.html" title="ostream class " alt="" coords="392,187,547,229"/> <area shape="rect" id="node11" href="iostream_8h.html" title="iostream class " alt="" coords="359,278,513,319"/> <area shape="rect" id="node13" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="326,369,481,410"/> <area shape="rect" id="node15" href="_arduino_stream_8h.html" title="ArduinoInStream and ArduinoOutStream classes. " alt="" coords="311,459,496,501"/> </map> | |||||
<area shape="rect" id="node2" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="29,95,200,136"/> | |||||
<area shape="rect" id="node3" href="_fat_file_system_8h.html" title="FatFileSystem class. " alt="" coords="5,184,189,225"/> | |||||
<area shape="rect" id="node4" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="375,95,529,136"/> | |||||
<area shape="rect" id="node9" href="fstream_8h.html" title="fstream, ifstream, and ofstream classes " alt="" coords="507,363,661,404"/> | |||||
<area shape="rect" id="node11" href="_stdio_stream_8h.html" title="StdioStream class. " alt="" coords="621,95,792,136"/> | |||||
<area shape="rect" id="node5" href="istream_8h.html" title="istream class " alt="" coords="213,184,368,225"/> | |||||
<area shape="rect" id="node10" href="ostream_8h.html" title="ostream class " alt="" coords="392,184,547,225"/> | |||||
<area shape="rect" id="node6" href="iostream_8h.html" title="iostream class " alt="" coords="359,273,513,315"/> | |||||
<area shape="rect" id="node7" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="326,363,482,404"/> | |||||
<area shape="rect" id="node8" href="_arduino_stream_8h.html" title="ArduinoInStream and ArduinoOutStream classes. " alt="" coords="311,452,497,493"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | ||||
Macros</h2></td></tr> | Macros</h2></td></tr> | ||||
<tr class="memitem:a9f85580ad6f1dfc86fff09a58ff0a1c0"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a9f85580ad6f1dfc86fff09a58ff0a1c0">isDirSeparator</a>(c)   ((c) == '/')</td></tr> | <tr class="memitem:a9f85580ad6f1dfc86fff09a58ff0a1c0"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a9f85580ad6f1dfc86fff09a58ff0a1c0">isDirSeparator</a>(c)   ((c) == '/')</td></tr> | ||||
<tr class="separator:a9f85580ad6f1dfc86fff09a58ff0a1c0"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:a9f85580ad6f1dfc86fff09a58ff0a1c0"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:a963f816fc88a5d8479c285ed4c630229"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a963f816fc88a5d8479c285ed4c630229">PGM_P</a>   const char*</td></tr> | |||||
<tr class="separator:a963f816fc88a5d8479c285ed4c630229"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:a48c60b057902adf805797f183286728d"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a48c60b057902adf805797f183286728d">pgm_read_byte</a>(addr)   (*(const unsigned char*)(addr))</td></tr> | <tr class="memitem:a48c60b057902adf805797f183286728d"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a48c60b057902adf805797f183286728d">pgm_read_byte</a>(addr)   (*(const unsigned char*)(addr))</td></tr> | ||||
<tr class="separator:a48c60b057902adf805797f183286728d"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:a48c60b057902adf805797f183286728d"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:a910fb5f01313d339d3b835d45e1e5ad0"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a910fb5f01313d339d3b835d45e1e5ad0">pgm_read_word</a>(addr)   (*(const uint16_t*)(addr))</td></tr> | <tr class="memitem:a910fb5f01313d339d3b835d45e1e5ad0"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a910fb5f01313d339d3b835d45e1e5ad0">pgm_read_word</a>(addr)   (*(const uint16_t*)(addr))</td></tr> | ||||
<tr class="separator:a910fb5f01313d339d3b835d45e1e5ad0"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:a910fb5f01313d339d3b835d45e1e5ad0"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:a75acaba9e781937468d0911423bc0c35"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a75acaba9e781937468d0911423bc0c35">PROGMEM</a>   const</td></tr> | |||||
<tr class="memitem:a75acaba9e781937468d0911423bc0c35"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a75acaba9e781937468d0911423bc0c35">PROGMEM</a></td></tr> | |||||
<tr class="separator:a75acaba9e781937468d0911423bc0c35"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:a75acaba9e781937468d0911423bc0c35"><td class="memSeparator" colspan="2"> </td></tr> | ||||
<tr class="memitem:a9c00057fd19e916cc1aa0a5949336beb"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a9c00057fd19e916cc1aa0a5949336beb">PSTR</a>(x)   (x)</td></tr> | <tr class="memitem:a9c00057fd19e916cc1aa0a5949336beb"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_fat_file_8h.html#a9c00057fd19e916cc1aa0a5949336beb">PSTR</a>(x)   (x)</td></tr> | ||||
<tr class="separator:a9c00057fd19e916cc1aa0a5949336beb"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:a9c00057fd19e916cc1aa0a5949336beb"><td class="memSeparator" colspan="2"> </td></tr> | ||||
</div><div class="memdoc"> | </div><div class="memdoc"> | ||||
<p>Expression for path name separator. </p> | <p>Expression for path name separator. </p> | ||||
</div> | |||||
</div> | |||||
<a class="anchor" id="a963f816fc88a5d8479c285ed4c630229"></a> | |||||
<div class="memitem"> | |||||
<div class="memproto"> | |||||
<table class="memname"> | |||||
<tr> | |||||
<td class="memname">#define PGM_P   const char*</td> | |||||
</tr> | |||||
</table> | |||||
</div><div class="memdoc"> | |||||
<p>pointer to flash for ARM </p> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<a class="anchor" id="a48c60b057902adf805797f183286728d"></a> | <a class="anchor" id="a48c60b057902adf805797f183286728d"></a> | ||||
<div class="memproto"> | <div class="memproto"> | ||||
<table class="memname"> | <table class="memname"> | ||||
<tr> | <tr> | ||||
<td class="memname">#define PROGMEM   const</td> | |||||
<td class="memname">#define PROGMEM</td> | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
</div><div class="memdoc"> | </div><div class="memdoc"> | ||||
</div><div class="memdoc"> | </div><div class="memdoc"> | ||||
<b>Initial value:</b><div class="fragment"><div class="line">=</div> | <b>Initial value:</b><div class="fragment"><div class="line">=</div> | ||||
<div class="line"> <a class="code" href="_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d">FNAME_FLAG_LOST_CHARS</a> | <a class="code" href="_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c">FNAME_FLAG_MIXED_CASE</a></div> | <div class="line"> <a class="code" href="_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d">FNAME_FLAG_LOST_CHARS</a> | <a class="code" href="_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c">FNAME_FLAG_MIXED_CASE</a></div> | ||||
<div class="ttc" id="_fat_file_8h_html_a63994c21f3b723a55247f063a1b01c9c"><div class="ttname"><a href="_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c">FNAME_FLAG_MIXED_CASE</a></div><div class="ttdeci">const uint8_t FNAME_FLAG_MIXED_CASE</div><div class="ttdef"><b>Definition:</b> FatFile.h:96</div></div> | |||||
<div class="ttc" id="_fat_file_8h_html_acd45286b7dfc5ba68be18c8c3a9d298d"><div class="ttname"><a href="_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d">FNAME_FLAG_LOST_CHARS</a></div><div class="ttdeci">const uint8_t FNAME_FLAG_LOST_CHARS</div><div class="ttdef"><b>Definition:</b> FatFile.h:94</div></div> | |||||
<div class="ttc" id="_fat_file_8h_html_a63994c21f3b723a55247f063a1b01c9c"><div class="ttname"><a href="_fat_file_8h.html#a63994c21f3b723a55247f063a1b01c9c">FNAME_FLAG_MIXED_CASE</a></div><div class="ttdeci">const uint8_t FNAME_FLAG_MIXED_CASE</div><div class="ttdef"><b>Definition:</b> FatFile.h:92</div></div> | |||||
<div class="ttc" id="_fat_file_8h_html_acd45286b7dfc5ba68be18c8c3a9d298d"><div class="ttname"><a href="_fat_file_8h.html#acd45286b7dfc5ba68be18c8c3a9d298d">FNAME_FLAG_LOST_CHARS</a></div><div class="ttdeci">const uint8_t FNAME_FLAG_LOST_CHARS</div><div class="ttdef"><b>Definition:</b> FatFile.h:90</div></div> | |||||
</div><!-- fragment --><p>LFN entries are required for file name. </p> | </div><!-- fragment --><p>LFN entries are required for file name. </p> | ||||
</div> | </div> | ||||
</div><!-- contents --> | </div><!-- contents --> | ||||
<!-- start footer part --> | <!-- start footer part --> | ||||
<hr class="footer"/><address class="footer"><small> | <hr class="footer"/><address class="footer"><small> | ||||
Generated on Sun Jul 19 2015 10:15:53 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | <img class="footer" src="doxygen.png" alt="doxygen"/> | ||||
</a> 1.8.8 | |||||
</a> 1.8.10 | |||||
</small></address> | </small></address> | ||||
</body> | </body> | ||||
</html> | </html> |
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | ||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | <meta http-equiv="X-UA-Compatible" content="IE=9"/> | ||||
<meta name="generator" content="Doxygen 1.8.8"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/FatLib/FatFileSystem.h File Reference</title> | <title>SdFat: Arduino/libraries/SdFat/src/FatLib/FatFileSystem.h File Reference</title> | ||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | <link href="tabs.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="jquery.js"></script> | <script type="text/javascript" src="jquery.js"></script> | ||||
<script type="text/javascript" src="dynsections.js"></script> | <script type="text/javascript" src="dynsections.js"></script> | ||||
<link href="search/search.css" rel="stylesheet" type="text/css"/> | <link href="search/search.css" rel="stylesheet" type="text/css"/> | ||||
<script type="text/javascript" src="search/searchdata.js"></script> | |||||
<script type="text/javascript" src="search/search.js"></script> | <script type="text/javascript" src="search/search.js"></script> | ||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
$(document).ready(function() { searchBox.OnSelectItem(0); }); | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | </script> | ||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | <link href="doxygen.css" rel="stylesheet" type="text/css" /> | ||||
</head> | </head> | ||||
<table cellspacing="0" cellpadding="0"> | <table cellspacing="0" cellpadding="0"> | ||||
<tbody> | <tbody> | ||||
<tr style="height: 56px;"> | <tr style="height: 56px;"> | ||||
<td style="padding-left: 0.5em;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | <div id="projectname">SdFat | ||||
</div> | </div> | ||||
</td> | </td> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
<!-- end header part --> | <!-- end header part --> | ||||
<!-- Generated by Doxygen 1.8.8 --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | <script type="text/javascript"> | ||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | var searchBox = new SearchBox("searchBox", "search",false,'Search'); | ||||
</script> | </script> | ||||
onmouseover="return searchBox.OnSearchSelectShow()" | onmouseover="return searchBox.OnSearchSelectShow()" | ||||
onmouseout="return searchBox.OnSearchSelectHide()" | onmouseout="return searchBox.OnSearchSelectHide()" | ||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | onkeydown="return searchBox.OnSearchSelectKey(event)"> | ||||
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Modules</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Pages</a></div> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | <!-- iframe showing the search results (closed by default) --> | ||||
<div id="MSearchResultsWindow"> | <div id="MSearchResultsWindow"> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_fat_file_system_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h" alt=""/></div> | <div class="center"><img src="_fat_file_system_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_file_system_8h"> | ||||
<area shape="rect" id="node3" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="115,245,211,272"/> <area shape="rect" id="node18" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="282,171,355,197"/> <area shape="rect" id="node28" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="381,96,485,123"/> <area shape="rect" id="node7" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="337,320,441,347"/> <area shape="rect" id="node14" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="5,320,99,347"/> <area shape="rect" id="node11" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="379,395,495,421"/> </map> | |||||
<area shape="rect" id="node2" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="89,244,185,271"/> | |||||
<area shape="rect" id="node8" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="236,169,309,196"/> | |||||
<area shape="rect" id="node11" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="345,95,451,121"/> | |||||
<area shape="rect" id="node4" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="220,319,325,345"/> | |||||
<area shape="rect" id="node7" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="5,319,100,345"/> | |||||
<area shape="rect" id="node6" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="266,393,370,420"/> | |||||
</map> | |||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | ||||
</div></div><!-- contents --> | </div></div><!-- contents --> | ||||
<!-- start footer part --> | <!-- start footer part --> | ||||
<hr class="footer"/><address class="footer"><small> | <hr class="footer"/><address class="footer"><small> | ||||
Generated on Sun Jul 19 2015 10:15:53 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | <img class="footer" src="doxygen.png" alt="doxygen"/> | ||||
</a> 1.8.8 | |||||
</a> 1.8.10 | |||||
</small></address> | </small></address> | ||||
</body> | </body> | ||||
</html> | </html> |