First Commit

This commit is contained in:
MindCreeper03
2025-02-27 19:31:50 +01:00
parent bcbb6aff9a
commit e490df1715
2470 changed files with 1479965 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
#include "SdFat.h"
#ifdef __AVR__
const uint32_t FILE_SIZE_MiB = 10UL;
#else // __AVR__
const uint32_t FILE_SIZE_MiB = 100UL;
#endif
bool waitBusy = true;
#define SD_CONFIG SdSpiConfig(SS, DEDICATED_SPI)
//#define SD_CONFIG SdSpiConfig(SS, SHARED_SPI)
// Config for Teensy 3.5/3.6 buit-in SD.
//#define SD_CONFIG SdSpiConfig(SDCARD_SS_PIN, DEDICATED_SPI)
//#define SD_CONFIG SdioConfig(FIFO_SDIO)
//------------------------------------------------------------------------------
const uint64_t FILE_SIZE = (uint64_t)FILE_SIZE_MiB << 20;
SdFs sd;
FsFile file;
uint8_t buf[512];
#define error(s) sd.errorHalt(&Serial, F(s))
//------------------------------------------------------------------------------
void clearSerialInput() {
uint32_t m = micros();
do {
if (Serial.read() >= 0) {
m = micros();
}
} while (micros() - m < 10000);
}
//------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
// Wait for USB Serial
while (!Serial) {
yield();
}
delay(1000);
//------------------------------------------------------------------------------
}
void loop() {
clearSerialInput();
Serial.println(F("\nType any character to start\n"));
while (!Serial.available()) {
yield();
}
// Initialize the SD card.
if (!sd.begin(SD_CONFIG)) {
sd.initErrorHalt();
}
if (!file.open("SdBusyTest.bin", O_RDWR | O_CREAT |O_TRUNC)) {
error("file open failed");
}
if (!file.preAllocate(FILE_SIZE)) {
error("preallocate failed");
}
Serial.print(F("Starting write of "));
Serial.print(FILE_SIZE_MiB);
Serial.println(F(" MiB."));
uint32_t maxWrite = 0;
uint32_t minWrite = 99999999;
uint32_t ms = millis();
uint32_t maxBusy = 0;
uint32_t minBusy = UINT32_MAX;
// Write a dummy sector to start a multi-sector write.
if(file.write(buf, sizeof(buf)) != sizeof(buf)) {
error("write failed for first sector");
}
while (file.position() < FILE_SIZE) {
uint32_t m = micros();
if (waitBusy) {
m = micros();
while (sd.card()->isBusy()) {}
m = micros() - m;
if (m < minBusy) {
minBusy = m;
}
if (m > maxBusy) {
maxBusy = m;
}
}
m = micros();
if (file.write(buf, sizeof(buf)) != sizeof(buf)) {
error("write failed");
}
m = micros() - m;
if (m < minWrite) {
minWrite = m;
}
if (m > maxWrite) {
maxWrite = m;
}
}
file.close();
ms = millis() - ms;
Serial.println(F("\nTimes in micros"));
if (waitBusy) {
Serial.print(F("minBusy: "));
Serial.println(minBusy);
Serial.print(F("maxBusy: "));
Serial.println(maxBusy);
}
Serial.print(F("minWrite: "));
Serial.println(minWrite);
Serial.print(F("maxWrite: "));
Serial.println(maxWrite);
Serial.print(1e-3*ms);
Serial.println(F(" Seconds"));
Serial.print(1.0*FILE_SIZE/ms);
Serial.println(F(" KB/sec"));
}

View File

