Forum Rule: Always post complete source code & details to reproduce any issue!
Page 21 of 22 FirstFirst ... 11 19 20 21 22 LastLast
Results 501 to 525 of 533

Thread: USBHost_t36 USB Mass Storage Driver Experiments

  1. #501
    Senior Member wwatson's Avatar
    Join Date
    Aug 2017
    Posts
    421
    @defragster

    I included T4_PowerButton.h. What else do I need to do to show hard faults if they happen? This is new to me

    Thanks

  2. #502
    Senior Member wwatson's Avatar
    Join Date
    Aug 2017
    Posts
    421
    @defragster

    I figured out how to install it from FrankB's cores. Locked up without info still

  3. #503
    Senior Member wwatson's Avatar
    Join Date
    Aug 2017
    Posts
    421
    @KurtE - Done...

  4. #504
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    @KurtE
    Was just looking over your code snippet so this is a question - it may be buried but I don't see where you are setting up expartVol/partVol .begin for the different partitions and then setting a mscfs based on that?

    EDIT: You may need a modified addfilesystem in MTP where you pass each partition based on type and do the begins accordingly in MTP. Forming idea in head but its giving me a headache.

  5. #505
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    @mjs513 which code fragment... MSC or MTP... So far in MTP I have not converted the main code to try to do anything with partitions, other than so far I am printing them out and I am able to get the first volume ID.

    So far I am not having any luck with anyone actually doing anything with the volume ID. I updated storage class to have the string which I pass off to the data back to the PC along with the name.

    On PC I don't so far see anywhere where it shows up. On Linux I am having issues of dynamically adding volumes and have them show up...

    Still looking. I think Linux still have issues with speed of startup. I think the linux times out after the USB starts that I we don't respond quickly enough probably to the start session or...

    Will play more!

  6. #506
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Just an FYI: I updated the Volume name sketch to also print out the total size and used size sort of plus elapsed time to get them for the different partitions:
    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 SD_DRIVE 1
    #define MS_DRIVE 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 == MS_DRIVE) {
        //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 == SD_DRIVE) {
        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 == MS_DRIVE) {
        myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        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.
    // Get Fat16 volume name.
    bool getFat16VolumeLabel(uint8_t  drvType, uint8_t part, UsbFs *myMsc) {
      FatVolume partVol;
    
      uint8_t buf[512];
    
      partVol.begin(myMsc->usbDrive(), true, part);
      partVol.chvol();
      if (drvType == MS_DRIVE) {
        myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        sd.card()->readSector(sd.dataStartSector(), buf);
        print_hexbytes(buf, 512);
      }
      Serial.print(F("Volume Name: "));
      for (size_t i = 0; i < 11; i++) {
        Serial.write(buf[i]);
      }
      Serial.println();
      partVol.ls(LS_SIZE | LS_DATE | LS_R);
    
      return true;
    }
    
    
    bool getUSBPartitionVolumeLabel(UsbFs *myMsc, uint8_t part, uint8_t *pszVolName, uint16_t cb) {
      MbrSector_t mbr;
      uint8_t buf[512];
      if (!pszVolName || (cb < 12)) return false; // don't want to deal with it
      myMsc->usbDrive()->readSector(0, (uint8_t*)&mbr);
      MbrPart_t *pt = &mbr.part[part - 1];
      switch (pt->type) {
        case 4:
        case 6:
        case 0xe:
          {
            FatVolume partVol;
            Serial.print("FAT16:\t");
    
            partVol.begin(myMsc->usbDrive(), true, part);
            partVol.chvol();
            myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
    
            size_t i;
            for (i = 0; i < 11; i++) {
              pszVolName[i]  = buf[i];
            }
            while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
            pszVolName[i] = 0;
          }
          break;
        case 11:
        case 12:
          {
            FatVolume partVol;
            Serial.print("FAT32:\t");
            partVol.begin(myMsc->usbDrive(), true, part);
            partVol.chvol();
            myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
    
            size_t i;
            for (i = 0; i < 11; i++) {
              pszVolName[i]  = buf[i];
            }
            while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
            pszVolName[i] = 0;
          }
          break;
        case 7:
          {
            Serial.print("exFAT:\t");
            ExFatFile root;
            DirLabel_t *dir;
    
            ExFatVolume expartVol;
    
            expartVol.begin(myMsc->usbDrive(), true, part);
            expartVol.chvol();
            if (!root.openRoot(&expartVol)) {
              Serial.println("openRoot failed");
              return false;
            }
            root.read(buf, 32);
            dir = reinterpret_cast<DirLabel_t*>(buf);
    
            size_t i;
            for (i = 0; i < dir->labelLength; i++) {
              pszVolName[i] = dir->unicode[2 * i];
            }
            pszVolName[i] = 0;
          }
    
          break;
        default:
          return false;
      }
      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 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;
      }
    }
    
    
    
    // Function to handle one MS Drive...
    void procesMSDrive(uint8_t drive_number, msController &msDrive, UsbFs &msc)
    {
      Serial.printf("Initialize USB drive...");
      cmsReport = 0;
      if (!msc.begin(&msDrive)) {
        Serial.println("");
        msc.errorPrint(&Serial);
        Serial.printf("initialization drive %u failed.\n", drive_number);
      } else {
        Serial.printf("USB drive %u is present.\n", drive_number);
      }
      cmsReport = -1;
    
      mbrDmp( &msc );
      for (uint8_t i = 1; i < 5; i++) {
    
        switch (partitionTable[i - 1]) {
          case 11:
          case 12:
            Serial.printf("\nFat Type: Fat32\n");
            if (!getFat32VolumeLabel(MS_DRIVE, i, &msc))
              Serial.printf("Failed to get volume label\n");
            break;
          case 4:
          case 6:
          case 0xe:
            Serial.printf("\nFat Type: Fat16\n");
            if (!getFat16VolumeLabel(MS_DRIVE, i, &msc))
              Serial.printf("Failed to get volume label\n");
            break;
          case 7:
            Serial.printf("\nFat Type: ExFat\n");
            if (!getExFatVolumeLabel(MS_DRIVE, i, &msc))
              Serial.printf("Failed to get volume label\n");
            break;
          default:
            Serial.println("No or Not Supported Partition");
        }
        // lets see if our all in one works
        uint8_t volName[32];
        Serial.println("Try calling getUSBPartitionVolumeLabel");
        if (getUSBPartitionVolumeLabel(&msc, i, volName, sizeof(volName))) {
          Serial.printf(">> Volume name:(%s)\n", volName);
        }
        elapsedMicros em_sizes = 0;
        uint64_t used_size =  (uint64_t)(msc.clusterCount() - msc.freeClusterCount())
                              * (uint64_t)msc.bytesPerCluster();
        uint64_t total_size = (uint64_t)msc.clusterCount() * (uint64_t)msc.bytesPerCluster();
        Serial.printf("Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                      (uint32_t)em_sizes);
      }
    }
    
    //================================================================
    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) {
        procesMSDrive(1, msDrive1, msc1);
      }
      if (msDrive2) {
        procesMSDrive(2, msDrive2, msc2);
      }
      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(SD_DRIVE, 1, &msc2))
            Serial.printf("Failed to get volume label\n");
        } else {
          Serial.printf("Fat Type: ExFAT\n");
          if (!getExFatVolumeLabel(SD_DRIVE, 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);
    }
    Output with two SD cards one with 3 partitions:
    Code:
    Waiting up to 5 seconds for USB drive 1
    Waiting up to 5 seconds for USB drive 2
    Initialize USB drive...FsVolume::begin(20001fe0)
    ExFatPartition::init(20001fe0, 1)
    FatPartition::init(20001fe0, 1)
    USB drive 1 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT16:	1,0,0x3,0x37,0x0,0xE,0xFE,0x3F,0x7C,243,2013741
    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: Fat16
    FatPartition::init(20001fe0, 1)
    Volume Name: CRUZER     
                         393481 T4.1-Cardlike.jpg
                        3355221 DSC03356.JPG
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(20001fe0, 1)
    >> Volume name:(CRUZER)
    Total Size:1030750208 Used:3817472 time us: 95999
    No or Not Supported Partition
    Try calling getUSBPartitionVolumeLabel
    Total Size:1030750208 Used:3817472 time us: 95501
    No or Not Supported Partition
    Try calling getUSBPartitionVolumeLabel
    Total Size:1030750208 Used:3817472 time us: 96001
    No or Not Supported Partition
    Try calling getUSBPartitionVolumeLabel
    Total Size:1030750208 Used:3817472 time us: 95751
    Initialize USB drive...FsVolume::begin(2000247c)
    ExFatPartition::init(2000247c, 1)
    FatPartition::init(2000247c, 1)
    USB drive 2 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
    FAT16:	2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
    exFAT:	3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
    pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
    
    Fat Type: Fat32
    FatPartition::init(2000247c, 1)
    Volume Name: VOLFAT32   
    2010-03-22 07:11    3343737 DSC03357.JPG
    2021-01-01 00:00          0 example.txt
    2021-02-24 16:35          0 OnFat32.txt
    Try calling getUSBPartitionVolumeLabel
    FAT32:	FatPartition::init(2000247c, 1)
    >> Volume name:(VOLFAT32)
    Total Size:4186095616 Used:3362816 time us: 6018748
    
    Fat Type: Fat16
    FatPartition::init(2000247c, 2)
    Volume Name: VOLFAT16   
    2021-01-13 17:56     340510 T4-Cardlike.jpg
    2021-02-24 16:34          0 OnFat16.txt
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(2000247c, 2)
    >> Volume name:(VOLFAT16)
    Total Size:4186095616 Used:3362816 time us: 6020248
    
    Fat Type: ExFat
    ExFatPartition::init(2000247c, 3)
    Volume Name: VolEXFAT
    2021-01-24 06:23       393481 T4.1-Cardlike.jpg
    2021-02-24 16:35            0 OnExFat.txt
    Try calling getUSBPartitionVolumeLabel
    exFAT:	ExFatPartition::init(2000247c, 3)
    >> Volume name:(VolEXFAT)
    Total Size:4186095616 Used:3362816 time us: 6019873
    No or Not Supported Partition
    Try calling getUSBPartitionVolumeLabel
    Total Size:4186095616 Used:3362816 time us: 6020500
    
    Initialize SD card...initialization failed.
    
    done...
    Press any key to run again
    Or the interesting stuff:
    Code:
    >> Volume name:(CRUZER)
    Total Size:1030750208 Used:3817472 time us: 95999
    
    
    >> Volume name:(VOLFAT32)
    Total Size:4186095616 Used:3362816 time us: 6018748
    >> Volume name:(VOLFAT16)
    Total Size:4186095616 Used:3362816 time us: 6020248
    >> Volume name:(VolEXFAT)
    Total Size:4186095616 Used:3362816 time us: 6019873
    It is interesting that the one smaller CRUZER didk took about .1 seconds.

    And the larger one with three partitions, each one took over 6 seconds...

    Wonder why? Or if it takes that long on other OS?

    WIll play more tomorrow.

  7. #507
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,706
    Quote Originally Posted by wwatson View Post
    @defragster

    I figured out how to install it from FrankB's cores. Locked up without info still
    Glad you got it - there is an #if 0 in setup that will quickly confirm Faults are trapped as configured.

    Locked up? Does it do the CARAT printing from timer with "#define SHOW_CLOCK_CARAT 1"? If not then it is locked up and not faulting.

    @KurtE - you leap frogged some minor edits - merged below. With your changes I see this:
    Code:
    ...
    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
    
    USB 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
    Try calling getUSBPartitionVolumeLabel
    exFAT:	>> Volume name:(120GB_Ext)
    Total Size:120026300416 Used:197394432 time us: 84001
    0 is No or Not Supported USB Partition
    Total Size:120026300416 Used:197394432 time us: 83990
    0 is No or Not Supported USB Partition
    Total Size:120026300416 Used:197394432 time us: 83990
    0 is No or Not Supported USB Partition
    Total Size:120026300416 Used:197394432 time us: 83990
    Initialize USB drive...^^^^USB drive 2 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,80,0x20,0x21,0x0,0xC,0xFE,0xFF,0xFF,2048,67108864
    FAT32:	2,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,67110912,54128640
    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
    
    USB Fat Type: Fat32
    Volume Name: B Info
    ...
    Try calling getUSBPartitionVolumeLabel
    FAT32:	>> Volume name:(B )
    Total Size:34347155456 Used:28836429824 time us: 3071498
    
    USB Fat Type: Fat32
    Volume Name: 64G_PT#2   
    2021-02-24 09:01          0 FPartTwo.txt
    Try calling getUSBPartitionVolumeLabel
    FAT32:	>> Volume name:(64G_PT#2)
    Total Size:34347155456 Used:28836429824 time us: 3071623
    0 is No or Not Supported USB Partition
    Total Size:34347155456 Used:28836429824 time us: 3071489
    0 is No or Not Supported USB Partition
    Total Size:34347155456 Used:28836429824 time us: 3071489
    ...
    Current code - Merged:
    Code:
    //  VolumeName.ino
    // VER: P494, p498, p506, p507
    //  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 SD_DRIVE 1
    #define MS_DRIVE 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 == MS_DRIVE) {
        //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 == SD_DRIVE) {
        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];
    
      if (drvType == MS_DRIVE) {
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        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.
    // Get Fat16 volume name.
    bool getFat16VolumeLabel(uint8_t  drvType, uint8_t part, UsbFs *myMsc) {
      FatVolume partVol;
    
      uint8_t buf[512];
    
      if (drvType == MS_DRIVE) {
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        sd.card()->readSector(sd.dataStartSector(), buf);
        print_hexbytes(buf, 512);
      }
      Serial.print(F("Volume Name: "));
      for (size_t i = 0; i < 11; i++) {
        Serial.write(buf[i]);
      }
      Serial.println();
      partVol.ls(LS_SIZE | LS_DATE | LS_R);
    
      return true;
    }
    
    
    bool getUSBPartitionVolumeLabel(UsbFs *myMsc, uint8_t part, uint8_t *pszVolName, uint16_t cb) {
      MbrSector_t mbr;
      uint8_t buf[512];
      if (!pszVolName || (cb < 12)) return false; // don't want to deal with it
      myMsc->usbDrive()->readSector(0, (uint8_t*)&mbr);
      MbrPart_t *pt = &mbr.part[part - 1];
      switch (pt->type) {
      case 4:
      case 6:
      case 0xe:
      {
        FatVolume partVol;
        Serial.print("FAT16:\t");
    
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
    
        size_t i;
        for (i = 0; i < 11; i++) {
          pszVolName[i]  = buf[i];
        }
        while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
        pszVolName[i] = 0;
      }
      break;
      case 11:
      case 12:
      {
        FatVolume partVol;
        Serial.print("FAT32:\t");
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
    
        size_t i;
        for (i = 0; i < 11; i++) {
          pszVolName[i]  = buf[i];
        }
        while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
        pszVolName[i] = 0;
      }
      break;
      case 7:
      {
        Serial.print("exFAT:\t");
        ExFatFile root;
        DirLabel_t *dir;
    
        ExFatVolume expartVol;
    
        expartVol.begin(myMsc->usbDrive(), true, part);
        expartVol.chvol();
        if (!root.openRoot(&expartVol)) {
          Serial.println("openRoot failed");
          return false;
        }
        root.read(buf, 32);
        dir = reinterpret_cast<DirLabel_t*>(buf);
    
        size_t i;
        for (i = 0; i < dir->labelLength; i++) {
          pszVolName[i] = dir->unicode[2 * i];
        }
        pszVolName[i] = 0;
      }
    
      break;
      default:
        return false;
      }
      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 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;
      }
    }
    
    
    
    // Function to handle one MS Drive...
    void procesMSDrive(uint8_t drive_number, msController &msDrive, UsbFs &msc)
    {
      Serial.printf("Initialize USB drive...");
      cmsReport = 0;
      if (!msc.begin(&msDrive)) {
        Serial.println("");
        msc.errorPrint(&Serial);
        Serial.printf("initialization drive %u failed.\n", drive_number);
      } else {
        Serial.printf("USB drive %u is present.\n", drive_number);
      }
      cmsReport = -1;
    
      mbrDmp( &msc );
      for (uint8_t i = 1; i < 5; i++) {
    
        switch (partitionTable[i - 1]) {
        case 11:
        case 12:
          Serial.printf("\nUSB Fat Type: Fat32\n");
          if (!getFat32VolumeLabel(MS_DRIVE, i, &msc))
            Serial.printf("Failed to get volume label\n");
          break;
        case 4:
        case 6:
        case 0xe:
          Serial.printf("\nUSB Fat Type: Fat16\n");
          if (!getFat16VolumeLabel(MS_DRIVE, i, &msc))
            Serial.printf("Failed to get volume label\n");
          break;
        case 7:
          Serial.printf("\nUSB Fat Type: ExFat\n");
          if (!getExFatVolumeLabel(MS_DRIVE, i, &msc))
            Serial.printf("Failed to get volume label\n");
          break;
        default:
          Serial.print( partitionTable[i - 1] );
          Serial.println(" is No or Not Supported USB Partition");
        }
        // lets see if our all in one works
        uint8_t volName[32];
        if ( 0 != partitionTable[i - 1] ) {
          Serial.println("Try calling getUSBPartitionVolumeLabel");
          if (getUSBPartitionVolumeLabel(&msc, i, volName, sizeof(volName))) {
            Serial.printf(">> Volume name:(%s)\n", volName);
          }
        }
        elapsedMicros em_sizes = 0;
        uint64_t used_size =  (uint64_t)(msc.clusterCount() - msc.freeClusterCount())
                              * (uint64_t)msc.bytesPerCluster();
        uint64_t total_size = (uint64_t)msc.clusterCount() * (uint64_t)msc.bytesPerCluster();
        Serial.printf("Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                      (uint32_t)em_sizes);
      }
    }
    
    //================================================================
    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) {
        procesMSDrive(1, msDrive1, msc1);
      }
      if (msDrive2) {
        procesMSDrive(2, msDrive2, msc2);
      }
      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("SD Fat Type: Fat32\n");
          if (!getFat32VolumeLabel(SD_DRIVE, 1, nullptr))
            Serial.printf("Failed to get volume label\n");
        } else {
          Serial.printf("SD Fat Type: ExFAT\n");
          if (!getExFatVolumeLabel(SD_DRIVE, 1, nullptr)) {
            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);
    }

  8. #508
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Thanks @defragster,

    I updated to your version.

    I ran again, still real slow on my older thumb drives:
    Code:
    Waiting up to 5 seconds for USB drive 1
    ^^Waiting up to 5 seconds for USB drive 2
    ^^^^Initialize USB drive...^^^^FsVolume::begin(20002000)
    ExFatPartition::init(20002000, 1)
    FatPartition::init(20002000, 1)
    USB drive 1 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT16:	1,0,0x3,0x37,0x0,0xE,0xFE,0x3F,0x7C,243,2013741
    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
    
    USB Fat Type: Fat16
    FatPartition::init(20002000, 1)
    Volume Name: CRUZER     
                         393481 T4.1-Cardlike.jpg
                        3355221 DSC03356.JPG
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(20002000, 1)
    >> Volume name:(CRUZER)
    Total Size:1030750208 Used:3817472 time us: 96749
    0 is No or Not Supported USB Partition
    Total Size:1030750208 Used:3817472 time us: 96116
    0 is No or Not Supported USB Partition
    Total Size:1030750208 Used:3817472 time us: 96241
    0 is No or Not Supported USB Partition
    Total Size:1030750208 Used:3817472 time us: 94741
    Initialize USB drive...^^^^^^^^FsVolume::begin(2000249c)
    ExFatPartition::init(2000249c, 1)
    FatPartition::init(2000249c, 1)
    USB drive 2 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
    FAT16:	2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
    exFAT:	3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
    pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
    
    USB Fat Type: Fat32
    FatPartition::init(2000249c, 1)
    Volume Name: VOLFAT32   
    2010-03-22 07:11    3343737 DSC03357.JPG
    2021-01-01 00:00          0 example.txt
    2021-02-24 16:35          0 OnFat32.txt
    Try calling getUSBPartitionVolumeLabel
    FAT32:	FatPartition::init(2000249c, 1)
    >> Volume name:(VOLFAT32)
    Total Size:4186095616 Used:3362816 time us: 6019373
    
    USB Fat Type: Fat16
    FatPartition::init(2000249c, 2)
    Volume Name: VOLFAT16   
    2021-01-13 17:56     340510 T4-Cardlike.jpg
    2021-02-24 16:34          0 OnFat16.txt
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(2000249c, 2)
    >> Volume name:(VOLFAT16)
    Total Size:4186095616 Used:3362816 time us: 6022123
    
    USB Fat Type: ExFat
    ExFatPartition::init(2000249c, 3)
    Volume Name: VolEXFAT
    2021-01-24 06:23       393481 T4.1-Cardlike.jpg
    2021-02-24 16:35            0 OnExFat.txt
    Try calling getUSBPartitionVolumeLabel
    exFAT:	ExFatPartition::init(2000249c, 3)
    >> Volume name:(VolEXFAT)
    Total Size:4186095616 Used:3362816 time us: 6019873
    0 is No or Not Supported USB Partition
    Total Size:4186095616 Used:3362816 time us: 6018365
    
    Initialize SD card...initialization failed.
    
    done...
    I reran without the older USB Hub and I think it did speed some on these slower drives like:
    Code:
    >> Volume name:(VOLFAT32)
    Total Size:4186095616 Used:3362816 time us: 5897998
    For the heck of it I tried plugging in a portable hard disk (WD My Passport) which is USB3 cable but used USB2... It failed to read in the MBR...
    Code:
    Waiting up to 5 seconds for USB drive 1
    ^^^^^^^^^~~~~Initialize USB drive...^^^^^^^^^~~
    mscError: 0X23
    initialization drive 2 failed.
    
    read MBR failed.
    
    USB Fat Type: Fat32
    FatPartition::init(2000249c, 1)
    Volume Name: 
    Try calling getUSBPartitionVolumeLabel
    Total Size:4186095616 Used:4186099712 time us: 1500000
    First up, wondering why the getting used space is so slow! Wondering how many reads does it need to do?

    Then if can not significantly speed up. May see about adding option to MSC to say load these drives fast, tell the host they have some bogus free/used space and then come back around and see after the host is not asking a lot of questions if I can then go back around and fill in the slow drives data... Probably will take that part up more under the MTP thread.

  9. #509
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    Morning all
    Decided to start playing. Ran @defragster's updated sketch on 3 devices: (1) an old 2GB thumb drive (FAT16 only), (2) a 32GB Sandisk thumb and (3) my HP 120GB SSD.

    One thing I noticed is that the used/totals are for the whole disk not just the partition. Other and obvious one is the times are proportional to the number of items on the disk.

    Code:
    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
    FAT32:	1,0,0x0,0x21,0x0,0xC,0xFE,0xFF,0xFF,32,62530592
    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
    
    USB Fat Type: Fat32
    Volume Name: LOST    DIR
    ...... long list of files 
    
    Try calling getUSBPartitionVolumeLabel
    FAT32:	>> Volume name:(LOST    DIR)
    Total Size:32000016384 Used:10393780224 time us: 9531498
    0 is No or Not Supported USB Partition
    Total Size:32000016384 Used:10393780224 time us: 9532739
    0 is No or Not Supported USB Partition
    Total Size:32000016384 Used:10393780224 time us: 9533114
    0 is No or Not Supported USB Partition
    Total Size:32000016384 Used:10393780224 time us: 9532989
    
    Initialize SD card...initialization failed.
    
    done...
    Press any key to run 
    
    =======================================================
    
    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
    FAT16:	1,80,0x1,0x1,0x0,0xE,0xFE,0x3F,0x79,63,1974208
    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
    
    USB Fat Type: Fat16
    Volume Name: NEW VOLUME 
    2020-11-17 13:56     220021 T4.1-Cardlike0.jpg
    Try calling getUSBPartitionVolumeLabel
    FAT16:	>> Volume name:(NEW VOLUME)
    Total Size:1010515968 Used:278528 time us: 90374
    0 is No or Not Supported USB Partition
    Total Size:1010515968 Used:278528 time us: 119492
    0 is No or Not Supported USB Partition
    Total Size:1010515968 Used:278528 time us: 90367
    0 is No or Not Supported USB Partition
    Total Size:1010515968 Used:278528 time us: 90367
    
    Initialize SD card...initialization failed.
    
    done...
    Press any key to run again
    
    =============================================
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    exFAT:	1,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,2048,204800000
    FAT32:	2,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,204802048,29634560
    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
    
    USB Fat Type: ExFat
    Volume Name: New Volume
    Try calling getUSBPartitionVolumeLabel
    exFAT:	>> Volume name:(New Volume)
    Total Size:104852357120 Used:43811733504 time us: 73499
    
    USB Fat Type: Fat32
    Volume Name: NEW VOLUME 
    2020-12-27 14:47    5725283 VSLAM_and_Navigation_System_of_Unmanned_Ground_Vehicle_Based_on_RGB-D_Camera.pdf
    Try calling getUSBPartitionVolumeLabel
    FAT32:	>> Volume name:(NEW VOLUME)
    Total Size:104852357120 Used:43811733504 time us: 73499
    0 is No or Not Supported USB Partition
    Total Size:104852357120 Used:43811733504 time us: 73489
    0 is No or Not Supported USB Partition
    Total Size:104852357120 Used:43811733504 time us: 73489
    
    Initialize SD card...initialization failed.
    
    done...
    Press any key to run again

  10. #510
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    @KurtE
    Just tried your updated MTP and this is what I am seeing. Look like it works for SSD:
    Code:
    MTP_test
    sd_addFilesystem: 0 20006328 RAM1
    RAM Storage 0 RAM1 199936 512
    sd_addFilesystem: 1 200063f0 RAM2
    RAM Storage 1 RAM2 3999744 4096
    sd_addFilesystem: 2 20006260 PROGM
    Program Storage 0 PROGM 983040 8192
    sd_addFilesystem: 3 20003a68 QSPI
    QSPI Storage 0 QSPI 16777216 8192
    sd_addFilesystem: 4 20003b64 sflash5
    SPIFlash Storage 0 5 sflash5 67108864 8192
    sd_addFilesystem: 5 20003c3c sflash6
    SPIFlash Storage 1 6 sflash6 67108864 8192
    SPIFlash Storage 2 7 prop failed or missing
    sd_addFilesystem: 6 20006e80 WINBOND1G
    Storage 0 3 WINBOND1G 131596288 9175040
    sd_addFilesystem: 7 20006f70 WINBOND2G
    Storage 1 4 WINBOND2G 265289728 9306112
    
    Initializing USB MSC drives...
    
    Setup done
    CMD: 1002(OPEN_SESSION)l: 16 T:0 : 1
    RESP:2001(RSP:OK)l: 16 T:0 : 1
    USB Drive Inserted
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    exFAT:	1,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,2048,204800000
    FAT32:	2,0,0xFE,0xFF,0xFF,0xC,0xFE,0xFF,0xFF,204802048,29634560
    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
    exFAT:	>> USB partition 0 valume ID: New Volume
    sd_addFilesystem: 8 200071b4 MSC0
    new Storage 0 MSC0 104852357120(0) 43811733504(73496)
    *MTPD::send_Event(4004) 9
    *MTPD::send_Event(400b)
    CMD: 1001(GET_DEVICE_INFO)l: 12 T:1
    RESP:2001(RSP:OK)l: 12 T:1
    CMD: 1014(GET_DEVICE_PROP_DESC)l: 16 T:2 : d402
    RESP:2001(RSP:OK)l: 16 T:2 : d402
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:3 : 9
    9 8 name:MSC0 vol:New Volume
    9 8 name:MSC0 vol:New Volume
    RESP:2001(RSP:OK)l: 16 T:3 : 9
    CMD: 1004(GET_STORAGE_IDS)l: 12 T:4
    RESP:2001(RSP:OK)l: 12 T:4
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:5 : 1
    1 0 name:RAM1 vol:
    1 0 name:RAM1 vol:
    RESP:2001(RSP:OK)l: 16 T:5 : 1
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:6 : 2
    2 1 name:RAM2 vol:
    2 1 name:RAM2 vol:
    RESP:2001(RSP:OK)l: 16 T:6 : 2
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:7 : 3
    3 2 name:PROGM vol:
    3 2 name:PROGM vol:
    RESP:2001(RSP:OK)l: 16 T:7 : 3
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:8 : 4
    4 3 name:QSPI vol:
    4 3 name:QSPI vol:
    RESP:2001(RSP:OK)l: 16 T:8 : 4
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:9 : 5
    5 4 name:sflash5 vol:
    5 4 name:sflash5 vol:
    RESP:2001(RSP:OK)l: 16 T:9 : 5
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:a : 6
    6 5 name:sflash6 vol:
    6 5 name:sflash6 vol:
    RESP:2001(RSP:OK)l: 16 T:a : 6
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:b : 7
    7 6 name:WINBOND1G vol:
    7 6 name:WINBOND1G vol:
    RESP:2001(RSP:OK)l: 16 T:b : 7
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:c : 8
    8 7 name:WINBOND2G vol:
    8 7 name:WINBOND2G vol:
    RESP:2001(RSP:OK)l: 16 T:c : 8
    CMD: 9801(GET_OBJECT_PROPS_SUPPORTED)l: 16 T:d : 3000
    RESP:2001(RSP:OK)l: 16 T:d : 3000
    CMD: 9801(GET_OBJECT_PROPS_SUPPORTED)l: 16 T:e : 3001
    RESP:2001(RSP:OK)l: 16 T:e : 3001
    but seems to be timing out if I use a 32GB Sandisk Thumb Drive:
    Code:
    MTP_test
    sd_addFilesystem: 0 20006328 RAM1
    RAM Storage 0 RAM1 199936 512
    sd_addFilesystem: 1 200063f0 RAM2
    RAM Storage 1 RAM2 3999744 4096
    sd_addFilesystem: 2 20006260 PROGM
    Program Storage 0 PROGM 983040 8192
    sd_addFilesystem: 3 20003a68 QSPI
    QSPI Storage 0 QSPI 16777216 8192
    sd_addFilesystem: 4 20003b64 sflash5
    SPIFlash Storage 0 5 sflash5 67108864 8192
    sd_addFilesystem: 5 20003c3c sflash6
    SPIFlash Storage 1 6 sflash6 67108864 8192
    SPIFlash Storage 2 7 prop failed or missing
    sd_addFilesystem: 6 20006e80 WINBOND1G
    Storage 0 3 WINBOND1G 131596288 9175040
    sd_addFilesystem: 7 20006f70 WINBOND2G
    Storage 1 4 WINBOND2G 265289728 9306112
    
    Initializing USB MSC drives...
    
    Setup done
    CMD: 1002(OPEN_SESSION)l: 16 T:0 : 1
    RESP:2001(RSP:OK)l: 16 T:0 : 1
    USB Drive Inserted
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x0,0x21,0x0,0xC,0xFE,0xFF,0xFF,32,62530592
    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
    FAT32:	>> USB partition 0 valume ID: LOST    DIR
    sd_addFilesystem: 8 200071b4 MSC0
    new Storage 0 MSC0 32000016384(0) 10393780224(9532495)
    *MTPD::send_Event(4004) 9
    *MTPD::send_Event(400b)
    CMD: 1001(GET_DEVICE_INFO)l: 12 T:1
    RESP:2001(RSP:OK)l: 12 T:1
    CMD: 1014(GET_DEVICE_PROP_DESC)l: 16 T:2 : d402
    RESP:2001(RSP:OK)l: 16 T:2 : d402
    CMD: 1005(GET_STORAGE_INFO)l: 16 T:3 : 9
    9 8 name:MSC0 vol:LOST    DIR
    9 8 name:MSC0 vol:LOST    DIR
    RESP:2001(RSP:OK)l: 16 T:3 : 9
    In the case of the thumb drive a Win Explorer opens but no devices are shown for the Teensy. In the case of the SSD all devices appear including MSC0.

  11. #511
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Morning,

    Try picking up the latest UsbMSCFat project - I added a hack into it that if you ask for the Used size, twice (or more) it remembers the first call to it, which we do as a debug message at the time we add the drive, but then when windows actually sees the drive list and asks for information, we give them the cached data, which allowed my drives to come up.

    But on Linux, I think the delay at startup (the time it took after the host sees the new device before we respond to a new session request or the like, it times out still...

    Now to maybe look at why the whole disk?

    Edit: looking at your data:
    new Storage 0 MSC0 32000016384(0) 10393780224(9,532,495)
    Slightly edited, it took over 9.5 seconds to compute the free/used data 8)

  12. #512
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    Quote Originally Posted by KurtE View Post
    Morning,

    Try picking up the latest UsbMSCFat project - I added a hack into it that if you ask for the Used size, twice (or more) it remembers the first call to it, which we do as a debug message at the time we add the drive, but then when windows actually sees the drive list and asks for information, we give them the cached data, which allowed my drives to come up.

    But on Linux, I think the delay at startup (the time it took after the host sees the new device before we respond to a new session request or the like, it times out still...

    Now to maybe look at why the whole disk?
    Thanks will pull down the latest changes and give it a go. Not even going to touch linux - having enough problems

  13. #513
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Quick note: I am thinking it might make sense to add the VolumeName.ino as an example sketch to maybe MscFS.h project. That way we can all keep track of it?

    Make sense?

  14. #514
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    @all - Another quick question: while starting to look at why the free space is TAKING SOOOOOOOO LLLLOOONNNGGG

    I noticed in the SDFat code:
    Code:
    //------------------------------------------------------------------------------
    /**
     * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters
     * updated.  This will increase the speed of the freeClusterCount() call
     * after the first call.  Extra flash will be required.
     */
    #define MAINTAIN_FREE_CLUSTER_COUNT 0
    Sort of like, If we turn this on, I don't need the last changes I made to the UsbMSCFat which sort of does a poor subset...

    But again it still would be slow for the first call through...

    Now to see what that call is doing!

  15. #515
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    Quote Originally Posted by KurtE View Post
    @all - Another quick question: while starting to look at why the free space is TAKING SOOOOOOOO LLLLOOONNNGGG

    I noticed in the SDFat code:
    Code:
    //------------------------------------------------------------------------------
    /**
     * Set MAINTAIN_FREE_CLUSTER_COUNT nonzero to keep the count of free clusters
     * updated.  This will increase the speed of the freeClusterCount() call
     * after the first call.  Extra flash will be required.
     */
    #define MAINTAIN_FREE_CLUSTER_COUNT 0
    Sort of like, If we turn this on, I don't need the last changes I made to the UsbMSCFat which sort of does a poor subset...

    But again it still would be slow for the first call through...

    Now to see what that call is doing!
    Very cool = I just gave you last set of chances a try and they worked = both thumb drives came up - even the SD Card.

  16. #516
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    Quote Originally Posted by KurtE View Post
    Quick note: I am thinking it might make sense to add the VolumeName.ino as an example sketch to maybe MscFS.h project. That way we can all keep track of it?

    Make sense?
    Makes absolute sense to me - that sketch is coming in handy for testing.

  17. #517
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Something does not appear to be working correctly at all with the freeClusterCount:

    Code:
    int32_t FatPartition::freeClusterCount() {
    #if MAINTAIN_FREE_CLUSTER_COUNT
      if (m_freeClusterCount >= 0) {
        return m_freeClusterCount;
      }
    #endif  // MAINTAIN_FREE_CLUSTER_COUNT
      uint32_t free = 0;
      uint32_t sector;
      uint32_t todo = m_lastCluster + 1;
      uint16_t n;
    
      if (FAT12_SUPPORT && fatType() == 12) {
        for (unsigned i = 2; i < todo; i++) {
          uint32_t c;
          int8_t fg = fatGet(i, &c);
          if (fg < 0) {
            DBG_FAIL_MACRO;
            goto fail;
          }
          if (fg && c == 0) {
            free++;
          }
        }
      } else if (fatType() == 16 || fatType() == 32) {
        Serial.printf("###FatPartition::freeClusterCount: FT:%u start:%u todo:%u\n", fatType(), m_fatStartSector, todo);
        sector = m_fatStartSector;
        while (todo) {
    ...
    Note: it will read the number todo sectors... I aded the Serial.printf

    I ran with just the one thumb drive with 3 partitions on it, without hub... Extract
    Code:
    Waiting up to 5 seconds for USB drive 1
    ^^Waiting up to 5 seconds for USB drive 2
    ^^^^^^^~~~~:(Initialize USB drive...^^^^^^^^FsVolume::begin(20002040)
    ExFatPartition::init(20002040, 1)
    FatPartition::init(20002040, 1)
    USB drive 1 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
    FAT16:	2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
    exFAT:	3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
    pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
    
    USB Fat Type: Fat32
    FatPartition::init(20002040, 1)
    >> Volume name:(VOLFAT32)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5899873
    
    USB Fat Type: Fat16
    >> Volume name:(VOLFAT16)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5897623
    
    USB Fat Type: ExFat
    >> Volume name:(VolEXFAT)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5899498
    As mentioned it looks like it is reading the whole disk for each one... Now to figure out where those values for the clusters and the like are coming from...

  18. #518
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    @KurtE
    Was toying with something like this for MTP but don;t think I am passing the right things:
    Code:
        uint32_t sd_addFilesystem(FS &fs, const char *name, const char *volumeID) {
          if (fsCount < MTPD_MAX_FILESYSTEMS) {
            sd_name[fsCount] = name;
            sd_volumeID[fsCount] = volumeID;
            sdx[fsCount] = &fs;
            Serial.printf("sd_addFilesystem: %d %x %s\n", fsCount, (uint32_t)&fs, name);
            return fsCount++;
          }
          return 0xFFFFFFFFUL;  // no room left
        }
    	
        uint32_t sd_addUsbFilesystem(FS &fs, const char *name, const char *volumeID, uint16_t part) {
          if (fsCount < MTPD_MAX_FILESYSTEMS) {
            sd_name[fsCount] = name;
            sd_volumeID[fsCount] = volumeID;
            
            Serial.printf("sd_addFilesystem: %d %x %s\n", fsCount, (uint32_t)&fs, name);
    		
      switch (part) {
        case 4:
        case 6:
        case 0xe:
          {
            FatVolume partVol;
            Serial.print("FAT16:\t");
    
            partVol.begin(&fs, true, part);
            //partVol.chvol();
    		sdx[fsCount] = &partVol;
           }
          break;
        case 11:
        case 12:
          {
            FatVolume partVol;
            partVol.begin(&fs true, part);
            //partVol.chvol();
    		sdx[fsCount] = &partVol;
    
          }
          break;
        case 7:
          {
            Serial.print("exFAT:\t");
    
            ExFatVolume expartVol;
    
            expartVol.begin(&fs true, part);
            //expartVol.chvol();
    		sdx[fsCount] = &expartVol;
    
      
          }
          break;
        default:
          //return false;
      }

  19. #519
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    6,730
    Quote Originally Posted by KurtE
    As mentioned it looks like it is reading the whole disk for each one... Now to figure out where those values for the clusters and the like are coming from...
    Maybe using the drive as the pointer instead of the volume so everything in MTP going to associated with the drive not the vol?

  20. #520
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Maybe the code in the sketch is wrong...

    It is not applying the partition... I am going to move those calls into the sections by partition type and see what I get...

    Looks like we crossed posted.

    I am going to hack up the test sketch above first to see if setting the active partition gets us reasonable data or not...

    And if so in MTP should do the same.

    However: I would think that the FS by default should always set the partition 0(1) as active as default?

  21. #521
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    So I tried adding in the above test sketch currently just to the FAT16 and FAT32 section code like:
    Code:
       for (uint8_t i = 1; i < 5; i++) {
    
        switch (partitionTable[i - 1]) {
        case 11:
        case 12:
          {
            Serial.printf("\nUSB Fat Type: Fat32\n");
            if (!getFat32VolumeLabel(MS_DRIVE, i, &msc))
              Serial.printf("Failed to get volume label\n");
              FatVolume partVol;
              partVol.begin(msc.usbDrive(), true, i);
              partVol.chvol();
              elapsedMicros em_sizes = 0;
              uint64_t used_size =  (uint64_t)(partVol.clusterCount() - partVol.freeClusterCount())
                                    * (uint64_t)partVol.bytesPerCluster();
              uint64_t total_size = (uint64_t)partVol.clusterCount() * (uint64_t)partVol.bytesPerCluster();
              Serial.printf("FAT16 Partition Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                            (uint32_t)em_sizes);
    
          }
          break;
        case 4:
        case 6:
        case 0xe:
          {
            Serial.printf("\nUSB Fat Type: Fat16\n");
            if (!getFat16VolumeLabel(MS_DRIVE, i, &msc))
              Serial.printf("Failed to get volume label\n");
    
              FatVolume partVol;
              partVol.begin(msc.usbDrive(), true, i);
              partVol.chvol();
              elapsedMicros em_sizes = 0;
              uint64_t used_size =  (uint64_t)(partVol.clusterCount() - partVol.freeClusterCount())
                                    * (uint64_t)partVol.bytesPerCluster();
              uint64_t total_size = (uint64_t)partVol.clusterCount() * (uint64_t)partVol.bytesPerCluster();
              Serial.printf("FAT32 Partition Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                            (uint32_t)em_sizes);
    
          }
          break;
        case 7:
          Serial.printf("\nUSB Fat Type: ExFat\n");
          if (!getExFatVolumeLabel(MS_DRIVE, i, &msc))
            Serial.printf("Failed to get volume label\n");
          break;
        default:
          Serial.print( partitionTable[i - 1] );
          Serial.println(" is No or Not Supported USB Partition");
          continue; // don't try to get the other stuff here...
        }
    And for the first partition is is running over the same data, but for second partition it helps:
    Code:
    ^^^^~~~~:(Initialize USB drive...^^^^^^^^FsVolume::begin(20002080)
    ExFatPartition::init(20002080, 1)
    FatPartition::init(20002080, 1)
    USB drive 1 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
    FAT16:	2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
    exFAT:	3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
    pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
    
    USB Fat Type: Fat32
    FatPartition::init(20002080, 1)
    Volume Name: VOLFAT32   
    2010-03-22 07:11    3343737 DSC03357.JPG
    2021-01-01 00:00          0 example.txt
    2021-02-24 16:35          0 OnFat32.txt
    FatPartition::init(20002080, 1)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    FAT16 Partition Total Size:4186095616 Used:3362816 time us: 5899625
    Try calling getUSBPartitionVolumeLabel
    FAT32:	FatPartition::init(20002080, 1)
    >> Volume name:(VOLFAT32)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5898498
    
    USB Fat Type: Fat16
    FatPartition::init(20002080, 2)
    Volume Name: VOLFAT16   
    2021-01-13 17:56     340510 T4-Cardlike.jpg
    2021-02-24 16:34          0 OnFat16.txt
    FatPartition::init(20002080, 2)
    ###FatPartition::freeClusterCount: FT:16 start:8194056 todo:65520
    FAT32 Partition Total Size:1073446912 Used:393216 time us: 187501
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(20002080, 2)
    >> Volume name:(VOLFAT16)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5901373
    
    USB Fat Type: ExFat
    ExFatPartition::init(20002080, 3)
    Volume Name: VolEXFAT
    2021-01-24 06:23       393481 T4.1-Cardlike.jpg
    2021-02-24 16:35            0 OnExFat.txt
    Try calling getUSBPartitionVolumeLabel
    exFAT:	ExFatPartition::init(20002080, 3)
    >> Volume name:(VolEXFAT)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    Total Size:4186095616 Used:3362816 time us: 5894748
    0 is No or Not Supported USB Partition
    
    Initialize SD card...FsVolume::begin(200039f0)
    ExFatPartition::init(200039f0, 1)
    SD card is present.
    
    SD Fat Type: ExFAT
    ExFatPartition::init(2006ff94, 1)
    Volume Name: EXFat_Vol
    done...
    Press any key to run again
    So now curious on what the Fat system actually says are the correct counts...

  22. #522
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    Full current sketch, Note I commented out the earlier calls to get sizes...
    Code:
    Waiting up to 5 seconds for USB drive 1
    ^^Waiting up to 5 seconds for USB drive 2
    ^^^^^^^~~~~:(Initialize USB drive...^^^^^^^^FsVolume::begin(20002100)
    ExFatPartition::init(20002100, 1)
    FatPartition::init(20002100, 1)
    USB drive 1 is present.
    
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    FAT32:	1,0,0x4,0x1,0x4,0xB,0xFE,0xC2,0xFF,2048,8192000
    FAT16:	2,0,0xE,0x51,0xFE,0xE,0x98,0x98,0x80,8194048,2097152
    exFAT:	3,0,0x98,0x99,0x80,0x7,0xEE,0xDC,0xD2,10291200,5435392
    pt_#0:	4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
    
    USB Fat Type: Fat32
    FatPartition::init(20002100, 1)
    Volume Name: VOLFAT32   
    2010-03-22 07:11    3343737 DSC03357.JPG
    2021-01-01 00:00          0 example.txt
    2021-02-24 16:35          0 OnFat32.txt
    FatPartition::init(20002100, 1)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
    FAT16 Partition Total Size:4186095616 Used:3362816 time us: 5900875
    Try calling getUSBPartitionVolumeLabel
    FAT32:	FatPartition::init(20002100, 1)
    >> Volume name:(VOLFAT32)
    
    USB Fat Type: Fat16
    FatPartition::init(20002100, 2)
    Volume Name: VOLFAT16   
    2021-01-13 17:56     340510 T4-Cardlike.jpg
    2021-02-24 16:34          0 OnFat16.txt
    FatPartition::init(20002100, 2)
    ###FatPartition::freeClusterCount: FT:16 start:8194056 todo:65520
    FAT32 Partition Total Size:1073446912 Used:393216 time us: 187877
    Try calling getUSBPartitionVolumeLabel
    FAT16:	FatPartition::init(20002100, 2)
    >> Volume name:(VOLFAT16)
    
    USB Fat Type: ExFat
    ExFatPartition::init(20002100, 3)
    Volume Name: VolEXFAT
    2021-01-24 06:23       393481 T4.1-Cardlike.jpg
    2021-02-24 16:35            0 OnExFat.txt
    ExFatPartition::init(20002100, 3)
    ###ExFatPartition::freeClusterCount: FT:10292096 start:84914 cluster count:0
    ExFat Partition Total Size:2782461952 Used:622592 time us: 17004
    Try calling getUSBPartitionVolumeLabel
    exFAT:	ExFatPartition::init(20002100, 3)
    >> Volume name:(VolEXFAT)
    0 is No or Not Supported USB Partition
    
    Initialize SD card...FsVolume::begin(20003a70)
    ExFatPartition::init(20003a70, 1)
    SD card is present.
    
    SD Fat Type: ExFAT
    ExFatPartition::init(2006ff94, 1)
    Volume Name: EXFat_Vol
    done...
    Press any key to run again
    And note output lines like: ###ExFatPartition::freeClusterCount: FT:10292096 start:84914 cluster count:0
    Were from edits of the SDFat library functions... Will play more...
    Code:
    //  VolumeName.ino
    // VER: P494, p498, p506, p507. p522
    //  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 SD_DRIVE 1
    #define MS_DRIVE 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 == MS_DRIVE) {
        //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 == SD_DRIVE) {
        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];
    
      if (drvType == MS_DRIVE) {
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        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.
    // Get Fat16 volume name.
    bool getFat16VolumeLabel(uint8_t  drvType, uint8_t part, UsbFs *myMsc) {
      FatVolume partVol;
    
      uint8_t buf[512];
    
      if (drvType == MS_DRIVE) {
        partVol.begin(myMsc->usbDrive(), true, part);
        partVol.chvol();
        myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
      }
    
      if (drvType == SD_DRIVE) {
        sd.card()->readSector(sd.dataStartSector(), buf);
        print_hexbytes(buf, 512);
      }
      Serial.print(F("Volume Name: "));
      for (size_t i = 0; i < 11; i++) {
        Serial.write(buf[i]);
      }
      Serial.println();
      partVol.ls(LS_SIZE | LS_DATE | LS_R);
    
      return true;
    }
    
    
    bool getUSBPartitionVolumeLabel(UsbFs *myMsc, uint8_t part, uint8_t *pszVolName, uint16_t cb) {
      MbrSector_t mbr;
      uint8_t buf[512];
      if (!pszVolName || (cb < 12)) return false; // don't want to deal with it
      myMsc->usbDrive()->readSector(0, (uint8_t*)&mbr);
      MbrPart_t *pt = &mbr.part[part - 1];
      switch (pt->type) {
        case 4:
        case 6:
        case 0xe:
          {
            FatVolume partVol;
            Serial.print("FAT16:\t");
    
            partVol.begin(myMsc->usbDrive(), true, part);
            partVol.chvol();
            myMsc->usbDrive()->readSector(partVol.rootDirStart(), buf);
    
            size_t i;
            for (i = 0; i < 11; i++) {
              pszVolName[i]  = buf[i];
            }
            while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
            pszVolName[i] = 0;
          }
          break;
        case 11:
        case 12:
          {
            FatVolume partVol;
            Serial.print("FAT32:\t");
            partVol.begin(myMsc->usbDrive(), true, part);
            partVol.chvol();
            myMsc->usbDrive()->readSector(partVol.dataStartSector(), buf);
    
            size_t i;
            for (i = 0; i < 11; i++) {
              pszVolName[i]  = buf[i];
            }
            while ((i > 0) && (pszVolName[i - 1] == ' ')) i--; // trim off trailing blanks
            pszVolName[i] = 0;
          }
          break;
        case 7:
          {
            Serial.print("exFAT:\t");
            ExFatFile root;
            DirLabel_t *dir;
    
            ExFatVolume expartVol;
    
            expartVol.begin(myMsc->usbDrive(), true, part);
            expartVol.chvol();
            if (!root.openRoot(&expartVol)) {
              Serial.println("openRoot failed");
              return false;
            }
            root.read(buf, 32);
            dir = reinterpret_cast<DirLabel_t*>(buf);
    
            size_t i;
            for (i = 0; i < dir->labelLength; i++) {
              pszVolName[i] = dir->unicode[2 * i];
            }
            pszVolName[i] = 0;
          }
    
          break;
        default:
          return false;
      }
      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 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;
      }
    }
    
    
    
    // Function to handle one MS Drive...
    void procesMSDrive(uint8_t drive_number, msController &msDrive, UsbFs &msc)
    {
      Serial.printf("Initialize USB drive...");
      cmsReport = 0;
      if (!msc.begin(&msDrive)) {
        Serial.println("");
        msc.errorPrint(&Serial);
        Serial.printf("initialization drive %u failed.\n", drive_number);
      } else {
        Serial.printf("USB drive %u is present.\n", drive_number);
      }
      cmsReport = -1;
    
      mbrDmp( &msc );
      for (uint8_t i = 1; i < 5; i++) {
    
        switch (partitionTable[i - 1]) {
          case 11:
          case 12:
            {
              Serial.printf("\nUSB Fat Type: Fat32\n");
              if (!getFat32VolumeLabel(MS_DRIVE, i, &msc))
                Serial.printf("Failed to get volume label\n");
              FatVolume partVol;
              partVol.begin(msc.usbDrive(), true, i);
              partVol.chvol();
              elapsedMicros em_sizes = 0;
              uint64_t used_size =  (uint64_t)(partVol.clusterCount() - partVol.freeClusterCount())
                                    * (uint64_t)partVol.bytesPerCluster();
              uint64_t total_size = (uint64_t)partVol.clusterCount() * (uint64_t)partVol.bytesPerCluster();
              Serial.printf("FAT16 Partition Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                            (uint32_t)em_sizes);
            }
            break;
          case 4:
          case 6:
          case 0xe:
            {
              Serial.printf("\nUSB Fat Type: Fat16\n");
              if (!getFat16VolumeLabel(MS_DRIVE, i, &msc))
                Serial.printf("Failed to get volume label\n");
    
              FatVolume partVol;
              partVol.begin(msc.usbDrive(), true, i);
              partVol.chvol();
              elapsedMicros em_sizes = 0;
              uint64_t used_size =  (uint64_t)(partVol.clusterCount() - partVol.freeClusterCount())
                                    * (uint64_t)partVol.bytesPerCluster();
              uint64_t total_size = (uint64_t)partVol.clusterCount() * (uint64_t)partVol.bytesPerCluster();
              Serial.printf("FAT32 Partition Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                            (uint32_t)em_sizes);
    
            }
            break;
          case 7:
            {
              Serial.printf("\nUSB Fat Type: ExFat\n");
              if (!getExFatVolumeLabel(MS_DRIVE, i, &msc))
                Serial.printf("Failed to get volume label\n");
              ExFatVolume partVol;
              partVol.begin(msc.usbDrive(), true, i);
              partVol.chvol();
              elapsedMicros em_sizes = 0;
              uint64_t used_size =  (uint64_t)(partVol.clusterCount() - partVol.freeClusterCount())
                                    * (uint64_t)partVol.bytesPerCluster();
              uint64_t total_size = (uint64_t)partVol.clusterCount() * (uint64_t)partVol.bytesPerCluster();
              Serial.printf("ExFat Partition Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                            (uint32_t)em_sizes);
            }
            break;
          default:
            Serial.print( partitionTable[i - 1] );
            Serial.println(" is No or Not Supported USB Partition");
            continue; // don't try to get the other stuff here...
        }
        // lets see if our all in one works
        uint8_t volName[32];
        if ( 0 != partitionTable[i - 1] ) {
          Serial.println("Try calling getUSBPartitionVolumeLabel");
          if (getUSBPartitionVolumeLabel(&msc, i, volName, sizeof(volName))) {
            Serial.printf(">> Volume name:(%s)\n", volName);
          }
        }
    #if 0
        elapsedMicros em_sizes = 0;
        uint64_t used_size =  (uint64_t)(msc.clusterCount() - msc.freeClusterCount())
                              * (uint64_t)msc.bytesPerCluster();
        uint64_t total_size = (uint64_t)msc.clusterCount() * (uint64_t)msc.bytesPerCluster();
        Serial.printf("Total Size:%llu Used:%llu time us: %u\n", total_size, used_size,
                      (uint32_t)em_sizes);
    #endif
      }
    }
    
    //================================================================
    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) {
        procesMSDrive(1, msDrive1, msc1);
      }
      if (msDrive2) {
        procesMSDrive(2, msDrive2, msc2);
      }
      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("SD Fat Type: Fat32\n");
          if (!getFat32VolumeLabel(SD_DRIVE, 1, nullptr))
            Serial.printf("Failed to get volume label\n");
        } else {
          Serial.printf("SD Fat Type: ExFAT\n");
          if (!getExFatVolumeLabel(SD_DRIVE, 1, nullptr)) {
            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);
    }
    Last edited by defragster; 02-26-2021 at 04:28 PM. Reason: Edited in post VER edit number

  23. #523
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,706
    Just plugged in my 5 TB external - yesterday's code - doesn't matter given the part ID #238:
    Code:
    msc # Partition Table
    	part,boot,bgnCHS[3],type,endCHS[3],start,length
    pt_#238:	1,0,0x0,0x2,0x0,0xEE,0xFF,0xFF,0xFF,1,4294967295
    We could add a set of Known Unknown part ID's

    I have one disk that came up 0us reading the sizes - will run again when up p#520 updates post
    Code here still dislikes Fat16 part it seems?:
    Code:
    Initialize USB drive...^^^^^^^
    Check USB drive format.
    initialization drive 2 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
    
    USB Fat Type: Fat16
    Volume Name: FATVOL16M  
    Try calling getUSBPartitionVolumeLabel
    FAT16:	>> Volume name:(FATVOL16M)
    Total Size:0 Used:0 time us: 0
    
    USB 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
    Try calling getUSBPartitionVolumeLabel
    exFAT:	>> Volume name:()
    Total Size:0 Used:0 time us: 0
    0 is No or Not Supported USB Partition
    Total Size:0 Used:0 time us: 0
    0 is No or Not Supported USB Partition
    Total Size:0 Used:0 time us: 0

  24. #524
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,706
    p#523 crosspost ...

    Windows view of USB Hub Drive >> H: << and Flash drives >> F: and G: << as below:
    Click image for larger version. 

Name:	p524Drives.png 
Views:	8 
Size:	29.0 KB 
ID:	23845

    Here is run on p#522 updated code - now has ExFat drive size:
    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
    
    USB 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
    ExFat Partition Total Size:120026300416 Used:197394432 time us: 83983
    Try calling getUSBPartitionVolumeLabel
    exFAT:	>> Volume name:(120GB_Ext)
    0 is No or Not Supported USB Partition
    0 is No or Not Supported USB Partition
    0 is No or Not Supported USB Partition
    Initialize USB drive...^^^^^^^
    Check USB drive format.
    initialization drive 2 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
    
    USB Fat Type: Fat16
    Volume Name: FATVOL16M  
    FAT32 Partition Total Size:14651392 Used:14655488 time us: 0
    Try calling getUSBPartitionVolumeLabel
    FAT16:	>> Volume name:(FATVOL16M)
    
    USB 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
    ExFat Partition Total Size:124117712896 Used:1179648 time us: 243251
    Try calling getUSBPartitionVolumeLabel
    exFAT:	>> Volume name:()
    0 is No or Not Supported USB Partition
    0 is No or Not Supported USB Partition
    
    Initialize SD card...SD card is present.
    
    SD Fat Type: Fat32
    Volume Name: SD1_8GB_AD 
    done...
    Press any key to run again
    Last edited by defragster; 02-26-2021 at 04:38 PM. Reason: UPDATED with WINDOWS view of drives

  25. #525
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,844
    @defragster and @mjs513 I am sort of curious about fragmentation works

    For the Fat32 volume:
    I mucked up the beginning of the method most all of the class variables
    Code:
    int32_t FatPartition::freeClusterCount() {
    #if MAINTAIN_FREE_CLUSTER_COUNT
      if (m_freeClusterCount >= 0) {
        return m_freeClusterCount;
      }
    #endif  // MAINTAIN_FREE_CLUSTER_COUNT
      uint32_t free = 0;
      uint32_t sector;
      uint32_t todo = m_lastCluster + 1;
      uint16_t n;
    
      if (FAT12_SUPPORT && fatType() == 12) {
        for (unsigned i = 2; i < todo; i++) {
          uint32_t c;
          int8_t fg = fatGet(i, &c);
          if (fg < 0) {
            DBG_FAIL_MACRO;
            goto fail;
          }
          if (fg && c == 0) {
            free++;
          }
        }
      } else if (fatType() == 16 || fatType() == 32) {
        Serial.printf("###FatPartition::freeClusterCount: FT:%u start:%u todo:%u\n", fatType(), m_fatStartSector, todo);
        Serial.printf("    m_sectorsPerCluster:%u\n", m_sectorsPerCluster);
        Serial.printf("    m_clusterSectorMask:%u\n", m_clusterSectorMask);
        Serial.printf("    m_sectorsPerClusterShift:%u\n", m_sectorsPerClusterShift);
        Serial.printf("    m_fatType:%u\n", m_fatType);
        Serial.printf("    m_rootDirEntryCount:%u\n", m_rootDirEntryCount);
        Serial.printf("    m_allocSearchStart:%u\n", m_allocSearchStart);
        Serial.printf("    m_sectorsPerFat:%u\n", m_sectorsPerFat);
        Serial.printf("    m_dataStartSector:%u\n", m_dataStartSector);
        Serial.printf("    m_fatStartSector:%u\n", m_fatStartSector);
        Serial.printf("    m_lastCluster:%u\n", m_lastCluster);
        Serial.printf("    m_rootDirStart:%u\n", m_rootDirStart);
        Serial.printf("    m_bytesPerSector:%u\n", m_bytesPerSector);
        sector = m_fatStartSector;
        while (todo) {
          cache_t* pc = cacheFetchFat(sector++, FsCache::CACHE_FOR_READ);
          if (!pc) {
            DBG_FAIL_MACRO;
            goto fail;
          }
          n =  fatType() == 16 ? m_bytesPerSector/2 : m_bytesPerSector/4;
          if (todo < n) {
            n = todo;
          }
          if (fatType() == 16) {
            for (uint16_t i = 0; i < n; i++) {
              if (pc->fat16[i] == 0) {
                free++;
              }
            }
          } else {
            for (uint16_t i = 0; i < n; i++) {
              if (pc->fat32[i] == 0) {
                free++;
              }
            }
          }
          todo -= n;
        }
      } else {
        // invalid FAT type
        DBG_FAIL_MACRO;
        goto fail;
      }
      setFreeClusterCount(free);
      return free;
    
     fail:
      return -1;
    }
    From the header file:
    Code:
      uint8_t  m_sectorsPerCluster;       // Cluster size in sectors.
      uint8_t  m_clusterSectorMask;       // Mask to extract sector of cluster.
      uint8_t  m_sectorsPerClusterShift;  // Cluster count to sector count shift.
      uint8_t  m_fatType = 0;             // Volume type (12, 16, OR 32).
      uint16_t m_rootDirEntryCount;       // Number of entries in FAT16 root dir.
      uint32_t m_allocSearchStart;        // Start cluster for alloc search.
      uint32_t m_sectorsPerFat;           // FAT size in sectors
      uint32_t m_dataStartSector;         // First data sector number.
      uint32_t m_fatStartSector;          // Start sector for first FAT.
      uint32_t m_lastCluster;             // Last cluster number in FAT.
      uint32_t m_rootDirStart;            // Start sector FAT16, cluster FAT32.
    Some of the Debug output
    Code:
    USB Fat Type: Fat32
    FatPartition::init(20002220, 1)
    Volume Name: VOLFAT32   
    2010-03-22 07:11    3343737 DSC03357.JPG
    2021-01-01 00:00          0 example.txt
    2021-02-24 16:35          0 OnFat32.txt
    FatPartition::init(20002220, 1)
    ###FatPartition::freeClusterCount: FT:32 start:2094 todo:1021998
        m_sectorsPerCluster:8
        m_clusterSectorMask:7
        m_sectorsPerClusterShift:3
        m_fatType:32
        m_rootDirEntryCount:0
        m_allocSearchStart:1
        m_sectorsPerFat:7993
        m_dataStartSector:18080
        m_fatStartSector:2094
        m_lastCluster:1021997
        m_rootDirStart:2
        m_bytesPerSector:512
    FAT16 Partition Total Size:4186095616 Used:3362816 time us: 5896750
    Try calling getUSBPartitionVolumeLabel
    FAT32:	FatPartition::init(20002220, 1)
    >> Volume name:(VOLFAT32)
    
    USB Fat Type: Fat16
    FatPartition::init(20002220, 2)
    Volume Name: VOLFAT16   
    2021-01-13 17:56     340510 T4-Cardlike.jpg
    2021-02-24 16:34          0 OnFat16.txt
    FatPartition::init(20002220, 2)
    ###FatPartition::freeClusterCount: FT:16 start:8194056 todo:65520
        m_sectorsPerCluster:32
        m_clusterSectorMask:31
        m_sectorsPerClusterShift:5
        m_fatType:16
        m_rootDirEntryCount:512
        m_allocSearchStart:1
        m_sectorsPerFat:256
        m_dataStartSector:8194600
        m_fatStartSector:8194056
        m_lastCluster:65519
        m_rootDirStart:8194568
        m_bytesPerSector:512
    FAT32 Partition Total Size:1073446912 Used:393216 time us: 188377
    So if I am reading this correct: in the Fat32 case:
    n = fatType() == 16 ? m_bytesPerSector/2 : m_bytesPerSector/4; So 512/4 = 128 per fat directory...
    SO I think we would read: 1021998/128=7985 Fat sectors?
    So the m_sectorsPerFat:7993 makes sense...

    so 2094+7993 =10087 as last sector...

    So if our read of the FAT took 5896750us and we did about 7990 reads, each read took 738us

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •