Done for now - Got Twin Drives Hacked in and working!!!!
Duplicated setup code for msDrive 1 and 2 in loop() - and pass ptr to msc1 or msc2 to the func( UsbFs *myMsc )'s that need it ( mbrDump and volLabel()'s )
>> Did this because I like my powered HUB with enclosed HDD ( used DigiStump USB power cut dongle to prevent Teensy powered back from Hub )
> Mounts TWO drives and gets proper partition tables and works with Device#1:HDD and any one of 3 flash drives plugged into it
> Fails to decipher the Fat16 first part on 2nd drive - as it does when it is the first drive on other hub - HexDump commented below
> Doing Press Any Key finds first ExFat HDD ( with volume label ) - but HANGS as before/above when it hits : "Initialize USB drive 2..." - SHOW_CLOCK_CARAT commented below
- > second ExFat never gets right Volume Label ???
> added \tab formatting to partition table with 'default' case showing the "pt_#0:" when unknown - in this case zero
> I have new empty SD card in shop - will get that next time - all the ones on my desk are lost or have TONS of data on - in these tests to date : Not Present
Code:
Waiting up to 5 seconds for USB drive 1
Waiting up to 5 seconds for USB drive 2
Initialize USB drive...USB drive 1 is present.
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
exFAT: 1,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,2048,234436608
pt_#0: 2,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 3,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
Fat Type: ExFat
Volume Name: 120GB_Ext
2020-01-23 17:04 32768000 A_00001.dat
2020-01-23 17:04 32768000 A_00002.dat
2020-01-23 17:04 32768000 A_00003.dat
2020-01-23 17:04 32768000 A_00004.dat
2020-01-23 17:04 32768000 A_00005.dat
2020-01-23 17:04 32768000 A_00006.dat
0 A_00007.dat
No or Not Supported Partition
No or Not Supported Partition
No or Not Supported Partition
Initialize USB drive 2...
Check USB drive format.
initialization failed.
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
FAT16: 1,0,0x20,0x21,0x0,0xE,0xE8,0x27,0x1,2048,28672
exFAT: 2,0,0xA,0x9,0x2,0x7,0xFE,0xFF,0xFF,32768,242450176
pt_#0: 3,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
Fat Type: Fat16
FAT first sector:(800)
Volume Name: NO NAME
Fat Type: ExFat
Volume Name:
2021-02-24 18:40 34 ExFat.txt
2021-02-24 18:41 131072 ExFatFldr/
2021-02-24 18:40 34 Folder_ExFat.txt
No or Not Supported Partition
No or Not Supported Partition
Initialize SD card...initialization failed.
done...
Press any key to run again
This Code also working (on HDD HUB) with the 16GB Write protected Flash - even on Power up (or Reset) and Press Any Key with the HUB's 120GB ExFat also working. - { this is the WP_Flash that HANGS when powered up connected )
This Code also working (on HDD HUB) with the 64GB Flash with TWO FAT32 partitions ( and hundreds of pages of FILE data on first RECOVERY partition) - even on Power up (or Reset) and Press Any Key with the HUB's 120GB ExFat also working.
Here is the code as I have it :
Code:
// VolumeName.ino
// An example of how to retrieve Fat32 and ExFat volume names using SdFat.
// Works with SD cards and USB mass storage drives.
#include "Arduino.h"
#include "mscFS.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);
//#define SHOW_CLOCK_CARAT 1
IntervalTimer clocked100ms;
volatile int32_t cmsReport = -1;
// 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.
msController msDrive1(myusb);
msController msDrive2(myusb);
#define sdDrive 1
#define msDrive 2
#define SD_CONFIG SdioConfig(FIFO_SDIO)
// set up variables using the mscFS utility library functions:
UsbFs msc1;
UsbFs msc2;
SdFs sd;
//FatVolume partVol;
//create holding array for partions
uint8_t partitionTable[4];
int32_t dataStart[4];
// Get ExFat volume name.
bool getExFatVolumeLabel(uint8_t drvType, uint8_t part, UsbFs *myMsc) {
uint8_t buf[32];
UsbExFat volName;
SdExFat volName1;
ExFatFile root;
//msController *mscDrive;
DirLabel_t *dir;
ExFatVolume expartVol;
if (drvType == msDrive) {
//mscDrive = &msDrive1;
//if (!volName.begin(&msDrive1)) {
// Serial.println("EXFat volName.begin failed");
// return false;
// }
expartVol.begin(myMsc->usbDrive(), true, part);
expartVol.chvol();
if (!root.openRoot(&expartVol)) {
Serial.println("openRoot failed");
return false;
}
}
if (drvType == sdDrive) {
if (!volName1.begin(SD_CONFIG)) {
return false;
}
if (!root.openRoot(&volName1)) {
Serial.println("openRoot failed");
return false;
}
}
root.read(buf, 32);
dir = reinterpret_cast<DirLabel_t*>(buf);
Serial.print(F("Volume Name: "));
for (size_t i = 0; i < dir->labelLength; i++) {
Serial.write(dir->unicode[2 * i]);
}
Serial.println();
expartVol.ls(LS_SIZE | LS_DATE | LS_R);
return true;
}
// Get Fat32 volume name.
bool getFat32VolumeLabel(uint8_t drvType, uint8_t part, UsbFs *myMsc) {
FatVolume partVol;
uint8_t buf[512];
partVol.begin(myMsc->usbDrive(), true, part);
partVol.chvol();
if (drvType == msDrive) {
myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
}
if (drvType == sdDrive) {
sd.card()->readSector(sd.dataStartSector(), buf);
}
Serial.print(F("Volume Name: "));
for (size_t i = 0; i < 11; i++) {
if ( buf[i] > 0 && buf[i] < 127 )
Serial.write(buf[i]);
}
Serial.println();
partVol.ls(LS_SIZE | LS_DATE | LS_R);
return true;
}
// Get Fat16 volume name.
bool getFat16VolumeLabel(uint8_t drvType, uint8_t part, UsbFs *myMsc) {
FatVolume partVol;
MbrSector_t mbr;
uint8_t buf[512];
partVol.begin(myMsc->usbDrive(), true, part);
partVol.chvol();
if (drvType == msDrive) {
// lets read in the Master boot record...
myMsc->usbDrive()->readSector(0, (uint8_t*)&mbr);
MbrPart_t *pt = &mbr.part[part - 1];
uint32_t starting_sector = getLe32(pt->relativeSectors);
myMsc->usbDrive()->readSector(starting_sector, buf);
Serial.printf("\nFAT first sector:(%x)\n", starting_sector);
//print_hexbytes(buf, 512);
pbs_t* pbs = (pbs_t*)&buf;
BpbFat16_t *bpt16 = reinterpret_cast<BpbFat16_t*>(pbs->bpb);
Serial.print(F("Volume Name: "));
for (size_t i = 0; i < 11; i++) {
Serial.write(bpt16->volumeLabel[i]);
}
}
if (drvType == sdDrive) {
sd.card()->readSector(sd.dataStartSector(), buf);
print_hexbytes(buf, 512);
Serial.print(F("Volume Name: "));
for (size_t i = 0; i < 11; i++) {
if ( buf[i] > 0 && buf[i] < 127 )
Serial.write(buf[i]);
}
}
Serial.println();
partVol.ls(LS_SIZE | LS_DATE | LS_R);
return true;
}
bool mbrDmp(UsbFs *myMsc) {
MbrSector_t mbr;
// bool valid = true;
if (!myMsc->usbDrive()->readSector(0, (uint8_t*)&mbr)) {
Serial.print("\nread MBR failed.\n");
//errorPrint();
return false;
}
Serial.print("\nmsc # Partition Table\n");
Serial.print("\tpart,boot,bgnCHS[3],type,endCHS[3],start,length\n");
for (uint8_t ip = 1; ip < 5; ip++) {
MbrPart_t *pt = &mbr.part[ip - 1];
// if ((pt->boot != 0 && pt->boot != 0X80) ||
// getLe32(pt->relativeSectors) > sdCardCapacity(&m_csd)) {
// valid = false;
// }
switch (pt->type) {
case 4:
case 6:
case 0xe:
Serial.print("FAT16:\t");
break;
case 11:
case 12:
Serial.print("FAT32:\t");
break;
case 7:
Serial.print("exFAT:\t");
break;
default:
Serial.print("pt_#");
Serial.print(pt->type);
Serial.print(":\t");
break;
}
partitionTable[ip - 1] = pt->type;
dataStart[ip - 1] = getLe32(pt->relativeSectors);
Serial.print( int(ip)); Serial.print( ',');
Serial.print(int(pt->boot), HEX); Serial.print( ',');
for (int i = 0; i < 3; i++ ) {
Serial.print("0x"); Serial.print(int(pt->beginCHS[i]), HEX); Serial.print( ',');
}
Serial.print("0x"); Serial.print(int(pt->type), HEX); Serial.print( ',');
for (int i = 0; i < 3; i++ ) {
Serial.print("0x"); Serial.print(int(pt->endCHS[i]), HEX); Serial.print( ',');
}
Serial.print(getLe32(pt->relativeSectors), DEC); Serial.print(',');
Serial.println(getLe32(pt->totalSectors));
}
return true;
}
void setup()
{
#if 0 // easy test to check HardFault Detection response
int *pp = 0;
*pp = 5;
#endif
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
SysCall::yield(); // wait for serial port to connect.
}
// Start USBHost_t36, HUB(s) and USB devices.
myusb.begin();
#ifdef SHOW_CLOCK_CARAT
clocked100ms.begin(clock_isr, 100000);
#endif
}
void clock_isr() {
if (cmsReport >= 0 ) {
if (cmsReport > 0 ) {
if (cmsReport < 10 )
Serial.print( "^");
else if ( cmsReport<50 && !(cmsReport % 10) )
Serial.print( "~");
else if ( !(cmsReport % 50) )
Serial.print( ":(");
}
cmsReport++;
}
}
void loop(void) {
//--------------------------------------------------
cmsReport = 0;
myusb.Task();
if (!msDrive1) {
Serial.println("Waiting up to 5 seconds for USB drive 1");
elapsedMillis em = 0;
while (!msDrive1 && (em < 5000) ) myusb.Task();
}
if (!msDrive2) {
Serial.println("Waiting up to 5 seconds for USB drive 2");
elapsedMillis em = 0;
while (!msDrive2 && (em < 5000) ) myusb.Task();
}
if (msDrive1) {
Serial.printf("Initialize USB drive...");
cmsReport = 0;
if (!msc1.begin(&msDrive1)) {
Serial.println("");
msc1.errorPrint(&Serial);
Serial.println("initialization failed.\n");
} else {
Serial.println("USB drive 1 is present.\n");
}
cmsReport = -1;
mbrDmp( &msc1 );
for (uint8_t i = 1; i < 5; i++) {
switch (partitionTable[i - 1]) {
case 11:
case 12:
Serial.printf("\nFat Type: Fat32\n");
if (!getFat32VolumeLabel(msDrive, i, &msc1))
Serial.printf("Failed to get volume label\n");
break;
case 4:
case 6:
case 0xe:
Serial.printf("\nFat Type: Fat16\n");
if (!getFat16VolumeLabel(msDrive, i, &msc1))
Serial.printf("Failed to get volume label\n");
break;
case 7:
Serial.printf("\nFat Type: ExFat\n");
if (!getExFatVolumeLabel(msDrive, i, &msc1))
Serial.printf("Failed to get volume label\n");
break;
default:
Serial.println("No or Not Supported Partition");
}
}
}
if (msDrive2) {
Serial.printf("Initialize USB drive 2...");
cmsReport = 0;
if (!msc2.begin(&msDrive2)) {
Serial.println("");
msc2.errorPrint(&Serial);
Serial.println("initialization failed.\n");
} else {
Serial.println("USB drive 2 is present.\n");
}
cmsReport = -1;
mbrDmp( &msc2 );
for (uint8_t i = 1; i < 5; i++) {
switch (partitionTable[i - 1]) {
case 11:
case 12:
Serial.printf("\nFat Type: Fat32\n");
if (!getFat32VolumeLabel(msDrive, i, &msc2))
Serial.printf("Failed to get volume label\n");
break;
case 4:
case 6:
case 0xe:
Serial.printf("\nFat Type: Fat16\n");
if (!getFat16VolumeLabel(msDrive, i, &msc2))
Serial.printf("Failed to get volume label\n");
break;
case 7:
Serial.printf("\nFat Type: ExFat\n");
if (!getExFatVolumeLabel(msDrive, i, &msc2))
Serial.printf("Failed to get volume label\n");
break;
default:
Serial.println("No or Not Supported Partition");
}
}
}
cmsReport = -1;
//--------------------------------------------------
Serial.printf("\nInitialize SD card...");
if (!sd.begin(SD_CONFIG)) {
Serial.println("initialization failed.\n");
} else {
Serial.println("SD card is present.\n");
if (sd.fatType() == 32) {
Serial.printf("Fat Type: Fat32\n");
if (!getFat32VolumeLabel(sdDrive, 1, &msc2))
Serial.printf("Failed to get volume label\n");
} else {
Serial.printf("Fat Type: ExFAT\n");
if (!getExFatVolumeLabel(sdDrive, 1, &msc2)) {
Serial.printf("Failed to get volume label\n");
}
}
//sd.ls(LS_SIZE | LS_DATE | LS_R);
}
Serial.println("done...");
Serial.println("Press any key to run again");
while (Serial.read() == -1);
while (Serial.read() != -1);
}
void print_hexbytes(const void *ptr, int len)
{
if (ptr == NULL || len <= 0) return;
const uint8_t *p = (const uint8_t *)ptr;
while (len) {
for (uint8_t i = 0; i < 32; i++) {
if (i > len) break;
Serial.printf("%02X ", p[i]);
}
Serial.print(":");
for (uint8_t i = 0; i < 32; i++) {
if (i > len) break;
Serial.printf("%c", ((p[i] >= ' ') && (p[i] <= '~')) ? p[i] : '.');
}
Serial.println();
p += 32;
len -= 32;
}
}
Minor note: The 128GB Flash reformatted with MSC that left 16GB first partition space WAS NOT the Bad Flash drive - That is another untried 64GB disk marked Bad.