@@ -0,0 +1,51 @@
#include "SdFat.h"
#define DUMP_RAW 0
#define DUMP_UPCASE 0
const uint8_t CS_PIN = SS;
//#define SD_CONFIG SdioConfig(FIFO_SDIO)
#define SD_CONFIG SdSpiConfig(CS_PIN)
SdExFat sd;
#define error(s) sd.errorHalt(&Serial, F(s))
void setup() {
Serial.begin(9600);
while (!Serial) {
yield();
}
Serial.println(F("Type any character to begin"));
while (!Serial.available()) {
yield();
}
if (!sd.begin(SD_CONFIG)){
error("begin failed");
}
#if DUMP_RAW
sd.dmpSector(&Serial, 0);
for (uint8_t i = 0; i < 24; i++) {
sd.dmpSector(&Serial, 0X8000 + i);
Serial.println();
}
return;
#endif // DUMP_RAW
ExFatFile root;
if (!root.openRoot(&sd)) {
error("openRoot failed");
}
sd.printDir(&Serial, &root);
// startSector = 0, sectorCount = 1.
sd.dmpFat(&Serial, 0, 1);
sd.dmpBitmap(&Serial);
sd.printVolInfo(&Serial);
sd.checkUpcase(&Serial);
#if DUMP_UPCASE
sd.printUpcase(&Serial);
#endif // DUMP_UPCASE
// sd.dmpCluster(&Serial, 8, 0, 4);
Serial.println("Done");
}
void loop() {
// put your main code here, to run repeatedly:
}

View File

@@ -0,0 +1,43 @@
#include "SdFat.h"
SdFs sd;
FsFile file;
const char* name[] = {
"SFN.TXT",
"LongFilename.txt",
#if USE_UTF8_LONG_NAMES
u8"très élégant.txt",
#endif // USE_UTF8_LONG_NAMES
nullptr};
char buf[32];
void setup() {
Serial.begin(9600);
while (!Serial) {}
Serial.println("Type any character to begin");
while (!Serial.available()) {}
if (!sd.begin(SS)) {
sd.initErrorHalt();
}
for (uint8_t i = 0; name[i]; i++) {
if (!file.open(name[i], O_CREAT |O_RDWR)) {
sd.errorHalt("open");
}
size_t len = strlen(name[i]);
size_t rtn = file.getName(buf, len);
if (rtn != 0) {
Serial.println("fail len");
}
rtn = file.getName(buf, len + 1);
if (rtn != len) {
Serial.println("fail len + 1");
}
Serial.print(rtn);
Serial.print(' ');
Serial.println(buf);
if (!file.remove()) {
sd.errorHalt("remove");
}
}
Serial.println("Done");
}
void loop() {}

View File

@@ -0,0 +1,140 @@
/*
* This sketch is a test of subdirectory and file creation.
* It also tests allocation of clusters to directories.
*
* It will create two subdirectories and create enough files
* to force the allocation of a cluster to each directory.
*
* More than 3000 files may be created on a FAT32 volume.
*
* Note: Some cards may 'stutter' others just get slow due
* to the number of flash erases this program causes.
*/
#include <SdFat.h>
const uint8_t SD_CHIP_SELECT = SS;
SdFat sd;
typedef File file_t;
// store error strings in flash to save RAM
#define error(s) sd.errorHalt(&Serial, F(s))
/*
* create enough files to force a cluster to be allocated to dir.
*/
void dirAllocTest(file_t* dir) {
char buf[32], name[32];
file_t file;
uint16_t n;
uint32_t size = dir->dirSize();
// create files and write name to file
for (n = 0; ; n++){
// make file name
sprintf(name, "%u.TXT", n);
// open start time
uint32_t t0 = millis();
if (!file.open(dir, name, O_WRONLY | O_CREAT | O_EXCL)) {
error("open for write failed");
}
// open end time and write start time
uint32_t t1 = millis();
// write file name to file
file.print(name);
if (!file.close()) error("close write");
// write end time
uint32_t t2 = millis();
Serial.print(F("WR "));
Serial.print(n);
Serial.write(' ');
// print time to create file
Serial.print(t1 - t0);
Serial.write(' ');
// print time to write file
Serial.println(t2 - t1);
// directory size will change when a cluster is added
if (dir->curPosition() > size) break;
}
// read files and check content
for (uint16_t i = 0; i <= n; i++) {
sprintf(name, "%u.TXT", i);
// open start time
uint32_t t0 = millis();
if (!file.open(dir, name, O_RDONLY)) {
error("open for read failed");
}
// open end time and read start time
uint32_t t1 = millis();
int16_t nr = file.read(buf, sizeof(buf));
if (nr < 5) error("file.read failed");
// read end time
uint32_t t2 = millis();
// check file content
if (strlen(name) != (size_t)nr || strncmp(name, buf, nr)) {
error("content compare failed");
}
if (!file.close()) error("close read failed");
Serial.print(F("RD "));
Serial.print(i);
Serial.write(' ');
// print open time
Serial.print(t1 - t0);
Serial.write(' ');
// print read time
Serial.println(t2 - t1);
}
}
void setup() {
file_t root;
Serial.begin(9600);
while (!Serial) {} // wait for Leonardo
Serial.println(F("Type any character to start"));
while (Serial.read() <= 0) {}
delay(200); // Catch Due reset problem
// initialize the SD card at SPI_FULL_SPEED for best performance.
// try lower speed if bus errors occur.
if (!sd.begin(SD_CHIP_SELECT, SPI_FULL_SPEED)) {
sd.initErrorHalt(&Serial);
}
root.openRoot(&sd);
uint32_t m = millis();
// write files to root if not FAT16
if (sd.fatType() != 16) {
Serial.println(F("Writing files to root"));
dirAllocTest(&root);
}
// create sub1 and write files
file_t sub1;
if (!sub1.mkdir(&root, "SUB1")) error("makdeDir SUB1 failed");
Serial.println(F("Writing files to SUB1"));
dirAllocTest(&sub1);
// create sub2 and write files
file_t sub2;
if (!sub2.mkdir(&sub1, "SUB2")) error("mkdir SUB2 failed");
Serial.println(F("Writing files to SUB2"));
dirAllocTest(&sub2);
m = millis() - m;
Serial.print(F("Done millis: "));
Serial.println(m);
}
void loop() { }

