Fix SdInfo example and file.timestamp. Remove Syscall::yield and SysCall::halt
Fix SdInfo example and file.timestamp. Remove Syscall::yield and SysCall::halt. Major restructuring for future portability to RTOS systems and RPI Pico.
This commit is contained in:
parent
a5e4bdeb76
commit
fb7415151b
168 changed files with 1497 additions and 1659 deletions
|
|
@ -4,7 +4,7 @@ Earlier releases of Version 1 are here:
|
|||
|
||||
https://github.com/greiman/SdFat/releases
|
||||
|
||||
###### UTF-8 encoded filenames are supported in v2.1.0.
|
||||
UTF-8 encoded filenames are supported in v2.1.0 or later.
|
||||
|
||||
Try the UnicodeFilenames example. Here is output from ls:
|
||||
<pre>
|
||||
|
|
|
|||
651
doc/Doxyfile
651
doc/Doxyfile
File diff suppressed because it is too large
Load diff
BIN
doc/html.zip
BIN
doc/html.zip
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -249,11 +249,9 @@ DirectoryFunctions - Use of chdir(), ls(), mkdir(), and rmdir().
|
|||
|
||||
examplesV1 folder - Examples from SdFat V1 for compatibility tests.
|
||||
|
||||
%ExFatFormatter - Produces optimal exFAT format for smaller SD cards.
|
||||
|
||||
ExFatLogger - A data-logger optimized for exFAT features.
|
||||
|
||||
ExFatUnicodeTest - Test program for Unicode file names.
|
||||
MinimumSizeSdReader - Example of small file reader for FAT16/FAT32.
|
||||
|
||||
OpenNext - Open all files in the root dir and print their filename.
|
||||
|
||||
|
|
@ -275,10 +273,16 @@ SoftwareSpi - Demo of limited Software SPI support in SdFat V2.
|
|||
|
||||
STM32Test - Example use of two SPI ports on an STM32 board.
|
||||
|
||||
TeensyDmaAdcLogger - Fast logger using DMA ADC.
|
||||
|
||||
TeensyRtcTimestamp - %File timestamps for Teensy3.
|
||||
|
||||
TeensySdioDemo - Demo of SDIO and SPI modes for the Teensy 3.5/3.6 built-in SD.
|
||||
|
||||
TeensySdioLogger - Fast logger using a ring buffer.
|
||||
|
||||
UnicodeFilenames - Test program for Unicode file names.
|
||||
|
||||
UserChipSelectFunction - Useful for port expanders or replacement of the standard GPIO functions.
|
||||
|
||||
UserSPIDriver - An example of an external SPI driver.
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@ MinimumSerial MinSerial;
|
|||
//------------------------------------------------------------------------------
|
||||
// This example was designed for exFAT but will support FAT16/FAT32.
|
||||
//
|
||||
// If an exFAT SD is required, the ExFatFormatter example will format
|
||||
// smaller cards with an exFAT file system.
|
||||
//
|
||||
// Note: Uno will not support SD_FAT_TYPE = 3.
|
||||
// SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h,
|
||||
// 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT.
|
||||
|
|
@ -152,9 +149,9 @@ const uint16_t ISR_TIMER0 = 160;
|
|||
//==============================================================================
|
||||
const uint32_t MAX_FILE_SIZE = MAX_FILE_SIZE_MiB << 20;
|
||||
|
||||
// Select fastest interface. Max SPI rate for AVR is 10 MHx.
|
||||
// Max SPI rate for AVR is 10 MHz for F_CPU 20 MHz, 8 MHz for F_CPU 16 MHz.
|
||||
#define SPI_CLOCK SD_SCK_MHZ(10)
|
||||
|
||||
// Select fastest interface.
|
||||
#if ENABLE_DEDICATED_SPI
|
||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)
|
||||
#else // ENABLE_DEDICATED_SPI
|
||||
|
|
@ -868,7 +865,7 @@ void loop(void) {
|
|||
Serial.println(F("r - record ADC data"));
|
||||
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = tolower(Serial.read());
|
||||
Serial.println();
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize the SD card.
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
Serial.println(F("Type any character to begin"));
|
||||
|
|
@ -568,7 +568,7 @@ void loop() {
|
|||
Serial.println(F("r - record data"));
|
||||
Serial.println(F("t - test without logging"));
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = tolower(Serial.read());
|
||||
Serial.println();
|
||||
|
|
|
|||
58
examples/MinimumSizeSdReader/MinimumSizeSdReader.ino
Normal file
58
examples/MinimumSizeSdReader/MinimumSizeSdReader.ino
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Create a text file on the SD with this path using short 8.3 names.
|
||||
#define SFN_PATH "/DIR/TEST.TXT"
|
||||
|
||||
// Modify CS_PIN for your chip select pin.
|
||||
#define CS_PIN SS
|
||||
|
||||
// Set USE_SD_H to one for SD.h or zero for SdFat.
|
||||
#define USE_SD_H 0
|
||||
|
||||
#if USE_SD_H
|
||||
#include "SD.h"
|
||||
File file;
|
||||
#else
|
||||
#include "SdFat.h"
|
||||
// Setting ENABLE_DEDICATED_SPI to zero saves over 200 more bytes.
|
||||
#if ENABLE_DEDICATED_SPI
|
||||
#warning "Set ENABLE_DEDICATED_SPI zero in SdFat/src/SdFatConfig.h for minimum size"
|
||||
#endif // ENABLE_DEDICATED_SPI
|
||||
// Insure FAT16/FAT32 only.
|
||||
SdFat32 SD;
|
||||
// FatFile does not support Stream functions, just simple read/write.
|
||||
FatFile file;
|
||||
#endif
|
||||
|
||||
void error(const char* msg) {
|
||||
Serial.println(msg);
|
||||
while(true);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
int n;
|
||||
char buf[4];
|
||||
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {}
|
||||
Serial.println("Type any character to begin");
|
||||
while (!Serial.available()) {}
|
||||
|
||||
if (!SD.begin(CS_PIN)) error("SD.begin");
|
||||
|
||||
#if USE_SD_H
|
||||
file = SD.open(SFN_PATH);
|
||||
if (!file) error("open");
|
||||
#else
|
||||
// Open existing file with a path of 8.3 names.
|
||||
// Directories will be opened O_RDONLY files O_RDWR.
|
||||
if (!file.openExistingSFN(SFN_PATH)) error("open");
|
||||
#endif
|
||||
while ((n = file.read(buf, sizeof(buf)))) {
|
||||
Serial.write(buf, n);
|
||||
}
|
||||
// close() is only needed if you write to the file. For example, read
|
||||
// config data, modify the data, rewind the file and write the data.
|
||||
// file.close();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
|
|
@ -63,12 +63,12 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
Serial.println("Type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize the SD.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("\nSPI pins:\n");
|
||||
cout << F("MISO: ") << int(MISO) << endl;
|
||||
|
|
@ -106,7 +106,7 @@ void loop() {
|
|||
|
||||
cout << F("\nEnter the chip select pin number: ");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cin.readline();
|
||||
if (cin >> chipSelect) {
|
||||
|
|
@ -182,6 +182,6 @@ void loop() {
|
|||
|
||||
cout << F("\nSuccess! Type any character to restart.\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
/* This example is for https://github.com/rogerclarkmelbourne/Arduino_STM32
|
||||
*
|
||||
* Example use of two SPI ports on an STM32 board.
|
||||
* Note SPI speed is limited to 18 MHz.
|
||||
*/
|
||||
#include <SPI.h>
|
||||
#include "SdFat.h"
|
||||
#include "FreeStack.h"
|
||||
|
||||
// Chip select PA4, shared SPI, 18 MHz, port 1.
|
||||
#define SD1_CONFIG SdSpiConfig(PA4, SHARED_SPI, SD_SCK_MHZ(18), &SPI)
|
||||
SdFs sd1;
|
||||
FsFile file1;
|
||||
|
||||
// Use mySPI2 since SPI2 is used in SPI.h as a different type.
|
||||
static SPIClass mySPI2(2);
|
||||
// Chip select PB12, dedicated SPI, 18 MHz, port 2.
|
||||
#if ENABLE_DEDICATED_SPI
|
||||
#define SD2_CONFIG SdSpiConfig(PB12, DEDICATED_SPI, SD_SCK_MHZ(18), &mySPI2)
|
||||
#else // ENABLE_DEDICATED_SPI
|
||||
#define SD2_CONFIG SdSpiConfig(PB12, SHARED_SPI, SD_SCK_MHZ(18), &mySPI2)
|
||||
#endif // ENABLE_DEDICATED_SPI
|
||||
|
||||
SdFs sd2;
|
||||
FsFile file2;
|
||||
|
||||
const uint8_t BUF_DIM = 100;
|
||||
uint8_t buf[BUF_DIM];
|
||||
|
||||
const uint32_t FILE_SIZE = 1000000;
|
||||
const uint32_t NWRITE = FILE_SIZE/BUF_DIM;
|
||||
//------------------------------------------------------------------------------
|
||||
// print error msg, any SD error codes, and halt.
|
||||
// store messages in flash
|
||||
#define error(msg) {Serial.println(msg); errorHalt();}
|
||||
void errorHalt() {
|
||||
if (sd1.sdErrorCode()) {
|
||||
sd1.errorHalt();
|
||||
}
|
||||
sd2.errorHalt();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
}
|
||||
Serial.print(F("FreeStack: "));
|
||||
Serial.println(FreeStack());
|
||||
|
||||
// fill buffer with known data
|
||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
||||
buf[i] = i;
|
||||
}
|
||||
|
||||
Serial.println(F("type any character to start"));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
}
|
||||
|
||||
// initialize the first card
|
||||
if (!sd1.begin(SD1_CONFIG)) {
|
||||
error("sd1.begin");
|
||||
}
|
||||
// create Dir1 on sd1 if it does not exist
|
||||
if (!sd1.exists("/Dir1")) {
|
||||
if (!sd1.mkdir("/Dir1")) {
|
||||
error("sd1.mkdir");
|
||||
}
|
||||
}
|
||||
// Make Dir1 the working directory on sd1.
|
||||
if (!sd1.chdir("Dir1")) {
|
||||
error("dsd1.chdir");
|
||||
}
|
||||
// initialize the second card
|
||||
if (!sd2.begin(SD2_CONFIG)) {
|
||||
error("sd2.begin");
|
||||
}
|
||||
// create Dir2 on sd2 if it does not exist
|
||||
if (!sd2.exists("/Dir2")) {
|
||||
if (!sd2.mkdir("/Dir2")) {
|
||||
error("sd2.mkdir");
|
||||
}
|
||||
}
|
||||
// Make Dir2 the working directory on sd2.
|
||||
if (!sd2.chdir("Dir2")) {
|
||||
error("sd2.chdir");
|
||||
}
|
||||
// remove test.bin from /Dir1 directory of sd1
|
||||
if (sd1.exists("test.bin")) {
|
||||
if (!sd1.remove("test.bin")) {
|
||||
error("remove test.bin");
|
||||
}
|
||||
}
|
||||
// remove rename.bin from /Dir2 directory of sd2
|
||||
if (sd2.exists("rename.bin")) {
|
||||
if (!sd2.remove("rename.bin")) {
|
||||
error("remove rename.bin");
|
||||
}
|
||||
}
|
||||
// list directories.
|
||||
Serial.println(F("------sd1 Dir1-------"));
|
||||
sd1.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("------sd2 Dir2-------"));
|
||||
sd2.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("---------------------"));
|
||||
|
||||
// create or open /Dir1/test.bin and truncate it to zero length
|
||||
if (!file1.open(&sd1, "test.bin", O_RDWR | O_CREAT | O_TRUNC)) {
|
||||
error("file1.open");
|
||||
}
|
||||
Serial.println(F("Writing test.bin to sd1"));
|
||||
|
||||
// write data to /Dir1/test.bin on sd1
|
||||
for (uint32_t i = 0; i < NWRITE; i++) {
|
||||
if (file1.write(buf, sizeof(buf)) != sizeof(buf)) {
|
||||
error("file1.write");
|
||||
}
|
||||
}
|
||||
|
||||
// create or open /Dir2/copy.bin and truncate it to zero length
|
||||
if (!file2.open(&sd2, "copy.bin", O_WRONLY | O_CREAT | O_TRUNC)) {
|
||||
error("file2.open");
|
||||
}
|
||||
Serial.println(F("Copying test.bin to copy.bin"));
|
||||
|
||||
// copy file1 to file2
|
||||
file1.rewind();
|
||||
uint32_t t = millis();
|
||||
|
||||
while (1) {
|
||||
int n = file1.read(buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
error("file1.read");
|
||||
}
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
if ((int)file2.write(buf, n) != n) {
|
||||
error("file2.write");
|
||||
}
|
||||
}
|
||||
t = millis() - t;
|
||||
Serial.print(F("File size: "));
|
||||
Serial.println(file2.fileSize());
|
||||
Serial.print(F("Copy time: "));
|
||||
Serial.print(t);
|
||||
Serial.println(F(" millis"));
|
||||
// close test.bin
|
||||
file1.close();
|
||||
// sync copy.bin so ls works.
|
||||
file2.close();
|
||||
// list directories.
|
||||
Serial.println(F("------sd1 -------"));
|
||||
sd1.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("------sd2 -------"));
|
||||
sd2.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("---------------------"));
|
||||
Serial.println(F("Renaming copy.bin"));
|
||||
// Rename copy.bin. The renamed file will be in Dir2.
|
||||
if (!sd2.rename("copy.bin", "rename.bin")) {
|
||||
error("rename copy.bin");
|
||||
}
|
||||
file2.close();
|
||||
// list directories.
|
||||
Serial.println(F("------sd1 -------"));
|
||||
sd1.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("------sd2 -------"));
|
||||
sd2.ls("/", LS_R | LS_SIZE);
|
||||
Serial.println(F("---------------------"));
|
||||
Serial.println(F("Done"));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void loop() {}
|
||||
|
|
@ -73,7 +73,7 @@ void sdErrorHalt() {
|
|||
cout << F(" = ") << int(m_card->errorCode()) << endl;
|
||||
cout << F("SD errorData = ") << int(m_card->errorData()) << endl;
|
||||
}
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void clearSerialInput() {
|
||||
|
|
@ -158,12 +158,12 @@ void setup() {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
printConfig(SD_CONFIG);
|
||||
cout << F("\nType any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Discard any extra characters.
|
||||
clearSerialInput();
|
||||
|
|
@ -183,7 +183,7 @@ void setup() {
|
|||
"Warning, all data on the card will be erased.\n"
|
||||
"Enter 'Y' to continue: ");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
c = Serial.read();
|
||||
cout << c << endl;
|
||||
|
|
@ -230,7 +230,7 @@ void setup() {
|
|||
"Enter option: ");
|
||||
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
c = Serial.read();
|
||||
cout << c << endl;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ bool cidDmp() {
|
|||
cout << F("Serial number: ") << hex << m_cid.psn << dec << endl;
|
||||
cout << F("Manufacturing date: ");
|
||||
cout << int(m_cid.mdt_month) << '/';
|
||||
cout << (2000 + m_cid.mdt_year_low + 10 * m_cid.mdt_year_high) << endl;
|
||||
cout << (2000 + 16*m_cid.mdt_year_high + m_cid.mdt_year_low) << endl;
|
||||
cout << endl;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -206,7 +206,7 @@ void setup() {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("SdFat version: ") << SD_FAT_VERSION_STR << endl;
|
||||
printConfig(SD_CONFIG);
|
||||
|
|
@ -220,7 +220,7 @@ void loop() {
|
|||
// F stores strings in flash to save RAM
|
||||
cout << F("\ntype any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
uint32_t t = millis();
|
||||
if (!sd.cardBegin(SD_CONFIG)) {
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ void setup() {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println("Type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
if (!sd.begin(SD_CONFIG)) {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void logData() {
|
|||
// Amount of data in ringBuf.
|
||||
size_t n = rb.bytesUsed();
|
||||
if ((n + file.curPosition()) > (LOG_FILE_SIZE - 20)) {
|
||||
Serial.println("File full - quiting.");
|
||||
Serial.println("File full - quitting.");
|
||||
break;
|
||||
}
|
||||
if (n > maxUsed) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// SD_CHIP_SELECT_MODE must be set to one or two in SdFat/SdFatConfig.h.
|
||||
// A value of one allows optional replacement and two requires replacement.
|
||||
#if SD_CHIP_SELECT_MODE == 1 || SD_CHIP_SELECT_MODE == 2
|
||||
#if SD_CHIP_SELECT_MODE == 1 || SD_CHIP_SELECT_MODE == 2
|
||||
|
||||
// SD chip select pin.
|
||||
#define SD_CS_PIN SS
|
||||
|
|
@ -34,11 +34,11 @@ void setup() {
|
|||
sd.initErrorHalt(&Serial);
|
||||
}
|
||||
sd.ls(&Serial, LS_SIZE);
|
||||
|
||||
|
||||
Serial.print(F("sdCsInit calls: "));
|
||||
Serial.println(initCalls);
|
||||
Serial.print(F("sdCsWrite calls: "));
|
||||
Serial.println(writeCalls);
|
||||
Serial.println(writeCalls);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void loop() {}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
cout << F("\nUse a freshly formatted SD for best performance.\n");
|
||||
|
|
@ -149,7 +149,7 @@ void loop() {
|
|||
// F() stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
#if HAS_UNUSED_STACK
|
||||
cout << F("FreeStack: ") << FreeStack() << endl;
|
||||
|
|
|
|||
|
|
@ -66,10 +66,10 @@ ostream& operator << (ostream& os, DateTime& dt) {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
|
||||
// Wait for USB Serial.
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// F() stores strings in flash to save RAM
|
||||
cout << endl << F("FreeStack: ") << FreeStack() << endl;
|
||||
|
|
@ -77,7 +77,7 @@ void setup() {
|
|||
#if WAIT_TO_START
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Discard input.
|
||||
do {
|
||||
|
|
@ -193,5 +193,5 @@ void loop() {
|
|||
}
|
||||
logfile.close();
|
||||
cout << F("Done!");
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
}
|
||||
|
|
@ -17,14 +17,14 @@ const char* name[] = {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println("type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
||||
Serial.println("begin failed");
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ ArduinoOutStream cout(Serial);
|
|||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(2000);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ void error(const char* s) {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
yield();
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ void loop() {
|
|||
if (!SD.begin(chipSelect)) {
|
||||
error("begin");
|
||||
}
|
||||
|
||||
|
||||
Serial.println(F("Starting print test. Please wait.\n"));
|
||||
|
||||
// do write test
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ File file;
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
yield();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ SdFile file;
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
|
||||
if (!sd.begin()) {
|
||||
Serial.println("begin failed");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ void setup() {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial.
|
||||
while(!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println(F("Type any character to start"));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Initialize the SD.
|
||||
if (!SD.begin(csPin)) {
|
||||
|
|
|
|||
|
|
@ -26,15 +26,15 @@ void setup() {
|
|||
char name[] = "append.txt";
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// F() stores strings in flash to save RAM
|
||||
cout << endl << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -55,15 +55,15 @@ void calcAverage() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// F() stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ void error(const char* s) {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
yield();
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ void loop() {
|
|||
|
||||
// F() stores strings in flash to save RAM
|
||||
Serial.println(F("Type any character to start"));
|
||||
|
||||
|
||||
while (!Serial.available()) {
|
||||
yield();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ void setup() {
|
|||
int i, j, k; // values from parsed line
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(2000);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -36,14 +36,14 @@ void logEvent(const char *msg) {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// F() stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(400); // catch Due reset problem
|
||||
|
||||
|
|
|
|||
|
|
@ -86,14 +86,14 @@ void makeTestFile() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ ArduinoOutStream cout(Serial);
|
|||
void setup() {
|
||||
int c;
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
|
|
|
|||
|
|
@ -798,7 +798,7 @@ void loop(void) {
|
|||
Serial.println(F("r - record ADC data"));
|
||||
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = tolower(Serial.read());
|
||||
if (ERROR_LED_PIN >= 0) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void loop() {
|
|||
Serial.print(F("\r\nEnter File Number: "));
|
||||
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
c = Serial.read();
|
||||
uint8_t i = c - '0';
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ struct block_t {
|
|||
//
|
||||
void fatalBlink() {
|
||||
while (true) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
if (ERROR_LED_PIN >= 0) {
|
||||
digitalWrite(ERROR_LED_PIN, HIGH);
|
||||
delay(200);
|
||||
|
|
@ -321,7 +321,7 @@ void openBinFile() {
|
|||
Serial.write(name, BASE_NAME_SIZE);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = Serial.read();
|
||||
Serial.write(c);
|
||||
|
|
@ -566,7 +566,7 @@ void setup(void) {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.print(F("\nFreeStack: "));
|
||||
Serial.println(FreeStack());
|
||||
|
|
@ -592,7 +592,7 @@ void setup(void) {
|
|||
if (sd.exists(TMP_FILE_NAME)) {
|
||||
Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
if (Serial.read() == 'Y') {
|
||||
recoverTmpFile();
|
||||
|
|
@ -617,11 +617,11 @@ void loop(void) {
|
|||
Serial.println(F("r - record data"));
|
||||
Serial.println(F("t - test without logging"));
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
#if WDT_YIELD_TIME_MICROS
|
||||
Serial.println(F("LowLatencyLogger can not run with watchdog timer"));
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
#endif
|
||||
|
||||
char c = tolower(Serial.read());
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ struct block_t {
|
|||
//
|
||||
void fatalBlink() {
|
||||
while (true) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
if (ERROR_LED_PIN >= 0) {
|
||||
digitalWrite(ERROR_LED_PIN, HIGH);
|
||||
delay(200);
|
||||
|
|
@ -321,7 +321,7 @@ void openBinFile() {
|
|||
Serial.write(name, BASE_NAME_SIZE);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = Serial.read();
|
||||
Serial.write(c);
|
||||
|
|
@ -566,7 +566,7 @@ void setup(void) {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.print(F("\nFreeStack: "));
|
||||
Serial.println(FreeStack());
|
||||
|
|
@ -592,7 +592,7 @@ void setup(void) {
|
|||
if (sd.exists(TMP_FILE_NAME)) {
|
||||
Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
if (Serial.read() == 'Y') {
|
||||
recoverTmpFile();
|
||||
|
|
@ -617,11 +617,11 @@ void loop(void) {
|
|||
Serial.println(F("r - record data"));
|
||||
Serial.println(F("t - test without logging"));
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
#if WDT_YIELD_TIME_MICROS
|
||||
Serial.println(F("LowLatencyLogger can not run with watchdog timer"));
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
#endif
|
||||
|
||||
char c = tolower(Serial.read());
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ const uint8_t DATAZ1 = 0x37; //Z-Axis Data 1
|
|||
|
||||
void writeADXL345Register(const uint8_t registerAddress, const uint8_t value) {
|
||||
// Max SPI clock frequency is 5 MHz with CPOL = 1 and CPHA = 1.
|
||||
SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3));
|
||||
SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE3));
|
||||
digitalWrite(ADXL345_CS, LOW);
|
||||
SPI.transfer(registerAddress);
|
||||
SPI.transfer(value);
|
||||
digitalWrite(ADXL345_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void userSetup() {
|
||||
|
|
@ -32,7 +32,7 @@ void userSetup() {
|
|||
//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
|
||||
writeADXL345Register(POWER_CTL, 0x08); //Measurement mode
|
||||
}
|
||||
|
||||
// Acquire a data record.
|
||||
|
|
@ -45,7 +45,7 @@ void acquireData(data_t* data) {
|
|||
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);
|
||||
data->accel[2] = SPI.transfer(0) | (SPI.transfer(0) << 8);
|
||||
digitalWrite(ADXL345_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ struct block_t {
|
|||
//
|
||||
void fatalBlink() {
|
||||
while (true) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
if (ERROR_LED_PIN >= 0) {
|
||||
digitalWrite(ERROR_LED_PIN, HIGH);
|
||||
delay(200);
|
||||
|
|
@ -321,7 +321,7 @@ void openBinFile() {
|
|||
Serial.write(name, BASE_NAME_SIZE);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
char c = Serial.read();
|
||||
Serial.write(c);
|
||||
|
|
@ -566,7 +566,7 @@ void setup(void) {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.print(F("\nFreeStack: "));
|
||||
Serial.println(FreeStack());
|
||||
|
|
@ -592,7 +592,7 @@ void setup(void) {
|
|||
if (sd.exists(TMP_FILE_NAME)) {
|
||||
Serial.println(F("\nType 'Y' to recover existing tmp file " TMP_FILE_NAME));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
if (Serial.read() == 'Y') {
|
||||
recoverTmpFile();
|
||||
|
|
@ -617,11 +617,11 @@ void loop(void) {
|
|||
Serial.println(F("r - record data"));
|
||||
Serial.println(F("t - test without logging"));
|
||||
while(!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
#if WDT_YIELD_TIME_MICROS
|
||||
Serial.println(F("LowLatencyLogger can not run with watchdog timer"));
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
#endif
|
||||
|
||||
char c = tolower(Serial.read());
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ static uint32_t startMicros;
|
|||
// Acquire a data record.
|
||||
void acquireData(data_t* data) {
|
||||
data->time = micros();
|
||||
mpu.getMotion6(&data->ax, &data->ay, &data->az,
|
||||
mpu.getMotion6(&data->ax, &data->ay, &data->az,
|
||||
&data->gx, &data->gy, &data->gz);
|
||||
}
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ void userSetup() {
|
|||
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
|
||||
Fastwire::setup(400, true);
|
||||
#endif
|
||||
mpu.initialize();
|
||||
mpu.initialize();
|
||||
}
|
||||
|
||||
// Print a data record.
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ SdFile file;
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
|
||||
Serial.println("Type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ ArduinoOutStream cout(Serial);
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -44,7 +44,7 @@ void loop() {
|
|||
// F stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(400); // catch Due reset problem
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("\nSPI pins:\n");
|
||||
cout << F("MISO: ") << int(MISO) << endl;
|
||||
|
|
@ -80,7 +80,7 @@ void loop() {
|
|||
|
||||
cout << F("\nEnter the chip select pin number: ");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cin.readline();
|
||||
if (cin >> chipSelect) {
|
||||
|
|
@ -156,6 +156,6 @@ void loop() {
|
|||
} while (Serial.available() && Serial.read() >= 0);
|
||||
cout << F("\nSuccess! Type any character to restart.\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
|
@ -45,10 +45,10 @@ ArduinoOutStream cout(Serial);
|
|||
//------------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -60,7 +60,7 @@ void loop(void) {
|
|||
// F stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
cout << F("FreeStack: ") << FreeStack() << endl;
|
||||
|
|
@ -101,7 +101,7 @@ void loop(void) {
|
|||
cout << F("Start raw write of ") << file.fileSize()/1000UL << F(" KB\n");
|
||||
cout << F("Target rate: ") << RATE_KB_PER_SEC << F(" KB/sec\n");
|
||||
cout << F("Target time: ") << TEST_TIME_SEC << F(" seconds\n");
|
||||
|
||||
|
||||
// tell card to setup for multiple block write with pre-erase
|
||||
if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) {
|
||||
error("writeStart failed");
|
||||
|
|
@ -173,7 +173,7 @@ void loop(void) {
|
|||
cout << F(" seconds\n");
|
||||
cout << F("Min block write time: ") << minWriteTime << F(" micros\n");
|
||||
cout << F("Max block write time: ") << maxWriteTime << F(" micros\n");
|
||||
cout << F("Avg block write time: ") << avgWriteTime << F(" micros\n");
|
||||
cout << F("Avg block write time: ") << avgWriteTime << F(" micros\n");
|
||||
// close file for next pass of loop
|
||||
file.close();
|
||||
Serial.println();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ File file;
|
|||
* delim - csv delimiter.
|
||||
*
|
||||
* return - negative value for failure.
|
||||
* delimiter, '\n' or zero(EOF) for success.
|
||||
* delimiter, '\n' or zero(EOF) for success.
|
||||
*/
|
||||
int csvReadText(File* file, char* str, size_t size, char delim) {
|
||||
char ch;
|
||||
|
|
@ -129,8 +129,8 @@ int csvReadFloat(File* file, float* num, char delim) {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
yield();
|
||||
}
|
||||
|
|
@ -144,8 +144,8 @@ void setup() {
|
|||
return;
|
||||
}
|
||||
// Remove existing file.
|
||||
SD.remove("READTEST.TXT");
|
||||
|
||||
SD.remove("READTEST.TXT");
|
||||
|
||||
// Create the file.
|
||||
file = SD.open("READTEST.TXT", FILE_WRITE);
|
||||
if (!file) {
|
||||
|
|
@ -169,7 +169,7 @@ void setup() {
|
|||
file.seek(0);
|
||||
|
||||
// Read the file and print fields.
|
||||
int16_t tcalc;
|
||||
int16_t tcalc;
|
||||
float t1, t2, h1, h2;
|
||||
// Must be dim 9 to allow for zero byte.
|
||||
char timeS[9], dateS[9];
|
||||
|
|
@ -188,7 +188,7 @@ void setup() {
|
|||
while ((ch = file.read()) > 0 && nr++ < 100) {
|
||||
Serial.write(ch);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
Serial.print(tcalc);
|
||||
Serial.print(CSV_DELIM);
|
||||
|
|
|
|||
|
|
@ -47,23 +47,23 @@ size_t readField(File* file, char* str, size_t size, const char* delim) {
|
|||
return n;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
#define errorHalt(msg) {Serial.println(F(msg)); SysCall::halt();}
|
||||
#define errorHalt(msg) {Serial.println(F(msg)); while (true) {}}
|
||||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println("Type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
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) {
|
||||
|
|
@ -93,7 +93,7 @@ void setup() {
|
|||
char *ptr; // Test for valid field.
|
||||
|
||||
// Read the file and store the data.
|
||||
|
||||
|
||||
for (i = 0; i < ROW_DIM; i++) {
|
||||
for (j = 0; j < COL_DIM; j++) {
|
||||
n = readField(&file, str, sizeof(str), ",\n");
|
||||
|
|
@ -117,7 +117,7 @@ void setup() {
|
|||
// Allow missing endl at eof.
|
||||
if (str[n-1] != '\n' && file.available()) {
|
||||
errorHalt("missing endl");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print the array.
|
||||
|
|
|
|||
|
|
@ -92,14 +92,14 @@ void writeFile() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const uint16_t NWRITE = FILE_SIZE/BUF_DIM;
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ void setup() {
|
|||
Serial.println(F(" millis"));
|
||||
// close test.bin
|
||||
file1.close();
|
||||
file2.close();
|
||||
file2.close();
|
||||
// list current directory on both cards
|
||||
Serial.println(F("------sd1 -------"));
|
||||
sd1.ls("/", LS_R | LS_DATE | LS_SIZE);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* and SDFormatter uses FAT12.
|
||||
*/
|
||||
#error use new Version 2 SdFormatter
|
||||
// Set USE_SDIO to zero for SPI card access.
|
||||
// Set USE_SDIO to zero for SPI card access.
|
||||
#define USE_SDIO 0
|
||||
//
|
||||
// Change the value of chipSelect if your hardware does
|
||||
|
|
@ -45,7 +45,7 @@ SdioCardEX card;
|
|||
#else // USE_SDIO
|
||||
Sd2Card card;
|
||||
#endif // USE_SDIO
|
||||
|
||||
|
||||
uint32_t cardSizeBlocks;
|
||||
uint32_t cardCapacityMB;
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ void sdErrorHalt() {
|
|||
cout << F("SD error: ") << hex << int(card.errorCode());
|
||||
cout << ',' << int(card.errorData()) << dec << endl;
|
||||
}
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
#if DEBUG_PRINT
|
||||
|
|
@ -171,10 +171,10 @@ void clearFatDir(uint32_t bgn, uint32_t count) {
|
|||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (!card.writeBlock(bgn + i, cache.data)) {
|
||||
sdError("Clear FAT/DIR writeBlock failed");
|
||||
}
|
||||
}
|
||||
if ((i & 0XFF) == 0) {
|
||||
cout << '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
#else // USE_SDIO
|
||||
if (!card.writeStart(bgn, count)) {
|
||||
|
|
@ -461,13 +461,13 @@ void formatCard() {
|
|||
void setup() {
|
||||
char c;
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Discard any extra characters.
|
||||
do {
|
||||
|
|
@ -487,7 +487,7 @@ void setup() {
|
|||
"Warning, all data on the card will be erased.\n"
|
||||
"Enter 'Y' to continue: ");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
c = Serial.read();
|
||||
|
|
@ -511,7 +511,7 @@ void setup() {
|
|||
"Enter option: ");
|
||||
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
c = Serial.read();
|
||||
cout << c << endl;
|
||||
|
|
@ -521,7 +521,7 @@ void setup() {
|
|||
}
|
||||
#if USE_SDIO
|
||||
if (!card.begin()) {
|
||||
sdError("card.begin failed");
|
||||
sdError("card.begin failed");
|
||||
}
|
||||
#else // USE_SDIO
|
||||
if (!card.begin(chipSelect, SPI_SPEED)) {
|
||||
|
|
@ -531,7 +531,7 @@ void setup() {
|
|||
"Is chip select correct at the top of this program?\n");
|
||||
sdError("card.begin failed");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
cardSizeBlocks = card.cardSize();
|
||||
if (cardSizeBlocks == 0) {
|
||||
sdError("cardSize");
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include "SdFat.h"
|
||||
#include "sdios.h"
|
||||
#error Use new Version 2 SdInfo
|
||||
// Set USE_SDIO to zero for SPI card access.
|
||||
// Set USE_SDIO to zero for SPI card access.
|
||||
#define USE_SDIO 0
|
||||
/*
|
||||
* SD chip select pin. Common values are:
|
||||
|
|
@ -143,10 +143,10 @@ void volDmp() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// use uppercase in hex and use 0X base prefix
|
||||
|
|
@ -154,7 +154,7 @@ void setup() {
|
|||
|
||||
// F stores strings in flash to save RAM
|
||||
cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
|
||||
#if !USE_SDIO
|
||||
#if !USE_SDIO
|
||||
if (DISABLE_CHIP_SELECT < 0) {
|
||||
cout << F(
|
||||
"\nAssuming the SD is the only SPI device.\n"
|
||||
|
|
@ -167,7 +167,7 @@ void setup() {
|
|||
}
|
||||
cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
|
||||
cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
|
||||
#endif // !USE_SDIO
|
||||
#endif // !USE_SDIO
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void loop() {
|
||||
|
|
@ -179,7 +179,7 @@ void loop() {
|
|||
// F stores strings in flash to save RAM
|
||||
cout << F("\ntype any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
uint32_t t = millis();
|
||||
|
|
@ -195,7 +195,7 @@ void loop() {
|
|||
sdErrorMsg("cardBegin failed");
|
||||
return;
|
||||
}
|
||||
#endif // USE_SDIO
|
||||
#endif // USE_SDIO
|
||||
t = millis() - t;
|
||||
|
||||
cardSize = sd.card()->cardSize();
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ SdFile file;
|
|||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println("Type any character to start");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
if (!sd.begin(SD_CHIP_SELECT_PIN)) {
|
||||
|
|
@ -43,7 +43,7 @@ void setup() {
|
|||
file.println(F("This line was printed using software SPI."));
|
||||
|
||||
file.rewind();
|
||||
|
||||
|
||||
while (file.available()) {
|
||||
Serial.write(file.read());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,17 +32,17 @@ void setup() {
|
|||
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
Serial.println(F("Type any character to start"));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println(F("Starting test"));
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(50))) {
|
||||
sd.errorHalt();
|
||||
}
|
||||
|
|
@ -146,7 +146,7 @@ void setup() {
|
|||
stdioFile.printField(n, '\n');
|
||||
#else // PRINT_FIELD
|
||||
stdioFile.println(n);
|
||||
#endif // PRINT_FIELD
|
||||
#endif // PRINT_FIELD
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ void setup() {
|
|||
stdioFile.printField(f[i], '\n', 4);
|
||||
#else // PRINT_FIELD
|
||||
stdioFile.println(f[i], 4);
|
||||
#endif // PRINT_FIELD
|
||||
#endif // PRINT_FIELD
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Simple performance test for Teensy 3.5/3.6 SDHC.
|
||||
// Demonstrates yield() efficiency.
|
||||
|
||||
// Warning SdFatSdio and SdFatSdioEX normally should
|
||||
// Warning SdFatSdio and SdFatSdioEX normally should
|
||||
// not both be used in a program.
|
||||
// Each has its own cache and member variables.
|
||||
|
||||
|
|
@ -48,8 +48,8 @@ void errorHalt(const char* msg) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
uint32_t kHzSdClk() {
|
||||
return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();
|
||||
}
|
||||
return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// Replace "weak" system yield() function.
|
||||
void yield() {
|
||||
|
|
@ -74,7 +74,7 @@ void runTest() {
|
|||
totalMicros = 0;
|
||||
yieldMicros = 0;
|
||||
yieldCalls = 0;
|
||||
yieldMaxUsec = 0;
|
||||
yieldMaxUsec = 0;
|
||||
if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
|
||||
errorHalt("open failed");
|
||||
}
|
||||
|
|
@ -100,19 +100,19 @@ void runTest() {
|
|||
Serial.print(',');
|
||||
file.rewind();
|
||||
t = micros();
|
||||
|
||||
|
||||
for (uint32_t n = 0; n < nRdWr; n++) {
|
||||
if ((int)nb != file.read(buf, nb)) {
|
||||
errorHalt("read failed");
|
||||
}
|
||||
// crude check of data.
|
||||
// crude check of data.
|
||||
if (buf32[0] != n || buf32[nb/4 - 1] != n) {
|
||||
errorHalt("data check");
|
||||
}
|
||||
}
|
||||
t = micros() - t;
|
||||
totalMicros += t;
|
||||
Serial.println(1000.0*FILE_SIZE/t);
|
||||
totalMicros += t;
|
||||
Serial.println(1000.0*FILE_SIZE/t);
|
||||
}
|
||||
file.close();
|
||||
Serial.print("\ntotalMicros ");
|
||||
|
|
@ -122,7 +122,7 @@ void runTest() {
|
|||
Serial.print("yieldCalls ");
|
||||
Serial.println(yieldCalls);
|
||||
Serial.print("yieldMaxUsec ");
|
||||
Serial.println(yieldMaxUsec);
|
||||
Serial.println(yieldMaxUsec);
|
||||
Serial.print("kHzSdClk ");
|
||||
Serial.println(kHzSdClk());
|
||||
Serial.println("Done");
|
||||
|
|
@ -133,8 +133,8 @@ void setup() {
|
|||
while (!Serial) {
|
||||
}
|
||||
Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA.");
|
||||
Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");
|
||||
Serial.println("Note the difference is speed and busy yield time.\n");
|
||||
Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");
|
||||
Serial.println("Note the difference is speed and busy yield time.\n");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void loop() {
|
||||
|
|
@ -163,7 +163,7 @@ void loop() {
|
|||
sd.initErrorHalt("SdFatSdio begin() failed");
|
||||
}
|
||||
// make sd the current volume.
|
||||
sd.chvol();
|
||||
sd.chvol();
|
||||
}
|
||||
runTest();
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ void dateTime(uint16_t* date, uint16_t* time) {
|
|||
void printTimestamps(SdFile& f) {
|
||||
cout << F("Creation: ");
|
||||
f.printCreateDateTime(&Serial);
|
||||
cout << endl << F("Modify: ");
|
||||
cout << endl << F("Modify: ");
|
||||
f.printModifyDateTime(&Serial);
|
||||
cout << endl << F("Access: ");
|
||||
f.printAccessDateTime(&Serial);
|
||||
|
|
@ -64,11 +64,11 @@ void setup(void) {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ const uint32_t NWRITE = FILE_SIZE/BUF_DIM;
|
|||
//------------------------------------------------------------------------------
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.print(F("FreeStack: "));
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ void setup() {
|
|||
|
||||
Serial.println(F("type any character to start"));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// disable sd2 while initializing sd1
|
||||
|
|
@ -146,7 +146,7 @@ void setup() {
|
|||
Serial.println(F(" millis"));
|
||||
// close test.bin
|
||||
file1.close();
|
||||
file2.close();
|
||||
file2.close();
|
||||
// list current directory on both cards
|
||||
Serial.println(F("------sd1 -------"));
|
||||
sd1.ls("/", LS_R | LS_DATE | LS_SIZE);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ void setup() {
|
|||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
if (!MAINTAIN_FREE_CLUSTER_COUNT) {
|
||||
cout << F("Please edit SdFatConfig.h and set\n");
|
||||
|
|
@ -48,7 +48,7 @@ void setup() {
|
|||
// F stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
cout << F("\nUse a freshly formatted SD for best performance.\n");
|
||||
|
|
@ -108,7 +108,7 @@ void loop() {
|
|||
// F( stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("chipSelect: ") << int(chipSelect) << endl;
|
||||
cout << F("FreeStack: ") << FreeStack() << endl;
|
||||
|
|
|
|||
|
|
@ -67,18 +67,18 @@ void setup() {
|
|||
char fileName[13] = FILE_BASE_NAME "00.csv";
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(1000);
|
||||
|
||||
Serial.println(F("Type any character to start"));
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
||||
|
|
@ -145,6 +145,6 @@ void loop() {
|
|||
// Close file and stop.
|
||||
file.close();
|
||||
Serial.println(F("Done"));
|
||||
SysCall::halt();
|
||||
while (true) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,15 +61,15 @@ void makeTestFile() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(400); // catch Due reset problem
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ void showDate(int m, int d, int y) {
|
|||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
delay(2000);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,16 +55,16 @@ void testGetline() {
|
|||
//------------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
Serial.begin(9600);
|
||||
|
||||
// Wait for USB Serial
|
||||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// F stores strings in flash to save RAM
|
||||
cout << F("Type any character to start\n");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Insert an empty SD. Type any character to start.") << endl;
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/STM32Test/STM32Test.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/STM32Test/STM32Test.ino"
|
||||
8c8
|
||||
<
|
||||
---
|
||||
> #error See new Version 2 STM32 example
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/SdFormatter/SdFormatter.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/SdFormatter/SdFormatter.ino"
|
||||
14c14
|
||||
<
|
||||
---
|
||||
> #error use new Version 2 SdFormatter
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/SdInfo/SdInfo.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/SdInfo/SdInfo.ino"
|
||||
7c7
|
||||
<
|
||||
---
|
||||
> #error Use new Version 2 SdInfo
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/SoftwareSpi/SoftwareSpi.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/SoftwareSpi/SoftwareSpi.ino"
|
||||
7a8
|
||||
> #error See Version 2 software SPI example
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/StdioBench/StdioBench.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/StdioBench/StdioBench.ino"
|
||||
3a4
|
||||
> #include "sdios.h"
|
||||
27c28
|
||||
< uint32_t printSize;
|
||||
---
|
||||
> uint32_t printSize = 0;
|
||||
29c30
|
||||
< uint32_t printTime;
|
||||
---
|
||||
> uint32_t printTime = 0;
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/TeensySdioDemo/TeensySdioDemo.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/TeensySdioDemo/TeensySdioDemo.ino"
|
||||
9c9
|
||||
<
|
||||
---
|
||||
> #error See Version 2 SDIO example
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/Timestamp/Timestamp.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/Timestamp/Timestamp.ino"
|
||||
8d7
|
||||
<
|
||||
55,59d53
|
||||
< dir_t d;
|
||||
< if (!f.dirEntry(&d)) {
|
||||
< error("f.dirEntry failed");
|
||||
< }
|
||||
<
|
||||
61,73c55,59
|
||||
< f.printFatDate(d.creationDate);
|
||||
< cout << ' ';
|
||||
< f.printFatTime(d.creationTime);
|
||||
< cout << endl;
|
||||
<
|
||||
< cout << F("Modify: ");
|
||||
< f.printFatDate(d.lastWriteDate);
|
||||
< cout <<' ';
|
||||
< f.printFatTime(d.lastWriteTime);
|
||||
< cout << endl;
|
||||
<
|
||||
< cout << F("Access: ");
|
||||
< f.printFatDate(d.lastAccessDate);
|
||||
---
|
||||
> f.printCreateDateTime(&Serial);
|
||||
> cout << endl << F("Modify: ");
|
||||
> f.printModifyDateTime(&Serial);
|
||||
> cout << endl << F("Access: ");
|
||||
> f.printAccessDateTime(&Serial);
|
||||
diff -rb "C:\\Users\\bill\\Documents\\Arduino\\libraries\\SdFat\\examples/wipe/wipe.ino" "C:\\Users\\bill\\Documents\\ArduinoSdFat\\libraries\\SdFat\\examples\\examplesV1/wipe/wipe.ino"
|
||||
1a2
|
||||
> #error wipe is not supported in SdFat V2. Use bool format(print_t* pr = nullptr).
|
||||
|
|
@ -9,20 +9,20 @@ SdFat sd;
|
|||
void setup() {
|
||||
int c;
|
||||
Serial.begin(9600);
|
||||
// Wait for USB Serial
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
Serial.println("Type 'Y' to wipe all data.");
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
c = Serial.read();
|
||||
if (c != 'Y') {
|
||||
sd.errorHalt("Quitting, you did not type 'Y'.");
|
||||
}
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
||||
sd.initErrorHalt();
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ void setup() {
|
|||
}
|
||||
// Must reinitialize after wipe.
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
// not over 50 MHz. Try a lower speed if SPI errors occur.
|
||||
if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
|
||||
sd.errorHalt("Second init failed.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ void setup() {
|
|||
|
||||
// Wait for USB Serial
|
||||
while (!Serial) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
cout << F("Insert an empty SD. Type any character to start.") << endl;
|
||||
while (!Serial.available()) {
|
||||
SysCall::yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
// Initialize at the highest speed supported by the board that is
|
||||
|
|
|
|||
|
|
@ -32,12 +32,11 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
class __FlashStringHelper;
|
||||
|
||||
#ifdef F
|
||||
#warning F() macro defined for non Arduino System
|
||||
#elif defined(__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
class __FlashStringHelper;
|
||||
#define F(str) (reinterpret_cast<const __FlashStringHelper *>(PSTR(str)))
|
||||
#else // F
|
||||
#define F(str) (str)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name=SdFat
|
||||
version=2.1.0
|
||||
version=2.1.1
|
||||
license=MIT
|
||||
author=Bill Greiman <fat16lib@sbcglobal.net>
|
||||
maintainer=Bill Greiman <fat16lib@sbcglobal.net>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
#include "ExFatVolume.h"
|
||||
#include "../common/upcase.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "ExFatLib.h"
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//------------------------------------------------------------------------------
|
||||
static void printHex(print_t* pr, uint8_t h);
|
||||
|
|
@ -294,7 +294,7 @@ void ExFatPartition::checkUpcase(print_t* pr) {
|
|||
uint8_t* upcase = nullptr;
|
||||
uint32_t size = 0;
|
||||
uint32_t sector = clusterStartSector(m_rootDirectoryCluster);
|
||||
uint8_t* cache = dataCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* cache = dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
pr->println(F("read root failed"));
|
||||
return;
|
||||
|
|
@ -315,7 +315,7 @@ void ExFatPartition::checkUpcase(print_t* pr) {
|
|||
}
|
||||
for (size_t i = 0; i < size/2; i++) {
|
||||
if ((i%256) == 0) {
|
||||
upcase = dataCacheGet(sector++, FsCache::CACHE_FOR_READ);
|
||||
upcase = dataCachePrepare(sector++, FsCache::CACHE_FOR_READ);
|
||||
if (!upcase) {
|
||||
pr->println(F("read upcase failed"));
|
||||
return;
|
||||
|
|
@ -378,7 +378,7 @@ void ExFatPartition::dmpFat(print_t* pr, uint32_t start, uint32_t count) {
|
|||
uint32_t cluster = 128*start;
|
||||
pr->println(F("FAT:"));
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
uint8_t* cache = dataCacheGet(sector + i, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* cache = dataCachePrepare(sector + i, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
pr->println(F("cache read failed"));
|
||||
return;
|
||||
|
|
@ -400,12 +400,12 @@ void ExFatPartition::dmpFat(print_t* pr, uint32_t start, uint32_t count) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void ExFatPartition::dmpSector(print_t* pr, uint32_t sector) {
|
||||
uint8_t* cache = dataCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* cache = dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
pr->println(F("dmpSector failed"));
|
||||
return;
|
||||
}
|
||||
for (uint16_t i = 0; i < 512; i++) {
|
||||
for (uint16_t i = 0; i < m_bytesPerSector; i++) {
|
||||
if (i%32 == 0) {
|
||||
if (i) {
|
||||
pr->println();
|
||||
|
|
@ -434,8 +434,8 @@ bool ExFatPartition::printDir(print_t* pr, ExFatFile* file) {
|
|||
#define RAW_ROOT
|
||||
#ifndef RAW_ROOT
|
||||
while (1) {
|
||||
uint8_t buf[32];
|
||||
if (file->read(buf, 32) != 32) {
|
||||
uint8_t buf[FS_DIR_SIZE];
|
||||
if (file->read(buf, FS_DIR_SIZE) != FS_DIR_SIZE) {
|
||||
break;
|
||||
}
|
||||
dir = reinterpret_cast<DirGeneric_t*>(buf);
|
||||
|
|
@ -446,7 +446,7 @@ bool ExFatPartition::printDir(print_t* pr, ExFatFile* file) {
|
|||
for (uint32_t iDir = 0; iDir < nDir; iDir++) {
|
||||
size_t i = iDir%16;
|
||||
if (i == 0) {
|
||||
uint8_t* cache = dataCacheGet(sector++, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* cache = dataCachePrepare(sector++, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -556,7 +556,7 @@ void ExFatPartition::printUpcase(print_t* pr) {
|
|||
uint32_t checksum = 0;
|
||||
DirUpcase_t* dir;
|
||||
sector = clusterStartSector(m_rootDirectoryCluster);
|
||||
upcase = dataCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
upcase = dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
dir = reinterpret_cast<DirUpcase_t*>(upcase);
|
||||
if (!dir) {
|
||||
pr->println(F("read root dir failed"));
|
||||
|
|
@ -575,7 +575,7 @@ void ExFatPartition::printUpcase(print_t* pr) {
|
|||
}
|
||||
for (uint16_t i = 0; i < size/2; i++) {
|
||||
if ((i%256) == 0) {
|
||||
upcase = dataCacheGet(sector++, FsCache::CACHE_FOR_READ);
|
||||
upcase = dataCachePrepare(sector++, FsCache::CACHE_FOR_READ);
|
||||
if (!upcase) {
|
||||
pr->println(F("read upcase failed"));
|
||||
return;
|
||||
|
|
@ -597,7 +597,7 @@ void ExFatPartition::printUpcase(print_t* pr) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool ExFatPartition::printVolInfo(print_t* pr) {
|
||||
uint8_t* cache = dataCacheGet(0, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* cache = dataCachePrepare(0, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
pr->println(F("read mbr failed"));
|
||||
return false;
|
||||
|
|
@ -610,7 +610,7 @@ bool ExFatPartition::printVolInfo(print_t* pr) {
|
|||
pr->print(F("bad partition size"));
|
||||
return false;
|
||||
}
|
||||
cache = dataCacheGet(volStart, FsCache::CACHE_FOR_READ);
|
||||
cache = dataCachePrepare(volStart, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
pr->println(F("read pbs failed"));
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,8 +25,7 @@
|
|||
#define DBG_FILE "ExFatFile.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/FsUtf.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "ExFatVolume.h"
|
||||
#include "ExFatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
/** test for legal character.
|
||||
*
|
||||
|
|
@ -44,7 +43,7 @@ inline bool lfnLegalChar(uint8_t c) {
|
|||
//------------------------------------------------------------------------------
|
||||
uint8_t* ExFatFile::dirCache(uint8_t set, uint8_t options) {
|
||||
DirPos_t pos = m_dirPos;
|
||||
if (m_vol->dirSeek(&pos, 32*set) != 1) {
|
||||
if (m_vol->dirSeek(&pos, FS_DIR_SIZE*set) != 1) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_vol->dirCache(&pos, options);
|
||||
|
|
@ -214,7 +213,7 @@ bool ExFatFile::open(ExFatFile* dirFile, const char* path, oflag_t oflag) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool ExFatFile::open(ExFatFile* dirFile, uint32_t index, oflag_t oflag) {
|
||||
if (dirFile->seekSet(32*index) && openNext(dirFile, oflag)) {
|
||||
if (dirFile->seekSet(FS_DIR_SIZE*index) && openNext(dirFile, oflag)) {
|
||||
if (dirIndex() == index) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -245,7 +244,7 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
DirFile_t* dirFile;
|
||||
DirStream_t* dirStream;
|
||||
DirName_t* dirName;
|
||||
uint8_t buf[32];
|
||||
uint8_t buf[FS_DIR_SIZE];
|
||||
uint8_t freeCount = 0;
|
||||
uint8_t freeNeed = 3;
|
||||
bool inSet = false;
|
||||
|
|
@ -278,18 +277,18 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
}
|
||||
|
||||
while (1) {
|
||||
n = dir->read(buf, 32);
|
||||
n = dir->read(buf, FS_DIR_SIZE);
|
||||
if (n == 0) {
|
||||
goto create;
|
||||
}
|
||||
if (n != 32) {
|
||||
if (n != FS_DIR_SIZE) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
if (!(buf[0] & 0x80)) {
|
||||
// Unused entry.
|
||||
if (freeCount == 0) {
|
||||
freePos.position = dir->curPosition() - 32;
|
||||
freePos.position = dir->curPosition() - FS_DIR_SIZE;
|
||||
freePos.cluster = dir->curCluster();
|
||||
}
|
||||
if (freeCount < freeNeed) {
|
||||
|
|
@ -321,7 +320,7 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
}
|
||||
m_vol = dir->volume();
|
||||
m_dirPos.cluster = dir->curCluster();
|
||||
m_dirPos.position = dir->curPosition() - 32;
|
||||
m_dirPos.position = dir->curPosition() - FS_DIR_SIZE;
|
||||
m_dirPos.isContiguous = dir->isContiguous();
|
||||
} else if (buf[0] == EXFAT_TYPE_STREAM) {
|
||||
dirStream = reinterpret_cast<DirStream_t*>(buf);
|
||||
|
|
@ -396,7 +395,7 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
goto fail;
|
||||
}
|
||||
while (freeCount < freeNeed) {
|
||||
n = dir->read(buf, 32);
|
||||
n = dir->read(buf, FS_DIR_SIZE);
|
||||
if (n == 0) {
|
||||
curCluster = dir->m_curCluster;
|
||||
if (!dir->addDirCluster()) {
|
||||
|
|
@ -406,12 +405,12 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
dir->m_curCluster = curCluster;
|
||||
continue;
|
||||
}
|
||||
if (n != 32) {
|
||||
if (n != FS_DIR_SIZE) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
if (freeCount == 0) {
|
||||
freePos.position = dir->curPosition() - 32;
|
||||
freePos.position = dir->curPosition() - FS_DIR_SIZE;
|
||||
freePos.cluster = dir->curCluster();
|
||||
}
|
||||
freeCount++;
|
||||
|
|
@ -428,7 +427,7 @@ bool ExFatFile::openPrivate(ExFatFile* dir, ExName_t* fname, oflag_t oflag) {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memset(cache, 0 , 32);
|
||||
memset(cache, 0 , FS_DIR_SIZE);
|
||||
if (i == 0) {
|
||||
dirFile = reinterpret_cast<DirFile_t*>(cache);
|
||||
dirFile->type = EXFAT_TYPE_FILE;
|
||||
|
|
@ -586,7 +585,7 @@ int ExFatFile::read(void* buf, size_t count) {
|
|||
n = toRead;
|
||||
}
|
||||
// read sector to cache and copy data to caller
|
||||
cache = m_vol->dataCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
cache = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -30,12 +30,10 @@
|
|||
*/
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include "ExFatConfig.h"
|
||||
#include "../common/FsDateTime.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "../common/FsApiConstants.h"
|
||||
#include "../common/FmtNumber.h"
|
||||
#include "ExFatTypes.h"
|
||||
#include "../common/FsName.h"
|
||||
#include "ExFatPartition.h"
|
||||
|
||||
class ExFatVolume;
|
||||
|
|
@ -43,6 +41,18 @@ class ExFatVolume;
|
|||
/** Expression for path name separator. */
|
||||
#define isDirSeparator(c) ((c) == '/')
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \class ExName_t
|
||||
* \brief Internal type for file name - do not use in user apps.
|
||||
*/
|
||||
class ExName_t : public FsName {
|
||||
public:
|
||||
/** Length of UTF-16 name */
|
||||
size_t nameLength;
|
||||
/** Hash for UTF-16 name */
|
||||
uint16_t nameHash;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \class ExFatFile
|
||||
* \brief Basic file class.
|
||||
|
|
@ -125,7 +135,7 @@ class ExFatFile {
|
|||
/** \return Total data length for file. */
|
||||
uint64_t dataLength() const {return m_dataLength;}
|
||||
/** \return Directory entry index. */
|
||||
uint32_t dirIndex() const {return m_dirPos.position/32;}
|
||||
uint32_t dirIndex() const {return m_dirPos.position/FS_DIR_SIZE;}
|
||||
/** Test for the existence of a file in a directory
|
||||
*
|
||||
* \param[in] path Path of the file to be tested for.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,8 +24,8 @@
|
|||
*/
|
||||
#define DBG_FILE "ExFatFilePrint.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "ExFatVolume.h"
|
||||
#include "ExFatLib.h"
|
||||
#include "../common/FsUtf.h"
|
||||
//------------------------------------------------------------------------------
|
||||
bool ExFatFile::ls(print_t* pr) {
|
||||
ExFatFile file;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
*/
|
||||
#define DBG_FILE "ExFatFileWrite.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "ExFatVolume.h"
|
||||
#include "ExFatLib.h"
|
||||
//==============================================================================
|
||||
#if READ_ONLY
|
||||
bool ExFatFile::mkdir(ExFatFile* parent, const char* path, bool pFlag) {
|
||||
|
|
@ -131,18 +130,15 @@ bool ExFatFile::addDirCluster() {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
cache = m_vol->cacheClear();
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memset(cache, 0, m_vol->bytesPerSector());
|
||||
sector = m_vol->clusterStartSector(m_curCluster);
|
||||
for (uint32_t i = 0; i < m_vol->sectorsPerCluster(); i++) {
|
||||
if (!m_vol->writeSector(sector + i, cache)) {
|
||||
for (uint32_t i = 0; i < m_vol->sectorsPerCluster(); i++) {
|
||||
cache = m_vol->dataCachePrepare(sector + i,
|
||||
FsCache::CACHE_RESERVE_FOR_WRITE);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memset(cache, 0, m_vol->bytesPerSector());
|
||||
}
|
||||
if (!isRoot()) {
|
||||
m_flags |= FILE_FLAG_DIR_DIRTY;
|
||||
|
|
@ -340,7 +336,7 @@ bool ExFatFile::rename(ExFatFile* dirFile, const char* newPath) {
|
|||
//------------------------------------------------------------------------------
|
||||
bool ExFatFile::rmdir() {
|
||||
int n;
|
||||
uint8_t dir[32];
|
||||
uint8_t dir[FS_DIR_SIZE];
|
||||
// must be open subdirectory
|
||||
if (!isSubDir()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -350,11 +346,11 @@ bool ExFatFile::rmdir() {
|
|||
|
||||
// make sure directory is empty
|
||||
while (1) {
|
||||
n = read(dir, 32);
|
||||
n = read(dir, FS_DIR_SIZE);
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
if (n != 32 || dir[0] & 0X80) {
|
||||
if (n != FS_DIR_SIZE || dir[0] & 0X80) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -493,7 +489,7 @@ bool ExFatFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
|||
time = FS_TIME(hour, minute, second);
|
||||
ms10 = second & 1 ? 100 : 0;
|
||||
|
||||
for (uint8_t is = 0;; is++) {
|
||||
for (uint8_t is = 0; is <= m_setCount; is++) {
|
||||
cache = dirCache(is, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -697,7 +693,7 @@ size_t ExFatFile::write(const void* buf, size_t nbyte) {
|
|||
// rewrite part of sector
|
||||
cacheOption = FsCache::CACHE_FOR_WRITE;
|
||||
}
|
||||
cache = m_vol->dataCacheGet(sector, cacheOption);
|
||||
cache = m_vol->dataCachePrepare(sector, cacheOption);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,8 +25,7 @@
|
|||
#define DBG_FILE "ExFatFormatter.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/upcase.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "ExFatFormatter.h"
|
||||
#include "ExFatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// Formatter assumes 512 byte sectors.
|
||||
const uint32_t BOOT_BACKUP_OFFSET = 12;
|
||||
|
|
@ -266,7 +265,7 @@ bool ExFatFormatter::format(BlockDevice* dev, uint8_t* secBuf, print_t* pr) {
|
|||
setLe64(dbm->size, bitmapSize);
|
||||
|
||||
// upcase directory entry.
|
||||
dup = reinterpret_cast<DirUpcase_t*>(secBuf +64);
|
||||
dup = reinterpret_cast<DirUpcase_t*>(secBuf + 64);
|
||||
dup->type = EXFAT_TYPE_UPCASE;
|
||||
setLe32(dup->checksum, m_upcaseChecksum);
|
||||
setLe32(dup->firstCluster, UPCASE_CLUSTER);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,8 +24,6 @@
|
|||
*/
|
||||
#ifndef ExFatFormatter_h
|
||||
#define ExFatFormatter_h
|
||||
#include "ExFatConfig.h"
|
||||
#include "../common/SysCall.h"
|
||||
#include "../common/BlockDevice.h"
|
||||
/**
|
||||
* \class ExFatFormatter
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,6 +25,5 @@
|
|||
#ifndef ExFatLib_h
|
||||
#define ExFatLib_h
|
||||
#include "ExFatVolume.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "ExFatFormatter.h"
|
||||
#endif // ExFatLib_h
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,7 +25,8 @@
|
|||
#define DBG_FILE "ExFatName.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/upcase.h"
|
||||
#include "ExFatFile.h"
|
||||
#include "../common/FsUtf.h"
|
||||
#include "ExFatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
static char toUpper(char c) {
|
||||
return 'a' <= c && c <= 'z' ? c - 'a' + 'A' : c;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
*/
|
||||
#define DBG_FILE "ExFatPartition.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "ExFatVolume.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "ExFatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// return 0 if error, 1 if no space, else start cluster.
|
||||
uint32_t ExFatPartition::bitmapFind(uint32_t cluster, uint32_t count) {
|
||||
|
|
@ -42,7 +41,7 @@ uint32_t ExFatPartition::bitmapFind(uint32_t cluster, uint32_t count) {
|
|||
while (true) {
|
||||
uint32_t sector = m_clusterHeapStartSector +
|
||||
(endAlloc >> (m_bytesPerSectorShift + 3));
|
||||
cache = bitmapCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
cache = bitmapCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -102,7 +101,7 @@ bool ExFatPartition::bitmapModify(uint32_t cluster,
|
|||
(start >> (m_bytesPerSectorShift + 3));
|
||||
i = (start >> 3) & m_sectorMask;
|
||||
while (true) {
|
||||
cache = bitmapCacheGet(sector++, FsCache::CACHE_FOR_WRITE);
|
||||
cache = bitmapCachePrepare(sector++, FsCache::CACHE_FOR_WRITE);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -141,7 +140,7 @@ uint32_t ExFatPartition::chainSize(uint32_t cluster) {
|
|||
uint8_t* ExFatPartition::dirCache(DirPos_t* pos, uint8_t options) {
|
||||
uint32_t sector = clusterStartSector(pos->cluster);
|
||||
sector += (m_clusterMask & pos->position) >> m_bytesPerSectorShift;
|
||||
uint8_t* cache = dataCacheGet(sector, options);
|
||||
uint8_t* cache = dataCachePrepare(sector, options);
|
||||
return cache ? cache + (pos->position & m_sectorMask) : nullptr;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -176,13 +175,16 @@ int8_t ExFatPartition::fatGet(uint32_t cluster, uint32_t* value) {
|
|||
}
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
|
||||
|
||||
cache = dataCacheGet(sector, FsCache::CACHE_FOR_READ);
|
||||
cache = dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
return -1;
|
||||
}
|
||||
next = getLe32(cache + ((cluster << 2) & m_sectorMask));
|
||||
if (next == EXFAT_EOC) {
|
||||
return 0;
|
||||
}
|
||||
*value = next;
|
||||
return next == EXFAT_EOC ? 0 : 1;
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool ExFatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
||||
|
|
@ -193,7 +195,7 @@ bool ExFatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
|||
goto fail;
|
||||
}
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
|
||||
cache = dataCacheGet(sector, FsCache::CACHE_FOR_WRITE);
|
||||
cache = dataCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -242,7 +244,7 @@ uint32_t ExFatPartition::freeClusterCount() {
|
|||
uint8_t* cache;
|
||||
|
||||
while (true) {
|
||||
cache = dataCacheGet(sector++, FsCache::CACHE_FOR_READ);
|
||||
cache = dataCachePrepare(sector++, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -275,7 +277,7 @@ bool ExFatPartition::init(BlockDevice* dev, uint8_t part) {
|
|||
m_fatType = 0;
|
||||
m_blockDev = dev;
|
||||
cacheInit(m_blockDev);
|
||||
cache = dataCacheGet(0, FsCache::CACHE_FOR_READ);
|
||||
cache = dataCachePrepare(0, FsCache::CACHE_FOR_READ);
|
||||
if (part > 4 || !cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -288,7 +290,7 @@ bool ExFatPartition::init(BlockDevice* dev, uint8_t part) {
|
|||
goto fail;
|
||||
}
|
||||
volStart = getLe32(mp->relativeSectors);
|
||||
cache = dataCacheGet(volStart, FsCache::CACHE_FOR_READ);
|
||||
cache = dataCachePrepare(volStart, FsCache::CACHE_FOR_READ);
|
||||
if (!cache) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -31,13 +31,25 @@
|
|||
#include "../common/SysCall.h"
|
||||
#include "../common/BlockDevice.h"
|
||||
#include "../common/FsCache.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "ExFatConfig.h"
|
||||
#include "ExFatTypes.h"
|
||||
/** Type for exFAT partition */
|
||||
const uint8_t FAT_TYPE_EXFAT = 64;
|
||||
|
||||
class ExFatFile;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \struct DirPos_t
|
||||
* \brief Internal type for position in directory file.
|
||||
*/
|
||||
struct DirPos_t {
|
||||
/** current cluster */
|
||||
uint32_t cluster;
|
||||
/** offset */
|
||||
uint32_t position;
|
||||
/** directory is contiguous */
|
||||
bool isContiguous;
|
||||
};
|
||||
//==============================================================================
|
||||
/**
|
||||
* \class ExFatPartition
|
||||
|
|
@ -123,11 +135,11 @@ class ExFatPartition {
|
|||
bool bitmapModify(uint32_t cluster, uint32_t count, bool value);
|
||||
//----------------------------------------------------------------------------
|
||||
// Cache functions.
|
||||
uint8_t* bitmapCacheGet(uint32_t sector, uint8_t option) {
|
||||
uint8_t* bitmapCachePrepare(uint32_t sector, uint8_t option) {
|
||||
#if USE_EXFAT_BITMAP_CACHE
|
||||
return m_bitmapCache.get(sector, option);
|
||||
return m_bitmapCache.prepare(sector, option);
|
||||
#else // USE_EXFAT_BITMAP_CACHE
|
||||
return m_dataCache.get(sector, option);
|
||||
return m_dataCache.prepare(sector, option);
|
||||
#endif // USE_EXFAT_BITMAP_CACHE
|
||||
}
|
||||
void cacheInit(BlockDevice* dev) {
|
||||
|
|
@ -145,8 +157,8 @@ class ExFatPartition {
|
|||
}
|
||||
void dataCacheDirty() {m_dataCache.dirty();}
|
||||
void dataCacheInvalidate() {m_dataCache.invalidate();}
|
||||
uint8_t* dataCacheGet(uint32_t sector, uint8_t option) {
|
||||
return m_dataCache.get(sector, option);
|
||||
uint8_t* dataCachePrepare(uint32_t sector, uint8_t option) {
|
||||
return m_dataCache.prepare(sector, option);
|
||||
}
|
||||
uint32_t dataCacheSector() {return m_dataCache.sector();}
|
||||
bool dataCacheSync() {return m_dataCache.sync();}
|
||||
|
|
@ -186,8 +198,8 @@ class ExFatPartition {
|
|||
}
|
||||
//----------------------------------------------------------------------------
|
||||
static const uint8_t m_bytesPerSectorShift = 9;
|
||||
static const uint16_t m_bytesPerSector = 512;
|
||||
static const uint16_t m_sectorMask = 0x1FF;
|
||||
static const uint16_t m_bytesPerSector = 1 << m_bytesPerSectorShift;
|
||||
static const uint16_t m_sectorMask = m_bytesPerSector - 1;
|
||||
//----------------------------------------------------------------------------
|
||||
#if USE_EXFAT_BITMAP_CACHE
|
||||
FsCache m_bitmapCache;
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef ExFatTypes_h
|
||||
#define ExFatTypes_h
|
||||
#include "ExFatConfig.h"
|
||||
#include "../common/FsUtf.h"
|
||||
#include "../common/FsName.h"
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \struct DirPos_t
|
||||
* \brief Internal type for position in directory file.
|
||||
*/
|
||||
struct DirPos_t {
|
||||
/** current cluster */
|
||||
uint32_t cluster;
|
||||
/** offset */
|
||||
uint32_t position;
|
||||
/** directory is contiguous */
|
||||
bool isContiguous;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \class ExName_t
|
||||
* \brief Internal type for file name - do not use in user apps.
|
||||
*/
|
||||
class ExName_t : public FsName {
|
||||
public:
|
||||
/** Length of UTF-16 name */
|
||||
size_t nameLength;
|
||||
/** Hash for UTF-16 name */
|
||||
uint16_t nameHash;
|
||||
};
|
||||
#endif // ExFatTypes_h
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
#define DBG_FILE "ExFatVolume.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "ExFatVolume.h"
|
||||
#include "ExFatLib.h"
|
||||
ExFatVolume* ExFatVolume::m_cwv = nullptr;
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ExFatVolume::chdir(const char* path) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
#ifndef ExFatVolume_h
|
||||
#define ExFatVolume_h
|
||||
#include "ExFatPartition.h"
|
||||
#include "ExFatFile.h"
|
||||
//==============================================================================
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -22,8 +22,7 @@
|
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "FatVolume.h"
|
||||
#include "FatFile.h"
|
||||
#include "FatLib.h"
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
//------------------------------------------------------------------------------
|
||||
static uint16_t getLfnChar(DirLfn_t* ldir, uint8_t i) {
|
||||
|
|
@ -44,6 +43,18 @@ static void printHex(print_t* pr, uint8_t h) {
|
|||
pr->print(h, HEX);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
static void printHex(print_t* pr, uint8_t w, uint16_t h) {
|
||||
char buf[5];
|
||||
char* ptr = buf + sizeof(buf);
|
||||
*--ptr = 0;
|
||||
for (uint8_t i = 0; i < w; i++) {
|
||||
char c = h & 0XF;
|
||||
*--ptr = c < 10 ? c + '0' : c + 'A' - 10;
|
||||
h >>= 4;
|
||||
}
|
||||
pr->write(ptr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
static void printHex(print_t* pr, uint16_t val) {
|
||||
bool space = true;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
|
|
@ -80,7 +91,7 @@ static void printHexLn(print_t* pr, Uint val) {
|
|||
pr->println();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool printFatDir(print_t* pr, DirFat_t* dir) {
|
||||
static bool printFatDir(print_t* pr, DirFat_t* dir) {
|
||||
DirLfn_t* ldir = reinterpret_cast<DirLfn_t*>(dir);
|
||||
if (!dir->name[0]) {
|
||||
pr->println(F("Unused"));
|
||||
|
|
@ -132,9 +143,47 @@ bool printFatDir(print_t* pr, DirFat_t* dir) {
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void FatFile::dmpFile(print_t* pr, uint32_t pos, size_t n) {
|
||||
char text[17];
|
||||
text[16] = 0;
|
||||
if (n >= 0XFFF0) {
|
||||
n = 0XFFF0;
|
||||
}
|
||||
if (!seekSet(pos)) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i <= n; i++) {
|
||||
if ((i & 15) == 0) {
|
||||
if (i) {
|
||||
pr->write(' ');
|
||||
pr->write(text);
|
||||
if (i == n) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pr->write('\r');
|
||||
pr->write('\n');
|
||||
if (i >= n) {
|
||||
break;
|
||||
}
|
||||
printHex(pr, 4, i);
|
||||
pr->write(' ');
|
||||
}
|
||||
int16_t h = read();
|
||||
if (h < 0) {
|
||||
break;
|
||||
}
|
||||
pr->write(' ');
|
||||
printHex(pr, 2, h);
|
||||
text[i&15] = ' ' <= h && h < 0X7F ? h : '.';
|
||||
}
|
||||
pr->write('\r');
|
||||
pr->write('\n');
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatPartition::dmpDirSector(print_t* pr, uint32_t sector) {
|
||||
DirFat_t dir[16];
|
||||
if (!readSector(sector, reinterpret_cast<uint8_t*>(dir))) {
|
||||
if (!cacheSafeRead(sector, reinterpret_cast<uint8_t*>(dir))) {
|
||||
pr->println(F("dmpDir failed"));
|
||||
return false;
|
||||
}
|
||||
|
|
@ -160,12 +209,12 @@ bool FatPartition::dmpRootDir(print_t* pr, uint32_t n) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void FatPartition::dmpSector(print_t* pr, uint32_t sector, uint8_t bits) {
|
||||
uint8_t data[512];
|
||||
if (!readSector(sector, data)) {
|
||||
uint8_t data[FatPartition::m_bytesPerSector];
|
||||
if (!cacheSafeRead(sector, data)) {
|
||||
pr->println(F("dmpSector failed"));
|
||||
return;
|
||||
}
|
||||
for (uint16_t i = 0; i < 512;) {
|
||||
for (uint16_t i = 0; i < m_bytesPerSector;) {
|
||||
if (i%32 == 0) {
|
||||
if (i) {
|
||||
pr->println();
|
||||
|
|
@ -196,7 +245,7 @@ void FatPartition::dmpFat(print_t* pr, uint32_t start, uint32_t count) {
|
|||
uint32_t sector = m_fatStartSector + start;
|
||||
uint32_t cluster = nf*start;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
cache_t* pc = cacheFetchFat(sector + i, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* pc = fatCachePrepare(sector + i, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
pr->println(F("cache read failed"));
|
||||
return;
|
||||
|
|
@ -210,7 +259,7 @@ void FatPartition::dmpFat(print_t* pr, uint32_t start, uint32_t count) {
|
|||
}
|
||||
cluster++;
|
||||
pr->write(' ');
|
||||
uint32_t v = fatType() == 32 ? pc->fat32[k] : pc->fat16[k];
|
||||
uint32_t v = fatType() == 32 ? getLe32(pc + 4*k) : getLe16(pc + 2*k);
|
||||
printHex(pr, v);
|
||||
}
|
||||
pr->println();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
*/
|
||||
#define DBG_FILE "FatFile.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "FatFile.h"
|
||||
#include "FatVolume.h"
|
||||
#include "FatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// Add a cluster to a file.
|
||||
bool FatFile::addCluster() {
|
||||
|
|
@ -55,7 +54,7 @@ bool FatFile::addCluster() {
|
|||
// Return with first sector of cluster in the cache.
|
||||
bool FatFile::addDirCluster() {
|
||||
uint32_t sector;
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
|
||||
if (isRootFixed()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -71,18 +70,13 @@ bool FatFile::addDirCluster() {
|
|||
goto fail;
|
||||
}
|
||||
sector = m_vol->clusterStartSector(m_curCluster);
|
||||
pc = m_vol->cacheFetchData(sector, FsCache::CACHE_RESERVE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memset(pc, 0, m_vol->bytesPerSector());
|
||||
// zero rest of clusters
|
||||
for (uint8_t i = 1; i < m_vol->sectorsPerCluster(); i++) {
|
||||
if (!m_vol->writeSector(sector + i, pc->data)) {
|
||||
for (uint8_t i = 0; i < m_vol->sectorsPerCluster(); i++) {
|
||||
pc = m_vol->dataCachePrepare(sector + i, FsCache::CACHE_RESERVE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memset(pc, 0, m_vol->bytesPerSector());
|
||||
}
|
||||
// Set position to EOF to avoid inconsistent curCluster/curPosition.
|
||||
m_curPosition += m_vol->bytesPerCluster();
|
||||
|
|
@ -95,13 +89,13 @@ bool FatFile::addDirCluster() {
|
|||
// cache a file's directory entry
|
||||
// return pointer to cached entry or null for failure
|
||||
DirFat_t* FatFile::cacheDirEntry(uint8_t action) {
|
||||
cache_t* pc;
|
||||
pc = m_vol->cacheFetchData(m_dirSector, action);
|
||||
if (!pc) {
|
||||
uint8_t* pc = m_vol->dataCachePrepare(m_dirSector, action);
|
||||
DirFat_t* dir = reinterpret_cast<DirFat_t*>(pc);
|
||||
if (!dir) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
return pc->dir + (m_dirIndex & 0XF);
|
||||
return dir + (m_dirIndex & 0XF);
|
||||
|
||||
fail:
|
||||
return nullptr;
|
||||
|
|
@ -206,7 +200,7 @@ uint32_t FatFile::dirSize() {
|
|||
return 0;
|
||||
}
|
||||
if (isRootFixed()) {
|
||||
return 32*m_vol->rootDirEntryCount();
|
||||
return FS_DIR_SIZE*m_vol->rootDirEntryCount();
|
||||
}
|
||||
uint16_t n = 0;
|
||||
uint32_t c = isRoot32() ? m_vol->rootDirStart() : m_firstCluster;
|
||||
|
|
@ -353,7 +347,7 @@ bool FatFile::mkdir(FatFile* parent, FatName_t* fname) {
|
|||
uint32_t sector;
|
||||
DirFat_t dot;
|
||||
DirFat_t* dir;
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
|
||||
if (!parent->isDir()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -399,19 +393,20 @@ bool FatFile::mkdir(FatFile* parent, FatName_t* fname) {
|
|||
|
||||
// cache sector for '.' and '..'
|
||||
sector = m_vol->clusterStartSector(m_firstCluster);
|
||||
pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
dir = reinterpret_cast<DirFat_t*>(pc);
|
||||
if (!dir) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
// copy '.' to sector
|
||||
memcpy(&pc->dir[0], &dot, sizeof(dot));
|
||||
memcpy(&dir[0], &dot, sizeof(dot));
|
||||
// make entry for '..'
|
||||
dot.name[1] = '.';
|
||||
setLe16(dot.firstClusterLow, parent->m_firstCluster & 0XFFFF);
|
||||
setLe16(dot.firstClusterHigh, parent->m_firstCluster >> 16);
|
||||
// copy '..' to sector
|
||||
memcpy(&pc->dir[1], &dot, sizeof(dot));
|
||||
memcpy(&dir[1], &dot, sizeof(dot));
|
||||
// write first sector
|
||||
return m_vol->cacheSync();
|
||||
|
||||
|
|
@ -619,7 +614,7 @@ bool FatFile::openNext(FatFile* dirFile, oflag_t oflag) {
|
|||
}
|
||||
while (1) {
|
||||
// read entry into cache
|
||||
index = dirFile->curPosition()/32;
|
||||
index = dirFile->curPosition()/FS_DIR_SIZE;
|
||||
DirFat_t* dir = dirFile->readDirCache();
|
||||
if (!dir) {
|
||||
if (dirFile->getError()) {
|
||||
|
|
@ -735,8 +730,7 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|||
uint16_t offset;
|
||||
size_t toRead;
|
||||
uint32_t sector; // raw device sector number
|
||||
cache_t* pc;
|
||||
|
||||
uint8_t* pc;
|
||||
// error if not open for read
|
||||
if (!isReadable()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -749,7 +743,8 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|||
nbyte = tmp32;
|
||||
}
|
||||
} else if (isRootFixed()) {
|
||||
uint16_t tmp16 = 32*m_vol->m_rootDirEntryCount - (uint16_t)m_curPosition;
|
||||
uint16_t tmp16 =
|
||||
FS_DIR_SIZE*m_vol->m_rootDirEntryCount - (uint16_t)m_curPosition;
|
||||
if (nbyte > tmp16) {
|
||||
nbyte = tmp16;
|
||||
}
|
||||
|
|
@ -798,12 +793,12 @@ int FatFile::read(void* buf, size_t nbyte) {
|
|||
n = toRead;
|
||||
}
|
||||
// read sector to cache and copy data to caller
|
||||
pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_READ);
|
||||
pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
uint8_t* src = pc->data + offset;
|
||||
uint8_t* src = pc + offset;
|
||||
memcpy(dst, src, n);
|
||||
#if USE_MULTI_SECTOR_IO
|
||||
} else if (toRead >= 2*m_vol->bytesPerSector()) {
|
||||
|
|
@ -880,9 +875,9 @@ DirFat_t* FatFile::readDirCache(bool skipReadOk) {
|
|||
}
|
||||
goto fail;
|
||||
}
|
||||
m_curPosition += 31;
|
||||
m_curPosition += FS_DIR_SIZE - 1;
|
||||
} else {
|
||||
m_curPosition += 32;
|
||||
m_curPosition += FS_DIR_SIZE;
|
||||
}
|
||||
// return pointer to entry
|
||||
return reinterpret_cast<DirFat_t*>(m_vol->cacheAddress()) + i;
|
||||
|
|
@ -912,7 +907,7 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|||
uint32_t dirCluster = 0;
|
||||
FatFile file;
|
||||
FatFile oldFile;
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
DirFat_t* dir;
|
||||
|
||||
// Must be an open file or subdirectory.
|
||||
|
|
@ -980,12 +975,13 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|||
if (dirCluster) {
|
||||
// get new dot dot
|
||||
uint32_t sector = m_vol->clusterStartSector(dirCluster);
|
||||
pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
dir = reinterpret_cast<DirFat_t*>(pc);
|
||||
if (!dir) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memcpy(&entry, &pc->dir[1], sizeof(entry));
|
||||
memcpy(&entry, &dir[1], sizeof(entry));
|
||||
|
||||
// free unused cluster
|
||||
if (!m_vol->freeChain(dirCluster)) {
|
||||
|
|
@ -994,12 +990,13 @@ bool FatFile::rename(FatFile* dirFile, const char* newPath) {
|
|||
}
|
||||
// store new dot dot
|
||||
sector = m_vol->clusterStartSector(m_firstCluster);
|
||||
pc = m_vol->cacheFetchData(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
uint8_t* pc = m_vol->dataCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
dir = reinterpret_cast<DirFat_t*>(pc);
|
||||
if (!dir) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
memcpy(&pc->dir[1], &entry, sizeof(entry));
|
||||
memcpy(&dir[1], &entry, sizeof(entry));
|
||||
}
|
||||
// Remove old directory entry;
|
||||
oldFile.m_firstCluster = 0;
|
||||
|
|
@ -1067,7 +1064,7 @@ bool FatFile::rmRfStar() {
|
|||
rewind();
|
||||
while (1) {
|
||||
// remember position
|
||||
index = m_curPosition/32;
|
||||
index = m_curPosition/FS_DIR_SIZE;
|
||||
|
||||
DirFat_t* dir = readDirCache();
|
||||
if (!dir) {
|
||||
|
|
@ -1156,7 +1153,7 @@ bool FatFile::seekSet(uint32_t pos) {
|
|||
goto fail;
|
||||
}
|
||||
} else if (isRootFixed()) {
|
||||
if (pos <= 32*m_vol->rootDirEntryCount()) {
|
||||
if (pos <= FS_DIR_SIZE*m_vol->rootDirEntryCount()) {
|
||||
goto done;
|
||||
}
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -1335,7 +1332,7 @@ bool FatFile::truncate() {
|
|||
size_t FatFile::write(const void* buf, size_t nbyte) {
|
||||
// convert void* to uint8_t* - must be before goto statements
|
||||
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
uint8_t cacheOption;
|
||||
// number of bytes left to write - must be before goto statements
|
||||
size_t nToWrite = nbyte;
|
||||
|
|
@ -1423,12 +1420,12 @@ size_t FatFile::write(const void* buf, size_t nbyte) {
|
|||
// rewrite part of sector
|
||||
cacheOption = FsCache::CACHE_FOR_WRITE;
|
||||
}
|
||||
pc = m_vol->cacheFetchData(sector, cacheOption);
|
||||
pc = m_vol->dataCachePrepare(sector, cacheOption);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
uint8_t* dst = pc->data + sectorOffset;
|
||||
uint8_t* dst = pc + sectorOffset;
|
||||
memcpy(dst, src, n);
|
||||
if (m_vol->bytesPerSector() == (n + sectorOffset)) {
|
||||
// Force write if sector is full - improves large writes.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -35,7 +35,6 @@
|
|||
#include "../common/FsApiConstants.h"
|
||||
#include "../common/FsDateTime.h"
|
||||
#include "../common/FsName.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "FatPartition.h"
|
||||
class FatVolume;
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -76,25 +75,41 @@ struct FatPos_t {
|
|||
#define isDirSeparator(c) ((c) == '/')
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \class FatName_t
|
||||
* \brief Internal type for File Name - do not use in user apps.
|
||||
* \class FatLfn_t
|
||||
* \brief Internal type for Long File Name - do not use in user apps.
|
||||
*/
|
||||
#if USE_LONG_FILE_NAMES
|
||||
class FatName_t : public FsName {
|
||||
|
||||
class FatLfn_t : public FsName {
|
||||
public:
|
||||
/** UTF-16 length of Long File Name */
|
||||
size_t len;
|
||||
/** Position for sequence number. */
|
||||
uint8_t seqPos;
|
||||
#else // USE_LONG_FILE_NAMES
|
||||
class FatName_t {
|
||||
public:
|
||||
#endif // USE_LONG_FILE_NAMES
|
||||
/** Flags for base and extension character case and LFN. */
|
||||
uint8_t flags;
|
||||
/** Short File Name */
|
||||
uint8_t sfn[11];
|
||||
};
|
||||
/**
|
||||
* \class FatSfn_t
|
||||
* \brief Internal type for Short 8.3 File Name - do not use in user apps.
|
||||
*/
|
||||
class FatSfn_t {
|
||||
public:
|
||||
/** Flags for base and extension character case and LFN. */
|
||||
uint8_t flags;
|
||||
/** Short File Name */
|
||||
uint8_t sfn[11];
|
||||
};
|
||||
|
||||
#if USE_LONG_FILE_NAMES
|
||||
/** Internal class for file names */
|
||||
typedef FatLfn_t FatName_t;
|
||||
#else // USE_LONG_FILE_NAMES
|
||||
/** Internal class for file names */
|
||||
typedef FatSfn_t FatName_t;
|
||||
#endif // USE_LONG_FILE_NAMES
|
||||
|
||||
/** Derived from a LFN with loss or conversion of characters. */
|
||||
const uint8_t FNAME_FLAG_LOST_CHARS = 0X01;
|
||||
/** Base-name or extension has mixed case. */
|
||||
|
|
@ -397,28 +412,6 @@ class FatFile {
|
|||
bool isSystem() const {return m_attributes & FILE_ATTR_SYSTEM;}
|
||||
/** \return True file is writable. */
|
||||
bool isWritable() const {return m_flags & FILE_FLAG_WRITE;}
|
||||
/** Check for a legal 8.3 character.
|
||||
* \param[in] c Character to be checked.
|
||||
* \return true for a legal 8.3 character.
|
||||
*/
|
||||
static bool legal83Char(uint8_t c) {
|
||||
if (c == '"' || c == '|') {
|
||||
return false;
|
||||
}
|
||||
// *+,./
|
||||
if (0X2A <= c && c <= 0X2F && c != 0X2D) {
|
||||
return false;
|
||||
}
|
||||
// :;<=>?
|
||||
if (0X3A <= c && c <= 0X3F) {
|
||||
return false;
|
||||
}
|
||||
// [\]
|
||||
if (0X5B <= c && c <= 0X5D) {
|
||||
return false;
|
||||
}
|
||||
return 0X20 < c && c < 0X7F;
|
||||
}
|
||||
/** List directory contents.
|
||||
*
|
||||
* \param[in] pr Print stream for list.
|
||||
|
|
@ -539,6 +532,16 @@ class FatFile {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool open(const char* path, oflag_t oflag = O_RDONLY);
|
||||
/** Open existing file wih Short 8.3 names.
|
||||
* \param[in] path with short 8.3 names.
|
||||
*
|
||||
* the purpose of this function is to save flash on Uno
|
||||
* and other small boards.
|
||||
*
|
||||
* Directories will be opened O_RDONLY, files O_RDWR.
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool openExistingSFN(const char* path);
|
||||
/** Open the next file or subdirectory in a directory.
|
||||
*
|
||||
* \param[in] dirFile An open FatFile instance for the directory
|
||||
|
|
@ -557,6 +560,7 @@ class FatFile {
|
|||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool openRoot(FatVolume* vol);
|
||||
|
||||
/** Return the next available byte without consuming it.
|
||||
*
|
||||
* \return The byte if no error and not at eof else -1;
|
||||
|
|
@ -993,8 +997,8 @@ class FatFile {
|
|||
return seekSet(32UL*index) ? readDirCache() : nullptr;
|
||||
}
|
||||
DirFat_t* cacheDirEntry(uint8_t action);
|
||||
bool cmpName(uint16_t index, FatName_t* fname, uint8_t lfnOrd);
|
||||
bool createLFN(uint16_t index, FatName_t* fname, uint8_t lfnOrd);
|
||||
bool cmpName(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd);
|
||||
bool createLFN(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd);
|
||||
uint16_t getLfnChar(DirLfn_t* ldir, uint8_t i);
|
||||
uint8_t lfnChecksum(uint8_t* name) {
|
||||
uint8_t sum = 0;
|
||||
|
|
@ -1003,12 +1007,15 @@ class FatFile {
|
|||
}
|
||||
return sum;
|
||||
}
|
||||
static bool makeSFN(FatName_t* fname);
|
||||
bool makeUniqueSfn(FatName_t* fname);
|
||||
static bool makeSFN(FatLfn_t* fname);
|
||||
bool makeUniqueSfn(FatLfn_t* fname);
|
||||
bool openCluster(FatFile* file);
|
||||
bool parsePathName(const char* str, FatName_t* fname, const char** ptr);
|
||||
bool parsePathName(const char* str, FatLfn_t* fname, const char** ptr);
|
||||
bool parsePathName(const char* str, FatSfn_t* fname, const char** ptr);
|
||||
bool mkdir(FatFile* parent, FatName_t* fname);
|
||||
bool open(FatFile* dirFile, FatName_t* fname, oflag_t oflag);
|
||||
bool open(FatFile* dirFile, FatLfn_t* fname, oflag_t oflag);
|
||||
bool open(FatFile* dirFile, FatSfn_t* fname, oflag_t oflag);
|
||||
bool openSFN(FatSfn_t* fname);
|
||||
bool openCachedEntry(FatFile* dirFile, uint16_t cacheIndex, oflag_t oflag,
|
||||
uint8_t lfnOrd);
|
||||
DirFat_t* readDirCache(bool skipReadOk = false);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -26,8 +26,7 @@
|
|||
#include "../common/DebugMacros.h"
|
||||
#include "../common/upcase.h"
|
||||
#include "../common/FsUtf.h"
|
||||
#include "FatFile.h"
|
||||
#include "FatVolume.h"
|
||||
#include "FatLib.h"
|
||||
#if USE_LONG_FILE_NAMES
|
||||
//------------------------------------------------------------------------------
|
||||
static bool isLower(char c) {
|
||||
|
|
@ -71,7 +70,7 @@ static uint16_t Bernstein(const char* bgn, const char* end, uint16_t hash) {
|
|||
return hash;
|
||||
}
|
||||
//==============================================================================
|
||||
bool FatFile::cmpName(uint16_t index, FatName_t* fname, uint8_t lfnOrd) {
|
||||
bool FatFile::cmpName(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd) {
|
||||
FatFile dir = *this;
|
||||
DirLfn_t* ldir;
|
||||
fname->reset();
|
||||
|
|
@ -109,7 +108,7 @@ bool FatFile::cmpName(uint16_t index, FatName_t* fname, uint8_t lfnOrd) {
|
|||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::createLFN(uint16_t index, FatName_t* fname, uint8_t lfnOrd) {
|
||||
bool FatFile::createLFN(uint16_t index, FatLfn_t* fname, uint8_t lfnOrd) {
|
||||
FatFile dir = *this;
|
||||
DirLfn_t* ldir;
|
||||
uint8_t checksum = lfnChecksum(fname->sfn);
|
||||
|
|
@ -146,7 +145,7 @@ bool FatFile::createLFN(uint16_t index, FatName_t* fname, uint8_t lfnOrd) {
|
|||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::makeSFN(FatName_t* fname) {
|
||||
bool FatFile::makeSFN(FatLfn_t* fname) {
|
||||
bool is83;
|
||||
// char c;
|
||||
uint8_t c;
|
||||
|
|
@ -177,14 +176,12 @@ bool FatFile::makeSFN(FatName_t* fname) {
|
|||
|
||||
for (; ptr < end; ptr++) {
|
||||
c = *ptr;
|
||||
// Could skip UTF-8 units where (0XC0 & c) == 0X80
|
||||
|
||||
if (c == '.' && ptr == dot) {
|
||||
in = 10; // Max index for full 8.3 name.
|
||||
i = 8; // Place for extension.
|
||||
bit = FAT_CASE_LC_EXT; // bit for extension.
|
||||
} else {
|
||||
if (!legal83Char(c)) {
|
||||
if (sfnReservedChar(c)) {
|
||||
is83 = false;
|
||||
// Skip UTF-8 trailing characters.
|
||||
if ((c & 0XC0) == 0X80) {
|
||||
|
|
@ -231,7 +228,7 @@ bool FatFile::makeSFN(FatName_t* fname) {
|
|||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::makeUniqueSfn(FatName_t* fname) {
|
||||
bool FatFile::makeUniqueSfn(FatLfn_t* fname) {
|
||||
const uint8_t FIRST_HASH_SEQ = 2; // min value is 2
|
||||
uint8_t pos = fname->seqPos;
|
||||
DirFat_t* dir;
|
||||
|
|
@ -287,7 +284,7 @@ bool FatFile::makeUniqueSfn(FatName_t* fname) {
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
||||
bool FatFile::open(FatFile* dirFile, FatLfn_t* fname, oflag_t oflag) {
|
||||
bool fnameFound = false;
|
||||
uint8_t lfnOrd = 0;
|
||||
uint8_t freeNeed;
|
||||
|
|
@ -302,6 +299,7 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
uint16_t time;
|
||||
DirFat_t* dir;
|
||||
DirLfn_t* ldir;
|
||||
auto vol = dirFile->m_vol;
|
||||
|
||||
if (!dirFile->isDir() || isOpen()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -312,7 +310,7 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
freeNeed = fname->flags & FNAME_FLAG_NEED_LFN ? 1 + nameOrd : 1;
|
||||
dirFile->rewind();
|
||||
while (1) {
|
||||
curIndex = dirFile->m_curPosition/32;
|
||||
curIndex = dirFile->m_curPosition/FS_DIR_SIZE;
|
||||
dir = dirFile->readDirCache();
|
||||
if (!dir) {
|
||||
if (dirFile->getError()) {
|
||||
|
|
@ -415,7 +413,7 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
freeFound += dirFile->m_vol->sectorsPerCluster();
|
||||
freeFound += vol->dirEntriesPerCluster();
|
||||
}
|
||||
if (fnameFound) {
|
||||
if (!dirFile->makeUniqueSfn(fname)) {
|
||||
|
|
@ -456,7 +454,7 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
}
|
||||
}
|
||||
// Force write of entry to device.
|
||||
dirFile->m_vol->cacheDirty();
|
||||
vol->cacheDirty();
|
||||
|
||||
open:
|
||||
// open entry in cache.
|
||||
|
|
@ -471,7 +469,7 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::parsePathName(const char* path,
|
||||
FatName_t* fname, const char** ptr) {
|
||||
FatLfn_t* fname, const char** ptr) {
|
||||
size_t len = 0;
|
||||
// Skip leading spaces.
|
||||
while (*path == ' ') {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,57 +25,8 @@
|
|||
#include <math.h>
|
||||
#define DBG_FILE "FatFilePrint.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "FatFile.h"
|
||||
//------------------------------------------------------------------------------
|
||||
static void printHex(print_t* pr, uint8_t w, uint16_t h) {
|
||||
char buf[5];
|
||||
char* ptr = buf + sizeof(buf);
|
||||
*--ptr = 0;
|
||||
for (uint8_t i = 0; i < w; i++) {
|
||||
char c = h & 0XF;
|
||||
*--ptr = c < 10 ? c + '0' : c + 'A' - 10;
|
||||
h >>= 4;
|
||||
}
|
||||
pr->write(ptr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void FatFile::dmpFile(print_t* pr, uint32_t pos, size_t n) {
|
||||
char text[17];
|
||||
text[16] = 0;
|
||||
if (n >= 0XFFF0) {
|
||||
n = 0XFFF0;
|
||||
}
|
||||
if (!seekSet(pos)) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i <= n; i++) {
|
||||
if ((i & 15) == 0) {
|
||||
if (i) {
|
||||
pr->write(' ');
|
||||
pr->write(text);
|
||||
if (i == n) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pr->write('\r');
|
||||
pr->write('\n');
|
||||
if (i >= n) {
|
||||
break;
|
||||
}
|
||||
printHex(pr, 4, i);
|
||||
pr->write(' ');
|
||||
}
|
||||
int16_t h = read();
|
||||
if (h < 0) {
|
||||
break;
|
||||
}
|
||||
pr->write(' ');
|
||||
printHex(pr, 2, h);
|
||||
text[i&15] = ' ' <= h && h < 0X7F ? h : '.';
|
||||
}
|
||||
pr->write('\r');
|
||||
pr->write('\n');
|
||||
}
|
||||
#include "FatLib.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::ls(print_t* pr, uint8_t flags, uint8_t indent) {
|
||||
FatFile file;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,15 +24,11 @@
|
|||
*/
|
||||
#define DBG_FILE "FatFileSFN.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "FatFile.h"
|
||||
#include "FatVolume.h"
|
||||
|
||||
#if !USE_LONG_FILE_NAMES
|
||||
#include "FatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
// open with filename in fname
|
||||
#define SFN_OPEN_USES_CHKSUM 0
|
||||
bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
||||
bool FatFile::open(FatFile* dirFile, FatSfn_t* fname, oflag_t oflag) {
|
||||
uint16_t date;
|
||||
uint16_t time;
|
||||
uint8_t ms10;
|
||||
|
|
@ -47,11 +43,8 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
DirLfn_t* ldir;
|
||||
|
||||
dirFile->rewind();
|
||||
while (1) {
|
||||
if (!emptyFound) {
|
||||
emptyIndex = index;
|
||||
}
|
||||
dir = reinterpret_cast<DirFat_t*>(dirFile->readDirCache(true));
|
||||
while (true) {
|
||||
dir = dirFile->readDirCache(true);
|
||||
if (!dir) {
|
||||
if (dirFile->getError()) {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -60,13 +53,15 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
// At EOF if no error.
|
||||
break;
|
||||
}
|
||||
if (dir->name[0] == FAT_NAME_FREE) {
|
||||
emptyFound = true;
|
||||
break;
|
||||
}
|
||||
if (dir->name[0] == FAT_NAME_DELETED) {
|
||||
if (dir->name[0] == FAT_NAME_FREE || dir->name[0] == FAT_NAME_FREE) {
|
||||
if (!emptyFound) {
|
||||
emptyIndex = index;
|
||||
emptyFound = true;
|
||||
}
|
||||
if (dir->name[0] == FAT_NAME_FREE) {
|
||||
break;
|
||||
}
|
||||
lfnOrd = 0;
|
||||
emptyFound = true;
|
||||
} else if (isFileOrSubdir(dir)) {
|
||||
if (!memcmp(fname->sfn, dir->name, 11)) {
|
||||
// don't open existing file if O_EXCL
|
||||
|
|
@ -152,8 +147,84 @@ bool FatFile::open(FatFile* dirFile, FatName_t* fname, oflag_t oflag) {
|
|||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::openExistingSFN(const char* path) {
|
||||
FatSfn_t fname;
|
||||
auto vol = FatVolume::cwv();
|
||||
while (*path == '/') {
|
||||
path++;
|
||||
}
|
||||
if (*path == 0) {
|
||||
return openRoot(vol);
|
||||
}
|
||||
*this = *vol->vwd();
|
||||
do {
|
||||
if (!parsePathName(path, &fname, &path)) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
if (!openSFN(&fname)) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
} while (*path);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::openSFN(FatSfn_t* fname) {
|
||||
DirFat_t dir;
|
||||
DirLfn_t* ldir;
|
||||
auto vol = m_vol;
|
||||
uint8_t lfnOrd = 0;
|
||||
if (!isDir()) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
while (true) {
|
||||
if (read(&dir, 32) != 32) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
if (dir.name[0] == 0) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
if (isFileOrSubdir(&dir) && memcmp(fname->sfn, dir.name, 11) == 0) {
|
||||
uint16_t dirIndex = (m_curPosition - 32) >> 5;
|
||||
uint32_t dirCluster = m_firstCluster;
|
||||
memset(this, 0 , sizeof(FatFile));
|
||||
m_attributes = dir.attributes & FILE_ATTR_COPY;
|
||||
if (isFileDir(&dir)) {
|
||||
m_attributes |= FILE_ATTR_FILE;
|
||||
}
|
||||
m_lfnOrd = lfnOrd;
|
||||
m_firstCluster = (uint32_t)getLe16(dir.firstClusterHigh) << 16;
|
||||
m_firstCluster |= getLe16(dir.firstClusterLow);
|
||||
m_fileSize = getLe32(dir.fileSize);
|
||||
m_flags = isFile() ? FILE_FLAG_READ | FILE_FLAG_WRITE : FILE_FLAG_READ;
|
||||
m_vol = vol;
|
||||
m_dirCluster = dirCluster;
|
||||
m_dirSector = m_vol->cacheSectorNumber();
|
||||
m_dirIndex = dirIndex;
|
||||
return true;
|
||||
} else if (isLongName(&dir)) {
|
||||
ldir = reinterpret_cast<DirLfn_t*>(&dir);
|
||||
if (ldir->order & FAT_ORDER_LAST_LONG_ENTRY) {
|
||||
lfnOrd = ldir->order & 0X1F;
|
||||
}
|
||||
} else {
|
||||
lfnOrd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// format directory name field from a 8.3 name string
|
||||
bool FatFile::parsePathName(const char* path, FatName_t* fname,
|
||||
bool FatFile::parsePathName(const char* path, FatSfn_t* fname,
|
||||
const char** ptr) {
|
||||
uint8_t uc = 0;
|
||||
uint8_t lc = 0;
|
||||
|
|
@ -175,7 +246,7 @@ bool FatFile::parsePathName(const char* path, FatName_t* fname,
|
|||
// bit for extension.
|
||||
bit = FNAME_FLAG_LC_EXT;
|
||||
} else {
|
||||
if (!legal83Char(c) || i > n) {
|
||||
if (sfnReservedChar(c) || i > n) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -204,6 +275,7 @@ bool FatFile::parsePathName(const char* path, FatName_t* fname,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
#if !USE_LONG_FILE_NAMES
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatFile::remove() {
|
||||
DirFat_t* dir;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "FatFormatter.h"
|
||||
#include "FatLib.h"
|
||||
// Set nonzero to use calculated CHS in MBR. Should not be required.
|
||||
#define USE_LBA_TO_CHS 1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,10 +24,8 @@
|
|||
*/
|
||||
#ifndef FatFormatter_h
|
||||
#define FatFormatter_h
|
||||
#include "FatFile.h"
|
||||
#include "../common/SysCall.h"
|
||||
#include "../common/BlockDevice.h"
|
||||
#include "../common/FsStructs.h"
|
||||
/**
|
||||
* \class FatFormatter
|
||||
* \brief Format a FAT volume.
|
||||
|
|
@ -59,7 +57,7 @@ class FatFormatter {
|
|||
uint32_t m_sectorCount;
|
||||
uint32_t m_totalSectors;
|
||||
BlockDevice* m_dev;
|
||||
print_t*m_pr;
|
||||
print_t* m_pr;
|
||||
uint8_t* m_secBuf;
|
||||
uint16_t m_reservedSectorCount;
|
||||
uint8_t m_partType;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,9 +25,7 @@
|
|||
#define DBG_FILE "FatName.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/FsUtf.h"
|
||||
#include "FatFile.h"
|
||||
#include "FatVolume.h"
|
||||
|
||||
#include "FatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
uint16_t FatFile::getLfnChar(DirLfn_t* ldir, uint8_t i) {
|
||||
if (i < 5) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -25,8 +25,7 @@
|
|||
#include <string.h>
|
||||
#define DBG_FILE "FatPartition.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "../common/FsStructs.h"
|
||||
#include "FatPartition.h"
|
||||
#include "FatLib.h"
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatPartition::allocateCluster(uint32_t current, uint32_t* next) {
|
||||
uint32_t find;
|
||||
|
|
@ -158,7 +157,7 @@ bool FatPartition::allocContiguous(uint32_t count, uint32_t* firstCluster) {
|
|||
int8_t FatPartition::fatGet(uint32_t cluster, uint32_t* value) {
|
||||
uint32_t sector;
|
||||
uint32_t next;
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
|
||||
// error if reserved cluster of beyond FAT
|
||||
if (cluster < 2 || cluster > m_lastCluster) {
|
||||
|
|
@ -168,44 +167,44 @@ int8_t FatPartition::fatGet(uint32_t cluster, uint32_t* value) {
|
|||
|
||||
if (fatType() == 32) {
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_READ);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
next = getLe32(reinterpret_cast<uint8_t*>
|
||||
(&pc->fat32[cluster & (m_sectorMask >> 2)]));
|
||||
uint16_t offset = (cluster << 2) & m_sectorMask;
|
||||
next = getLe32(pc + offset);
|
||||
} else if (fatType() == 16) {
|
||||
cluster &= 0XFFFF;
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 1) );
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_READ);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
next = getLe16(reinterpret_cast<uint8_t*>
|
||||
(&pc->fat16[cluster & (m_sectorMask >> 1)]));
|
||||
uint16_t offset = (cluster << 1) & m_sectorMask;
|
||||
next = getLe16(pc + offset);
|
||||
} else if (FAT12_SUPPORT && fatType() == 12) {
|
||||
uint16_t index = cluster;
|
||||
index += index >> 1;
|
||||
sector = m_fatStartSector + (index >> m_bytesPerSectorShift);
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_READ);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
index &= m_sectorMask;
|
||||
uint16_t tmp = pc->data[index];
|
||||
uint16_t tmp = pc[index];
|
||||
index++;
|
||||
if (index == m_bytesPerSector) {
|
||||
pc = cacheFetchFat(sector + 1, FsCache::CACHE_FOR_READ);
|
||||
pc = fatCachePrepare(sector + 1, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
tmp |= pc->data[index] << 8;
|
||||
tmp |= pc[index] << 8;
|
||||
next = cluster & 1 ? tmp >> 4 : tmp & 0XFFF;
|
||||
} else {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -224,7 +223,7 @@ int8_t FatPartition::fatGet(uint32_t cluster, uint32_t* value) {
|
|||
// Store a FAT entry
|
||||
bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
||||
uint32_t sector;
|
||||
cache_t* pc;
|
||||
uint8_t* pc;
|
||||
|
||||
// error if reserved cluster of beyond FAT
|
||||
if (cluster < 2 || cluster > m_lastCluster) {
|
||||
|
|
@ -234,26 +233,26 @@ bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
|||
|
||||
if (fatType() == 32) {
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 2));
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_WRITE);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
setLe32(reinterpret_cast<uint8_t*>
|
||||
(&pc->fat32[cluster & (m_sectorMask >> 2)]), value);
|
||||
uint16_t offset = (cluster << 2) & m_sectorMask;
|
||||
setLe32(pc + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fatType() == 16) {
|
||||
cluster &= 0XFFFF;
|
||||
sector = m_fatStartSector + (cluster >> (m_bytesPerSectorShift - 1) );
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_WRITE);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
setLe16(reinterpret_cast<uint8_t*>
|
||||
(&pc->fat16[cluster & (m_sectorMask >> 1)]), value);
|
||||
uint16_t offset = (cluster << 1) & m_sectorMask;
|
||||
setLe16(pc + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +260,7 @@ bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
|||
uint16_t index = cluster;
|
||||
index += index >> 1;
|
||||
sector = m_fatStartSector + (index >> m_bytesPerSectorShift);
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_WRITE);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -269,15 +268,15 @@ bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
|||
index &= m_sectorMask;
|
||||
uint8_t tmp = value;
|
||||
if (cluster & 1) {
|
||||
tmp = (pc->data[index] & 0XF) | tmp << 4;
|
||||
tmp = (pc[index] & 0XF) | tmp << 4;
|
||||
}
|
||||
pc->data[index] = tmp;
|
||||
pc[index] = tmp;
|
||||
|
||||
index++;
|
||||
if (index == m_bytesPerSector) {
|
||||
sector++;
|
||||
index = 0;
|
||||
pc = cacheFetchFat(sector, FsCache::CACHE_FOR_WRITE);
|
||||
pc = fatCachePrepare(sector, FsCache::CACHE_FOR_WRITE);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -285,9 +284,9 @@ bool FatPartition::fatPut(uint32_t cluster, uint32_t value) {
|
|||
}
|
||||
tmp = value >> 4;
|
||||
if (!(cluster & 1)) {
|
||||
tmp = ((pc->data[index] & 0XF0)) | tmp >> 4;
|
||||
tmp = ((pc[index] & 0XF0)) | tmp >> 4;
|
||||
}
|
||||
pc->data[index] = tmp;
|
||||
pc[index] = tmp;
|
||||
return true;
|
||||
} else {
|
||||
DBG_FAIL_MACRO;
|
||||
|
|
@ -353,7 +352,7 @@ int32_t FatPartition::freeClusterCount() {
|
|||
} else if (fatType() == 16 || fatType() == 32) {
|
||||
sector = m_fatStartSector;
|
||||
while (todo) {
|
||||
cache_t* pc = cacheFetchFat(sector++, FsCache::CACHE_FOR_READ);
|
||||
uint8_t* pc = fatCachePrepare(sector++, FsCache::CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
|
|
@ -363,14 +362,16 @@ int32_t FatPartition::freeClusterCount() {
|
|||
n = todo;
|
||||
}
|
||||
if (fatType() == 16) {
|
||||
uint16_t* p16 = reinterpret_cast<uint16_t*>(pc);
|
||||
for (uint16_t i = 0; i < n; i++) {
|
||||
if (pc->fat16[i] == 0) {
|
||||
if (p16[i] == 0) {
|
||||
free++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t* p32 = reinterpret_cast<uint32_t*>(pc);
|
||||
for (uint16_t i = 0; i < n; i++) {
|
||||
if (pc->fat32[i] == 0) {
|
||||
if (p32[i] == 0) {
|
||||
free++;
|
||||
}
|
||||
}
|
||||
|
|
@ -412,7 +413,7 @@ bool FatPartition::init(BlockDevice* dev, uint8_t part) {
|
|||
goto fail;
|
||||
}
|
||||
mbr = reinterpret_cast<MbrSector_t*>
|
||||
(cacheFetchData(0, FsCache::CACHE_FOR_READ));
|
||||
(dataCachePrepare(0, FsCache::CACHE_FOR_READ));
|
||||
MbrPart_t* mp = mbr->part + part - 1;
|
||||
|
||||
if (!mbr || mp->type == 0 || (mp->boot != 0 && mp->boot != 0X80)) {
|
||||
|
|
@ -422,9 +423,10 @@ bool FatPartition::init(BlockDevice* dev, uint8_t part) {
|
|||
volumeStartSector = getLe32(mp->relativeSectors);
|
||||
}
|
||||
pbs = reinterpret_cast<pbs_t*>
|
||||
(cacheFetchData(volumeStartSector, FsCache::CACHE_FOR_READ));
|
||||
(dataCachePrepare(volumeStartSector, FsCache::CACHE_FOR_READ));
|
||||
bpb = reinterpret_cast<BpbFat32_t*>(pbs->bpb);
|
||||
if (!pbs || bpb->fatCount != 2 || getLe16(bpb->bytesPerSector) != 512) {
|
||||
if (!pbs || bpb->fatCount != 2 ||
|
||||
getLe16(bpb->bytesPerSector) != m_bytesPerSector) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -452,7 +454,7 @@ bool FatPartition::init(BlockDevice* dev, uint8_t part) {
|
|||
m_rootDirStart = m_fatStartSector + 2 * m_sectorsPerFat;
|
||||
// data start for FAT16 and FAT32
|
||||
m_dataStartSector = m_rootDirStart +
|
||||
((32 * m_rootDirEntryCount + m_bytesPerSector - 1)/m_bytesPerSector);
|
||||
((FS_DIR_SIZE*m_rootDirEntryCount + m_bytesPerSector - 1)/m_bytesPerSector);
|
||||
|
||||
// total sectors for FAT16 or FAT32
|
||||
totalSectors = getLe16(bpb->totalSectors16);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -43,20 +43,6 @@ const uint8_t FAT_TYPE_FAT16 = 16;
|
|||
/** Type for FAT12 partition */
|
||||
const uint8_t FAT_TYPE_FAT32 = 32;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Cache type for a sector.
|
||||
*/
|
||||
union cache_t {
|
||||
/** Used to access cached file data sectors. */
|
||||
uint8_t data[512];
|
||||
/** Used to access cached FAT16 entries. */
|
||||
uint16_t fat16[256];
|
||||
/** Used to access cached FAT32 entries. */
|
||||
uint32_t fat32[128];
|
||||
/** Used to access cached directory entries. */
|
||||
DirFat_t dir[16];
|
||||
};
|
||||
//==============================================================================
|
||||
/**
|
||||
* \class FatPartition
|
||||
|
|
@ -84,6 +70,10 @@ class FatPartition {
|
|||
uint8_t bytesPerSectorShift() const {
|
||||
return m_bytesPerSectorShift;
|
||||
}
|
||||
/** \return Number of directory entries per sector. */
|
||||
uint16_t dirEntriesPerCluster() const {
|
||||
return m_sectorsPerCluster*(m_bytesPerSector/FS_DIR_SIZE);
|
||||
}
|
||||
/** \return Mask for sector offset. */
|
||||
uint16_t sectorMask() const {
|
||||
return m_sectorMask;
|
||||
|
|
@ -186,8 +176,8 @@ class FatPartition {
|
|||
friend class FatFile;
|
||||
//----------------------------------------------------------------------------
|
||||
static const uint8_t m_bytesPerSectorShift = 9;
|
||||
static const uint16_t m_bytesPerSector = 512;
|
||||
static const uint16_t m_sectorMask = 0x1FF;
|
||||
static const uint16_t m_bytesPerSector = 1 << m_bytesPerSectorShift;
|
||||
static const uint16_t m_sectorMask = m_bytesPerSector - 1;
|
||||
//----------------------------------------------------------------------------
|
||||
BlockDevice* m_blockDev; // sector device
|
||||
uint8_t m_sectorsPerCluster; // Cluster size in sectors.
|
||||
|
|
@ -215,15 +205,9 @@ class FatPartition {
|
|||
bool cacheSafeWrite(uint32_t sector, const uint8_t* dst, size_t count) {
|
||||
return m_cache.cacheSafeWrite(sector, dst, count);
|
||||
}
|
||||
bool readSector(uint32_t sector, uint8_t* dst) {
|
||||
return m_blockDev->readSector(sector, dst);
|
||||
}
|
||||
bool syncDevice() {
|
||||
return m_blockDev->syncDevice();
|
||||
}
|
||||
bool writeSector(uint32_t sector, const uint8_t* src) {
|
||||
return m_blockDev->writeSector(sector, src);
|
||||
}
|
||||
#if MAINTAIN_FREE_CLUSTER_COUNT
|
||||
int32_t m_freeClusterCount; // Count of free clusters in volume.
|
||||
void setFreeClusterCount(int32_t value) {
|
||||
|
|
@ -244,26 +228,30 @@ class FatPartition {
|
|||
#endif // MAINTAIN_FREE_CLUSTER_COUNT
|
||||
// sector caches
|
||||
FsCache m_cache;
|
||||
bool cachePrepare(uint32_t sector, uint8_t option) {
|
||||
return m_cache.prepare(sector, option);
|
||||
}
|
||||
FsCache* dataCache() {return &m_cache;}
|
||||
#if USE_SEPARATE_FAT_CACHE
|
||||
FsCache m_fatCache;
|
||||
cache_t* cacheFetchFat(uint32_t sector, uint8_t options) {
|
||||
uint8_t* fatCachePrepare(uint32_t sector, uint8_t options) {
|
||||
options |= FsCache::CACHE_STATUS_MIRROR_FAT;
|
||||
return reinterpret_cast<cache_t*>(m_fatCache.get(sector, options));
|
||||
return m_fatCache.prepare(sector, options);
|
||||
}
|
||||
bool cacheSync() {
|
||||
return m_cache.sync() && m_fatCache.sync() && syncDevice();
|
||||
}
|
||||
#else // USE_SEPARATE_FAT_CACHE
|
||||
cache_t* cacheFetchFat(uint32_t sector, uint8_t options) {
|
||||
uint8_t* fatCachePrepare(uint32_t sector, uint8_t options) {
|
||||
options |= FsCache::CACHE_STATUS_MIRROR_FAT;
|
||||
return cacheFetchData(sector, options);
|
||||
return dataCachePrepare(sector, options);
|
||||
}
|
||||
bool cacheSync() {
|
||||
return m_cache.sync() && syncDevice();
|
||||
}
|
||||
#endif // USE_SEPARATE_FAT_CACHE
|
||||
cache_t* cacheFetchData(uint32_t sector, uint8_t options) {
|
||||
return reinterpret_cast<cache_t*>(m_cache.get(sector, options));
|
||||
uint8_t* dataCachePrepare(uint32_t sector, uint8_t options) {
|
||||
return m_cache.prepare(sector, options);
|
||||
}
|
||||
void cacheInvalidate() {
|
||||
m_cache.invalidate();
|
||||
|
|
@ -271,8 +259,8 @@ class FatPartition {
|
|||
bool cacheSyncData() {
|
||||
return m_cache.sync();
|
||||
}
|
||||
cache_t* cacheAddress() {
|
||||
return reinterpret_cast<cache_t*>(m_cache.cacheBuffer());
|
||||
uint8_t* cacheAddress() {
|
||||
return m_cache.cacheBuffer();
|
||||
}
|
||||
uint32_t cacheSectorNumber() {
|
||||
return m_cache.sector();
|
||||
|
|
@ -299,7 +287,4 @@ class FatPartition {
|
|||
return cluster > m_lastCluster;
|
||||
}
|
||||
};
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
bool printFatDir(print_t* pr, DirFat_t* dir);
|
||||
#endif // DOXYGEN_SHOULD_SKIP_THIS
|
||||
#endif // FatPartition
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
*/
|
||||
#define DBG_FILE "FatVolume.cpp"
|
||||
#include "../common/DebugMacros.h"
|
||||
#include "FatVolume.h"
|
||||
#include "FatLib.h"
|
||||
FatVolume* FatVolume::m_cwv = nullptr;
|
||||
//------------------------------------------------------------------------------
|
||||
bool FatVolume::chdir(const char *path) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
#ifndef FatVolume_h
|
||||
#define FatVolume_h
|
||||
#include "FatPartition.h"
|
||||
#include "FatFile.h"
|
||||
/**
|
||||
* \file
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
@ -39,7 +39,7 @@ inline char* stackBegin() {
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline char* stackPointer() {
|
||||
#if defined(__AVR__)
|
||||
#if defined(__AVR__)
|
||||
return reinterpret_cast<char*>(SP);
|
||||
#elif defined(__arm__)
|
||||
register uint32_t sp asm("sp");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2011-2020 Bill Greiman
|
||||
* Copyright (c) 2011-2021 Bill Greiman
|
||||
* This file is part of the SdFat library for SD memory cards.
|
||||
*
|
||||
* MIT License
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue