mborgerson
Well-known member
I'm exploring the USBHost MassStorageDriver to learn more about USB Host functionality with the ultimate goal of writing code to connect a USB webcam to the host port and receiving uncompressed image frames for storage on the SD card of a T4.1. I started testing transfer times for reading and writing data to a reasonably fast SanDisk 128GB USB3 thumb drive. I soon discovered that the mass storage driver does not like to send data from EXTMEM to the thumb drive.
Here's the minimalist code to show the issue:
and here's the output:
USB Mass storage test
Waiting for USB Filesystem
USB Filesystem ready
Writing buffer in DTCM to USBHost Mass Storage . . .
took 9250 uSeconds
Writing buffer in DMAMEM to USBHost Mass Storage . . .
took 7375 uSeconds
Writing buffer in EXTMEM to USBHost Mass Storage . . .
Note that there is no time for the write from EXTMEM and the program hangs---but does not crash.
Here's the minimalist code to show the issue:
C++:
// Minimalist demo to demonstrate problem in
// USB Host Mass storage writing. Files don't write to
// thumb drive if source data is in EXTMEM.
// Compiled with TeensyDuino 1.58 and Arduino IDE 2.0.4
// M. Borgerson 11/23/2023
#include "SD.h"
#include <USBHost_t36.h>
#include "TimeLib.h"
USBHost myusb;
USBHub hub1(myusb);
// For now, use a file on a USB Thumb drive and the Mass Storage Driver
// in place of USB Camera, in the hope that a VGA frame from the camera
// will transfer at least as fast as a file from the thumb drive.
USBDrive mbDrive1(myusb);
USBFilesystem usbFS(myusb);
#define BUFFSIZE 131072 // 128KB buffer
uint8_t DTBuffer[BUFFSIZE]; // no specifier--ends up in DTCM
uint8_t DMBuffer[BUFFSIZE] DMAMEM;
uint8_t EXBuffer[BUFFSIZE] EXTMEM;
const int pinLED = 5;
#define LEDON digitalWriteFast(pinLED, HIGH);
#define LEDOFF digitalWriteFast(pinLED, LOW);
#define LEDTOGGLE digitalToggleFast(pinLED);
void setup() {
// Wait for USB Serial
// while (!Serial) {
// yield();
// }
delay(1000);
int32_t wtime;
pinMode(pinLED, OUTPUT);
Serial.println("\n\nUSB Mass storage test");
if (CrashReport) {
Serial.print(CrashReport);
Serial.println("Press any key to continue");
while (Serial.read() != -1)
;
while (Serial.read() == -1)
;
}
memset(DTBuffer,0xDD, BUFFSIZE);
memset(DMBuffer,0xDE, BUFFSIZE);
memset(EXBuffer,0xDF, BUFFSIZE);
// Start USBHost_t36, HUB(s) and USB devices.
myusb.begin();
Serial.println("Waiting for USB Filesystem");
while (!usbFS) {
myusb.Task();
}
Serial.println("USB Filesystem ready");
Serial.println("Writing buffer in DTCM to USBHost Mass Storage . . .");
wtime = USBWrite(&DTBuffer[0], sizeof(DTBuffer));
Serial.printf(" took %ld uSeconds\n",wtime);
delay(10); myusb.Task();
Serial.println("Writing buffer in DMAMEM to USBHost Mass Storage . . .");
wtime = USBWrite(&DMBuffer[0], sizeof(DMBuffer)); // !!! Sometimes it works !!!
Serial.printf(" took %ld uSeconds\n",wtime);
delay(10); myusb.Task();
Serial.println("Writing buffer in EXTMEM to USBHost Mass Storage . . . ");
wtime = USBWrite(&EXBuffer[0], sizeof(EXBuffer)); // !!!! Doesn't finish !!!!
Serial.printf(" took %ld uSeconds\n",wtime);
}
void loop() {
myusb.Task();
}
// Write Buffer to USB file, keeping track of timing
int32_t USBWrite(uint8_t *bptr, uint32_t buffsize) {
elapsedMicros utotal;
uint32_t totaltime;
File testFile;
if(usbFS.exists("testfile.dat")) usbFS.remove("testFile.dat");
testFile = usbFS.open("testfile.dat", FILE_WRITE);
if (testFile) { // If file is open, do the test
utotal = 0;
testFile.write(bptr, buffsize);
totaltime = utotal;
testFile.close();
} else {
Serial.println("Could not open testFile!");
totaltime = -1;
}
return totaltime;
}
and here's the output:
USB Mass storage test
Waiting for USB Filesystem
USB Filesystem ready
Writing buffer in DTCM to USBHost Mass Storage . . .
took 9250 uSeconds
Writing buffer in DMAMEM to USBHost Mass Storage . . .
took 7375 uSeconds
Writing buffer in EXTMEM to USBHost Mass Storage . . .
Note that there is no time for the write from EXTMEM and the program hangs---but does not crash.