View File

@@ -0,0 +1,99 @@
/*
* This sketch will remove the files and directories
* created by the SdFatMakeDir.pde sketch.
*
* Performance is erratic due to the large number
* of flash erase operations caused by many random
* writes to file structures.
*/
#include <SdFat.h>
const uint8_t SD_CHIP_SELECT = SS;
SdFat sd;
typedef File file_t;
// store error strings in flash to save RAM
#define error(s) sd.errorHalt(&Serial, F(s))
/*
* remove all files in dir.
*/
void deleteFiles(FatFile* dir) {
char name[32];
file_t file;
// open and delete files
for (uint16_t n = 0; ; n++){
sprintf(name, "%u.TXT", n);
// open start time
uint32_t t0 = millis();
// assume done if open fails
if (!file.open(dir, name, O_WRONLY)) return;
// open end time and remove start time
uint32_t t1 = millis();
if (!file.remove()) error("file.remove failed");
// remove end time
uint32_t t2 = millis();
Serial.print(F("RM "));
Serial.print(n);
Serial.write(' ');
// open time
Serial.print(t1 - t0);
Serial.write(' ');
// remove time
Serial.println(t2 - t1);
}
}
void setup() {
file_t root;
Serial.begin(9600);
while (!Serial) {} // wait for Leonardo
Serial.println(F("Type any character to start"));
while (Serial.read() <= 0) {}
delay(200); // Catch Due reset problem
// initialize the SD card at SPI_FULL_SPEED for best performance.
// try lower speed if bus errors occur.
if (!sd.begin(SD_CHIP_SELECT, SPI_FULL_SPEED)) {
sd.initErrorHalt(&Serial);
}
root.openRoot(&sd);
// delete files in root if not FAT16.
if (sd.fatType() != 16) {
Serial.println(F("Remove files in root"));
deleteFiles(&root);
}
// open SUB1 and delete files
file_t sub1;
if (!sub1.open("SUB1", O_RDONLY)) error("open SUB1 failed");
Serial.println(F("Remove files in SUB1"));
deleteFiles(&sub1);
// open SUB2 and delete files
file_t sub2;
if (!sub2.open(&sub1, "SUB2", O_RDONLY)) error("open SUB2 failed");
Serial.println(F("Remove files in SUB2"));
deleteFiles(&sub2);
// remove SUB2
if (!sub2.rmdir()) error("sub2.rmdir failed");
Serial.println(F("SUB2 removed"));
// remove SUB1
if (!sub1.rmdir()) error("sub1.rmdir failed");
Serial.println(F("SUB1 removed"));
Serial.println(F("Done"));
}
void loop() { }

