| @@ -0,0 +1,608 @@ | |||
| /** | |||
| * 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")); | |||
| } | |||
| } | |||
| @@ -0,0 +1,8 @@ | |||
| #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 | |||
| @@ -0,0 +1 @@ | |||
| Test of shared SPI for LowLatencyLogger. | |||
| @@ -65,16 +65,22 @@ ostream& operator << (ostream& os, DateTime& dt) { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial. | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| // F() stores strings in flash to save RAM | |||
| cout << endl << F("FreeStack: ") << FreeStack() << endl; | |||
| #if WAIT_TO_START | |||
| 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 | |||
| #if USE_DS1307 | |||
| @@ -184,5 +190,5 @@ void loop() { | |||
| } | |||
| logfile.close(); | |||
| cout << F("Done!"); | |||
| while (1); | |||
| SysCall::halt(); | |||
| } | |||
| @@ -7,7 +7,7 @@ | |||
| SdFat sd; | |||
| SdFile file; | |||
| char* name[] = { | |||
| const char* name[] = { | |||
| "low.low", "low.Mix", "low.UP", | |||
| "Mix.low", "Mix.Mix", "Mix.UP", | |||
| "UP.low", "UP.Mix", "UP.UP" | |||
| @@ -15,9 +15,15 @@ char* name[] = { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println("type any character to start"); | |||
| while (Serial.read() < 0) {} | |||
| while (Serial.read() < 0) { | |||
| SysCall::yield(); | |||
| } | |||
| if (!sd.begin()) { | |||
| Serial.println("begin failed"); | |||
| return; | |||
| @@ -7,7 +7,10 @@ ArduinoOutStream cout(Serial); | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(2000); | |||
| cout << "Hello, World!\n"; | |||
| @@ -15,15 +15,19 @@ const uint16_t N_PRINT = 20000; | |||
| File file; | |||
| //------------------------------------------------------------------------------ | |||
| void error(char* s) { | |||
| void error(const char* s) { | |||
| Serial.println(s); | |||
| while(1); | |||
| while (1) { | |||
| yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| // wait for Leonardo | |||
| yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| @@ -37,17 +41,14 @@ void loop() { | |||
| // F() stores strings in flash to save RAM | |||
| Serial.println(F("Type any character to start")); | |||
| while (Serial.read() <= 0) { | |||
| yield(); | |||
| } | |||
| delay(400); // catch Due reset problem | |||
| // initialize the SD card | |||
| if (!SD.begin(chipSelect)) { | |||
| error("begin"); | |||
| } | |||
| Serial.println(F("Starting print test. Please wait.\n")); | |||
| // do write test | |||
| @@ -9,7 +9,11 @@ File file; | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| yield(); | |||
| } | |||
| if (!SD.begin()) { | |||
| Serial.println("begin failed"); | |||
| @@ -12,8 +12,12 @@ SdFile file; | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| if (!sd.begin()) { | |||
| Serial.println("begin failed"); | |||
| return; | |||
| @@ -12,10 +12,13 @@ File file; | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| // Wait for USB Serial. | |||
| while(!Serial) {} | |||
| while(!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println(F("Type any character to start")); | |||
| while (!Serial.available()) {} | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| // Initialize the SD. | |||
| if (!SD.begin(csPin)) { | |||
| Serial.println(F("begin error")); | |||
| @@ -25,12 +25,16 @@ void setup() { | |||
| char name[] = "append.txt"; | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| // F() stores strings in flash to save RAM | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| @@ -54,12 +54,16 @@ void calcAverage() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| // F() stores strings in flash to save RAM | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| @@ -18,14 +18,20 @@ uint8_t buf[BUF_SIZE]; | |||
| File file; | |||
| //------------------------------------------------------------------------------ | |||
| void error(char* s) { | |||
| void error(const char* s) { | |||
| Serial.println(s); | |||
| while(1); | |||
| while (1) { | |||
| yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void loop() { | |||
| @@ -34,13 +40,16 @@ void loop() { | |||
| uint32_t totalLatency; | |||
| // discard any input | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| // F() stores strings in flash to save RAM | |||
| 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)) { | |||
| error("begin"); | |||
| } | |||
| @@ -12,7 +12,11 @@ void setup() { | |||
| int i, j, k; // values from parsed line | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(2000); | |||
| // initialize input string | |||
| @@ -15,11 +15,14 @@ ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void loop() { | |||
| int32_t n; | |||
| int32_t n = 0; | |||
| cout << "\nenter an integer\n"; | |||
| @@ -36,11 +36,15 @@ void logEvent(const char *msg) { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| // F() stores strings in flash to save RAM | |||
| cout << F("Type any character to start\n"); | |||
| while (Serial.read() <= 0) {} | |||
| while (Serial.read() <= 0) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(400); // catch Due reset problem | |||
| // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | |||
| @@ -83,13 +83,17 @@ void makeTestFile() { | |||
| wrfile.close(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void setup(void) { | |||
| void setup() { | |||
| 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) {} | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| @@ -103,4 +107,4 @@ void setup(void) { | |||
| cout << F("\nDone\n"); | |||
| } | |||
| void loop(void) {} | |||
| void loop() {} | |||
| @@ -17,8 +17,11 @@ ArduinoOutStream cout(Serial); | |||
| void setup() { | |||
| int c; | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | |||
| @@ -136,7 +136,7 @@ const uint8_t PIN_COUNT = sizeof(PIN_LIST)/sizeof(PIN_LIST[0]); | |||
| const uint16_t MIN_ADC_CYCLES = 15; | |||
| // 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. | |||
| const uint16_t ISR_TIMER0 = 160; | |||
| @@ -294,8 +294,7 @@ void adcInit(metadata_t* meta) { | |||
| adps = ADC_PRESCALER; | |||
| #else // ADC_PRESCALER | |||
| // 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--) { | |||
| if (adcCycles >= (MIN_ADC_CYCLES << adps)) { | |||
| @@ -385,7 +384,7 @@ void adcInit(metadata_t* meta) { | |||
| meta->cpuFrequency = F_CPU; | |||
| float sampleRate = (float)meta->cpuFrequency/meta->sampleInterval; | |||
| 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(meta->pinNumber[i], DEC); | |||
| } | |||
| @@ -471,7 +470,6 @@ void binaryToCsv() { | |||
| csvStream.println(); | |||
| uint32_t tPct = millis(); | |||
| while (!Serial.available() && binFile.read(&buf, 512) == 512) { | |||
| uint16_t i; | |||
| if (buf.count == 0) { | |||
| break; | |||
| } | |||
| @@ -794,7 +792,9 @@ void setup(void) { | |||
| //------------------------------------------------------------------------------ | |||
| void loop(void) { | |||
| // discard any input | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| Serial.println(); | |||
| Serial.println(F("type:")); | |||
| Serial.println(F("c - convert file to csv")); | |||
| @@ -802,7 +802,9 @@ void loop(void) { | |||
| Serial.println(F("e - overrun error details")); | |||
| Serial.println(F("r - record ADC data")); | |||
| while(!Serial.available()) {} | |||
| while(!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| char c = tolower(Serial.read()); | |||
| if (ERROR_LED_PIN >= 0) { | |||
| digitalWrite(ERROR_LED_PIN, LOW); | |||
| @@ -67,21 +67,24 @@ void loop() { | |||
| while (Serial.read() > 0) {} | |||
| 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")); | |||
| 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")); | |||
| } | |||
| Serial.println(); | |||
| char last; | |||
| char last = 0; | |||
| // 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); | |||
| } | |||
| // Add new line if missing from last line. | |||
| @@ -20,6 +20,9 @@ | |||
| // 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 = false; | |||
| // Acquire a data record. | |||
| void acquireData(data_t* data) { | |||
| data->time = micros(); | |||
| @@ -364,6 +367,10 @@ void logData() { | |||
| 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; | |||
| @@ -387,8 +394,10 @@ void logData() { | |||
| uint32_t overrun = 0; | |||
| uint32_t overrunTotal = 0; | |||
| uint32_t count = 0; | |||
| uint32_t maxDelta = 0; | |||
| uint32_t minDelta = 99999; | |||
| uint32_t maxLatency = 0; | |||
| int32_t diff; | |||
| // Start at a multiple of interval. | |||
| uint32_t logTime = micros()/LOG_INTERVAL_USEC + 1; | |||
| logTime *= LOG_INTERVAL_USEC; | |||
| @@ -401,7 +410,7 @@ void logData() { | |||
| } | |||
| if (closeFile) { | |||
| if (curBlock != 0 && curBlock->count >= 0) { | |||
| if (curBlock != 0) { | |||
| // Put buffer in full queue. | |||
| fullQueue[fullHead] = curBlock; | |||
| fullHead = queueNext(fullHead); | |||
| @@ -415,21 +424,24 @@ void logData() { | |||
| curBlock->overrun = overrun; | |||
| 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) { | |||
| overrun++; | |||
| } else { | |||
| acquireData(&curBlock->data[curBlock->count++]); | |||
| 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; | |||
| } | |||
| } | |||
| @@ -490,6 +502,9 @@ void logData() { | |||
| 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: ")); | |||
| @@ -504,7 +519,11 @@ void setup(void) { | |||
| pinMode(ERROR_LED_PIN, OUTPUT); | |||
| } | |||
| Serial.begin(9600); | |||
| while (!Serial) {} | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.print(F("FreeStack: ")); | |||
| Serial.println(FreeStack()); | |||
| @@ -522,7 +541,9 @@ void setup(void) { | |||
| //------------------------------------------------------------------------------ | |||
| void loop(void) { | |||
| // discard any input | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| Serial.println(); | |||
| Serial.println(F("type:")); | |||
| Serial.println(F("c - convert file to csv")); | |||
| @@ -530,7 +551,9 @@ void loop(void) { | |||
| Serial.println(F("e - overrun error details")); | |||
| Serial.println(F("r - record data")); | |||
| while(!Serial.available()) {} | |||
| while(!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| char c = tolower(Serial.read()); | |||
| // Discard extra Serial data. | |||
| @@ -4,7 +4,7 @@ | |||
| #include <SPI.h> | |||
| #include "SdFat.h" | |||
| // SD chip select pin | |||
| // SD default chip select pin. | |||
| const uint8_t chipSelect = SS; | |||
| // file system object | |||
| @@ -14,9 +14,16 @@ SdFile file; | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| @@ -25,8 +25,9 @@ ArduinoOutStream cout(Serial); | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| // wait for Leonardo | |||
| SysCall::yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| @@ -39,8 +39,11 @@ void reformatMsg() { | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // Wait for Leonardo. | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| cout << F("\nSPI pins:\n"); | |||
| cout << F("MISO: ") << int(MISO) << endl; | |||
| cout << F("MOSI: ") << int(MOSI) << endl; | |||
| @@ -65,7 +68,9 @@ void setup() { | |||
| bool firstTry = true; | |||
| void loop() { | |||
| // read any existing Serial data | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| if (!firstTry) { | |||
| cout << F("\nRestarting\n"); | |||
| @@ -73,9 +78,9 @@ void loop() { | |||
| firstTry = false; | |||
| cout << F("\nEnter the chip select pin number: "); | |||
| while (!Serial.available()) {} | |||
| delay(400); // catch Due restart problem | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| cin.readline(); | |||
| if (cin >> chipSelect) { | |||
| cout << chipSelect << endl; | |||
| @@ -51,15 +51,22 @@ struct { | |||
| //------------------------------------------------------------------------------ | |||
| void setup(void) { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void loop(void) { | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| // F stores strings in flash to save RAM | |||
| 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; | |||
| @@ -2,7 +2,7 @@ | |||
| // | |||
| #include <SPI.h> | |||
| #include <SdFat.h> | |||
| #define CS_PIN 10 | |||
| #define CS_PIN SS | |||
| // 5 X 4 array | |||
| #define ROW_DIM 5 | |||
| @@ -30,7 +30,7 @@ File 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; | |||
| size_t n = 0; | |||
| while ((n + 1) < size && file->read(&ch, 1) == 1) { | |||
| @@ -47,22 +47,30 @@ size_t readField(File* file, char* str, size_t size, char* delim) { | |||
| return n; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| #define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||
| #define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();} | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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. | |||
| if (!SD.begin(CS_PIN)) { | |||
| errorHalt("begin failed"); | |||
| } | |||
| } | |||
| // Create or open the file. | |||
| file = SD.open("READNUM.TXT", FILE_WRITE); | |||
| if (!file) { | |||
| errorHalt("open failed"); | |||
| } | |||
| // Rewind file so test data is not appended. | |||
| file.seek(0); | |||
| file.rewind(); | |||
| // Write test data. | |||
| file.print(F( | |||
| @@ -74,7 +82,7 @@ void setup() { | |||
| )); | |||
| // Rewind the file for read. | |||
| file.seek(0); | |||
| file.rewind(); | |||
| // Array for data. | |||
| int array[ROW_DIM][COL_DIM]; | |||
| @@ -3,7 +3,7 @@ | |||
| // | |||
| #include <SPI.h> | |||
| #include <SdFat.h> | |||
| #define CS_PIN 10 | |||
| #define CS_PIN SS | |||
| SdFat SD; | |||
| File file; | |||
| @@ -27,7 +27,7 @@ File 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; | |||
| size_t n = 0; | |||
| while ((n + 1) < size && file->read(&ch, 1) == 1) { | |||
| @@ -44,11 +44,19 @@ size_t readField(File* file, char* str, size_t size, char* delim) { | |||
| return n; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| #define errorHalt(msg) {Serial.println(F(msg)); while(1);} | |||
| #define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();} | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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. | |||
| if (!SD.begin(CS_PIN)) errorHalt("begin failed"); | |||
| @@ -57,7 +65,7 @@ void setup() { | |||
| if (!file) errorHalt("open failed"); | |||
| // Rewind file so test data is not appended. | |||
| file.seek(0); | |||
| file.rewind(); | |||
| // Write test data. | |||
| file.print(F( | |||
| @@ -69,7 +77,7 @@ void setup() { | |||
| )); | |||
| // Rewind the file for read. | |||
| file.seek(0); | |||
| file.rewind(); | |||
| size_t n; // Length of returned field with delimiter. | |||
| char str[20]; // Must hold longest field with delimiter and zero byte. | |||
| @@ -29,11 +29,12 @@ void setup() | |||
| { | |||
| // Open serial communications and wait for port to open: | |||
| Serial.begin(9600); | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| ; // wait for serial port to connect. Needed for Leonardo only | |||
| SysCall::yield(); | |||
| } | |||
| Serial.print("Initializing SD card..."); | |||
| // On the Ethernet Shield, CS is pin 4. It's set as an output by default. | |||
| // Note that even if it's not used as the CS pin, the hardware SS pin | |||
| @@ -27,11 +27,15 @@ SdFile myFile; | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| 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 | |||
| // Use half speed like the native library. | |||
| // change to SPI_FULL_SPEED for more performance. | |||
| @@ -74,7 +74,7 @@ void sdError_F(const __FlashStringHelper* str) { | |||
| cout << F("SD error: ") << hex << int(card.errorCode()); | |||
| cout << ',' << int(card.errorData()) << dec << endl; | |||
| } | |||
| while (1); | |||
| SysCall::halt(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| #if DEBUG_PRINT | |||
| @@ -440,8 +440,16 @@ void formatCard() { | |||
| void setup() { | |||
| char c; | |||
| 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( | |||
| "\n" | |||
| "This program can erase and/or format SD/SDHC cards.\n" | |||
| @@ -455,8 +463,9 @@ void setup() { | |||
| "\n" | |||
| "Warning, all data on the card will be erased.\n" | |||
| "Enter 'Y' to continue: "); | |||
| while (!Serial.available()) {} | |||
| delay(400); // catch Due restart problem | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| c = Serial.read(); | |||
| cout << c << endl; | |||
| @@ -465,7 +474,9 @@ void setup() { | |||
| return; | |||
| } | |||
| // read any existing Serial data | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| cout << F( | |||
| "\n" | |||
| @@ -476,7 +487,9 @@ void setup() { | |||
| "\n" | |||
| "Enter option: "); | |||
| while (!Serial.available()) {} | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| c = Serial.read(); | |||
| cout << c << endl; | |||
| if (!strchr("EFQ", c)) { | |||
| @@ -145,7 +145,11 @@ void volDmp() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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 | |||
| cout << uppercase << showbase << endl; | |||
| @@ -168,12 +172,15 @@ void setup() { | |||
| //------------------------------------------------------------------------------ | |||
| void loop() { | |||
| // read any existing Serial data | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| // F stores strings in flash to save RAM | |||
| 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(); | |||
| // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | |||
| @@ -23,10 +23,14 @@ SdFile file; | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // Wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println("Type any character to start"); | |||
| while (Serial.read() <= 0) {} | |||
| while (Serial.read() <= 0) { | |||
| SysCall::yield(); | |||
| } | |||
| if (!sd.begin(SD_CHIP_SELECT_PIN)) { | |||
| sd.initErrorHalt(); | |||
| @@ -17,24 +17,27 @@ StdioStream stdioFile; | |||
| float f[100]; | |||
| char buf[20]; | |||
| char* label[] = | |||
| const char* label[] = | |||
| { "uint8_t 0 to 255, 100 times ", "uint16_t 0 to 20000", | |||
| "uint32_t 0 to 20000", "uint32_t 1000000000 to 1000010000", | |||
| "float nnn.ffff, 10000 times" | |||
| }; | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| uint32_t m; | |||
| uint32_t printSize; | |||
| uint32_t stdioSize; | |||
| uint32_t stdioSize = 0; | |||
| uint32_t printTime; | |||
| uint32_t stdioTime; | |||
| uint32_t stdioTime = 0; | |||
| Serial.begin(9600); | |||
| while (!Serial) {} | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println(F("Type any character to start")); | |||
| while (!Serial.available()); | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println(F("Starting test")); | |||
| if (!sd.begin(SD_CS_PIN)) { | |||
| sd.errorHalt(); | |||
| @@ -45,19 +45,22 @@ void list() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.print(F("FreeStack: ")); | |||
| Serial.println(FreeStack()); | |||
| // 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; | |||
| } | |||
| Serial.println(F("type any character to start")); | |||
| while (Serial.read() <= 0) {} | |||
| while (Serial.read() <= 0) { | |||
| SysCall::yield(); | |||
| } | |||
| // disable sd2 while initializing sd1 | |||
| pinMode(SD2_CS, OUTPUT); | |||
| digitalWrite(SD2_CS, HIGH); | |||
| @@ -140,7 +143,7 @@ void setup() { | |||
| Serial.println(F("Writing SD1:/Dir1/TEST1.bin")); | |||
| // 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)) { | |||
| sd1.errorExit("sd1.write"); | |||
| } | |||
| @@ -168,7 +171,7 @@ void setup() { | |||
| if (n == 0) { | |||
| break; | |||
| } | |||
| if (file2.write(buf, n) != n) { | |||
| if ((int)file2.write(buf, n) != n) { | |||
| sd2.errorExit("write3"); | |||
| } | |||
| } | |||
| @@ -196,7 +199,7 @@ void setup() { | |||
| if (n != sizeof(buf)) { | |||
| sd2.errorExit("read2"); | |||
| } | |||
| if (file3.write(buf, n) != n) { | |||
| if ((int)file3.write(buf, n) != n) { | |||
| sd3.errorExit("write2"); | |||
| } | |||
| } | |||
| @@ -206,11 +209,11 @@ void setup() { | |||
| // Verify content of file3 | |||
| file3.rewind(); | |||
| 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)) { | |||
| 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]) { | |||
| sd3.errorExit("Verify error"); | |||
| } | |||
| @@ -75,12 +75,14 @@ void printTimestamps(SdFile& f) { | |||
| //------------------------------------------------------------------------------ | |||
| void setup(void) { | |||
| 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.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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | |||
| @@ -170,4 +172,4 @@ void setup(void) { | |||
| cout << F("\nDone\n"); | |||
| } | |||
| void loop(void) {} | |||
| void loop() {} | |||
| @@ -24,19 +24,23 @@ const uint16_t NWRITE = FILE_SIZE/BUF_DIM; | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.print(F("FreeStack: ")); | |||
| Serial.println(FreeStack()); | |||
| // 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; | |||
| } | |||
| 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 | |||
| pinMode(SD2_CS, OUTPUT); | |||
| @@ -102,7 +106,7 @@ void setup() { | |||
| Serial.println(F("Writing test.bin to 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)) { | |||
| sd1.errorExit("sd1.write"); | |||
| } | |||
| @@ -129,7 +133,7 @@ void setup() { | |||
| if (n == 0) { | |||
| break; | |||
| } | |||
| if (file2.write(buf, n) != n) { | |||
| if ((int)file2.write(buf, n) != n) { | |||
| sd2.errorExit("write2"); | |||
| } | |||
| } | |||
| @@ -13,7 +13,7 @@ | |||
| */ | |||
| const uint8_t chipSelect = SS; | |||
| #define TEST_FILE "CLUSTER.TST" | |||
| #define TEST_FILE "Cluster.test" | |||
| // file system | |||
| SdFat sd; | |||
| @@ -35,8 +35,10 @@ void printFreeSpace() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| if (!MAINTAIN_FREE_CLUSTER_COUNT) { | |||
| cout << F("Please edit SdFatConfig.h and set\n"); | |||
| cout << F("MAINTAIN_FREE_CLUSTER_COUNT nonzero for\n"); | |||
| @@ -44,9 +46,9 @@ void setup() { | |||
| } | |||
| // F stores strings in flash to save RAM | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | |||
| @@ -36,7 +36,7 @@ SdFile file; | |||
| // Serial output stream | |||
| 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)) | |||
| //------------------------------------------------------------------------------ | |||
| void cidDmp() { | |||
| @@ -62,7 +62,11 @@ void cidDmp() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(1000); | |||
| cout << F("\nUse a freshly formatted SD for best performance.\n"); | |||
| @@ -78,12 +82,15 @@ void loop() { | |||
| uint32_t totalLatency; | |||
| // discard any input | |||
| while (Serial.read() >= 0) {} | |||
| do { | |||
| delay(10); | |||
| } while (Serial.read() >= 0); | |||
| // F( stores strings in flash to save RAM | |||
| 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; | |||
| @@ -129,7 +136,9 @@ void loop() { | |||
| for (uint32_t i = 0; i < n; i++) { | |||
| uint32_t m = micros(); | |||
| if (file.write(buf, sizeof(buf)) != sizeof(buf)) { | |||
| error("write failed"); | |||
| sd.errorPrint("write failed"); | |||
| file.close(); | |||
| return; | |||
| } | |||
| m = micros() - m; | |||
| if (maxLatency < m) { | |||
| @@ -146,11 +155,11 @@ void loop() { | |||
| cout << s/t <<',' << maxLatency << ',' << minLatency; | |||
| cout << ',' << totalLatency/n << endl; | |||
| } | |||
| cout << endl << F("Starting read test, please wait.") << endl; | |||
| cout << endl <<F("read speed and latency") << endl; | |||
| cout << F("speed,max,min,avg") << endl; | |||
| cout << F("KB/Sec,usec,usec,usec") << endl; | |||
| // do read test | |||
| for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) { | |||
| file.rewind(); | |||
| @@ -161,8 +170,11 @@ void loop() { | |||
| for (uint32_t i = 0; i < n; i++) { | |||
| buf[BUF_SIZE-1] = 0; | |||
| 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; | |||
| if (maxLatency < m) { | |||
| @@ -176,6 +188,7 @@ void loop() { | |||
| error("data check"); | |||
| } | |||
| } | |||
| s = file.fileSize(); | |||
| t = millis() - t; | |||
| cout << s/t <<',' << maxLatency << ',' << minLatency; | |||
| cout << ',' << totalLatency/n << endl; | |||
| @@ -67,12 +67,18 @@ void setup() { | |||
| char fileName[13] = FILE_BASE_NAME "00.csv"; | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(1000); | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| if (!sd.begin(chipSelect, SPI_HALF_SPEED)) { | |||
| @@ -138,6 +144,6 @@ void loop() { | |||
| // Close file and stop. | |||
| file.close(); | |||
| Serial.println(F("Done")); | |||
| while(1) {} | |||
| SysCall::halt(); | |||
| } | |||
| } | |||
| @@ -28,7 +28,11 @@ ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(1000); | |||
| cout << F("Type any character to start\n"); | |||
| @@ -60,7 +60,11 @@ void makeTestFile() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup(void) { | |||
| 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) {} | |||
| @@ -42,7 +42,10 @@ void showDate(int m, int d, int y) { | |||
| void setup(void) { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| delay(2000); | |||
| cout << endl << "default formatting" << endl; | |||
| @@ -54,7 +54,11 @@ void testGetline() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup(void) { | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| // F stores strings in flash to save RAM | |||
| cout << F("Type any character to start\n"); | |||
| @@ -21,7 +21,7 @@ char fileName[] = "testfile.csv"; | |||
| //------------------------------------------------------------------------------ | |||
| // read and print CSV test file | |||
| void readFile() { | |||
| long lg; | |||
| long lg = 0; | |||
| float f1, f2; | |||
| char text[10]; | |||
| char c1, c2, c3; // space for commas. | |||
| @@ -91,7 +91,11 @@ void writeFile() { | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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) {} | |||
| delay(400); // catch Due reset problem | |||
| @@ -19,11 +19,15 @@ ArduinoOutStream cout(Serial); | |||
| //------------------------------------------------------------------------------ | |||
| void setup() { | |||
| 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; | |||
| 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 | |||
| // breadboards. use SPI_FULL_SPEED for better performance. | |||
| @@ -8,9 +8,14 @@ SdFat sd; | |||
| void setup() { | |||
| int c; | |||
| Serial.begin(9600); | |||
| while (!Serial) {} // wait for Leonardo | |||
| // Wait for USB Serial | |||
| while (!Serial) { | |||
| SysCall::yield(); | |||
| } | |||
| Serial.println("Type 'Y' to wipe all data."); | |||
| while ((c = Serial.read()) <= 0) {} | |||
| while ((c = Serial.read()) <= 0) { | |||
| SysCall::yield(); | |||
| } | |||
| if (c != 'Y') { | |||
| sd.errorHalt("Quitting, you did not type 'Y'."); | |||
| } | |||
| @@ -25,7 +25,7 @@ | |||
| */ | |||
| #include "FatLibConfig.h" | |||
| #if ENABLE_ARDUINO_FEATURES | |||
| #include "SystemInclude.h" | |||
| #include "SysCall.h" | |||
| #include "bufstream.h" | |||
| //============================================================================== | |||
| /** | |||
| @@ -50,7 +50,9 @@ class ArduinoInStream : public ibufstream { | |||
| size_t i = 0; | |||
| uint32_t t; | |||
| m_line[0] = '\0'; | |||
| while (!m_hw->available()) {} | |||
| while (!m_hw->available()) { | |||
| SysCall::yield(); | |||
| } | |||
| while (1) { | |||
| t = millis(); | |||
| @@ -77,6 +79,8 @@ done: | |||
| * \return true/false. | |||
| */ | |||
| bool seekoff(off_type off, seekdir way) { | |||
| (void)off; | |||
| (void)way; | |||
| return false; | |||
| } | |||
| /** Internal - do not use. | |||
| @@ -84,6 +88,7 @@ done: | |||
| * \return true/false. | |||
| */ | |||
| bool seekpos(pos_type pos) { | |||
| (void)pos; | |||
| return false; | |||
| } | |||
| @@ -121,9 +126,12 @@ class ArduinoOutStream : public ostream { | |||
| m_pr->write(str); | |||
| } | |||
| bool seekoff(off_type off, seekdir way) { | |||
| (void)off; | |||
| (void)way; | |||
| return false; | |||
| } | |||
| bool seekpos(pos_type pos) { | |||
| (void)pos; | |||
| return false; | |||
| } | |||
| bool sync() { | |||
| @@ -127,7 +127,7 @@ typedef struct masterBootRecord mbr_t; | |||
| * | |||
| * 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 | |||
| * following values: 512, 1024, 2048 or 4096 | |||
| @@ -24,7 +24,7 @@ | |||
| * \brief FatVolume class | |||
| */ | |||
| #include <stddef.h> | |||
| #include "SystemInclude.h" | |||
| #include "SysCall.h" | |||
| #include "FatLibConfig.h" | |||
| #include "FatStructs.h" | |||
| //------------------------------------------------------------------------------ | |||
| @@ -35,7 +35,7 @@ | |||
| #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_HALT_IF(b) if (b) {Serial.println(F(#b));\ | |||
| DBG_FAIL_MACRO; while (1);} | |||
| DBG_FAIL_MACRO; SysCall::halt();} | |||
| #else // DEBUG_MODE | |||
| #define DBG_FAIL_MACRO | |||
| #define DBG_PRINT_IF(b) | |||
| @@ -280,8 +280,12 @@ class FatVolume { | |||
| } | |||
| } | |||
| #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 | |||
| // block caches | |||
| @@ -273,7 +273,7 @@ int StdioStream::write(const void* buf, size_t count) { | |||
| //------------------------------------------------------------------------------ | |||
| #if (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||
| size_t StdioStream::print(const __FlashStringHelper *str) { | |||
| const char *p = (const char*)str; | |||
| const char *p = (const char*)str; | |||
| uint8_t c; | |||
| while ((c = pgm_read_byte(p))) { | |||
| if (putc(c) < 0) { | |||
| @@ -281,7 +281,7 @@ size_t StdioStream::print(const __FlashStringHelper *str) { | |||
| } | |||
| p++; | |||
| } | |||
| return p - (const char*)str; | |||
| return p - (const char*)str; | |||
| } | |||
| #endif // (defined(ARDUINO) && ENABLE_ARDUINO_FEATURES) || defined(DOXYGEN) | |||
| //------------------------------------------------------------------------------ | |||
| @@ -448,7 +448,7 @@ int StdioStream::fillGet() { | |||
| // private | |||
| bool StdioStream::fillBuf() { | |||
| 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)) { | |||
| m_flags |= F_ERR; | |||
| return false; | |||
| @@ -476,7 +476,7 @@ bool StdioStream::fillBuf() { | |||
| // private | |||
| bool StdioStream::flushBuf() { | |||
| if (!(m_flags & | |||
| F_SWR)) { /////////////////check for F_ERR ??//////////////////////// | |||
| F_SWR)) { // check for F_ERR ??//////////////////////// | |||
| if (!(m_flags & F_SRW)) { | |||
| m_flags |= F_ERR; | |||
| return false; | |||
| @@ -404,7 +404,7 @@ class StdioStream : private FatFile { | |||
| 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. | |||
| * | |||
| * \param[in] str the string to print. | |||
| @@ -0,0 +1,67 @@ | |||
| /* 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 | |||
| @@ -65,6 +65,8 @@ class ibufstream : public istream { | |||
| pos->position = m_pos; | |||
| } | |||
| bool seekoff(off_type off, seekdir way) { | |||
| (void)off; | |||
| (void)way; | |||
| return false; | |||
| } | |||
| bool seekpos(pos_type pos) { | |||
| @@ -137,6 +139,8 @@ class obufstream : public ostream { | |||
| } | |||
| } | |||
| bool seekoff(off_type off, seekdir way) { | |||
| (void)off; | |||
| (void)way; | |||
| return false; | |||
| } | |||
| bool seekpos(pos_type pos) { | |||
| @@ -91,7 +91,7 @@ void istream::getBool(bool *b) { | |||
| #else // __AVR__ | |||
| falseOk = falseOk && c == falsePtr[i]; | |||
| trueOk = trueOk && c == truePtr[i]; | |||
| #endif // __AVR | |||
| #endif // __AVR__ | |||
| if (trueOk == false && falseOk == false) { | |||
| break; | |||
| } | |||
| @@ -23,13 +23,8 @@ | |||
| * \file | |||
| * \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. */ | |||
| extern char *__brkval; | |||
| /** End of bss section.*/ | |||
| @@ -40,12 +35,22 @@ extern char __bss_end; | |||
| static int FreeStack() { | |||
| char top; | |||
| return __brkval ? &top - __brkval : &top - &__bss_end; | |||
| } | |||
| } | |||
| #elif defined(PLATFORM_ID) // Particle board | |||
| static int FreeStack() { | |||
| 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 | |||
| #warning FreeStack is not defined for this system. | |||
| #endif // __arm | |||
| static int FreeStack() { | |||
| return 0; | |||
| } | |||
| #endif | |||
| #endif // FreeStack_h | |||
| @@ -21,12 +21,12 @@ | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::errorHalt(Print* pr) { | |||
| errorPrint(pr); | |||
| while (1) {} | |||
| SysCall::halt(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::errorHalt(Print* pr, char const* msg) { | |||
| errorPrint(pr, msg); | |||
| while (1) {} | |||
| SysCall::halt(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::errorPrint(Print* pr) { | |||
| @@ -47,7 +47,7 @@ void SdFatBase::errorPrint(Print* pr, char const* msg) { | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::initErrorHalt(Print* pr) { | |||
| initErrorPrint(pr); | |||
| while (1) {} | |||
| SysCall::halt(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::initErrorHalt(Print* pr, char const *msg) { | |||
| @@ -75,7 +75,7 @@ void SdFatBase::initErrorPrint(Print* pr, char const *msg) { | |||
| pr->println(msg); | |||
| initErrorPrint(pr); | |||
| } | |||
| #if defined(ARDUINO) || defined(DOXYGEN) | |||
| #if defined(ARDUINO) || defined(DOXYGEN) | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | |||
| pr->print(F("error: ")); | |||
| @@ -85,7 +85,7 @@ void SdFatBase::errorPrint(Print* pr, const __FlashStringHelper* msg) { | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::errorHalt(Print* pr, const __FlashStringHelper* msg) { | |||
| errorPrint(pr, msg); | |||
| while (1) {} | |||
| SysCall::halt(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void SdFatBase::initErrorHalt(Print* pr, const __FlashStringHelper* msg) { | |||
| @@ -97,4 +97,4 @@ void SdFatBase::initErrorPrint(Print* pr, const __FlashStringHelper* msg) { | |||
| pr->println(msg); | |||
| initErrorPrint(pr); | |||
| } | |||
| #endif // defined(ARDUINO) || defined(DOXYGEN) | |||
| #endif // defined(ARDUINO) || defined(DOXYGEN) | |||
| @@ -32,7 +32,7 @@ | |||
| #endif // ARDUINO | |||
| //------------------------------------------------------------------------------ | |||
| /** SdFat version YYYYMMDD */ | |||
| #define SD_FAT_VERSION 20160123 | |||
| #define SD_FAT_VERSION 20160212 | |||
| //============================================================================== | |||
| /** | |||
| * \class SdBaseFile | |||
| @@ -186,7 +186,7 @@ class SdFatBase : public FatFileSystem { | |||
| * \param[in] msg Message to print. | |||
| */ | |||
| 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. | |||
| * | |||
| * \param[in] msg Message to print. | |||
| @@ -199,7 +199,7 @@ class SdFatBase : public FatFileSystem { | |||
| * \param[in] pr Print destination. | |||
| * \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. | |||
| * | |||
| * \param[in] msg Message to print. | |||
| @@ -212,7 +212,7 @@ class SdFatBase : public FatFileSystem { | |||
| * \param[in] pr Print destination. | |||
| * \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. | |||
| * | |||
| * \param[in] msg Message to print. | |||
| @@ -224,7 +224,7 @@ class SdFatBase : public FatFileSystem { | |||
| * \param[in] pr Print device for message. | |||
| * \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. | |||
| * | |||
| * \param[in] msg Message to print. | |||
| @@ -238,8 +238,8 @@ class SdFatBase : public FatFileSystem { | |||
| * \param[in] msg Message to print. | |||
| */ | |||
| void initErrorPrint(Print* pr, const __FlashStringHelper* msg); | |||
| #endif //defined(ARDUINO) || defined(DOXYGEN) | |||
| #endif // defined(ARDUINO) || defined(DOXYGEN) | |||
| private: | |||
| uint8_t cardErrorCode() { | |||
| return m_sdCard.errorCode(); | |||
| @@ -272,11 +272,11 @@ class SdFat : public SdFatBase { | |||
| SdFat() { | |||
| m_spi.setSpiIf(0); | |||
| } | |||
| SdFat(uint8_t spiIf) { | |||
| explicit SdFat(uint8_t spiIf) { | |||
| 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. | |||
| * | |||
| * \param[in] csPin SD card chip select pin. | |||
| @@ -294,6 +294,7 @@ class SdFat : public SdFatBase { | |||
| bool cardBegin(uint8_t csPin = SS, uint8_t divisor = 2) { | |||
| return card()->begin(&m_spi, csPin, divisor); | |||
| } | |||
| private: | |||
| SpiDefault_t m_spi; | |||
| }; | |||
| @@ -46,11 +46,11 @@ bool fastDigitalRead(uint8_t pin) { | |||
| */ | |||
| static inline __attribute__((always_inline)) | |||
| 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 | |||
| //------------------------------------------------------------------------------ | |||
| @@ -59,7 +59,7 @@ void fastDigitalWrite(uint8_t pin, bool value) { | |||
| * @return value read | |||
| */ | |||
| 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; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| @@ -68,8 +68,8 @@ bool fastDigitalRead(uint8_t pin){ | |||
| * @param[in] level value to write | |||
| */ | |||
| 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; | |||
| } else { | |||
| g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; | |||
| @@ -78,8 +78,8 @@ void fastDigitalWrite(uint8_t pin, bool value){ | |||
| #endif // CORE_TEENSY | |||
| //------------------------------------------------------------------------------ | |||
| 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);} | |||
| #else // __arm__ | |||
| @@ -87,7 +87,7 @@ inline void fastPinMode(uint8_t pin, uint8_t mode) {pinMode(pin, mode);} | |||
| #include <avr/io.h> | |||
| /** GpioPinMap type */ | |||
| 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* port; /**< address of PORT for this pin */ | |||
| uint8_t mask; /**< bit mask for this pin */ | |||
| @@ -161,7 +161,7 @@ volatile uint8_t* portReg(uint8_t pin) { | |||
| static inline __attribute__((always_inline)) | |||
| void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { | |||
| uint8_t s; | |||
| if (address > (uint8_t*)0X3F) { | |||
| if (address > reinterpret_cast<uint8_t*>(0X3F)) { | |||
| s = SREG; | |||
| cli(); | |||
| } | |||
| @@ -170,7 +170,7 @@ void fastBitWriteSafe(volatile uint8_t* address, uint8_t mask, bool level) { | |||
| } else { | |||
| *address &= ~mask; | |||
| } | |||
| if (address > (uint8_t*)0X3F) { | |||
| if (address > reinterpret_cast<uint8_t*>(0X3F)) { | |||
| SREG = s; | |||
| } | |||
| } | |||
| @@ -192,7 +192,7 @@ bool fastDigitalRead(uint8_t pin) { | |||
| */ | |||
| static inline __attribute__((always_inline)) | |||
| 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 | |||
| *pinReg(pin) = pinMask(pin); | |||
| } else { | |||
| @@ -272,7 +272,7 @@ class DigitalPin { | |||
| /** Parenthesis operator. | |||
| * @return Pin's level | |||
| */ | |||
| inline operator bool () const __attribute__((always_inline)) { | |||
| inline operator bool () const __attribute__((always_inline)) { | |||
| return read(); | |||
| } | |||
| //---------------------------------------------------------------------------- | |||
| @@ -336,4 +336,4 @@ class DigitalPin { | |||
| } | |||
| }; | |||
| #endif // DigitalPin_h | |||
| /** @} */ | |||
| /** @} */ | |||
| @@ -115,13 +115,13 @@ uint8_t const SPI_SIXTEENTH_SPEED = 32; | |||
| //------------------------------------------------------------------------------ | |||
| // SD operation timeouts | |||
| /** init timeout ms */ | |||
| uint16_t const SD_INIT_TIMEOUT = 2000; | |||
| unsigned const SD_INIT_TIMEOUT = 2000; | |||
| /** erase timeout ms */ | |||
| uint16_t const SD_ERASE_TIMEOUT = 10000; | |||
| unsigned const SD_ERASE_TIMEOUT = 10000; | |||
| /** read timeout ms */ | |||
| uint16_t const SD_READ_TIMEOUT = 300; | |||
| unsigned const SD_READ_TIMEOUT = 300; | |||
| /** write time out ms */ | |||
| uint16_t const SD_WRITE_TIMEOUT = 600; | |||
| unsigned const SD_WRITE_TIMEOUT = 600; | |||
| //------------------------------------------------------------------------------ | |||
| // SD card commands | |||
| /** GO_IDLE_STATE - init card in spi mode if CS low */ | |||
| @@ -44,7 +44,7 @@ class SdSpiBase { | |||
| virtual void beginTransaction(uint8_t divisor); | |||
| /** | |||
| * End SPI transaction. | |||
| */ | |||
| */ | |||
| virtual void endTransaction(); | |||
| /** Receive a byte. | |||
| * | |||
| @@ -146,6 +146,8 @@ class SdSpiLib { | |||
| * \param[in] chipSelectPin SD card chip select pin. | |||
| */ | |||
| void begin(uint8_t chipSelectPin) { | |||
| pinMode(chipSelectPin, OUTPUT); | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| SPI.begin(); | |||
| } | |||
| /** Set SPI options for access to SD/SDHC cards. | |||
| @@ -154,10 +156,10 @@ class SdSpiLib { | |||
| */ | |||
| void beginTransaction(uint8_t divisor) { | |||
| #if ENABLE_SPI_TRANSACTIONS | |||
| SPI.beginTransaction(SPISettings()); | |||
| SPI.beginTransaction(SPISettings()); | |||
| #else // #if ENABLE_SPI_TRANSACTIONS | |||
| SPI.setBitOrder(MSBFIRST); | |||
| SPI.setDataMode(SPI_MODE0); | |||
| SPI.setBitOrder(MSBFIRST); | |||
| SPI.setDataMode(SPI_MODE0); | |||
| #endif // #if ENABLE_SPI_TRANSACTIONS | |||
| #ifndef SPI_CLOCK_DIV128 | |||
| @@ -184,7 +186,7 @@ class SdSpiLib { | |||
| } | |||
| /** | |||
| * End SPI transaction. | |||
| */ | |||
| */ | |||
| void endTransaction() { | |||
| #if ENABLE_SPI_TRANSACTIONS | |||
| SPI.endTransaction(); | |||
| @@ -213,7 +215,7 @@ class SdSpiLib { | |||
| } | |||
| return 0; | |||
| } | |||
| #endif // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||
| #endif // defined(PLATFORM_ID) && USE_SPI_LIB_DMA | |||
| /** Send a byte. | |||
| * | |||
| * \param[in] b Byte to send | |||
| @@ -240,7 +242,7 @@ class SdSpiLib { | |||
| #if SD_SPI_CONFIGURATION > 1 || defined(DOXYGEN) | |||
| #ifdef ARDUINO | |||
| #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" | |||
| #endif // ARDUINO | |||
| /** | |||
| @@ -263,7 +265,9 @@ class SdSpiSoft : public SdSpiBase { | |||
| * Initialize hardware SPI - dummy for soft SPI | |||
| * \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 | |||
| */ | |||
| @@ -212,7 +212,7 @@ uint8_t SdSpiCard::cardCommand(uint8_t cmd, uint32_t arg) { | |||
| #if USE_SD_CRC | |||
| // form message | |||
| uint8_t d[6] = {cmd , pa[3], pa[2], pa[1], pa[0]}; | |||
| d[0] |= 0X40; | |||
| // add crc | |||
| @@ -333,12 +333,20 @@ bool SdSpiCard::eraseSingleBlockEnable() { | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| bool SdSpiCard::isBusy() { | |||
| bool rtn = true; | |||
| bool selected = m_selected; | |||
| chipSelectLow(); | |||
| for (uint8_t i = 0; i < 8; i++) { | |||
| if (0XFF == spiReceive()) { | |||
| return false; | |||
| rtn = false; | |||
| break; | |||
| } | |||
| } | |||
| return true; | |||
| if (!selected) { | |||
| chipSelectHigh(); | |||
| } | |||
| return rtn; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | |||
| @@ -354,7 +362,7 @@ bool SdSpiCard::readBlock(uint32_t blockNumber, uint8_t* dst) { | |||
| if (!readData(dst, 512)) { | |||
| goto fail; | |||
| } | |||
| chipSelectHigh(); | |||
| chipSelectHigh(); | |||
| return true; | |||
| fail: | |||
| @@ -367,7 +375,7 @@ bool SdSpiCard::readBlocks(uint32_t block, uint8_t* dst, size_t count) { | |||
| return false; | |||
| } | |||
| for (uint16_t b = 0; b < count; b++, dst += 512) { | |||
| if (!readData(dst)) { | |||
| if (!readData(dst, 512)) { | |||
| return false; | |||
| } | |||
| } | |||
| @@ -375,7 +383,15 @@ bool SdSpiCard::readBlocks(uint32_t block, uint8_t* dst, size_t count) { | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| 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) { | |||
| @@ -540,21 +556,26 @@ bool SdSpiCard::writeBlocks(uint32_t block, const uint8_t* src, size_t count) { | |||
| } | |||
| } | |||
| return writeStop(); | |||
| fail: | |||
| chipSelectHigh(); | |||
| return false; | |||
| return false; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| bool SdSpiCard::writeData(const uint8_t* src) { | |||
| bool selected = m_selected; | |||
| chipSelectLow(); | |||
| // wait for previous write to finish | |||
| if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | |||
| error(SD_CARD_ERROR_WRITE_TIMEOUT); | |||
| error(SD_CARD_ERROR_WRITE_TIMEOUT); | |||
| goto fail; | |||
| } | |||
| if (!writeData(WRITE_MULTIPLE_TOKEN, src)) { | |||
| goto fail; | |||
| } | |||
| if (!selected) { | |||
| chipSelectHigh(); | |||
| } | |||
| return true; | |||
| fail: | |||
| @@ -609,6 +630,7 @@ fail: | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| bool SdSpiCard::writeStop() { | |||
| chipSelectLow(); | |||
| if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | |||
| goto fail; | |||
| } | |||
| @@ -41,7 +41,8 @@ class SdSpiCard { | |||
| typedef SdSpiBase m_spi_t; | |||
| #endif // SD_SPI_CONFIGURATION < 3 | |||
| /** 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. | |||
| * \param[in] spi SPI object. | |||
| * \param[in] chipSelectPin SD chip select pin. | |||
| @@ -217,7 +218,7 @@ class SdSpiCard { | |||
| * the value false is returned for failure. | |||
| */ | |||
| 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. | |||
| * \return The value true is returned for success and | |||
| * the value false is returned for failure. | |||
| @@ -308,9 +309,13 @@ class Sd2Card : public SdSpiCard { | |||
| bool init(uint8_t sckDivisor = 2, uint8_t chipSelectPin = SS) { | |||
| return begin(chipSelectPin, sckDivisor); | |||
| } | |||
| private: | |||
| bool begin(m_spi_t* spi, uint8_t chipSelectPin = SS, | |||
| uint8_t sckDivisor = SPI_FULL_SPEED) { | |||
| (void)spi; | |||
| (void)chipSelectPin; | |||
| (void)sckDivisor; | |||
| return false; | |||
| } | |||
| SpiDefault_t m_spi; | |||
| @@ -1,5 +1,5 @@ | |||
| /* Arduino SdFat Library | |||
| * Copyright (C) 2012 by William Greiman | |||
| * Copyright (C) 2016 by William Greiman | |||
| * | |||
| * This file is part of the Arduino SdFat Library | |||
| * | |||
| @@ -23,13 +23,13 @@ | |||
| static uint32_t bugDelay = 0; // fix for SPI DMA bug. | |||
| static volatile bool SPI_DMA_TransferCompleted = false; | |||
| //static uint8_t m_spiIf = 1; | |||
| static SPIClass* const spiPtr[] = { | |||
| &SPI | |||
| &SPI | |||
| #if Wiring_SPI1 | |||
| ,&SPI1 | |||
| , &SPI1 | |||
| #if Wiring_SPI2 | |||
| ,&SPI2 | |||
| , &SPI2 | |||
| #endif // Wiring_SPI2 | |||
| #endif // Wiring_SPI1 | |||
| }; | |||
| @@ -72,36 +72,39 @@ void SdSpi::beginTransaction(uint8_t divisor) { | |||
| // delay for SPI transfer done callback too soon bug. | |||
| bugDelay = 24*divisor*(1 + m_spiIf)/60; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| //----------------------------------------------------------------------------- | |||
| void SdSpi::endTransaction() { | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| //----------------------------------------------------------------------------- | |||
| /** SPI receive a byte */ | |||
| uint8_t SdSpi::receive() { | |||
| return spiPtr[m_spiIf]->transfer(0xFF); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||
| uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||
| SPI_DMA_TransferCompleted = false; | |||
| spiPtr[m_spiIf]->transfer(0, buf, n, SD_SPI_DMA_TransferComplete_Callback); | |||
| while(!SPI_DMA_TransferCompleted); | |||
| while (!SPI_DMA_TransferCompleted) {} | |||
| if (bugDelay) { | |||
| delayMicroseconds(bugDelay); | |||
| } | |||
| return 0; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| //----------------------------------------------------------------------------- | |||
| /** SPI send a byte */ | |||
| void SdSpi::send(uint8_t b) { | |||
| spiPtr[m_spiIf]->transfer(b); | |||
| } | |||
| //----------------------------------------------------------------------------- | |||
| //----------------------------------------------------------------------------- | |||
| void SdSpi::send(const uint8_t* buf , size_t n) { | |||
| SPI_DMA_TransferCompleted = false; | |||
| spiPtr[m_spiIf]->transfer((void *)buf, 0, n, SD_SPI_DMA_TransferComplete_Callback); | |||
| while(!SPI_DMA_TransferCompleted); | |||
| spiPtr[m_spiIf]->transfer(const_cast<uint8_t*>(buf), 0, n, | |||
| SD_SPI_DMA_TransferComplete_Callback); | |||
| while (!SPI_DMA_TransferCompleted) {} | |||
| if (bugDelay) { | |||
| delayMicroseconds(bugDelay); | |||
| } | |||
| } | |||
| #endif //defined(PLATFORM_ID) | |||
| #endif // defined(PLATFORM_ID) | |||
| @@ -232,6 +232,8 @@ void SdSpi::send(const uint8_t* buf , size_t n) { | |||
| * Initialize SPI pins. | |||
| */ | |||
| void SdSpi::begin(uint8_t chipSelectPin) { | |||
| pinMode(chipSelectPin, OUTPUT); | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| SPI.begin(); | |||
| } | |||
| /** Set SPI options for access to SD/SDHC cards. | |||
| @@ -1,14 +1,29 @@ | |||
| /* 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 | |||
| #define SystemInclude_h | |||
| #if defined(ARDUINO) | |||
| #include <Arduino.h> | |||
| #include <SPI.h> | |||
| #elif defined(PLATFORM_ID) //Only defined if a Particle device | |||
| #include "application.h" | |||
| #else // | |||
| #error "Unknown system" | |||
| #endif // defined(ARDUINO) | |||
| #ifndef F | |||
| #define F(str) (str) | |||
| #endif // F | |||
| #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 | |||
| @@ -6,7 +6,6 @@ | |||
| #include <SdFat.h> | |||
| #include <SdFatTestSuite.h> | |||
| SdFat SD; | |||
| #define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||
| #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | |||
| void setup() { | |||
| boolean b; | |||
| @@ -3,7 +3,6 @@ | |||
| #include <SdFat.h> | |||
| #include <SdFatTestSuite.h> | |||
| SdFat SD; | |||
| #define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||
| #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | |||
| void setup() { | |||
| @@ -5,7 +5,6 @@ | |||
| #include <SdFat.h> | |||
| #include <SdFatTestSuite.h> | |||
| SdFat SD; | |||
| #define FILE_WRITE O_RDWR | O_CREAT | O_AT_END | |||
| #define ATS_PrintTestStatus(msg, b) testVerify_P(b, PSTR(msg)) | |||
| void setup() { | |||
| @@ -83,7 +83,7 @@ void dirAllocTest(FatFile* dir) { | |||
| uint32_t t2 = millis(); | |||
| // 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"); | |||
| } | |||
| if (!file.close()) error("close read failed"); | |||
| @@ -2,7 +2,7 @@ | |||
| #include <SdFat.h> | |||
| #include <SdFatTestSuite.h> | |||
| SdFat sd; | |||
| char *testName = "SDFAT.TST"; | |||
| const char *testName = "SDFAT.TST"; | |||
| //------------------------------------------------------------------------------ | |||
| void fstreamOpen() { | |||
| ios::openmode nocreate[] = {ios::in, ios::in | ios::out}; | |||
| @@ -7,7 +7,7 @@ SdFile file; | |||
| char name[260]; | |||
| //------------------------------------------------------------------------------ | |||
| char* testName[] = { | |||
| const char* testName[] = { | |||
| "low.low", | |||
| "low.Mix", | |||
| "low.UP", | |||
| @@ -40,11 +40,11 @@ bool checkName(char first, size_t len) { | |||
| return false; | |||
| } | |||
| for (i = 1; i < (len - 4); i++) { | |||
| if (name[i] != ('0' + (i + 1) %10)) { | |||
| if (name[i] != (char)('0' + (i + 1) %10)) { | |||
| return false; | |||
| } | |||
| } | |||
| char* p = ".txt"; | |||
| const char* p = ".txt"; | |||
| while (*p) { | |||
| if (name[i++] != *p++) { | |||
| return false; | |||
| @@ -65,7 +65,7 @@ void makeName(char first, size_t len) { | |||
| for (i = 1; i < (len - 4); i++) { | |||
| name[i] = '0' + (i + 1) %10; | |||
| } | |||
| char* p = ".txt"; | |||
| const char* p = ".txt"; | |||
| while (*p) name[i++] = *p++; | |||
| name[i] = 0; | |||
| } | |||
| @@ -74,7 +74,6 @@ void makeName(char first, size_t len) { | |||
| void basicTest() { | |||
| size_t i; | |||
| size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | |||
| uint16_t index; | |||
| uint16_t maxIndex = 0; | |||
| makeName('Z', 256); | |||
| @@ -15,7 +15,7 @@ char cinBuf[10]; | |||
| // Serial input stream | |||
| ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); | |||
| //------------------------------------------------------------------------------ | |||
| char* testName[] = { | |||
| const char* testName[] = { | |||
| "low.low", | |||
| "low.Mix", | |||
| "low.UP", | |||
| @@ -48,11 +48,11 @@ bool checkName(char first, size_t len) { | |||
| return false; | |||
| } | |||
| for (i = 1; i < (len - 4); i++) { | |||
| if (name[i] != ('0' + (i + 1) %10)) { | |||
| if (name[i] != (char)('0' + (i + 1) %10)) { | |||
| return false; | |||
| } | |||
| } | |||
| char* p = ".txt"; | |||
| const char* p = ".txt"; | |||
| while (*p) { | |||
| if (name[i++] != *p++) { | |||
| return false; | |||
| @@ -73,7 +73,7 @@ void makeName(char first, size_t len) { | |||
| for (i = 1; i < (len - 4); i++) { | |||
| name[i] = '0' + (i + 1) %10; | |||
| } | |||
| char* p = ".txt"; | |||
| const char* p = ".txt"; | |||
| while (*p) name[i++] = *p++; | |||
| name[i] = 0; | |||
| } | |||
| @@ -82,7 +82,6 @@ void makeName(char first, size_t len) { | |||
| void basicTest() { | |||
| size_t i; | |||
| size_t n = sd.vol()->fatType() == 32 ? 255 : 99; | |||
| uint16_t index; | |||
| uint16_t maxIndex = 0; | |||
| makeName('Z', 256); | |||
| @@ -144,7 +144,7 @@ void ostreamNumber() { | |||
| void ostreamStr() { | |||
| char buf[40]; | |||
| obufstream ob(buf, sizeof(buf)); | |||
| char* c = "c"; | |||
| char c[] = "c"; | |||
| const char* cc = "CC"; | |||
| signed char* sc = (signed char*)"sc"; | |||
| const signed char* csc = (const signed char*)"CSC"; | |||
| @@ -1,3 +1,9 @@ | |||
| 12 Feb 2016 | |||
| Mods for Particle.io boards. | |||
| Features for shared SPI with multiple block write. | |||
| 23 Jan 2016 | |||
| New Examples. | |||
| @@ -103,11 +103,12 @@ Include dependency graph for ArduinoFiles.h:</div> | |||
| <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> | |||
| <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> | |||
| </div> | |||
| </div><div class="textblock"><div class="dynheader"> | |||
| @@ -167,7 +168,7 @@ Macros</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -95,23 +95,24 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); | |||
| <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> | |||
| <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 /> | |||
| </div><div class="textblock"><div class="dynheader"> | |||
| Include dependency graph for ArduinoStream.h:</div> | |||
| <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> | |||
| <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> | |||
| </div> | |||
| </div><table class="memberdecls"> | |||
| @@ -129,7 +130,7 @@ Classes</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -162,7 +162,7 @@ Functions</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -108,10 +108,11 @@ Include dependency graph for FatFile.h:</div> | |||
| <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> | |||
| <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> | |||
| </div> | |||
| </div><div class="textblock"><div class="dynheader"> | |||
| @@ -327,7 +328,7 @@ Variables</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -102,12 +102,13 @@ Include dependency graph for FatFileSystem.h:</div> | |||
| <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> | |||
| <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> | |||
| </div> | |||
| </div><table class="memberdecls"> | |||
| @@ -122,7 +123,7 @@ Classes</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -267,7 +267,7 @@ Macros</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -1275,7 +1275,7 @@ Variables</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -96,7 +96,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); | |||
| <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> | |||
| <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_structs_8h.html">FatStructs.h</a>"</code><br /> | |||
| </div><div class="textblock"><div class="dynheader"> | |||
| @@ -104,9 +104,10 @@ Include dependency graph for FatVolume.h:</div> | |||
| <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> | |||
| <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> | |||
| </div> | |||
| </div><div class="textblock"><div class="dynheader"> | |||
| @@ -164,7 +165,7 @@ Typedefs</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -85,19 +85,87 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); | |||
| </div> | |||
| </div><!-- top --> | |||
| <div class="header"> | |||
| <div class="summary"> | |||
| <a href="#func-members">Functions</a> | | |||
| <a href="#var-members">Variables</a> </div> | |||
| <div class="headertitle"> | |||
| <div class="title">FreeStack.h File Reference</div> </div> | |||
| </div><!--header--> | |||
| <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> | |||
| <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> | |||
| <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 --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -136,7 +136,7 @@ Classes</h2></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: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> | |||
| </table> | |||
| <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2> | |||
| @@ -147,7 +147,7 @@ Macros</h2></td></tr> | |||
| <div class="memproto"> | |||
| <table class="memname"> | |||
| <tr> | |||
| <td class="memname">#define SD_FAT_VERSION   20160123</td> | |||
| <td class="memname">#define SD_FAT_VERSION   20160212</td> | |||
| </tr> | |||
| </table> | |||
| </div><div class="memdoc"> | |||
| @@ -158,7 +158,7 @@ Macros</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -432,7 +432,7 @@ Variables</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -117,7 +117,7 @@ Functions</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -155,7 +155,7 @@ Typedefs</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -131,7 +131,7 @@ Classes</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -133,7 +133,7 @@ Variables</h2></td></tr> | |||
| </div></div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -105,10 +105,11 @@ Include dependency graph for StdioStream.h:</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"> | |||
| <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="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> | |||
| </div> | |||
| </div><table class="memberdecls"> | |||
| @@ -236,7 +237,7 @@ Variables</h2></td></tr> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||
| @@ -0,0 +1,157 @@ | |||
| <!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> | |||
| @@ -137,12 +137,13 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); | |||
| <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_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> | |||
| </div><!-- directory --> | |||
| </div><!-- contents --> | |||
| <!-- start footer part --> | |||
| <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"/> | |||
| </a> 1.8.10 | |||
| </small></address> | |||