/** | |||||
* This program logs data to a binary file. Functions are included | |||||
* to convert the binary file to a csv text file. | |||||
* | |||||
* Samples are logged at regular intervals. The maximum logging rate | |||||
* depends on the quality of your SD card and the time required to | |||||
* read sensor data. This example has been tested at 500 Hz with | |||||
* good SD card on an Uno. 4000 HZ is possible on a Due. | |||||
* | |||||
* If your SD card has a long write latency, it may be necessary to use | |||||
* slower sample rates. Using a Mega Arduino helps overcome latency | |||||
* problems since 13 512 byte buffers will be used. | |||||
* | |||||
* Data is written to the file using a SD multiple block write command. | |||||
*/ | |||||
#include <SPI.h> | |||||
#include "SdFat.h" | |||||
#include "FreeStack.h" | |||||
//------------------------------------------------------------------------------ | |||||
// User data functions. Modify these functions for your data items. | |||||
#include "UserDataType.h" // Edit this include file to change data_t. | |||||
// Set useSharedSpi true for use of an SPI sensor. | |||||
const bool useSharedSpi = true; | |||||
const uint8_t ADXL345_CS = 9; | |||||
const uint8_t POWER_CTL = 0x2D; //Power Control Register | |||||
const uint8_t DATA_FORMAT = 0x31; | |||||
const uint8_t DATAX0 = 0x32; //X-Axis Data 0 | |||||
const uint8_t DATAX1 = 0x33; //X-Axis Data 1 | |||||
const uint8_t DATAY0 = 0x34; //Y-Axis Data 0 | |||||
const uint8_t DATAY1 = 0x35; //Y-Axis Data 1 | |||||
const uint8_t DATAZ0 = 0x36; //Z-Axis Data 0 | |||||
const uint8_t DATAZ1 = 0x37; //Z-Axis Data 1 | |||||
void writeADXL345Register(const uint8_t registerAddress, const uint8_t value) { | |||||
SPI.setDataMode(SPI_MODE3); | |||||
digitalWrite(ADXL345_CS, LOW); | |||||
SPI.transfer(registerAddress); | |||||
SPI.transfer(value); | |||||
digitalWrite(ADXL345_CS, HIGH); | |||||
} | |||||
void setupADXL345() { | |||||
SPI.begin(); | |||||
pinMode(ADXL345_CS, OUTPUT); | |||||
digitalWrite(ADXL345_CS, HIGH); | |||||
//Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register. | |||||
writeADXL345Register(DATA_FORMAT, 0x01); | |||||
//Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register. | |||||
writeADXL345Register(POWER_CTL, 0x08); //Measurement mode | |||||
} | |||||
// Acquire a data record. | |||||
void acquireData(data_t* data) { | |||||
data->time = micros(); | |||||
SPI.setDataMode(SPI_MODE3); | |||||
digitalWrite(ADXL345_CS, LOW); | |||||
// Read multiple bytes so or 0XC0 with address. | |||||
SPI.transfer(DATAX0 | 0XC0); | |||||
data->accel[0] = SPI.transfer(0) | (SPI.transfer(0) << 8); | |||||
data->accel[1] = SPI.transfer(0) | (SPI.transfer(0) << 8); | |||||
data->accel[2] = SPI.transfer(0) | (SPI.transfer(0) << 8); | |||||
digitalWrite(ADXL345_CS, HIGH); | |||||
} | |||||
// Print a data record. | |||||
void printData(Print* pr, data_t* data) { | |||||
pr->print(data->time); | |||||
for (int i = 0; i < ACCEL_DIM; i++) { | |||||
pr->write(','); | |||||
pr->print(data->accel[i]); | |||||
} | |||||
pr->println(); | |||||
} | |||||
// Print data header. | |||||
void printHeader(Print* pr) { | |||||
pr->println(F("time,ax,ay,az")); | |||||
} | |||||
//============================================================================== | |||||
// Start of configuration constants. | |||||
//============================================================================== | |||||
//Interval between data records in microseconds. | |||||
const uint32_t LOG_INTERVAL_USEC = 10000; | |||||
//------------------------------------------------------------------------------ | |||||
// Pin definitions. | |||||
// | |||||
// SD chip select pin. | |||||
const uint8_t SD_CS_PIN = SS; | |||||
// | |||||
// Digital pin to indicate an error, set to -1 if not used. | |||||
// The led blinks for fatal errors. The led goes on solid for SD write | |||||
// overrun errors and logging continues. | |||||
const int8_t ERROR_LED_PIN = -1; | |||||
//------------------------------------------------------------------------------ | |||||
// File definitions. | |||||
// | |||||
// Maximum file size in blocks. | |||||
// The program creates a contiguous file with FILE_BLOCK_COUNT 512 byte blocks. | |||||
// This file is flash erased using special SD commands. The file will be | |||||
// truncated if logging is stopped early. | |||||
const uint32_t FILE_BLOCK_COUNT = 256000; | |||||
// log file base name. Must be six characters or less. | |||||
#define FILE_BASE_NAME "data" | |||||
//------------------------------------------------------------------------------ | |||||
// Buffer definitions. | |||||
// | |||||
// The logger will use SdFat's buffer plus BUFFER_BLOCK_COUNT additional | |||||
// buffers. | |||||
// | |||||
#ifndef RAMEND | |||||
// Assume ARM. Use total of nine 512 byte buffers. | |||||
const uint8_t BUFFER_BLOCK_COUNT = 8; | |||||
// | |||||
#elif RAMEND < 0X8FF | |||||
#error Too little SRAM | |||||
// | |||||
#elif RAMEND < 0X10FF | |||||
// Use total of two 512 byte buffers. | |||||
const uint8_t BUFFER_BLOCK_COUNT = 1; | |||||
// | |||||
#elif RAMEND < 0X20FF | |||||
// Use total of five 512 byte buffers. | |||||
const uint8_t BUFFER_BLOCK_COUNT = 4; | |||||
// | |||||
#else // RAMEND | |||||
// Use total of 13 512 byte buffers. | |||||
const uint8_t BUFFER_BLOCK_COUNT = 12; | |||||
#endif // RAMEND | |||||
//============================================================================== | |||||
// End of configuration constants. | |||||
//============================================================================== | |||||
// Temporary log file. Will be deleted if a reset or power failure occurs. | |||||
#define TMP_FILE_NAME "tmp_log.bin" | |||||
// Size of file base name. Must not be larger than six. | |||||
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; | |||||
SdFat sd; | |||||
SdBaseFile binFile; | |||||
char binName[13] = FILE_BASE_NAME "00.bin"; | |||||
// Number of data records in a block. | |||||
const uint16_t DATA_DIM = (512 - 4)/sizeof(data_t); | |||||
//Compute fill so block size is 512 bytes. FILL_DIM may be zero. | |||||
const uint16_t FILL_DIM = 512 - 4 - DATA_DIM*sizeof(data_t); | |||||
struct block_t { | |||||
uint16_t count; | |||||
uint16_t overrun; | |||||
data_t data[DATA_DIM]; | |||||
uint8_t fill[FILL_DIM]; | |||||
}; | |||||
const uint8_t QUEUE_DIM = BUFFER_BLOCK_COUNT + 2; | |||||
block_t* emptyQueue[QUEUE_DIM]; | |||||
uint8_t emptyHead; | |||||
uint8_t emptyTail; | |||||
block_t* fullQueue[QUEUE_DIM]; | |||||
uint8_t fullHead; | |||||
uint8_t fullTail; | |||||
// Advance queue index. | |||||
inline uint8_t queueNext(uint8_t ht) { | |||||
return ht < (QUEUE_DIM - 1) ? ht + 1 : 0; | |||||
} | |||||
//============================================================================== | |||||
// Error messages stored in flash. | |||||
#define error(msg) errorFlash(F(msg)) | |||||
//------------------------------------------------------------------------------ | |||||
void errorFlash(const __FlashStringHelper* msg) { | |||||
sd.errorPrint(msg); | |||||
fatalBlink(); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
// | |||||
void fatalBlink() { | |||||
while (true) { | |||||
if (ERROR_LED_PIN >= 0) { | |||||
digitalWrite(ERROR_LED_PIN, HIGH); | |||||
delay(200); | |||||
digitalWrite(ERROR_LED_PIN, LOW); | |||||
delay(200); | |||||
} | |||||
} | |||||
} | |||||
//============================================================================== | |||||
// Convert binary file to csv file. | |||||
void binaryToCsv() { | |||||
uint8_t lastPct = 0; | |||||
block_t block; | |||||
uint32_t t0 = millis(); | |||||
uint32_t syncCluster = 0; | |||||
SdFile csvFile; | |||||
char csvName[13]; | |||||
if (!binFile.isOpen()) { | |||||
Serial.println(); | |||||
Serial.println(F("No current binary file")); | |||||
return; | |||||
} | |||||
binFile.rewind(); | |||||
// Create a new csvFile. | |||||
strcpy(csvName, binName); | |||||
strcpy(&csvName[BASE_NAME_SIZE + 3], "csv"); | |||||
if (!csvFile.open(csvName, O_WRITE | O_CREAT | O_TRUNC)) { | |||||
error("open csvFile failed"); | |||||
} | |||||
Serial.println(); | |||||
Serial.print(F("Writing: ")); | |||||
Serial.print(csvName); | |||||
Serial.println(F(" - type any character to stop")); | |||||
printHeader(&csvFile); | |||||
uint32_t tPct = millis(); | |||||
while (!Serial.available() && binFile.read(&block, 512) == 512) { | |||||
uint16_t i; | |||||
if (block.count == 0) { | |||||
break; | |||||
} | |||||
if (block.overrun) { | |||||
csvFile.print(F("OVERRUN,")); | |||||
csvFile.println(block.overrun); | |||||
} | |||||
for (i = 0; i < block.count; i++) { | |||||
printData(&csvFile, &block.data[i]); | |||||
} | |||||
if (csvFile.curCluster() != syncCluster) { | |||||
csvFile.sync(); | |||||
syncCluster = csvFile.curCluster(); | |||||
} | |||||
if ((millis() - tPct) > 1000) { | |||||
uint8_t pct = binFile.curPosition()/(binFile.fileSize()/100); | |||||
if (pct != lastPct) { | |||||
tPct = millis(); | |||||
lastPct = pct; | |||||
Serial.print(pct, DEC); | |||||
Serial.println('%'); | |||||
} | |||||
} | |||||
if (Serial.available()) { | |||||
break; | |||||
} | |||||
} | |||||
csvFile.close(); | |||||
Serial.print(F("Done: ")); | |||||
Serial.print(0.001*(millis() - t0)); | |||||
Serial.println(F(" Seconds")); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
// read data file and check for overruns | |||||
void checkOverrun() { | |||||
bool headerPrinted = false; | |||||
block_t block; | |||||
uint32_t bgnBlock, endBlock; | |||||
uint32_t bn = 0; | |||||
if (!binFile.isOpen()) { | |||||
Serial.println(); | |||||
Serial.println(F("No current binary file")); | |||||
return; | |||||
} | |||||
if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { | |||||
error("contiguousRange failed"); | |||||
} | |||||
binFile.rewind(); | |||||
Serial.println(); | |||||
Serial.println(F("Checking overrun errors - type any character to stop")); | |||||
while (binFile.read(&block, 512) == 512) { | |||||
if (block.count == 0) { | |||||
break; | |||||
} | |||||
if (block.overrun) { | |||||
if (!headerPrinted) { | |||||
Serial.println(); | |||||
Serial.println(F("Overruns:")); | |||||
Serial.println(F("fileBlockNumber,sdBlockNumber,overrunCount")); | |||||
headerPrinted = true; | |||||
} | |||||
Serial.print(bn); | |||||
Serial.print(','); | |||||
Serial.print(bgnBlock + bn); | |||||
Serial.print(','); | |||||
Serial.println(block.overrun); | |||||
} | |||||
bn++; | |||||
} | |||||
if (!headerPrinted) { | |||||
Serial.println(F("No errors found")); | |||||
} else { | |||||
Serial.println(F("Done")); | |||||
} | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
// dump data file to Serial | |||||
void dumpData() { | |||||
block_t block; | |||||
if (!binFile.isOpen()) { | |||||
Serial.println(); | |||||
Serial.println(F("No current binary file")); | |||||
return; | |||||
} | |||||
binFile.rewind(); | |||||
Serial.println(); | |||||
Serial.println(F("Type any character to stop")); | |||||
delay(1000); | |||||
printHeader(&Serial); | |||||
while (!Serial.available() && binFile.read(&block , 512) == 512) { | |||||
if (block.count == 0) { | |||||
break; | |||||
} | |||||
if (block.overrun) { | |||||
Serial.print(F("OVERRUN,")); | |||||
Serial.println(block.overrun); | |||||
} | |||||
for (uint16_t i = 0; i < block.count; i++) { | |||||
printData(&Serial, &block.data[i]); | |||||
} | |||||
} | |||||
Serial.println(F("Done")); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
// log data | |||||
// max number of blocks to erase per erase call | |||||
uint32_t const ERASE_SIZE = 262144L; | |||||
void logData() { | |||||
uint32_t bgnBlock, endBlock; | |||||
// Allocate extra buffer space. | |||||
block_t block[BUFFER_BLOCK_COUNT]; | |||||
block_t* curBlock = 0; | |||||
Serial.println(); | |||||
// Find unused file name. | |||||
if (BASE_NAME_SIZE > 6) { | |||||
error("FILE_BASE_NAME too long"); | |||||
} | |||||
while (sd.exists(binName)) { | |||||
if (binName[BASE_NAME_SIZE + 1] != '9') { | |||||
binName[BASE_NAME_SIZE + 1]++; | |||||
} else { | |||||
binName[BASE_NAME_SIZE + 1] = '0'; | |||||
if (binName[BASE_NAME_SIZE] == '9') { | |||||
error("Can't create file name"); | |||||
} | |||||
binName[BASE_NAME_SIZE]++; | |||||
} | |||||
} | |||||
// Delete old tmp file. | |||||
if (sd.exists(TMP_FILE_NAME)) { | |||||
Serial.println(F("Deleting tmp file")); | |||||
if (!sd.remove(TMP_FILE_NAME)) { | |||||
error("Can't remove tmp file"); | |||||
} | |||||
} | |||||
// Create new file. | |||||
Serial.println(F("Creating new file")); | |||||
binFile.close(); | |||||
if (!binFile.createContiguous(sd.vwd(), | |||||
TMP_FILE_NAME, 512 * FILE_BLOCK_COUNT)) { | |||||
error("createContiguous failed"); | |||||
} | |||||
// Get the address of the file on the SD. | |||||
if (!binFile.contiguousRange(&bgnBlock, &endBlock)) { | |||||
error("contiguousRange failed"); | |||||
} | |||||
// Use SdFat's internal buffer. | |||||
uint8_t* cache = (uint8_t*)sd.vol()->cacheClear(); | |||||
if (cache == 0) { | |||||
error("cacheClear failed"); | |||||
} | |||||
// Flash erase all data in the file. | |||||
Serial.println(F("Erasing all data")); | |||||
uint32_t bgnErase = bgnBlock; | |||||
uint32_t endErase; | |||||
while (bgnErase < endBlock) { | |||||
endErase = bgnErase + ERASE_SIZE; | |||||
if (endErase > endBlock) { | |||||
endErase = endBlock; | |||||
} | |||||
if (!sd.card()->erase(bgnErase, endErase)) { | |||||
error("erase failed"); | |||||
} | |||||
bgnErase = endErase + 1; | |||||
} | |||||
// Start a multiple block write. | |||||
if (!sd.card()->writeStart(bgnBlock, FILE_BLOCK_COUNT)) { | |||||
error("writeBegin failed"); | |||||
} | |||||
// Set chip select high if other devices use SPI. | |||||
if (useSharedSpi) { | |||||
sd.card()->chipSelectHigh(); | |||||
} | |||||
// Initialize queues. | |||||
emptyHead = emptyTail = 0; | |||||
fullHead = fullTail = 0; | |||||
// Use SdFat buffer for one block. | |||||
emptyQueue[emptyHead] = (block_t*)cache; | |||||
emptyHead = queueNext(emptyHead); | |||||
// Put rest of buffers in the empty queue. | |||||
for (uint8_t i = 0; i < BUFFER_BLOCK_COUNT; i++) { | |||||
emptyQueue[emptyHead] = &block[i]; | |||||
emptyHead = queueNext(emptyHead); | |||||
} | |||||
Serial.println(F("Logging - type any character to stop")); | |||||
// Wait for Serial Idle. | |||||
Serial.flush(); | |||||
delay(10); | |||||
uint32_t bn = 0; | |||||
uint32_t t0 = millis(); | |||||
uint32_t t1 = t0; | |||||
uint32_t overrun = 0; | |||||
uint32_t overrunTotal = 0; | |||||
uint32_t count = 0; | |||||
uint32_t maxDelta = 0; | |||||
uint32_t minDelta = 99999; | |||||
uint32_t maxLatency = 0; | |||||
// Start at a multiple of interval. | |||||
uint32_t logTime = micros()/LOG_INTERVAL_USEC + 1; | |||||
logTime *= LOG_INTERVAL_USEC; | |||||
bool closeFile = false; | |||||
while (1) { | |||||
// Time for next data record. | |||||
logTime += LOG_INTERVAL_USEC; | |||||
if (Serial.available()) { | |||||
closeFile = true; | |||||
} | |||||
if (closeFile) { | |||||
if (curBlock != 0) { | |||||
// Put buffer in full queue. | |||||
fullQueue[fullHead] = curBlock; | |||||
fullHead = queueNext(fullHead); | |||||
curBlock = 0; | |||||
} | |||||
} else { | |||||
if (curBlock == 0 && emptyTail != emptyHead) { | |||||
curBlock = emptyQueue[emptyTail]; | |||||
emptyTail = queueNext(emptyTail); | |||||
curBlock->count = 0; | |||||
curBlock->overrun = overrun; | |||||
overrun = 0; | |||||
} | |||||
if ((int32_t)(logTime - micros()) < 0) { | |||||
error("Rate too fast"); | |||||
} | |||||
int32_t delta; | |||||
do { | |||||
delta = micros() - logTime; | |||||
} while (delta < 0); | |||||
if (curBlock == 0) { | |||||
overrun++; | |||||
} else { | |||||
acquireData(&curBlock->data[curBlock->count++]); | |||||
if (curBlock->count == DATA_DIM) { | |||||
fullQueue[fullHead] = curBlock; | |||||
fullHead = queueNext(fullHead); | |||||
curBlock = 0; | |||||
} | |||||
if ((uint32_t)delta > maxDelta) maxDelta = delta; | |||||
if ((uint32_t)delta < minDelta) minDelta = delta; | |||||
} | |||||
} | |||||
if (fullHead == fullTail) { | |||||
// Exit loop if done. | |||||
if (closeFile) { | |||||
break; | |||||
} | |||||
} else if (!sd.card()->isBusy()) { | |||||
// Get address of block to write. | |||||
block_t* pBlock = fullQueue[fullTail]; | |||||
fullTail = queueNext(fullTail); | |||||
// Write block to SD. | |||||
uint32_t usec = micros(); | |||||
if (!sd.card()->writeData((uint8_t*)pBlock)) { | |||||
error("write data failed"); | |||||
} | |||||
usec = micros() - usec; | |||||
t1 = millis(); | |||||
if (usec > maxLatency) { | |||||
maxLatency = usec; | |||||
} | |||||
count += pBlock->count; | |||||
// Add overruns and possibly light LED. | |||||
if (pBlock->overrun) { | |||||
overrunTotal += pBlock->overrun; | |||||
if (ERROR_LED_PIN >= 0) { | |||||
digitalWrite(ERROR_LED_PIN, HIGH); | |||||
} | |||||
} | |||||
// Move block to empty queue. | |||||
emptyQueue[emptyHead] = pBlock; | |||||
emptyHead = queueNext(emptyHead); | |||||
bn++; | |||||
if (bn == FILE_BLOCK_COUNT) { | |||||
// File full so stop | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (!sd.card()->writeStop()) { | |||||
error("writeStop failed"); | |||||
} | |||||
// Truncate file if recording stopped early. | |||||
if (bn != FILE_BLOCK_COUNT) { | |||||
Serial.println(F("Truncating file")); | |||||
if (!binFile.truncate(512L * bn)) { | |||||
error("Can't truncate file"); | |||||
} | |||||
} | |||||
if (!binFile.rename(sd.vwd(), binName)) { | |||||
error("Can't rename file"); | |||||
} | |||||
Serial.print(F("File renamed: ")); | |||||
Serial.println(binName); | |||||
Serial.print(F("Max block write usec: ")); | |||||
Serial.println(maxLatency); | |||||
Serial.print(F("Record time sec: ")); | |||||
Serial.println(0.001*(t1 - t0), 3); | |||||
Serial.print(minDelta); | |||||
Serial.print(F(" <= jitter microseconds <= ")); | |||||
Serial.println(maxDelta); | |||||
Serial.print(F("Sample count: ")); | |||||
Serial.println(count); | |||||
Serial.print(F("Samples/sec: ")); | |||||
Serial.println((1000.0)*count/(t1-t0)); | |||||
Serial.print(F("Overruns: ")); | |||||
Serial.println(overrunTotal); | |||||
Serial.println(F("Done")); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void setup(void) { | |||||
if (ERROR_LED_PIN >= 0) { | |||||
pinMode(ERROR_LED_PIN, OUTPUT); | |||||
} | |||||
Serial.begin(9600); | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.print(F("FreeStack: ")); | |||||
Serial.println(FreeStack()); | |||||
Serial.print(F("Records/block: ")); | |||||
Serial.println(DATA_DIM); | |||||
if (sizeof(block_t) != 512) { | |||||
error("Invalid block size"); | |||||
} | |||||
// initialize file system. | |||||
if (!sd.begin(SD_CS_PIN, SPI_FULL_SPEED)) { | |||||
sd.initErrorPrint(); | |||||
fatalBlink(); | |||||
} | |||||
setupADXL345(); | |||||
} | |||||
//------------------------------------------------------------------------------ | |||||
void loop(void) { | |||||
// discard any input | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
Serial.println(); | |||||
Serial.println(F("type:")); | |||||
Serial.println(F("c - convert file to csv")); | |||||
Serial.println(F("d - dump data to Serial")); | |||||
Serial.println(F("e - overrun error details")); | |||||
Serial.println(F("r - record data")); | |||||
while(!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
char c = tolower(Serial.read()); | |||||
// Discard extra Serial data. | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
if (ERROR_LED_PIN >= 0) { | |||||
digitalWrite(ERROR_LED_PIN, LOW); | |||||
} | |||||
if (c == 'c') { | |||||
binaryToCsv(); | |||||
} else if (c == 'd') { | |||||
dumpData(); | |||||
} else if (c == 'e') { | |||||
checkOverrun(); | |||||
} else if (c == 'r') { | |||||
logData(); | |||||
} else { | |||||
Serial.println(F("Invalid entry")); | |||||
} | |||||
} |
#ifndef UserDataType_h | |||||
#define UserDataType_h | |||||
const uint8_t ACCEL_DIM = 3; | |||||
struct data_t { | |||||
unsigned long time; | |||||
int16_t accel[ACCEL_DIM]; | |||||
}; | |||||
#endif // UserDataType_h |
Test of shared SPI for LowLatencyLogger. |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial. | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// F() stores strings in flash to save RAM | // F() stores strings in flash to save RAM | ||||
cout << endl << F("FreeStack: ") << FreeStack() << endl; | cout << endl << F("FreeStack: ") << FreeStack() << endl; | ||||
#if WAIT_TO_START | #if WAIT_TO_START | ||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() >= 0) {} | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
do { | |||||
delay(10); | |||||
} while(Serial.read() >= 0); | |||||
#endif // WAIT_TO_START | #endif // WAIT_TO_START | ||||
#if USE_DS1307 | #if USE_DS1307 | ||||
} | } | ||||
logfile.close(); | logfile.close(); | ||||
cout << F("Done!"); | cout << F("Done!"); | ||||
while (1); | |||||
SysCall::halt(); | |||||
} | } |
SdFat sd; | SdFat sd; | ||||
SdFile file; | SdFile file; | ||||
char* name[] = { | |||||
const char* name[] = { | |||||
"low.low", "low.Mix", "low.UP", | "low.low", "low.Mix", "low.UP", | ||||
"Mix.low", "Mix.Mix", "Mix.UP", | "Mix.low", "Mix.Mix", "Mix.UP", | ||||
"UP.low", "UP.Mix", "UP.UP" | "UP.low", "UP.Mix", "UP.UP" | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("type any character to start"); | Serial.println("type any character to start"); | ||||
while (Serial.read() < 0) {} | |||||
while (Serial.read() < 0) { | |||||
SysCall::yield(); | |||||
} | |||||
if (!sd.begin()) { | if (!sd.begin()) { | ||||
Serial.println("begin failed"); | Serial.println("begin failed"); | ||||
return; | return; |
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(2000); | delay(2000); | ||||
cout << "Hello, World!\n"; | cout << "Hello, World!\n"; |
File file; | File file; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void error(char* s) { | |||||
void error(const char* s) { | |||||
Serial.println(s); | Serial.println(s); | ||||
while(1); | |||||
while (1) { | |||||
yield(); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial | |||||
while (!Serial) { | while (!Serial) { | ||||
// wait for Leonardo | |||||
yield(); | |||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// F() stores strings in flash to save RAM | // F() stores strings in flash to save RAM | ||||
Serial.println(F("Type any character to start")); | Serial.println(F("Type any character to start")); | ||||
while (Serial.read() <= 0) { | while (Serial.read() <= 0) { | ||||
yield(); | |||||
} | } | ||||
delay(400); // catch Due reset problem | |||||
// initialize the SD card | // initialize the SD card | ||||
if (!SD.begin(chipSelect)) { | if (!SD.begin(chipSelect)) { | ||||
error("begin"); | error("begin"); | ||||
} | } | ||||
Serial.println(F("Starting print test. Please wait.\n")); | Serial.println(F("Starting print test. Please wait.\n")); | ||||
// do write test | // do write test |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
yield(); | |||||
} | |||||
if (!SD.begin()) { | if (!SD.begin()) { | ||||
Serial.println("begin failed"); | Serial.println("begin failed"); |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
if (!sd.begin()) { | if (!sd.begin()) { | ||||
Serial.println("begin failed"); | Serial.println("begin failed"); | ||||
return; | return; |
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial. | // Wait for USB Serial. | ||||
while(!Serial) {} | |||||
while(!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println(F("Type any character to start")); | Serial.println(F("Type any character to start")); | ||||
while (!Serial.available()) {} | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
// Initialize the SD. | // Initialize the SD. | ||||
if (!SD.begin(csPin)) { | if (!SD.begin(csPin)) { | ||||
Serial.println(F("begin error")); | Serial.println(F("begin error")); |
char name[] = "append.txt"; | char name[] = "append.txt"; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// F() stores strings in flash to save RAM | // F() stores strings in flash to save RAM | ||||
cout << endl << F("Type any character to start\n"); | cout << endl << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // Catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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. |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// F() 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) {} | |||||
delay(400); // Catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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. |
File file; | File file; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void error(char* s) { | |||||
void error(const char* s) { | |||||
Serial.println(s); | Serial.println(s); | ||||
while(1); | |||||
while (1) { | |||||
yield(); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
yield(); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop() { | void loop() { | ||||
uint32_t totalLatency; | uint32_t totalLatency; | ||||
// discard any input | // discard any input | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
// F() stores strings in flash to save RAM | // F() stores strings in flash to save RAM | ||||
Serial.println(F("Type any character to start")); | Serial.println(F("Type any character to start")); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
yield(); | |||||
} | |||||
if (!SD.begin(chipSelect)) { | if (!SD.begin(chipSelect)) { | ||||
error("begin"); | error("begin"); | ||||
} | } |
int i, j, k; // values from parsed line | int i, j, k; // values from parsed line | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(2000); | delay(2000); | ||||
// initialize input string | // initialize input string |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop() { | void loop() { | ||||
int32_t n; | |||||
int32_t n = 0; | |||||
cout << "\nenter an integer\n"; | cout << "\nenter an integer\n"; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// F() 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) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(400); // catch Due reset problem | delay(400); // catch Due reset problem | ||||
// 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 |
wrfile.close(); | wrfile.close(); | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup(void) { | |||||
void setup() { | |||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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. | ||||
cout << F("\nDone\n"); | cout << F("\nDone\n"); | ||||
} | } | ||||
void loop(void) {} | |||||
void loop() {} |
void setup() { | void setup() { | ||||
int c; | int c; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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(chipSelect, SPI_HALF_SPEED)) { | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { |
const uint16_t MIN_ADC_CYCLES = 15; | const uint16_t MIN_ADC_CYCLES = 15; | ||||
// Extra cpu cycles to setup ADC with more than one pin per sample. | // Extra cpu cycles to setup ADC with more than one pin per sample. | ||||
const uint16_t ISR_SETUP_ADC = 100; | |||||
const uint16_t ISR_SETUP_ADC = PIN_COUNT > 1 ? 100 : 0; | |||||
// Maximum cycles for timer0 system interrupt, millis, micros. | // Maximum cycles for timer0 system interrupt, millis, micros. | ||||
const uint16_t ISR_TIMER0 = 160; | const uint16_t ISR_TIMER0 = 160; | ||||
adps = ADC_PRESCALER; | adps = ADC_PRESCALER; | ||||
#else // ADC_PRESCALER | #else // ADC_PRESCALER | ||||
// Allow extra cpu cycles to change ADC settings if more than one pin. | // Allow extra cpu cycles to change ADC settings if more than one pin. | ||||
int32_t adcCycles = (ticks - ISR_TIMER0)/PIN_COUNT; | |||||
- (PIN_COUNT > 1 ? ISR_SETUP_ADC : 0); | |||||
int32_t adcCycles = (ticks - ISR_TIMER0)/PIN_COUNT - ISR_SETUP_ADC; | |||||
for (adps = 7; adps > 0; adps--) { | for (adps = 7; adps > 0; adps--) { | ||||
if (adcCycles >= (MIN_ADC_CYCLES << adps)) { | if (adcCycles >= (MIN_ADC_CYCLES << adps)) { | ||||
meta->cpuFrequency = F_CPU; | meta->cpuFrequency = F_CPU; | ||||
float sampleRate = (float)meta->cpuFrequency/meta->sampleInterval; | float sampleRate = (float)meta->cpuFrequency/meta->sampleInterval; | ||||
Serial.print(F("Sample pins:")); | Serial.print(F("Sample pins:")); | ||||
for (int i = 0; i < meta->pinCount; i++) { | |||||
for (uint8_t i = 0; i < meta->pinCount; i++) { | |||||
Serial.print(' '); | Serial.print(' '); | ||||
Serial.print(meta->pinNumber[i], DEC); | Serial.print(meta->pinNumber[i], DEC); | ||||
} | } | ||||
csvStream.println(); | csvStream.println(); | ||||
uint32_t tPct = millis(); | uint32_t tPct = millis(); | ||||
while (!Serial.available() && binFile.read(&buf, 512) == 512) { | while (!Serial.available() && binFile.read(&buf, 512) == 512) { | ||||
uint16_t i; | |||||
if (buf.count == 0) { | if (buf.count == 0) { | ||||
break; | break; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop(void) { | void loop(void) { | ||||
// discard any input | // discard any input | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
Serial.println(); | Serial.println(); | ||||
Serial.println(F("type:")); | Serial.println(F("type:")); | ||||
Serial.println(F("c - convert file to csv")); | Serial.println(F("c - convert file to csv")); | ||||
Serial.println(F("e - overrun error details")); | Serial.println(F("e - overrun error details")); | ||||
Serial.println(F("r - record ADC data")); | Serial.println(F("r - record ADC data")); | ||||
while(!Serial.available()) {} | |||||
while(!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
char c = tolower(Serial.read()); | char c = tolower(Serial.read()); | ||||
if (ERROR_LED_PIN >= 0) { | if (ERROR_LED_PIN >= 0) { | ||||
digitalWrite(ERROR_LED_PIN, LOW); | digitalWrite(ERROR_LED_PIN, LOW); |
while (Serial.read() > 0) {} | while (Serial.read() > 0) {} | ||||
Serial.print(F("\r\nEnter File Number: ")); | Serial.print(F("\r\nEnter File Number: ")); | ||||
while ((c = Serial.read()) < 0) {}; | |||||
if (!isdigit(c) || (c -= '0') >= n) { | |||||
while ((c = Serial.read()) < 0) { | |||||
SysCall::yield(); | |||||
} | |||||
uint8_t i = c - '0'; | |||||
if (!isdigit(c) || i >= n) { | |||||
Serial.println(F("Invald number")); | Serial.println(F("Invald number")); | ||||
return; | return; | ||||
} | } | ||||
Serial.println(c); | |||||
if (!file.open(&dirFile, dirIndex[c], O_READ)) { | |||||
Serial.println(i); | |||||
if (!file.open(&dirFile, dirIndex[i], O_READ)) { | |||||
sd.errorHalt(F("open")); | sd.errorHalt(F("open")); | ||||
} | } | ||||
Serial.println(); | Serial.println(); | ||||
char last; | |||||
char last = 0; | |||||
// Copy up to 500 characters to Serial. | // Copy up to 500 characters to Serial. | ||||
for (int i = 0; i < 500 && (c = file.read()) > 0; i++) { | |||||
for (int k = 0; k < 500 && (c = file.read()) > 0; k++) { | |||||
Serial.write(last = (char)c); | Serial.write(last = (char)c); | ||||
} | } | ||||
// Add new line if missing from last line. | // Add new line if missing from last line. |
// 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. | ||||
// Set useSharedSpi true for use of an SPI sensor. | |||||
const bool useSharedSpi = false; | |||||
// Acquire a data record. | // Acquire a data record. | ||||
void acquireData(data_t* data) { | void acquireData(data_t* data) { | ||||
data->time = micros(); | data->time = micros(); | ||||
if (!sd.card()->writeStart(bgnBlock, FILE_BLOCK_COUNT)) { | if (!sd.card()->writeStart(bgnBlock, FILE_BLOCK_COUNT)) { | ||||
error("writeBegin failed"); | error("writeBegin failed"); | ||||
} | } | ||||
// Set chip select high if other devices use SPI. | |||||
if (useSharedSpi) { | |||||
sd.card()->chipSelectHigh(); | |||||
} | |||||
// Initialize queues. | // Initialize queues. | ||||
emptyHead = emptyTail = 0; | emptyHead = emptyTail = 0; | ||||
fullHead = fullTail = 0; | fullHead = fullTail = 0; | ||||
uint32_t overrun = 0; | uint32_t overrun = 0; | ||||
uint32_t overrunTotal = 0; | uint32_t overrunTotal = 0; | ||||
uint32_t count = 0; | uint32_t count = 0; | ||||
uint32_t maxDelta = 0; | |||||
uint32_t minDelta = 99999; | |||||
uint32_t maxLatency = 0; | uint32_t maxLatency = 0; | ||||
int32_t diff; | |||||
// Start at a multiple of interval. | // Start at a multiple of interval. | ||||
uint32_t logTime = micros()/LOG_INTERVAL_USEC + 1; | uint32_t logTime = micros()/LOG_INTERVAL_USEC + 1; | ||||
logTime *= LOG_INTERVAL_USEC; | logTime *= LOG_INTERVAL_USEC; | ||||
} | } | ||||
if (closeFile) { | if (closeFile) { | ||||
if (curBlock != 0 && curBlock->count >= 0) { | |||||
if (curBlock != 0) { | |||||
// Put buffer in full queue. | // Put buffer in full queue. | ||||
fullQueue[fullHead] = curBlock; | fullQueue[fullHead] = curBlock; | ||||
fullHead = queueNext(fullHead); | fullHead = queueNext(fullHead); | ||||
curBlock->overrun = overrun; | curBlock->overrun = overrun; | ||||
overrun = 0; | overrun = 0; | ||||
} | } | ||||
do { | |||||
diff = logTime - micros(); | |||||
} while(diff > 0); | |||||
if (diff < -10) { | |||||
error("LOG_INTERVAL_USEC too small"); | |||||
if ((int32_t)(logTime - micros()) < 0) { | |||||
error("Rate too fast"); | |||||
} | } | ||||
int32_t delta; | |||||
do { | |||||
delta = micros() - logTime; | |||||
} while (delta < 0); | |||||
if (curBlock == 0) { | if (curBlock == 0) { | ||||
overrun++; | overrun++; | ||||
} else { | } else { | ||||
acquireData(&curBlock->data[curBlock->count++]); | |||||
acquireData(&curBlock->data[curBlock->count++]); | |||||
if (curBlock->count == DATA_DIM) { | if (curBlock->count == DATA_DIM) { | ||||
fullQueue[fullHead] = curBlock; | fullQueue[fullHead] = curBlock; | ||||
fullHead = queueNext(fullHead); | fullHead = queueNext(fullHead); | ||||
curBlock = 0; | curBlock = 0; | ||||
} | } | ||||
if ((uint32_t)delta > maxDelta) maxDelta = delta; | |||||
if ((uint32_t)delta < minDelta) minDelta = delta; | |||||
} | } | ||||
} | } | ||||
Serial.println(maxLatency); | Serial.println(maxLatency); | ||||
Serial.print(F("Record time sec: ")); | Serial.print(F("Record time sec: ")); | ||||
Serial.println(0.001*(t1 - t0), 3); | Serial.println(0.001*(t1 - t0), 3); | ||||
Serial.print(minDelta); | |||||
Serial.print(F(" <= jitter microseconds <= ")); | |||||
Serial.println(maxDelta); | |||||
Serial.print(F("Sample count: ")); | Serial.print(F("Sample count: ")); | ||||
Serial.println(count); | Serial.println(count); | ||||
Serial.print(F("Samples/sec: ")); | Serial.print(F("Samples/sec: ")); | ||||
pinMode(ERROR_LED_PIN, OUTPUT); | pinMode(ERROR_LED_PIN, OUTPUT); | ||||
} | } | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.print(F("FreeStack: ")); | Serial.print(F("FreeStack: ")); | ||||
Serial.println(FreeStack()); | Serial.println(FreeStack()); | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop(void) { | void loop(void) { | ||||
// discard any input | // discard any input | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
Serial.println(); | Serial.println(); | ||||
Serial.println(F("type:")); | Serial.println(F("type:")); | ||||
Serial.println(F("c - convert file to csv")); | Serial.println(F("c - convert file to csv")); | ||||
Serial.println(F("e - overrun error details")); | Serial.println(F("e - overrun error details")); | ||||
Serial.println(F("r - record data")); | Serial.println(F("r - record data")); | ||||
while(!Serial.available()) {} | |||||
while(!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
char c = tolower(Serial.read()); | char c = tolower(Serial.read()); | ||||
// Discard extra Serial data. | // Discard extra Serial data. |
#include <SPI.h> | #include <SPI.h> | ||||
#include "SdFat.h" | #include "SdFat.h" | ||||
// SD chip select pin | |||||
// SD default chip select pin. | |||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
// file system object | // file system object | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
delay(1000); | |||||
Serial.println(); | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type any character to start"); | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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. |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial | |||||
while (!Serial) { | while (!Serial) { | ||||
// wait for Leonardo | |||||
SysCall::yield(); | |||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // Wait for Leonardo. | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("\nSPI pins:\n"); | cout << F("\nSPI pins:\n"); | ||||
cout << F("MISO: ") << int(MISO) << endl; | cout << F("MISO: ") << int(MISO) << endl; | ||||
cout << F("MOSI: ") << int(MOSI) << endl; | cout << F("MOSI: ") << int(MOSI) << endl; | ||||
bool firstTry = true; | bool firstTry = true; | ||||
void loop() { | void loop() { | ||||
// read any existing Serial data | // read any existing Serial data | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
if (!firstTry) { | if (!firstTry) { | ||||
cout << F("\nRestarting\n"); | cout << F("\nRestarting\n"); | ||||
firstTry = false; | firstTry = false; | ||||
cout << F("\nEnter the chip select pin number: "); | cout << F("\nEnter the chip select pin number: "); | ||||
while (!Serial.available()) {} | |||||
delay(400); // catch Due restart problem | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
cin.readline(); | cin.readline(); | ||||
if (cin >> chipSelect) { | if (cin >> chipSelect) { | ||||
cout << chipSelect << endl; | cout << chipSelect << endl; |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup(void) { | void setup(void) { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop(void) { | void loop(void) { | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
// F 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) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("FreeStack: ") << FreeStack() << endl; | cout << F("FreeStack: ") << FreeStack() << endl; | ||||
// | // | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | #include <SdFat.h> | ||||
#define CS_PIN 10 | |||||
#define CS_PIN SS | |||||
// 5 X 4 array | // 5 X 4 array | ||||
#define ROW_DIM 5 | #define ROW_DIM 5 | ||||
* if not at end-of-file. | * if not at end-of-file. | ||||
* | * | ||||
*/ | */ | ||||
size_t readField(File* file, char* str, size_t size, char* delim) { | |||||
size_t readField(File* file, char* str, size_t size, const char* delim) { | |||||
char ch; | char ch; | ||||
size_t n = 0; | size_t n = 0; | ||||
while ((n + 1) < size && file->read(&ch, 1) == 1) { | while ((n + 1) < size && file->read(&ch, 1) == 1) { | ||||
return n; | return n; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||||
#define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();} | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type any character to start"); | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// Initialize the SD. | // Initialize the SD. | ||||
if (!SD.begin(CS_PIN)) { | if (!SD.begin(CS_PIN)) { | ||||
errorHalt("begin failed"); | errorHalt("begin failed"); | ||||
} | |||||
} | |||||
// Create or open the file. | // Create or open the file. | ||||
file = SD.open("READNUM.TXT", FILE_WRITE); | file = SD.open("READNUM.TXT", FILE_WRITE); | ||||
if (!file) { | if (!file) { | ||||
errorHalt("open failed"); | errorHalt("open failed"); | ||||
} | } | ||||
// Rewind file so test data is not appended. | // Rewind file so test data is not appended. | ||||
file.seek(0); | |||||
file.rewind(); | |||||
// Write test data. | // Write test data. | ||||
file.print(F( | file.print(F( | ||||
)); | )); | ||||
// Rewind the file for read. | // Rewind the file for read. | ||||
file.seek(0); | |||||
file.rewind(); | |||||
// Array for data. | // Array for data. | ||||
int array[ROW_DIM][COL_DIM]; | int array[ROW_DIM][COL_DIM]; |
// | // | ||||
#include <SPI.h> | #include <SPI.h> | ||||
#include <SdFat.h> | #include <SdFat.h> | ||||
#define CS_PIN 10 | |||||
#define CS_PIN SS | |||||
SdFat SD; | SdFat SD; | ||||
File file; | File file; | ||||
* if not at end-of-file. | * if not at end-of-file. | ||||
* | * | ||||
*/ | */ | ||||
size_t readField(File* file, char* str, size_t size, char* delim) { | |||||
size_t readField(File* file, char* str, size_t size, const char* delim) { | |||||
char ch; | char ch; | ||||
size_t n = 0; | size_t n = 0; | ||||
while ((n + 1) < size && file->read(&ch, 1) == 1) { | while ((n + 1) < size && file->read(&ch, 1) == 1) { | ||||
return n; | return n; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||||
#define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();} | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type any character to start"); | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// Initialize the SD. | // Initialize the SD. | ||||
if (!SD.begin(CS_PIN)) errorHalt("begin failed"); | if (!SD.begin(CS_PIN)) errorHalt("begin failed"); | ||||
if (!file) errorHalt("open failed"); | if (!file) errorHalt("open failed"); | ||||
// Rewind file so test data is not appended. | // Rewind file so test data is not appended. | ||||
file.seek(0); | |||||
file.rewind(); | |||||
// Write test data. | // Write test data. | ||||
file.print(F( | file.print(F( | ||||
)); | )); | ||||
// Rewind the file for read. | // Rewind the file for read. | ||||
file.seek(0); | |||||
file.rewind(); | |||||
size_t n; // Length of returned field with delimiter. | size_t n; // Length of returned field with delimiter. | ||||
char str[20]; // Must hold longest field with delimiter and zero byte. | char str[20]; // Must hold longest field with delimiter and zero byte. |
{ | { | ||||
// Open serial communications and wait for port to open: | // Open serial communications and wait for port to open: | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
// Wait for USB Serial | |||||
while (!Serial) { | while (!Serial) { | ||||
; // wait for serial port to connect. Needed for Leonardo only | |||||
SysCall::yield(); | |||||
} | } | ||||
Serial.print("Initializing SD card..."); | Serial.print("Initializing SD card..."); | ||||
// On the Ethernet Shield, CS is pin 4. It's set as an output by default. | // On the Ethernet Shield, CS is pin 4. It's set as an output by default. | ||||
// Note that even if it's not used as the CS pin, the hardware SS pin | // Note that even if it's not used as the CS pin, the hardware SS pin |
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type any character to start"); | Serial.println("Type any character to start"); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// Initialize SdFat or print a detailed error message and halt | // Initialize SdFat or print a detailed error message and halt | ||||
// Use half speed like the native library. | // Use half speed like the native library. | ||||
// change to SPI_FULL_SPEED for more performance. | // change to SPI_FULL_SPEED for more performance. |
cout << F("SD error: ") << hex << int(card.errorCode()); | cout << F("SD error: ") << hex << int(card.errorCode()); | ||||
cout << ',' << int(card.errorData()) << dec << endl; | cout << ',' << int(card.errorData()) << dec << endl; | ||||
} | } | ||||
while (1); | |||||
SysCall::halt(); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#if DEBUG_PRINT | #if DEBUG_PRINT | ||||
void setup() { | void setup() { | ||||
char c; | char c; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("Type any character to start\n"); | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// Discard any extra characters. | |||||
do {delay(10);} while (Serial.read() >= 0); | |||||
cout << F( | cout << F( | ||||
"\n" | "\n" | ||||
"This program can erase and/or format SD/SDHC cards.\n" | "This program can erase and/or format SD/SDHC cards.\n" | ||||
"\n" | "\n" | ||||
"Warning, all data on the card will be erased.\n" | "Warning, all data on the card will be erased.\n" | ||||
"Enter 'Y' to continue: "); | "Enter 'Y' to continue: "); | ||||
while (!Serial.available()) {} | |||||
delay(400); // catch Due restart problem | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
c = Serial.read(); | c = Serial.read(); | ||||
cout << c << endl; | cout << c << endl; | ||||
return; | return; | ||||
} | } | ||||
// read any existing Serial data | // read any existing Serial data | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
cout << F( | cout << F( | ||||
"\n" | "\n" | ||||
"\n" | "\n" | ||||
"Enter option: "); | "Enter option: "); | ||||
while (!Serial.available()) {} | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
c = Serial.read(); | c = Serial.read(); | ||||
cout << c << endl; | cout << c << endl; | ||||
if (!strchr("EFQ", c)) { | if (!strchr("EFQ", c)) { |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while(!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void loop() { | void loop() { | ||||
// read any existing Serial data | // read any existing Serial data | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
// F 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) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
uint32_t t = millis(); | uint32_t t = millis(); | ||||
// 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 |
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // Wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type any character to start"); | Serial.println("Type any character to start"); | ||||
while (Serial.read() <= 0) {} | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
if (!sd.begin(SD_CHIP_SELECT_PIN)) { | if (!sd.begin(SD_CHIP_SELECT_PIN)) { | ||||
sd.initErrorHalt(); | sd.initErrorHalt(); |
float f[100]; | float f[100]; | ||||
char buf[20]; | char buf[20]; | ||||
char* label[] = | |||||
const char* label[] = | |||||
{ "uint8_t 0 to 255, 100 times ", "uint16_t 0 to 20000", | { "uint8_t 0 to 255, 100 times ", "uint16_t 0 to 20000", | ||||
"uint32_t 0 to 20000", "uint32_t 1000000000 to 1000010000", | "uint32_t 0 to 20000", "uint32_t 1000000000 to 1000010000", | ||||
"float nnn.ffff, 10000 times" | "float nnn.ffff, 10000 times" | ||||
}; | }; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
uint32_t m; | |||||
uint32_t printSize; | uint32_t printSize; | ||||
uint32_t stdioSize; | |||||
uint32_t stdioSize = 0; | |||||
uint32_t printTime; | uint32_t printTime; | ||||
uint32_t stdioTime; | |||||
uint32_t stdioTime = 0; | |||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println(F("Type any character to start")); | Serial.println(F("Type any character to start")); | ||||
while (!Serial.available()); | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println(F("Starting test")); | Serial.println(F("Starting test")); | ||||
if (!sd.begin(SD_CS_PIN)) { | if (!sd.begin(SD_CS_PIN)) { | ||||
sd.errorHalt(); | sd.errorHalt(); |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.print(F("FreeStack: ")); | Serial.print(F("FreeStack: ")); | ||||
Serial.println(FreeStack()); | Serial.println(FreeStack()); | ||||
// fill buffer with known data | // fill buffer with known data | ||||
for (int i = 0; i < sizeof(buf); i++) { | |||||
for (size_t i = 0; i < sizeof(buf); i++) { | |||||
buf[i] = i; | buf[i] = i; | ||||
} | } | ||||
Serial.println(F("type any character to start")); | Serial.println(F("type any character to start")); | ||||
while (Serial.read() <= 0) {} | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// disable sd2 while initializing sd1 | // disable sd2 while initializing sd1 | ||||
pinMode(SD2_CS, OUTPUT); | pinMode(SD2_CS, OUTPUT); | ||||
digitalWrite(SD2_CS, HIGH); | digitalWrite(SD2_CS, HIGH); | ||||
Serial.println(F("Writing SD1:/Dir1/TEST1.bin")); | Serial.println(F("Writing SD1:/Dir1/TEST1.bin")); | ||||
// write data to /Dir1/TEST1.bin on sd1 | // write data to /Dir1/TEST1.bin on sd1 | ||||
for (int i = 0; i < NWRITE; i++) { | |||||
for (uint16_t i = 0; i < NWRITE; i++) { | |||||
if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | ||||
sd1.errorExit("sd1.write"); | sd1.errorExit("sd1.write"); | ||||
} | } | ||||
if (n == 0) { | if (n == 0) { | ||||
break; | break; | ||||
} | } | ||||
if (file2.write(buf, n) != n) { | |||||
if ((int)file2.write(buf, n) != n) { | |||||
sd2.errorExit("write3"); | sd2.errorExit("write3"); | ||||
} | } | ||||
} | } | ||||
if (n != sizeof(buf)) { | if (n != sizeof(buf)) { | ||||
sd2.errorExit("read2"); | sd2.errorExit("read2"); | ||||
} | } | ||||
if (file3.write(buf, n) != n) { | |||||
if ((int)file3.write(buf, n) != n) { | |||||
sd3.errorExit("write2"); | sd3.errorExit("write2"); | ||||
} | } | ||||
} | } | ||||
// Verify content of file3 | // Verify content of file3 | ||||
file3.rewind(); | file3.rewind(); | ||||
Serial.println(F("Verifying content of TEST3.bin")); | Serial.println(F("Verifying content of TEST3.bin")); | ||||
for (int i = 0; i < NWRITE; i++) { | |||||
for (uint16_t i = 0; i < NWRITE; i++) { | |||||
if (file3.read(buf, sizeof(buf)) != sizeof(buf)) { | if (file3.read(buf, sizeof(buf)) != sizeof(buf)) { | ||||
sd3.errorExit("sd3.read"); | sd3.errorExit("sd3.read"); | ||||
} | } | ||||
for (int j = 0; j < sizeof(buf); j++) { | |||||
for (size_t j = 0; j < sizeof(buf); j++) { | |||||
if (j != buf[j]) { | if (j != buf[j]) { | ||||
sd3.errorExit("Verify error"); | sd3.errorExit("Verify error"); | ||||
} | } |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup(void) { | void setup(void) { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (!Serial.available()); | |||||
delay(400); // catch Due reset problem | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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(chipSelect, SPI_HALF_SPEED)) { | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | ||||
cout << F("\nDone\n"); | cout << F("\nDone\n"); | ||||
} | } | ||||
void loop(void) {} | |||||
void loop() {} |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.print(F("FreeStack: ")); | Serial.print(F("FreeStack: ")); | ||||
Serial.println(FreeStack()); | Serial.println(FreeStack()); | ||||
// fill buffer with known data | // fill buffer with known data | ||||
for (int i = 0; i < sizeof(buf); i++) { | |||||
for (size_t i = 0; i < sizeof(buf); i++) { | |||||
buf[i] = i; | buf[i] = i; | ||||
} | } | ||||
Serial.println(F("type any character to start")); | Serial.println(F("type any character to start")); | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// disable sd2 while initializing sd1 | // disable sd2 while initializing sd1 | ||||
pinMode(SD2_CS, OUTPUT); | pinMode(SD2_CS, OUTPUT); | ||||
Serial.println(F("Writing test.bin to sd1")); | Serial.println(F("Writing test.bin to sd1")); | ||||
// write data to /Dir1/test.bin on sd1 | // write data to /Dir1/test.bin on sd1 | ||||
for (int i = 0; i < NWRITE; i++) { | |||||
for (uint16_t i = 0; i < NWRITE; i++) { | |||||
if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | ||||
sd1.errorExit("sd1.write"); | sd1.errorExit("sd1.write"); | ||||
} | } | ||||
if (n == 0) { | if (n == 0) { | ||||
break; | break; | ||||
} | } | ||||
if (file2.write(buf, n) != n) { | |||||
if ((int)file2.write(buf, n) != n) { | |||||
sd2.errorExit("write2"); | sd2.errorExit("write2"); | ||||
} | } | ||||
} | } |
*/ | */ | ||||
const uint8_t chipSelect = SS; | const uint8_t chipSelect = SS; | ||||
#define TEST_FILE "CLUSTER.TST" | |||||
#define TEST_FILE "Cluster.test" | |||||
// file system | // file system | ||||
SdFat sd; | SdFat sd; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
if (!MAINTAIN_FREE_CLUSTER_COUNT) { | if (!MAINTAIN_FREE_CLUSTER_COUNT) { | ||||
cout << F("Please edit SdFatConfig.h and set\n"); | cout << F("Please edit SdFatConfig.h and set\n"); | ||||
cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); | cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); | ||||
} | } | ||||
// F 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) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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(chipSelect, SPI_HALF_SPEED)) { | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { |
// Serial output stream | // Serial output stream | ||||
ArduinoOutStream cout(Serial); | ArduinoOutStream cout(Serial); | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// store error strings in flash to save RAM | |||||
// Store error strings in flash to save RAM. | |||||
#define error(s) sd.errorHalt(F(s)) | #define error(s) sd.errorHalt(F(s)) | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void cidDmp() { | void cidDmp() { | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(1000); | delay(1000); | ||||
cout << F("\nUse a freshly formatted SD for best performance.\n"); | cout << F("\nUse a freshly formatted SD for best performance.\n"); | ||||
uint32_t totalLatency; | uint32_t totalLatency; | ||||
// discard any input | // discard any input | ||||
while (Serial.read() >= 0) {} | |||||
do { | |||||
delay(10); | |||||
} while (Serial.read() >= 0); | |||||
// F( 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) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("FreeStack: ") << FreeStack() << endl; | cout << F("FreeStack: ") << FreeStack() << endl; | ||||
for (uint32_t i = 0; i < n; i++) { | for (uint32_t i = 0; i < n; i++) { | ||||
uint32_t m = micros(); | uint32_t m = micros(); | ||||
if (file.write(buf, sizeof(buf)) != sizeof(buf)) { | if (file.write(buf, sizeof(buf)) != sizeof(buf)) { | ||||
error("write failed"); | |||||
sd.errorPrint("write failed"); | |||||
file.close(); | |||||
return; | |||||
} | } | ||||
m = micros() - m; | m = micros() - m; | ||||
if (maxLatency < m) { | if (maxLatency < m) { | ||||
cout << s/t <<',' << maxLatency << ',' << minLatency; | cout << s/t <<',' << maxLatency << ',' << minLatency; | ||||
cout << ',' << totalLatency/n << endl; | cout << ',' << totalLatency/n << endl; | ||||
} | } | ||||
cout << endl << F("Starting read test, please wait.") << endl; | cout << endl << F("Starting read test, please wait.") << endl; | ||||
cout << endl <<F("read speed and latency") << endl; | cout << endl <<F("read speed and latency") << endl; | ||||
cout << F("speed,max,min,avg") << endl; | cout << F("speed,max,min,avg") << endl; | ||||
cout << F("KB/Sec,usec,usec,usec") << endl; | cout << F("KB/Sec,usec,usec,usec") << endl; | ||||
// do read test | // do read test | ||||
for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) { | for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) { | ||||
file.rewind(); | file.rewind(); | ||||
for (uint32_t i = 0; i < n; i++) { | for (uint32_t i = 0; i < n; i++) { | ||||
buf[BUF_SIZE-1] = 0; | buf[BUF_SIZE-1] = 0; | ||||
uint32_t m = micros(); | uint32_t m = micros(); | ||||
if (file.read(buf, sizeof(buf)) != sizeof(buf)) { | |||||
error("read failed"); | |||||
int32_t nr = file.read(buf, sizeof(buf)); | |||||
if (nr != sizeof(buf)) { | |||||
sd.errorPrint("read failed"); | |||||
file.close(); | |||||
return; | |||||
} | } | ||||
m = micros() - m; | m = micros() - m; | ||||
if (maxLatency < m) { | if (maxLatency < m) { | ||||
error("data check"); | error("data check"); | ||||
} | } | ||||
} | } | ||||
s = file.fileSize(); | |||||
t = millis() - t; | t = millis() - t; | ||||
cout << s/t <<',' << maxLatency << ',' << minLatency; | cout << s/t <<',' << maxLatency << ',' << minLatency; | ||||
cout << ',' << totalLatency/n << endl; | cout << ',' << totalLatency/n << endl; |
char fileName[13] = FILE_BASE_NAME "00.csv"; | char fileName[13] = FILE_BASE_NAME "00.csv"; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(1000); | delay(1000); | ||||
Serial.println(F("Type any character to start")); | Serial.println(F("Type any character to start")); | ||||
while (!Serial.available()) {} | |||||
while (!Serial.available()) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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(chipSelect, SPI_HALF_SPEED)) { | if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | ||||
// Close file and stop. | // Close file and stop. | ||||
file.close(); | file.close(); | ||||
Serial.println(F("Done")); | Serial.println(F("Done")); | ||||
while(1) {} | |||||
SysCall::halt(); | |||||
} | } | ||||
} | } |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(1000); | delay(1000); | ||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup(void) { | void setup(void) { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // Wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("Type any character to start\n"); | cout << F("Type any character to start\n"); | ||||
while (Serial.read() <= 0) {} | while (Serial.read() <= 0) {} |
void setup(void) { | void setup(void) { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
delay(2000); | delay(2000); | ||||
cout << endl << "default formatting" << endl; | cout << endl << "default formatting" << endl; |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup(void) { | void setup(void) { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
// F 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"); |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// read and print CSV test file | // read and print CSV test file | ||||
void readFile() { | void readFile() { | ||||
long lg; | |||||
long lg = 0; | |||||
float f1, f2; | float f1, f2; | ||||
char text[10]; | char text[10]; | ||||
char c1, c2, c3; // space for commas. | char c1, c2, c3; // space for commas. | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
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 |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void setup() { | void setup() { | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
cout << F("Insert an empty SD. Type any character to start.") << endl; | cout << F("Insert an empty SD. Type any character to start.") << endl; | ||||
while (Serial.read() <= 0) {} | |||||
delay(400); // catch Due reset problem | |||||
while (Serial.read() <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
// 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. |
void setup() { | void setup() { | ||||
int c; | int c; | ||||
Serial.begin(9600); | Serial.begin(9600); | ||||
while (!Serial) {} // wait for Leonardo | |||||
// Wait for USB Serial | |||||
while (!Serial) { | |||||
SysCall::yield(); | |||||
} | |||||
Serial.println("Type 'Y' to wipe all data."); | Serial.println("Type 'Y' to wipe all data."); | ||||
while ((c = Serial.read()) <= 0) {} | |||||
while ((c = Serial.read()) <= 0) { | |||||
SysCall::yield(); | |||||
} | |||||
if (c != 'Y') { | if (c != 'Y') { | ||||
sd.errorHalt("Quitting, you did not type 'Y'."); | sd.errorHalt("Quitting, you did not type 'Y'."); | ||||
} | } |
*/ | */ | ||||
#include "FatLibConfig.h" | #include "FatLibConfig.h" | ||||
#if ENABLE_ARDUINO_FEATURES | #if ENABLE_ARDUINO_FEATURES | ||||
#include "SystemInclude.h" | |||||
#include "SysCall.h" | |||||
#include "bufstream.h" | #include "bufstream.h" | ||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
size_t i = 0; | size_t i = 0; | ||||
uint32_t t; | uint32_t t; | ||||
m_line[0] = '\0'; | m_line[0] = '\0'; | ||||
while (!m_hw->available()) {} | |||||
while (!m_hw->available()) { | |||||
SysCall::yield(); | |||||
} | |||||
while (1) { | while (1) { | ||||
t = millis(); | t = millis(); | ||||
* \return true/false. | * \return true/false. | ||||
*/ | */ | ||||
bool seekoff(off_type off, seekdir way) { | bool seekoff(off_type off, seekdir way) { | ||||
(void)off; | |||||
(void)way; | |||||
return false; | return false; | ||||
} | } | ||||
/** Internal - do not use. | /** Internal - do not use. | ||||
* \return true/false. | * \return true/false. | ||||
*/ | */ | ||||
bool seekpos(pos_type pos) { | bool seekpos(pos_type pos) { | ||||
(void)pos; | |||||
return false; | return false; | ||||
} | } | ||||
m_pr->write(str); | m_pr->write(str); | ||||
} | } | ||||
bool seekoff(off_type off, seekdir way) { | bool seekoff(off_type off, seekdir way) { | ||||
(void)off; | |||||
(void)way; | |||||
return false; | return false; | ||||
} | } | ||||
bool seekpos(pos_type pos) { | bool seekpos(pos_type pos) { | ||||
(void)pos; | |||||
return false; | return false; | ||||
} | } | ||||
bool sync() { | bool sync() { |
* | * | ||||
* The BIOS parameter block describes the physical layout of a FAT volume. | * The BIOS parameter block describes the physical layout of a FAT volume. | ||||
*/ | */ | ||||
struct biosParmBlock{ | |||||
struct biosParmBlock { | |||||
/** | /** | ||||
* Count of bytes per sector. This value may take on only the | * Count of bytes per sector. This value may take on only the | ||||
* following values: 512, 1024, 2048 or 4096 | * following values: 512, 1024, 2048 or 4096 |
* \brief FatVolume class | * \brief FatVolume class | ||||
*/ | */ | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include "SystemInclude.h" | |||||
#include "SysCall.h" | |||||
#include "FatLibConfig.h" | #include "FatLibConfig.h" | ||||
#include "FatStructs.h" | #include "FatStructs.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));\ | ||||
DBG_FAIL_MACRO; while (1);} | |||||
DBG_FAIL_MACRO; SysCall::halt();} | |||||
#else // DEBUG_MODE | #else // DEBUG_MODE | ||||
#define DBG_FAIL_MACRO | #define DBG_FAIL_MACRO | ||||
#define DBG_PRINT_IF(b) | #define DBG_PRINT_IF(b) | ||||
} | } | ||||
} | } | ||||
#else // MAINTAIN_FREE_CLUSTER_COUNT | #else // MAINTAIN_FREE_CLUSTER_COUNT | ||||
void setFreeClusterCount(int32_t value) {} | |||||
void updateFreeClusterCount(int32_t change) {} | |||||
void setFreeClusterCount(int32_t value) { | |||||
(void)value; | |||||
} | |||||
void updateFreeClusterCount(int32_t change) { | |||||
(void)change; | |||||
} | |||||
#endif // MAINTAIN_FREE_CLUSTER_COUNT | #endif // MAINTAIN_FREE_CLUSTER_COUNT | ||||
// block caches | // block caches |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | #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*)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*)str; | |||||
return p - (const char*)str; | |||||
} | } | ||||
#endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | #endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// private | // private | ||||
bool StdioStream::fillBuf() { | bool StdioStream::fillBuf() { | ||||
if (!(m_flags & | if (!(m_flags & | ||||
F_SRD)) { /////////////check for F_ERR and F_EOF ??///////////////// | |||||
F_SRD)) { // check for F_ERR and F_EOF ??///////////////// | |||||
if (!(m_flags & F_SRW)) { | if (!(m_flags & F_SRW)) { | ||||
m_flags |= F_ERR; | m_flags |= F_ERR; | ||||
return false; | return false; | ||||
// private | // private | ||||
bool StdioStream::flushBuf() { | bool StdioStream::flushBuf() { | ||||
if (!(m_flags & | if (!(m_flags & | ||||
F_SWR)) { /////////////////check for F_ERR ??//////////////////////// | |||||
F_SWR)) { // check for F_ERR ??//////////////////////// | |||||
if (!(m_flags & F_SRW)) { | if (!(m_flags & F_SRW)) { | ||||
m_flags |= F_ERR; | m_flags |= F_ERR; | ||||
return false; | return false; |
return n < 0 ? 0 : n; | return n < 0 ? 0 : n; | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
#if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||||
#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. |
/* FatLib Library | |||||
* Copyright (C) 2013 by William Greiman | |||||
* | |||||
* This file is part of the FatLib 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 FatLib Library. If not, see | |||||
* <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef SysCall_h | |||||
#define SysCall_h | |||||
/** | |||||
* \file | |||||
* \brief SysCall class | |||||
*/ | |||||
#if defined(ARDUINO) | |||||
#include <Arduino.h> | |||||
#include <SPI.h> | |||||
#elif defined(PLATFORM_ID) // Only defined if a Particle device | |||||
#include "application.h" | |||||
#else // defined(ARDUINO) | |||||
#error "Unknown system" | |||||
#endif // defined(ARDUINO) | |||||
#ifndef F | |||||
/** Define macro for strings stored in flash. */ | |||||
#define F(str) (str) | |||||
#endif // F | |||||
/** | |||||
* \class SysCall | |||||
* \brief SysCall - Class to wrap system calls. | |||||
*/ | |||||
class SysCall { | |||||
public: | |||||
/** Halt execution of this thread. */ | |||||
static void halt() { | |||||
while (1) { | |||||
yield(); | |||||
} | |||||
} | |||||
/** Yield to other threads. */ | |||||
static void yield(); | |||||
}; | |||||
#if defined(ARDUINO) | |||||
inline void SysCall::yield() { | |||||
// Use the external Arduino yield() function. | |||||
::yield(); | |||||
} | |||||
#elif defined(PLATFORM_ID) // Only defined if a Particle device | |||||
inline void SysCall::yield() { | |||||
Particle.process(); | |||||
} | |||||
#else // defined(ARDUINO) | |||||
inline void SysCall::yield() {} | |||||
#endif // defined(ARDUINO) | |||||
#endif // SysCall_h |
pos->position = m_pos; | pos->position = m_pos; | ||||
} | } | ||||
bool seekoff(off_type off, seekdir way) { | bool seekoff(off_type off, seekdir way) { | ||||
(void)off; | |||||
(void)way; | |||||
return false; | return false; | ||||
} | } | ||||
bool seekpos(pos_type pos) { | bool seekpos(pos_type pos) { | ||||
} | } | ||||
} | } | ||||
bool seekoff(off_type off, seekdir way) { | bool seekoff(off_type off, seekdir way) { | ||||
(void)off; | |||||
(void)way; | |||||
return false; | return false; | ||||
} | } | ||||
bool seekpos(pos_type pos) { | bool seekpos(pos_type pos) { |
#else // __AVR__ | #else // __AVR__ | ||||
falseOk = falseOk && c == falsePtr[i]; | falseOk = falseOk && c == falsePtr[i]; | ||||
trueOk = trueOk && c == truePtr[i]; | trueOk = trueOk && c == truePtr[i]; | ||||
#endif // __AVR | |||||
#endif // __AVR__ | |||||
if (trueOk == false && falseOk == false) { | if (trueOk == false && falseOk == false) { | ||||
break; | break; | ||||
} | } |
* \file | * \file | ||||
* \brief FreeStack() function. | * \brief FreeStack() function. | ||||
*/ | */ | ||||
#ifdef __arm__ | |||||
extern "C" char* sbrk(int incr); | |||||
static int FreeStack() { | |||||
char top; | |||||
return &top - reinterpret_cast<char*>(sbrk(0)); | |||||
} | |||||
#elif __AVR__ // __arm__ | |||||
#if defined(__AVR__) || defined(DOXYGEN) | |||||
/** boundary between stack and heap. */ | /** boundary between stack and heap. */ | ||||
extern char *__brkval; | extern char *__brkval; | ||||
/** End of bss section.*/ | /** End of bss section.*/ | ||||
static int FreeStack() { | static int FreeStack() { | ||||
char top; | char top; | ||||
return __brkval ? &top - __brkval : &top - &__bss_end; | return __brkval ? &top - __brkval : &top - &__bss_end; | ||||
} | |||||
} | |||||
#elif defined(PLATFORM_ID) // Particle board | #elif defined(PLATFORM_ID) // Particle board | ||||
static int FreeStack() { | static int FreeStack() { | ||||
return System.freeMemory(); | return System.freeMemory(); | ||||
} | } | ||||
#elif defined(__arm__) | |||||
extern "C" char* sbrk(int incr); | |||||
static int FreeStack() { | |||||
char top; | |||||
return &top - reinterpret_cast<char*>(sbrk(0)); | |||||
} | |||||
#else | #else | ||||
#warning FreeStack is not defined for this system. | #warning FreeStack is not defined for this system. | ||||
#endif // __arm | |||||
static int FreeStack() { | |||||
return 0; | |||||
} | |||||
#endif | |||||
#endif // FreeStack_h | #endif // FreeStack_h |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorHalt(Print* pr) { | void SdFatBase::errorHalt(Print* pr) { | ||||
errorPrint(pr); | errorPrint(pr); | ||||
while (1) {} | |||||
SysCall::halt(); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorHalt(Print* pr, char const* msg) { | void SdFatBase::errorHalt(Print* pr, char const* msg) { | ||||
errorPrint(pr, msg); | errorPrint(pr, msg); | ||||
while (1) {} | |||||
SysCall::halt(); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorPrint(Print* pr) { | void SdFatBase::errorPrint(Print* pr) { | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::initErrorHalt(Print* pr) { | void SdFatBase::initErrorHalt(Print* pr) { | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
while (1) {} | |||||
SysCall::halt(); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::initErrorHalt(Print* pr, char const *msg) { | void SdFatBase::initErrorHalt(Print* pr, char const *msg) { | ||||
pr->println(msg); | pr->println(msg); | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
} | } | ||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | ||||
pr->print(F("error: ")); | pr->print(F("error: ")); | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { | void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { | ||||
errorPrint(pr, msg); | errorPrint(pr, msg); | ||||
while (1) {} | |||||
SysCall::halt(); | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { | void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { | ||||
pr->println(msg); | pr->println(msg); | ||||
initErrorPrint(pr); | initErrorPrint(pr); | ||||
} | } | ||||
#endif // defined(ARDUINO) || defined(DOXYGEN) | |||||
#endif // defined(ARDUINO) || defined(DOXYGEN) |
#endif // ARDUINO | #endif // ARDUINO | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
/** SdFat version YYYYMMDD */ | /** SdFat version YYYYMMDD */ | ||||
#define SD_FAT_VERSION 20160123 | |||||
#define SD_FAT_VERSION 20160212 | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
* \class SdBaseFile | * \class SdBaseFile | ||||
* \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) | |||||
#if defined(ARDUINO) || defined(DOXYGEN) | |||||
/** %Print msg, any SD error code, and halt. | /** %Print msg, any SD error code, and halt. | ||||
* | * | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
* \param[in] pr Print destination. | * \param[in] pr Print destination. | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void errorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
void errorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
/** %Print msg, any SD error code. | /** %Print msg, any SD error code. | ||||
* | * | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
* \param[in] pr Print destination. | * \param[in] pr Print destination. | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void errorPrint(Print* pr, const __FlashStringHelper* msg); | |||||
void errorPrint(Print* pr, const __FlashStringHelper* msg); | |||||
/**Print message, error details, and halt after SdFat::init() fails. | /**Print message, error details, and halt after SdFat::init() fails. | ||||
* | * | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
* \param[in] pr Print device for message. | * \param[in] pr Print device for message. | ||||
* \param[in] msg Message to print. | * \param[in] msg Message to print. | ||||
*/ | */ | ||||
void initErrorHalt(Print* pr, const __FlashStringHelper* msg); | |||||
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) | |||||
#endif // defined(ARDUINO) || defined(DOXYGEN) | |||||
private: | private: | ||||
uint8_t cardErrorCode() { | uint8_t cardErrorCode() { | ||||
return m_sdCard.errorCode(); | return m_sdCard.errorCode(); | ||||
SdFat() { | SdFat() { | ||||
m_spi.setSpiIf(0); | m_spi.setSpiIf(0); | ||||
} | } | ||||
SdFat(uint8_t spiIf) { | |||||
explicit SdFat(uint8_t spiIf) { | |||||
m_spi.setSpiIf(spiIf < SPI_INTERFACE_COUNT ? spiIf : 0); | m_spi.setSpiIf(spiIf < SPI_INTERFACE_COUNT ? spiIf : 0); | ||||
} | } | ||||
#endif // IMPLEMENT_SPI_INTERFACE_SELECTION | |||||
#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. | ||||
bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) { | bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) { | ||||
return card()->begin(&m_spi, csPin, divisor); | return card()->begin(&m_spi, csPin, divisor); | ||||
} | } | ||||
private: | private: | ||||
SpiDefault_t m_spi; | SpiDefault_t m_spi; | ||||
}; | }; |
*/ | */ | ||||
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; | |||||
} | |||||
} | } | ||||
#else // CORE_TEENSY | #else // CORE_TEENSY | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
* @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; | ||||
#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, uint8_t 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> | ||||
/** GpioPinMap type */ | /** GpioPinMap type */ | ||||
struct GpioPinMap_t { | struct GpioPinMap_t { | ||||
volatile uint8_t* pin; /**< address of PIN for this pin */ | |||||
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* port; /**< address of PORT for this pin */ | volatile uint8_t* port; /**< address of PORT for this pin */ | ||||
uint8_t mask; /**< bit mask for this pin */ | uint8_t mask; /**< bit mask for this pin */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { | void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { | ||||
uint8_t s; | uint8_t s; | ||||
if (address > (uint8_t*)0X3F) { | |||||
if (address > reinterpret_cast<uint8_t*>(0X3F)) { | |||||
s = SREG; | s = SREG; | ||||
cli(); | cli(); | ||||
} | } | ||||
} else { | } else { | ||||
*address &= ~mask; | *address &= ~mask; | ||||
} | } | ||||
if (address > (uint8_t*)0X3F) { | |||||
if (address > reinterpret_cast<uint8_t*>(0X3F)) { | |||||
SREG = s; | SREG = s; | ||||
} | } | ||||
} | } | ||||
*/ | */ | ||||
static inline __attribute__((always_inline)) | static inline __attribute__((always_inline)) | ||||
void fastDigitalToggle(uint8_t pin) { | void fastDigitalToggle(uint8_t pin) { | ||||
if (pinReg(pin) > (uint8_t*)0X3F) { | |||||
if (pinReg(pin) > reinterpret_cast<uint8_t*>(0X3F)) { | |||||
// must write bit to high address port | // must write bit to high address port | ||||
*pinReg(pin) = pinMask(pin); | *pinReg(pin) = pinMask(pin); | ||||
} else { | } else { | ||||
/** 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(); | ||||
} | } | ||||
//---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||
} | } | ||||
}; | }; | ||||
#endif // DigitalPin_h | #endif // DigitalPin_h | ||||
/** @} */ | |||||
/** @} */ |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// SD operation timeouts | // SD operation timeouts | ||||
/** init timeout ms */ | /** init timeout ms */ | ||||
uint16_t const SD_INIT_TIMEOUT = 2000; | |||||
unsigned const SD_INIT_TIMEOUT = 2000; | |||||
/** erase timeout ms */ | /** erase timeout ms */ | ||||
uint16_t const SD_ERASE_TIMEOUT = 10000; | |||||
unsigned const SD_ERASE_TIMEOUT = 10000; | |||||
/** read timeout ms */ | /** read timeout ms */ | ||||
uint16_t const SD_READ_TIMEOUT = 300; | |||||
unsigned const SD_READ_TIMEOUT = 300; | |||||
/** write time out ms */ | /** write time out ms */ | ||||
uint16_t const SD_WRITE_TIMEOUT = 600; | |||||
unsigned const SD_WRITE_TIMEOUT = 600; | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
// SD card commands | // SD card commands | ||||
/** GO_IDLE_STATE - init card in spi mode if CS low */ | /** GO_IDLE_STATE - init card in spi mode if CS low */ |
virtual void beginTransaction(uint8_t divisor); | virtual void beginTransaction(uint8_t divisor); | ||||
/** | /** | ||||
* End SPI transaction. | * End SPI transaction. | ||||
*/ | |||||
*/ | |||||
virtual void endTransaction(); | virtual void endTransaction(); | ||||
/** Receive a byte. | /** Receive a byte. | ||||
* | * | ||||
* \param[in] chipSelectPin SD card chip select pin. | * \param[in] chipSelectPin SD card chip select pin. | ||||
*/ | */ | ||||
void begin(uint8_t chipSelectPin) { | void begin(uint8_t chipSelectPin) { | ||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
SPI.begin(); | SPI.begin(); | ||||
} | } | ||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. | ||||
*/ | */ | ||||
void beginTransaction(uint8_t divisor) { | void beginTransaction(uint8_t divisor) { | ||||
#if ENABLE_SPI_TRANSACTIONS | #if ENABLE_SPI_TRANSACTIONS | ||||
SPI.beginTransaction(SPISettings()); | |||||
SPI.beginTransaction(SPISettings()); | |||||
#else // #if ENABLE_SPI_TRANSACTIONS | #else // #if ENABLE_SPI_TRANSACTIONS | ||||
SPI.setBitOrder(MSBFIRST); | |||||
SPI.setDataMode(SPI_MODE0); | |||||
SPI.setBitOrder(MSBFIRST); | |||||
SPI.setDataMode(SPI_MODE0); | |||||
#endif // #if ENABLE_SPI_TRANSACTIONS | #endif // #if ENABLE_SPI_TRANSACTIONS | ||||
#ifndef SPI_CLOCK_DIV128 | #ifndef SPI_CLOCK_DIV128 | ||||
} | } | ||||
/** | /** | ||||
* End SPI transaction. | * End SPI transaction. | ||||
*/ | |||||
*/ | |||||
void endTransaction() { | void endTransaction() { | ||||
#if ENABLE_SPI_TRANSACTIONS | #if ENABLE_SPI_TRANSACTIONS | ||||
SPI.endTransaction(); | SPI.endTransaction(); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
#endif // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||||
#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 | ||||
#if SD_SPI_CONFIGURATION > 1 || defined(DOXYGEN) | #if SD_SPI_CONFIGURATION > 1 || defined(DOXYGEN) | ||||
#ifdef ARDUINO | #ifdef ARDUINO | ||||
#include "SoftSPI.h" | #include "SoftSPI.h" | ||||
#elif defined(PLATFORM_ID) //Only defined if a Particle device | |||||
#elif defined(PLATFORM_ID) // Only defined if a Particle device | |||||
#include "SoftSPIParticle.h" | #include "SoftSPIParticle.h" | ||||
#endif // ARDUINO | #endif // ARDUINO | ||||
/** | /** | ||||
* Initialize hardware SPI - dummy for soft SPI | * Initialize hardware SPI - dummy for soft SPI | ||||
* \param[in] divisor SCK divisor - ignored. | * \param[in] divisor SCK divisor - ignored. | ||||
*/ | */ | ||||
void beginTransaction(uint8_t divisor) {} | |||||
void beginTransaction(uint8_t divisor) { | |||||
(void)divisor; | |||||
} | |||||
/** | /** | ||||
* End SPI transaction - dummy for soft SPI | * End SPI transaction - dummy for soft SPI | ||||
*/ | */ |
#if USE_SD_CRC | #if USE_SD_CRC | ||||
// form message | // form message | ||||
uint8_t d[6] = {cmd , pa[3], pa[2], pa[1], pa[0]}; | uint8_t d[6] = {cmd , pa[3], pa[2], pa[1], pa[0]}; | ||||
d[0] |= 0X40; | d[0] |= 0X40; | ||||
// add crc | // add crc | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::isBusy() { | bool SdSpiCard::isBusy() { | ||||
bool rtn = true; | |||||
bool selected = m_selected; | |||||
chipSelectLow(); | |||||
for (uint8_t i = 0; i < 8; i++) { | for (uint8_t i = 0; i < 8; i++) { | ||||
if (0XFF == spiReceive()) { | if (0XFF == spiReceive()) { | ||||
return false; | |||||
rtn = false; | |||||
break; | |||||
} | } | ||||
} | } | ||||
return true; | |||||
if (!selected) { | |||||
chipSelectHigh(); | |||||
} | |||||
return rtn; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | ||||
if (!readData(dst, 512)) { | if (!readData(dst, 512)) { | ||||
goto fail; | goto fail; | ||||
} | } | ||||
chipSelectHigh(); | |||||
chipSelectHigh(); | |||||
return true; | return true; | ||||
fail: | fail: | ||||
return false; | return false; | ||||
} | } | ||||
for (uint16_t b = 0; b < count; b++, dst += 512) { | for (uint16_t b = 0; b < count; b++, dst += 512) { | ||||
if (!readData(dst)) { | |||||
if (!readData(dst, 512)) { | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::readData(uint8_t *dst) { | bool SdSpiCard::readData(uint8_t *dst) { | ||||
return readData(dst, 512); | |||||
bool selected = m_selected; | |||||
chipSelectLow(); | |||||
if (!readData(dst, 512)) { | |||||
return false; | |||||
} | |||||
if (!selected) { | |||||
chipSelectHigh(); | |||||
} | |||||
return true; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::readData(uint8_t* dst, size_t count) { | bool SdSpiCard::readData(uint8_t* dst, size_t count) { | ||||
} | } | ||||
} | } | ||||
return writeStop(); | return writeStop(); | ||||
fail: | fail: | ||||
chipSelectHigh(); | chipSelectHigh(); | ||||
return false; | |||||
return false; | |||||
} | } | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
bool SdSpiCard::writeData(const uint8_t* src) { | bool SdSpiCard::writeData(const uint8_t* src) { | ||||
bool selected = m_selected; | |||||
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); | |||||
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; | ||||
} | } | ||||
if (!selected) { | |||||
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; | ||||
} | } |
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_selected(false), 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. | ||||
* the value false is returned for failure. | * the value false is returned for failure. | ||||
*/ | */ | ||||
bool writeBlocks(uint32_t block, const uint8_t* src, size_t count); | bool writeBlocks(uint32_t block, const uint8_t* src, size_t count); | ||||
/** Write one data block in a multiple block write sequence | |||||
/** Write one data block in a multiple block write sequence. | |||||
* \param[in] src Pointer to the location of the data to be written. | * \param[in] src Pointer to the location of the data to be written. | ||||
* \return The value true is returned for success and | * \return The value true is returned for success and | ||||
* the value false is returned for failure. | * the value false is returned for failure. | ||||
bool init(uint8_t sckDivisor = 2, uint8_t chipSelectPin = SS) { | bool init(uint8_t sckDivisor = 2, uint8_t chipSelectPin = SS) { | ||||
return begin(chipSelectPin, sckDivisor); | return begin(chipSelectPin, sckDivisor); | ||||
} | } | ||||
private: | private: | ||||
bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS, | bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS, | ||||
uint8_t sckDivisor = SPI_FULL_SPEED) { | uint8_t sckDivisor = SPI_FULL_SPEED) { | ||||
(void)spi; | |||||
(void)chipSelectPin; | |||||
(void)sckDivisor; | |||||
return false; | return false; | ||||
} | } | ||||
SpiDefault_t m_spi; | SpiDefault_t m_spi; |
/* Arduino SdFat Library | /* Arduino SdFat Library | ||||
* Copyright (C) 2012 by William Greiman | |||||
* Copyright (C) 2016 by William Greiman | |||||
* | * | ||||
* This file is part of the Arduino SdFat Library | * This file is part of the Arduino SdFat Library | ||||
* | * | ||||
static uint32_t bugDelay = 0; // fix for SPI DMA bug. | static uint32_t bugDelay = 0; // fix for SPI DMA bug. | ||||
static volatile bool SPI_DMA_TransferCompleted = false; | static volatile bool SPI_DMA_TransferCompleted = false; | ||||
//static uint8_t m_spiIf = 1; | |||||
static SPIClass* const spiPtr[] = { | static SPIClass* const spiPtr[] = { | ||||
&SPI | |||||
&SPI | |||||
#if Wiring_SPI1 | #if Wiring_SPI1 | ||||
,&SPI1 | |||||
, &SPI1 | |||||
#if Wiring_SPI2 | #if Wiring_SPI2 | ||||
,&SPI2 | |||||
, &SPI2 | |||||
#endif // Wiring_SPI2 | #endif // Wiring_SPI2 | ||||
#endif // Wiring_SPI1 | #endif // Wiring_SPI1 | ||||
}; | }; | ||||
// delay for SPI transfer done callback too soon bug. | // delay for SPI transfer done callback too soon bug. | ||||
bugDelay = 24*divisor*(1 + m_spiIf)/60; | bugDelay = 24*divisor*(1 + m_spiIf)/60; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | |||||
//----------------------------------------------------------------------------- | |||||
void SdSpi::endTransaction() { | void SdSpi::endTransaction() { | ||||
} | } | ||||
//------------------------------------------------------------------------------ | |||||
//----------------------------------------------------------------------------- | |||||
/** SPI receive a byte */ | /** SPI receive a byte */ | ||||
uint8_t SdSpi::receive() { | uint8_t SdSpi::receive() { | ||||
return spiPtr[m_spiIf]->transfer(0xFF); | return spiPtr[m_spiIf]->transfer(0xFF); | ||||
} | } | ||||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||||
uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||||
SPI_DMA_TransferCompleted = false; | SPI_DMA_TransferCompleted = false; | ||||
spiPtr[m_spiIf]->transfer(0, buf, n, SD_SPI_DMA_TransferComplete_Callback); | spiPtr[m_spiIf]->transfer(0, buf, n, SD_SPI_DMA_TransferComplete_Callback); | ||||
while(!SPI_DMA_TransferCompleted); | |||||
while (!SPI_DMA_TransferCompleted) {} | |||||
if (bugDelay) { | if (bugDelay) { | ||||
delayMicroseconds(bugDelay); | delayMicroseconds(bugDelay); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
//------------------------------------------------------------------------------ | |||||
//----------------------------------------------------------------------------- | |||||
/** SPI send a byte */ | /** SPI send a byte */ | ||||
void SdSpi::send(uint8_t b) { | void SdSpi::send(uint8_t b) { | ||||
spiPtr[m_spiIf]->transfer(b); | spiPtr[m_spiIf]->transfer(b); | ||||
} | } | ||||
//----------------------------------------------------------------------------- | |||||
//----------------------------------------------------------------------------- | |||||
void SdSpi::send(const uint8_t* buf , size_t n) { | void SdSpi::send(const uint8_t* buf , size_t n) { | ||||
SPI_DMA_TransferCompleted = false; | SPI_DMA_TransferCompleted = false; | ||||
spiPtr[m_spiIf]->transfer((void *)buf, 0, n, SD_SPI_DMA_TransferComplete_Callback); | |||||
while(!SPI_DMA_TransferCompleted); | |||||
spiPtr[m_spiIf]->transfer(const_cast<uint8_t*>(buf), 0, n, | |||||
SD_SPI_DMA_TransferComplete_Callback); | |||||
while (!SPI_DMA_TransferCompleted) {} | |||||
if (bugDelay) { | if (bugDelay) { | ||||
delayMicroseconds(bugDelay); | delayMicroseconds(bugDelay); | ||||
} | } | ||||
} | } | ||||
#endif //defined(PLATFORM_ID) | |||||
#endif // defined(PLATFORM_ID) |
* Initialize SPI pins. | * Initialize SPI pins. | ||||
*/ | */ | ||||
void SdSpi::begin(uint8_t chipSelectPin) { | void SdSpi::begin(uint8_t chipSelectPin) { | ||||
pinMode(chipSelectPin, OUTPUT); | |||||
digitalWrite(chipSelectPin, HIGH); | |||||
SPI.begin(); | SPI.begin(); | ||||
} | } | ||||
/** Set SPI options for access to SD/SDHC cards. | /** Set SPI options for access to SD/SDHC cards. |
/* Arduino SdFat Library | |||||
* Copyright (C) 2016 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 SystemInclude_h | #ifndef SystemInclude_h | ||||
#define SystemInclude_h | #define SystemInclude_h | ||||
#if defined(ARDUINO) | #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 | |||||
#include "FatLib/SysCall.h" | |||||
#elif defined(PLATFORM_ID) // Only defined if a Particle device | |||||
#include "SysCall.h" | |||||
#else // System type | |||||
#error Unknown System. | |||||
#endif // System type | |||||
#endif // SystemInclude_h | #endif // SystemInclude_h |
#include <SdFat.h> | #include <SdFat.h> | ||||
#include <SdFatTestSuite.h> | #include <SdFatTestSuite.h> | ||||
SdFat SD; | SdFat SD; | ||||
#define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||||
#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | ||||
void setup() { | void setup() { | ||||
boolean b; | boolean b; |
#include <SdFat.h> | #include <SdFat.h> | ||||
#include <SdFatTestSuite.h> | #include <SdFatTestSuite.h> | ||||
SdFat SD; | SdFat SD; | ||||
#define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||||
#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | ||||
void setup() { | void setup() { |
#include <SdFat.h> | #include <SdFat.h> | ||||
#include <SdFatTestSuite.h> | #include <SdFatTestSuite.h> | ||||
SdFat SD; | SdFat SD; | ||||
#define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||||
#define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | ||||
void setup() { | void setup() { |
uint32_t t2 = millis(); | uint32_t t2 = millis(); | ||||
// check file content | // check file content | ||||
if (strlen(name) != nr || strncmp(name, buf, nr)) { | |||||
if (strlen(name) != (size_t)nr || strncmp(name, buf, nr)) { | |||||
error("content compare failed"); | error("content compare failed"); | ||||
} | } | ||||
if (!file.close()) error("close read failed"); | if (!file.close()) error("close read failed"); |
#include <SdFat.h> | #include <SdFat.h> | ||||
#include <SdFatTestSuite.h> | #include <SdFatTestSuite.h> | ||||
SdFat sd; | SdFat sd; | ||||
char *testName = "SDFAT.TST"; | |||||
const char *testName = "SDFAT.TST"; | |||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
void fstreamOpen() { | void fstreamOpen() { | ||||
ios::openmode nocreate[] = {ios::in, ios::in | ios::out}; | ios::openmode nocreate[] = {ios::in, ios::in | ios::out}; |
char name[260]; | char name[260]; | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
char* testName[] = { | |||||
const char* testName[] = { | |||||
"low.low", | "low.low", | ||||
"low.Mix", | "low.Mix", | ||||
"low.UP", | "low.UP", | ||||
return false; | return false; | ||||
} | } | ||||
for (i = 1; i < (len - 4); i++) { | for (i = 1; i < (len - 4); i++) { | ||||
if (name[i] != ('0' + (i + 1) %10)) { | |||||
if (name[i] != (char)('0' + (i + 1) %10)) { | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
char* p = ".txt"; | |||||
const char* p = ".txt"; | |||||
while (*p) { | while (*p) { | ||||
if (name[i++] != *p++) { | if (name[i++] != *p++) { | ||||
return false; | return false; | ||||
for (i = 1; i < (len - 4); i++) { | for (i = 1; i < (len - 4); i++) { | ||||
name[i] = '0' + (i + 1) %10; | name[i] = '0' + (i + 1) %10; | ||||
} | } | ||||
char* p = ".txt"; | |||||
const char* p = ".txt"; | |||||
while (*p) name[i++] = *p++; | while (*p) name[i++] = *p++; | ||||
name[i] = 0; | name[i] = 0; | ||||
} | } | ||||
void basicTest() { | void basicTest() { | ||||
size_t i; | size_t i; | ||||
size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | ||||
uint16_t index; | |||||
uint16_t maxIndex = 0; | uint16_t maxIndex = 0; | ||||
makeName('Z', 256); | makeName('Z', 256); |
// Serial input stream | // Serial input stream | ||||
ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); | ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); | ||||
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||
char* testName[] = { | |||||
const char* testName[] = { | |||||
"low.low", | "low.low", | ||||
"low.Mix", | "low.Mix", | ||||
"low.UP", | "low.UP", | ||||
return false; | return false; | ||||
} | } | ||||
for (i = 1; i < (len - 4); i++) { | for (i = 1; i < (len - 4); i++) { | ||||
if (name[i] != ('0' + (i + 1) %10)) { | |||||
if (name[i] != (char)('0' + (i + 1) %10)) { | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
char* p = ".txt"; | |||||
const char* p = ".txt"; | |||||
while (*p) { | while (*p) { | ||||
if (name[i++] != *p++) { | if (name[i++] != *p++) { | ||||
return false; | return false; | ||||
for (i = 1; i < (len - 4); i++) { | for (i = 1; i < (len - 4); i++) { | ||||
name[i] = '0' + (i + 1) %10; | name[i] = '0' + (i + 1) %10; | ||||
} | } | ||||
char* p = ".txt"; | |||||
const char* p = ".txt"; | |||||
while (*p) name[i++] = *p++; | while (*p) name[i++] = *p++; | ||||
name[i] = 0; | name[i] = 0; | ||||
} | } | ||||
void basicTest() { | void basicTest() { | ||||
size_t i; | size_t i; | ||||
size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | ||||
uint16_t index; | |||||
uint16_t maxIndex = 0; | uint16_t maxIndex = 0; | ||||
makeName('Z', 256); | makeName('Z', 256); |
void ostreamStr() { | void ostreamStr() { | ||||
char buf[40]; | char buf[40]; | ||||
obufstream ob(buf, sizeof(buf)); | obufstream ob(buf, sizeof(buf)); | ||||
char* c = "c"; | |||||
char c[] = "c"; | |||||
const char* cc = "CC"; | const char* cc = "CC"; | ||||
signed char* sc = (signed char*)"sc"; | signed char* sc = (signed char*)"sc"; | ||||
const signed char* csc = (const signed char*)"CSC"; | const signed char* csc = (const signed char*)"CSC"; |
12 Feb 2016 | |||||
Mods for Particle.io boards. | |||||
Features for shared SPI with multiple block write. | |||||
23 Jan 2016 | 23 Jan 2016 | ||||
New Examples. | New Examples. |
<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="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"/> | |||||
<area shape="rect" id="node2" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="324,244,429,271"/> | |||||
<area shape="rect" id="node5" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="212,95,285,121"/> | |||||
<area shape="rect" id="node4" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="370,319,474,345"/> | |||||
<area shape="rect" id="node9" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="103,244,197,271"/> | |||||
<area shape="rect" id="node10" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="201,169,297,196"/> | |||||
<area shape="rect" id="node11" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="221,244,300,271"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<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 "SystemInclude.h"</code><br /> | |||||
<code>#include "<a class="el" href="_sys_call_8h.html">SysCall.h</a>"</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="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"/> | |||||
<area shape="rect" id="node2" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="5,543,111,569"/> | |||||
<area shape="rect" id="node5" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="440,543,519,569"/> | |||||
<area shape="rect" id="node6" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="347,95,438,121"/> | |||||
<area shape="rect" id="node4" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="51,617,155,644"/> | |||||
<area shape="rect" id="node8" href="iostream_8h.html" title="iostream class " alt="" coords="318,169,401,196"/> | |||||
<area shape="rect" id="node9" href="istream_8h.html" title="istream class " alt="" coords="220,244,296,271"/> | |||||
<area shape="rect" id="node16" href="ostream_8h.html" title="ostream class " alt="" coords="321,244,401,271"/> | |||||
<area shape="rect" id="node10" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="245,319,295,345"/> | |||||
<area shape="rect" id="node11" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="233,393,307,420"/> | |||||
<area shape="rect" id="node14" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="264,543,359,569"/> | |||||
<area shape="rect" id="node15" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="234,468,330,495"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<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="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"/> | |||||
<area shape="rect" id="node5" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="107,169,212,196"/> | |||||
<area shape="rect" id="node8" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="339,169,433,196"/> | |||||
<area shape="rect" id="node9" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="197,95,293,121"/> | |||||
<area shape="rect" id="node7" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="151,244,255,271"/> | |||||
<area shape="rect" id="node10" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="236,169,315,196"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<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="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"/> | |||||
<area shape="rect" id="node2" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="115,244,211,271"/> | |||||
<area shape="rect" id="node9" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="283,169,356,196"/> | |||||
<area shape="rect" id="node12" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="381,95,487,121"/> | |||||
<area shape="rect" id="node4" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="124,319,203,345"/> | |||||
<area shape="rect" id="node5" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="337,319,443,345"/> | |||||
<area shape="rect" id="node8" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="5,319,100,345"/> | |||||
<area shape="rect" id="node7" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="383,393,487,420"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<p><a class="el" href="class_fat_volume.html" title="Access FAT16 and FAT32 volumes on raw file devices. ">FatVolume</a> class. | <p><a class="el" href="class_fat_volume.html" title="Access FAT16 and FAT32 volumes on raw file devices. ">FatVolume</a> class. | ||||
<a href="#details">More...</a></p> | <a href="#details">More...</a></p> | ||||
<div class="textblock"><code>#include <stddef.h></code><br /> | <div class="textblock"><code>#include <stddef.h></code><br /> | ||||
<code>#include "SystemInclude.h"</code><br /> | |||||
<code>#include "<a class="el" href="_sys_call_8h.html">SysCall.h</a>"</code><br /> | |||||
<code>#include "<a class="el" href="_fat_lib_config_8h.html">FatLibConfig.h</a>"</code><br /> | <code>#include "<a class="el" href="_fat_lib_config_8h.html">FatLibConfig.h</a>"</code><br /> | ||||
<code>#include "<a class="el" href="_fat_structs_8h.html">FatStructs.h</a>"</code><br /> | <code>#include "<a class="el" href="_fat_structs_8h.html">FatStructs.h</a>"</code><br /> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
<div class="dyncontent"> | <div class="dyncontent"> | ||||
<div class="center"><img src="_fat_volume_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h" alt=""/></div> | <div class="center"><img src="_fat_volume_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_fat_volume_8h"> | ||||
<area shape="rect" id="node3" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="97,95,203,121"/> | |||||
<area shape="rect" id="node6" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="227,95,321,121"/> | |||||
<area shape="rect" id="node5" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="142,169,246,196"/> | |||||
<area shape="rect" id="node3" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="97,95,176,121"/> | |||||
<area shape="rect" id="node4" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="200,95,305,121"/> | |||||
<area shape="rect" id="node7" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="329,95,424,121"/> | |||||
<area shape="rect" id="node6" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="245,169,349,196"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><div class="textblock"><div class="dynheader"> | </div><div class="textblock"><div class="dynheader"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</div> | </div> | ||||
</div><!-- top --> | </div><!-- top --> | ||||
<div class="header"> | <div class="header"> | ||||
<div class="summary"> | |||||
<a href="#func-members">Functions</a> | | |||||
<a href="#var-members">Variables</a> </div> | |||||
<div class="headertitle"> | <div class="headertitle"> | ||||
<div class="title">FreeStack.h File Reference</div> </div> | <div class="title">FreeStack.h File Reference</div> </div> | ||||
</div><!--header--> | </div><!--header--> | ||||
<div class="contents"> | <div class="contents"> | ||||
<p>FreeStack() function. | |||||
<p><a class="el" href="_free_stack_8h.html#a2c0121d5649d35329a8d0a71e4ffb89b">FreeStack()</a> function. | |||||
<a href="#details">More...</a></p> | <a href="#details">More...</a></p> | ||||
<table class="memberdecls"> | |||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a> | |||||
Functions</h2></td></tr> | |||||
<tr class="memitem:a2c0121d5649d35329a8d0a71e4ffb89b"><td class="memItemLeft" align="right" valign="top">static int </td><td class="memItemRight" valign="bottom"><a class="el" href="_free_stack_8h.html#a2c0121d5649d35329a8d0a71e4ffb89b">FreeStack</a> ()</td></tr> | |||||
<tr class="separator:a2c0121d5649d35329a8d0a71e4ffb89b"><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:ad193a2cc121e0d4614a1c21eb463fb56"><td class="memItemLeft" align="right" valign="top">char * </td><td class="memItemRight" valign="bottom"><a class="el" href="_free_stack_8h.html#ad193a2cc121e0d4614a1c21eb463fb56">__brkval</a></td></tr> | |||||
<tr class="separator:ad193a2cc121e0d4614a1c21eb463fb56"><td class="memSeparator" colspan="2"> </td></tr> | |||||
<tr class="memitem:adbad17f740c2d7f2bc4833681c93c932"><td class="memItemLeft" align="right" valign="top">char </td><td class="memItemRight" valign="bottom"><a class="el" href="_free_stack_8h.html#adbad17f740c2d7f2bc4833681c93c932">__bss_end</a></td></tr> | |||||
<tr class="separator:adbad17f740c2d7f2bc4833681c93c932"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</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>FreeStack() function. </p> | |||||
</div></div><!-- contents --> | |||||
<div class="textblock"><p><a class="el" href="_free_stack_8h.html#a2c0121d5649d35329a8d0a71e4ffb89b">FreeStack()</a> function. </p> | |||||
</div><h2 class="groupheader">Function Documentation</h2> | |||||
<a class="anchor" id="a2c0121d5649d35329a8d0a71e4ffb89b"></a> | |||||
<div class="memitem"> | |||||
<div class="memproto"> | |||||
<table class="mlabels"> | |||||
<tr> | |||||
<td class="mlabels-left"> | |||||
<table class="memname"> | |||||
<tr> | |||||
<td class="memname">static int FreeStack </td> | |||||
<td>(</td> | |||||
<td class="paramname"></td><td>)</td> | |||||
<td></td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
<td class="mlabels-right"> | |||||
<span class="mlabels"><span class="mlabel">static</span></span> </td> | |||||
</tr> | |||||
</table> | |||||
</div><div class="memdoc"> | |||||
<p>Amount of free stack space. </p><dl class="section return"><dt>Returns</dt><dd>The number of free bytes. </dd></dl> | |||||
</div> | |||||
</div> | |||||
<h2 class="groupheader">Variable Documentation</h2> | |||||
<a class="anchor" id="ad193a2cc121e0d4614a1c21eb463fb56"></a> | |||||
<div class="memitem"> | |||||
<div class="memproto"> | |||||
<table class="memname"> | |||||
<tr> | |||||
<td class="memname">char* __brkval</td> | |||||
</tr> | |||||
</table> | |||||
</div><div class="memdoc"> | |||||
<p>boundary between stack and heap. </p> | |||||
</div> | |||||
</div> | |||||
<a class="anchor" id="adbad17f740c2d7f2bc4833681c93c932"></a> | |||||
<div class="memitem"> | |||||
<div class="memproto"> | |||||
<table class="memname"> | |||||
<tr> | |||||
<td class="memname">char __bss_end</td> | |||||
</tr> | |||||
</table> | |||||
</div><div class="memdoc"> | |||||
<p>End of bss section. </p> | |||||
</div> | |||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</table><table class="memberdecls"> | </table><table class="memberdecls"> | ||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a> | <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a> | ||||
Macros</h2></td></tr> | Macros</h2></td></tr> | ||||
<tr class="memitem:aca25ecce379f446043bdee2c55304210"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_sd_fat_8h.html#aca25ecce379f446043bdee2c55304210">SD_FAT_VERSION</a>   20160123</td></tr> | |||||
<tr class="memitem:aca25ecce379f446043bdee2c55304210"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_sd_fat_8h.html#aca25ecce379f446043bdee2c55304210">SD_FAT_VERSION</a>   20160212</td></tr> | |||||
<tr class="separator:aca25ecce379f446043bdee2c55304210"><td class="memSeparator" colspan="2"> </td></tr> | <tr class="separator:aca25ecce379f446043bdee2c55304210"><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="memproto"> | <div class="memproto"> | ||||
<table class="memname"> | <table class="memname"> | ||||
<tr> | <tr> | ||||
<td class="memname">#define SD_FAT_VERSION   20160123</td> | |||||
<td class="memname">#define SD_FAT_VERSION   20160212</td> | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
</div><div class="memdoc"> | </div><div class="memdoc"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<div class="center"><img src="_stdio_stream_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h" alt=""/></div> | <div class="center"><img src="_stdio_stream_8h__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h" alt=""/></div> | ||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h"> | <map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_stdio_stream_8h"> | ||||
<area shape="rect" id="node3" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="155,95,229,121"/> | <area shape="rect" id="node3" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="155,95,229,121"/> | ||||
<area shape="rect" id="node6" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="353,244,458,271"/> | |||||
<area shape="rect" id="node9" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="102,244,197,271"/> | |||||
<area shape="rect" id="node6" href="_fat_lib_config_8h.html" title="configuration definitions " alt="" coords="366,244,471,271"/> | |||||
<area shape="rect" id="node9" href="_fat_structs_8h.html" title="FAT file structures. " alt="" coords="53,244,147,271"/> | |||||
<area shape="rect" id="node10" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="144,169,240,196"/> | <area shape="rect" id="node10" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="144,169,240,196"/> | ||||
<area shape="rect" id="node8" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="399,319,503,345"/> | |||||
<area shape="rect" id="node8" href="_sd_fat_config_8h.html" title="configuration definitions " alt="" coords="412,319,516,345"/> | |||||
<area shape="rect" id="node11" href="_sys_call_8h.html" title="SysCall class. " alt="" coords="171,244,250,271"/> | |||||
</map> | </map> | ||||
</div> | </div> | ||||
</div><table class="memberdecls"> | </div><table class="memberdecls"> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/> | |||||
<meta name="generator" content="Doxygen 1.8.10"/> | |||||
<title>SdFat: Arduino/libraries/SdFat/src/FatLib/SysCall.h File Reference</title> | |||||
<link href="tabs.css" rel="stylesheet" type="text/css"/> | |||||
<script type="text/javascript" src="jquery.js"></script> | |||||
<script type="text/javascript" src="dynsections.js"></script> | |||||
<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"> | |||||
$(document).ready(function() { init_search(); }); | |||||
</script> | |||||
<link href="doxygen.css" rel="stylesheet" type="text/css" /> | |||||
</head> | |||||
<body> | |||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! --> | |||||
<div id="titlearea"> | |||||
<table cellspacing="0" cellpadding="0"> | |||||
<tbody> | |||||
<tr style="height: 56px;"> | |||||
<td id="projectalign" style="padding-left: 0.5em;"> | |||||
<div id="projectname">SdFat | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<!-- end header part --> | |||||
<!-- Generated by Doxygen 1.8.10 --> | |||||
<script type="text/javascript"> | |||||
var searchBox = new SearchBox("searchBox", "search",false,'Search'); | |||||
</script> | |||||
<div id="navrow1" class="tabs"> | |||||
<ul class="tablist"> | |||||
<li><a href="index.html"><span>Main Page</span></a></li> | |||||
<li><a href="modules.html"><span>Modules</span></a></li> | |||||
<li><a href="annotated.html"><span>Classes</span></a></li> | |||||
<li class="current"><a href="files.html"><span>Files</span></a></li> | |||||
<li> | |||||
<div id="MSearchBox" class="MSearchBoxInactive"> | |||||
<span class="left"> | |||||
<img id="MSearchSelect" src="search/mag_sel.png" | |||||
onmouseover="return searchBox.OnSearchSelectShow()" | |||||
onmouseout="return searchBox.OnSearchSelectHide()" | |||||
alt=""/> | |||||
<input type="text" id="MSearchField" value="Search" accesskey="S" | |||||
onfocus="searchBox.OnSearchFieldFocus(true)" | |||||
onblur="searchBox.OnSearchFieldFocus(false)" | |||||
onkeyup="searchBox.OnSearchFieldChange(event)"/> | |||||
</span><span class="right"> | |||||
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a> | |||||
</span> | |||||
</div> | |||||
</li> | |||||
</ul> | |||||
</div> | |||||
<div id="navrow2" class="tabs2"> | |||||
<ul class="tablist"> | |||||
<li><a href="files.html"><span>File List</span></a></li> | |||||
<li><a href="globals.html"><span>File Members</span></a></li> | |||||
</ul> | |||||
</div> | |||||
<!-- window showing the filter options --> | |||||
<div id="MSearchSelectWindow" | |||||
onmouseover="return searchBox.OnSearchSelectShow()" | |||||
onmouseout="return searchBox.OnSearchSelectHide()" | |||||
onkeydown="return searchBox.OnSearchSelectKey(event)"> | |||||
</div> | |||||
<!-- iframe showing the search results (closed by default) --> | |||||
<div id="MSearchResultsWindow"> | |||||
<iframe src="javascript:void(0)" frameborder="0" | |||||
name="MSearchResults" id="MSearchResults"> | |||||
</iframe> | |||||
</div> | |||||
<div id="nav-path" class="navpath"> | |||||
<ul> | |||||
<li class="navelem"><a class="el" href="dir_a991eec27578c865874ede3d8ec657c2.html">Arduino</a></li><li class="navelem"><a class="el" href="dir_481cc946b8a81b8d9363a4aad6201160.html">libraries</a></li><li class="navelem"><a class="el" href="dir_1281b15c327061056ab3b326e90c50cf.html">SdFat</a></li><li class="navelem"><a class="el" href="dir_c18d6c86f7b0afecac5c3a8a9885031e.html">src</a></li><li class="navelem"><a class="el" href="dir_7e472674a7b7d2590a789f197241f95f.html">FatLib</a></li> </ul> | |||||
</div> | |||||
</div><!-- top --> | |||||
<div class="header"> | |||||
<div class="summary"> | |||||
<a href="#nested-classes">Classes</a> | | |||||
<a href="#define-members">Macros</a> </div> | |||||
<div class="headertitle"> | |||||
<div class="title">SysCall.h File Reference</div> </div> | |||||
</div><!--header--> | |||||
<div class="contents"> | |||||
<p><a class="el" href="class_sys_call.html" title="SysCall - Class to wrap system calls. ">SysCall</a> class. | |||||
<a href="#details">More...</a></p> | |||||
<div class="textblock"><div class="dynheader"> | |||||
This graph shows which files directly or indirectly include this file:</div> | |||||
<div class="dyncontent"> | |||||
<div class="center"><img src="_sys_call_8h__dep__incl.png" border="0" usemap="#_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_sys_call_8hdep" alt=""/></div> | |||||
<map name="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_sys_call_8hdep" id="_arduino_2libraries_2_sd_fat_2src_2_fat_lib_2_sys_call_8hdep"> | |||||
<area shape="rect" id="node2" href="_fat_volume_8h.html" title="FatVolume class. " alt="" coords="309,95,472,136"/> | |||||
<area shape="rect" id="node10" href="_arduino_stream_8h.html" title="ArduinoInStream and ArduinoOutStream classes. " alt="" coords="60,631,246,672"/> | |||||
<area shape="rect" id="node3" href="_fat_file_8h.html" title="FatFile class. " alt="" coords="313,184,468,225"/> | |||||
<area shape="rect" id="node5" href="_fat_file_system_8h.html" title="FatFileSystem class. " alt="" coords="544,363,728,404"/> | |||||
<area shape="rect" id="node4" href="_arduino_files_8h.html" title="PrintFile class. " alt="" coords="550,273,721,315"/> | |||||
<area shape="rect" id="node6" href="ios_8h.html" title="ios_base and ios classes " alt="" coords="126,273,281,315"/> | |||||
<area shape="rect" id="node11" href="fstream_8h.html" title="fstream, ifstream, and ofstream classes " alt="" coords="44,541,198,583"/> | |||||
<area shape="rect" id="node13" href="_stdio_stream_8h.html" title="StdioStream class. " alt="" coords="305,273,476,315"/> | |||||
<area shape="rect" id="node7" href="istream_8h.html" title="istream class " alt="" coords="305,363,460,404"/> | |||||
<area shape="rect" id="node12" href="ostream_8h.html" title="ostream class " alt="" coords="126,363,281,404"/> | |||||
<area shape="rect" id="node8" href="iostream_8h.html" title="iostream class " alt="" coords="190,452,345,493"/> | |||||
<area shape="rect" id="node9" href="bufstream_8h.html" title="ibufstream and obufstream classes " alt="" coords="223,541,379,583"/> | |||||
</map> | |||||
</div> | |||||
</div><table class="memberdecls"> | |||||
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a> | |||||
Classes</h2></td></tr> | |||||
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class  </td><td class="memItemRight" valign="bottom"><a class="el" href="class_sys_call.html">SysCall</a></td></tr> | |||||
<tr class="memdesc:"><td class="mdescLeft"> </td><td class="mdescRight"><a class="el" href="class_sys_call.html" title="SysCall - Class to wrap system calls. ">SysCall</a> - Class to wrap system calls. <a href="class_sys_call.html#details">More...</a><br /></td></tr> | |||||
<tr class="separator:"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</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:a0e3009529aac180ed5f48296d6670d6b"><td class="memItemLeft" align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="_sys_call_8h.html#a0e3009529aac180ed5f48296d6670d6b">F</a>(str)   (str)</td></tr> | |||||
<tr class="separator:a0e3009529aac180ed5f48296d6670d6b"><td class="memSeparator" colspan="2"> </td></tr> | |||||
</table> | |||||
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> | |||||
<div class="textblock"><p><a class="el" href="class_sys_call.html" title="SysCall - Class to wrap system calls. ">SysCall</a> class. </p> | |||||
</div><h2 class="groupheader">Macro Definition Documentation</h2> | |||||
<a class="anchor" id="a0e3009529aac180ed5f48296d6670d6b"></a> | |||||
<div class="memitem"> | |||||
<div class="memproto"> | |||||
<table class="memname"> | |||||
<tr> | |||||
<td class="memname">#define F</td> | |||||
<td>(</td> | |||||
<td class="paramtype"> </td> | |||||
<td class="paramname">str</td><td>)</td> | |||||
<td>   (str)</td> | |||||
</tr> | |||||
</table> | |||||
</div><div class="memdoc"> | |||||
<p>Define macro for strings stored in flash. </p> | |||||
</div> | |||||
</div> | |||||
</div><!-- contents --> | |||||
<!-- start footer part --> | |||||
<hr class="footer"/><address class="footer"><small> | |||||
Generated on Fri Feb 12 2016 13:43:49 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
<img class="footer" src="doxygen.png" alt="doxygen"/> | |||||
</a> 1.8.10 | |||||
</small></address> | |||||
</body> | |||||
</html> |
<tr id="row_46_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structsetw.html" target="_self">setw</a></td><td class="desc">Type for setw manipulator </td></tr> | <tr id="row_46_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="structsetw.html" target="_self">setw</a></td><td class="desc">Type for setw manipulator </td></tr> | ||||
<tr id="row_47_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_soft_s_p_i.html" target="_self">SoftSPI</a></td><td class="desc">Fast software SPI </td></tr> | <tr id="row_47_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_soft_s_p_i.html" target="_self">SoftSPI</a></td><td class="desc">Fast software SPI </td></tr> | ||||
<tr id="row_48_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_stdio_stream.html" target="_self">StdioStream</a></td><td class="desc"><a class="el" href="class_stdio_stream.html" title="StdioStream implements a minimal stdio stream. ">StdioStream</a> implements a minimal stdio stream </td></tr> | <tr id="row_48_" class="even"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_stdio_stream.html" target="_self">StdioStream</a></td><td class="desc"><a class="el" href="class_stdio_stream.html" title="StdioStream implements a minimal stdio stream. ">StdioStream</a> implements a minimal stdio stream </td></tr> | ||||
<tr id="row_49_"><td class="entry"><span style="width:16px;display:inline-block;"> </span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_sys_call.html" target="_self">SysCall</a></td><td class="desc"><a class="el" href="class_sys_call.html" title="SysCall - Class to wrap system calls. ">SysCall</a> - Class to wrap system calls </td></tr> | |||||
</table> | </table> | ||||
</div><!-- directory --> | </div><!-- directory --> | ||||
</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 Sat Jan 23 2016 13:44:27 for SdFat by  <a href="http://www.doxygen.org/index.html"> | |||||
Generated on Fri Feb 12 2016 13:43:49 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.10 | </a> 1.8.10 | ||||
</small></address> | </small></address> |