View File

@@ -0,0 +1,162 @@
/*
* This program tests the dateTimeCallback() function
* and the timestamp() function.
*/
#include <SPI.h>
#include "SdFat.h"
#include "sdios.h"
SdFs sd;
FsFile file;
// Default SD chip select is SS pin
const uint8_t chipSelect = SS;
// create Serial stream
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// store error strings in flash to save RAM
#define error(s) sd.errorHalt(F(s))
//------------------------------------------------------------------------------
/*
* date/time values for debug
* normally supplied by a real-time clock or GPS
*/
// date 1-Oct-21
uint16_t year = 2021;
uint8_t month = 10;
uint8_t day = 1;
// time 20:30:40
uint8_t hour = 20;
uint8_t minute = 30;
uint8_t second = 40;
//------------------------------------------------------------------------------
/*
* User provided date time callback function.
* See SdFile::dateTimeCallback() for usage.
*/
void dateTime(uint16_t* date, uint16_t* time) {
// User gets date and time from GPS or real-time
// clock in real callback function
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(year, month, day);
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(hour, minute, second);
}
//------------------------------------------------------------------------------
/*
* Function to print all timestamps.
*/
void printTimestamps(FsFile& f) {
cout << F("Creation: ");
f.printCreateDateTime(&Serial);
cout << endl << F("Modify: ");
f.printModifyDateTime(&Serial);
cout << endl << F("Access: ");
f.printAccessDateTime(&Serial);
cout << endl;
}
//------------------------------------------------------------------------------
void setup(void) {
Serial.begin(9600);
// Wait for USB Serial
while (!Serial) {
yield();
}
cout << F("Type any character to start\n");
while (!Serial.available()) {
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))) {
sd.initErrorHalt();
}
// remove files if they exist
sd.remove("callback.txt");
sd.remove("default.txt");
sd.remove("stamp.txt");
// create a new file with default timestamps
if (!file.open("default.txt", O_WRONLY | O_CREAT)) {
error("open default.txt failed");
}
cout << F("\nOpen with default times\n");
printTimestamps(file);
// close file
file.close();
/*
* Test the date time callback function.
*
* dateTimeCallback() sets the function
* that is called when a file is created
* or when a file's directory entry is
* modified by sync().
*
* The callback can be disabled by the call
* SdFile::dateTimeCallbackCancel()
*/
// set date time callback function
SdFile::dateTimeCallback(dateTime);
// create a new file with callback timestamps
if (!file.open("callback.txt", O_WRONLY | O_CREAT)) {
error("open callback.txt failed");
}
cout << ("\nOpen with callback times\n");
printTimestamps(file);
// change call back date
day += 1;
// must add two to see change since FAT second field is 5-bits
second += 2;
// modify file by writing a byte
file.write('t');
// force dir update
file.sync();
cout << F("\nTimes after write\n");
printTimestamps(file);
// close file
file.close();
/*
* Test timestamp() function
*
* Cancel callback so sync will not
* change access/modify timestamp
*/
SdFile::dateTimeCallbackCancel();
// create a new file with default timestamps
if (!file.open("stamp.txt", O_WRONLY | O_CREAT)) {
error("open stamp.txt failed");
}
// set creation date time
if (!file.timestamp(T_CREATE, 2021, 11, 10, 1, 2, 3)) {
error("set create time failed");
}
// set write/modification date time
if (!file.timestamp(T_WRITE, 2021, 11, 11, 4, 5, 6)) {
error("set write time failed");
}
// set access date
if (!file.timestamp(T_ACCESS, 2021, 11, 12, 7, 8, 9)) {
error("set access time failed");
}
cout << F("\nTimes after timestamp() calls\n");
printTimestamps(file);
file.close();
cout << F("\nDone\n");
}
void loop() {}