/*
MSC SdFat usage from SD library
Starting with Teensyduino 1.54, the SD library is a thin wrapper for SdFat.
You can access the main SdFat filesystem with ".mscfs".
This example shows some of the ways to select optimized SdFat drivers and
how to use special file truncation and pre-allocation for optimized data
logging.
This example code is in the public domain.
*/
#include <USBHost_t36.h>
// Setup USBHost_t36 and as many HUB ports as needed.
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHub hub3(myusb);
USBHub hub4(myusb);
// Setup MSC for the number of USB Drives you are using. (Two for this example)
// Mutiple USB drives can be used. Hot plugging is supported. There is a slight
// delay after a USB MSC device is plugged in. This is waiting for initialization
// but after it is initialized ther should be no delay.
// mscController is now USBDrive.
USBDrive msDrive1(myusb);
// USBFilesystem is a class based on claimed partitions discovered during
// initialization. We are using the first discovered partition here. More
// discovered partitions can be used by adding more instances of the
// 'USBFilesystem' class.
USBFilesystem partition1(myusb);
elapsedMillis mscTimeOut;
void setup()
{
Serial.begin(9600);
while (!Serial); // wait for Arduino Serial Monitor
// Start USBHost_t36, HUB(s) and USB devices.
myusb.begin();
myusb.Task();
Serial.print("Initializing MSC drive...");
uint8_t errCode = MS_INIT_PASS;
mscTimeOut = 0;
// Wait for MSC drive to be auto detected. Uses 5 second timeout
// and no drive detected error. Waits for drive to be inserted.
while(!msDrive1) {
if((mscTimeOut > MSC_CONNECT_TIMEOUT) && (msDrive1.errorCode() == MS_NO_MEDIA_ERR)) {
Serial.println("No drive connected yet!!!!");
Serial.println("Connect a drive to continue...\n");
while(!msDrive1);
}
delay(1);
}
mscTimeOut = 0;
while(!partition1) {
myusb.Task();
if(mscTimeOut > MEDIA_READY_TIMEOUT) {
Serial.println("initialization failed!");
return;
}
delay(1);
}
Serial.println("initialization done.");
Serial.println();
// After the MSC drive is initialized, you can access it using the ordinary
// SD library functions, regardless of whether it was initialized by
// SD library SD.begin() or SdFat library SD.sdfs.begin() or MSC auto
// initialization. MSC access to SdFat is achieved as in this example:
// "partition1.mscfs.ls()".
Serial.println("Print directory using SD functions");
File root = partition1.open("/");
while (true) {
File entry = root.openNextFile();
if (!entry) break; // no more files
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
} else {
printSpaces(40 - strlen(entry.name()));
Serial.print(" ");
Serial.println(entry.size(), DEC);
}
entry.close();
}
// You can also access the SD card with SdFat's functions
//
Serial.println();
Serial.println("Print directory using SdFat ls() function");
partition1.mscfs.ls(LS_R);
// You can access files using SdFat which uses "FsFile" for open files
// FsFile offers more capability than regular SD "File". As shown in this
// example, you can truncate tiles. You can also pre-allocate a file on
// the MSC drive (if it does not yet have any data, the reason we truncate
// first). Pre-allocation impoves the speed of writes within the already
// allocated space while data logging or performing other small writes.
//
Serial.println();
Serial.println("Writing to datalog.bin using SdFat functions");
FsFile myfile = partition1.mscfs.open("datalog.bin", O_WRITE | O_CREAT);
unsigned int len = myfile.fileSize();
Serial.print("datalog.bin started with ");
Serial.print(len);
Serial.println(" bytes");
if (len > 0) {
// reduce the file to zero if it already had data
myfile.truncate();
}
if (myfile.preAllocate(40*1024*1024)) {
Serial.print(" Allocate 40 megabytes for datalog.bin");
} else {
Serial.print(" unable to preallocate this file");
}
myfile.print("Just some test data written to the file (by SdFat functions)");
myfile.write((uint8_t)'\0'); // add a null byte to mark end of string
myfile.close();
// You can also use regular SD functions, even to access the same file. Just
// remember to close the SdFat FsFile before opening as a regular SD File.
//
Serial.println();
Serial.println("Reading to datalog.bin using SD functions");
File f = partition1.open("datalog.bin");
if (f) {
char mybuffer[100];
int index = 0;
while (f.available()) {
char c = f.read();
mybuffer[index] = c;
if (c == 0) break; // end of string
index = index + 1;
if (index == 99) break; // buffer full
}
mybuffer[index] = 0;
Serial.print(" Read from file: ");
Serial.println(mybuffer);
} else {
Serial.println("unable to open datalog.bin :(");
}
f.close();
// When mixing SD and SdFat file access, remember for writing that
// SD defaults to appending if you open with FILE_WRITE. You must
// use FILE_WRITE_BEGIN if you wish to overwrite the file from the
// start. With SdFat, O_WRITE or O_RDWR starts overwriting from the
// beginning. You must add O_AT_END if you wish to appead.
}
void loop()
{
// nothing happens after setup finishes.
}
void printSpaces(int num) {
for (int i = 0; i < num; i++) {
Serial.print(" ");
}
}