Many TLAs: MTP MSC FS SD SDFat LittleFS UsbMSCFat to work with each other 8)

Alright guy's. Will hang tough:)

Thanks.

I hear you, but we are slowly getting the pieces into place and things are coming along. Been having some fun trying to make some simpler to create MTP sketches and include things like detecting when SD card inserted on T4.x... Maybe T35/6 as well... Have not tested in awhile.
Also with external SD readers that have an IO pin for card detection... Still WIP...

Right now trying to figure out why: trying to get the Free space on FAT32 external volume is REAL REAL REAL slow. I know one of the reasons is we have to read in every ... FAT sector and count the bits... But I also through we had option turned on to cache the free after the first time we call it... And that is not working...

In my SD wrap class I enabled the Free Space callback to my code (like we do for MSC drives) so I see what is happening...

Debug Run:
Code:
:\GitHub\MTP_t4\examples\SD_MTP-logger\SD_MTP-logger.ino Sep  1 2021 17:40:06
Initializing SD ...
Date: 1/9/2021 17:41:17
addFSToStorage: Added FS
sd_addFilesystem: 0 200040ac SDIO 20004568 200040ac
Total Size: 66002944 Used Size: 21889024
Trying to open SPI config: 10 255 0 16000000
addFSToStorage: Added FS
sd_addFilesystem: 1 2000458c SPI10 20004a48 2000458c
Total Size: 32014073856 Used Size: 524288
SD initialized.

Menu Options:
	[0-9] - Set Active Storage
	l - List files on disk
	e - Erase files on disk
	s - Start Logging data (Restarting logger will append records to existing log)
	x - Stop Logging data
	d - Dump Log
	h - Menu

CMD: 1002(OPEN_SESSION)l: 16 T:0 : 1
RESP:2001(RSP:OK)l: 16 T:0 : 1
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: 1004(GET_STORAGE_IDS)l: 12 T:3
RESP:2001(RSP:OK)l: 12 T:3
CMD: 1005(GET_STORAGE_INFO)l: 16 T:4 : 10001


}}}}}}}}} SDMTPClass::usedSizeCB called 20004a6c 0 536887468 cs:254 ft:16
2
65537 0 name:SDIO


}}}}}}}}} SDMTPClass::usedSizeCB called 20004a6c 0 536887468 cs:254 ft:16
1
65537 0 name:SDIO
RESP:2001(RSP:OK)l: 16 T:4 : 10001
CMD: 1005(GET_STORAGE_INFO)l: 16 T:5 : 20001


}}}}}}}}} SDMTPClass::usedSizeCB called 20004a6c 1 536888716 cs:10 ft:32
10016
131073 1 name:SPI10


}}}}}}}}} SDMTPClass::usedSizeCB called 20004a6c 1 536888716 cs:10 ft:32
7143
131073 1 name:SPI10
RESP:2001(RSP:OK)l: 16 T:5 : 20001
Two SD drives one is internal the other with CS=10...

When I try to enumerate the top level Teensy Object, the used size is called like 2 or 3 times for each one of these.
The internal small FAT16 one takes like: 1 ms

The larger 32GB Fat32 external drive is taking like: 10 seconds, 7 seconds, 10 seconds... Yes seconds...

So will debug to see why the values are not cached... And/Or may try to do some stuff where I will tell MTP a lie and when it asks for free space... If I suspect it will slow... (Size > X Fat32...) then say 50% free... To see if I can quickly get the drives to work in MTP.

MTP will timeout in many of these cases.
 
@KurtE not sure if this is maintained - certainly not without 'work' ? But is part of the design.

FS Information Sector :: wikipedia.org/wiki/Design_of_the_FAT_file_system
The "FS Information Sector" was introduced in FAT32[42] for speeding up access times of certain operations (in particular, getting the amount of free space). It is located at a logical sector number specified in the FAT32 EBPB boot record at position 0x030 (usually logical sector 1, immediately after the boot record itself).
Code:
Byte offset	____ Length (bytes)	______ Contents
    0x1E8	____ 4	    _____________ Last known number of free data clusters on the volume, or 0xFFFFFFFF if unknown. Should be set to 0xFFFFFFFF during format and updated by the operating system later on. Must not be absolutely relied upon to be correct in all scenarios. Before using this value, the operating system should sanity check this value to be less than or equal to the volume's count of clusters.

So it can be 'cached' and stored On Disk
 
For some reason the TINY partition is FAT16 - not supported?

Cleaned that for fresh use to 18GB FAT32 and 100GB NTFS.

Can't build now as the WIP FS updates have broken the DiskIO build it seems?

As far as I know NTFS is not supported with SdFat only Fat16, Fat32 and EXFat. I never tried using Fat16. Going to wait until things settle and stabilize as per Paul and Mike. There are plenty of other things to work with like speeding up read and writes in MSC. @KurtE has already given clues as how to do this with the msReadSectorsWithCB() method. But still is fun to forget about work and play:)
 
As far as I know NTFS is not supported with SdFat only Fat16, Fat32 and EXFat. I never tried using Fat16. Going to wait until things settle and stabilize as per Paul and Mike. There are plenty of other things to work with like speeding up read and writes in MSC. @KurtE has already given clues as how to do this with the msReadSectorsWithCB() method. But still is fun to forget about work and play:)

Opps - had the list right in front of me ... and let it default to NTFS on PC formatting ... will go back to ExFAT as it SHOULD be

<EDIT>: FIXED for future testing :: 18GB FAT32 and 100GB ExFAT
 
@KurtE not sure if this is maintained - certainly not without 'work' ? But is part of the design.

FS Information Sector :: wikipedia.org/wiki/Design_of_the_FAT_file_system
The "FS Information Sector" was introduced in FAT32[42] for speeding up access times of certain operations (in particular, getting the amount of free space). It is located at a logical sector number specified in the FAT32 EBPB boot record at position 0x030 (usually logical sector 1, immediately after the boot record itself).
Code:
Byte offset	____ Length (bytes)	______ Contents
    0x1E8	____ 4	    _____________ Last known number of free data clusters on the volume, or 0xFFFFFFFF if unknown. Should be set to 0xFFFFFFFF during format and updated by the operating system later on. Must not be absolutely relied upon to be correct in all scenarios. Before using this value, the operating system should sanity check this value to be less than or equal to the volume's count of clusters.

So it can be 'cached' and stored On Disk

Thanks, earlier I was experimenting with at least reading this... Through MSC stuff Also as mentioned, I had/have speed ups in the MSC case to reading in the FAT sectors, by read me in N sectors or the like and call me with each one, such that we can get the data as quickly as possible...

I will probably play with using some of these techniques. in this SD case as well.

However I first want to see why the asking for it multiple times the option in SD Library to keep this data is not...
That issSdFatConfig file has:
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.
 */
#ifdef __arm__
#define MAINTAIN_FREE_CLUSTER_COUNT 1
#else
#define MAINTAIN_FREE_CLUSTER_COUNT 0
#endif
Maybe need to check if I somehow overwrote this?
 
That issSdFatConfig file has:
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.
 */
#ifdef __arm__
#define MAINTAIN_FREE_CLUSTER_COUNT 1
#else
#define MAINTAIN_FREE_CLUSTER_COUNT 0
#endif
Maybe need to check if I somehow overwrote this?
Aargh...

My Sublime project was looking at Arduino1.8.13, but I am using Arduino1.8.15 ... Double Argh!

The default one just has: #define MAINTAIN_FREE_CLUSTER_COUNT 0


@Paul - Again looks like our current version of SDFat(beta) is somewhere between your library version and the current one up at: https://github.com/greiman/SdFat-beta
Yours is 13 commits behind... But the stuff I saw in the build was neither version...

The current one up on greiman

Has stuff in it now like:
Code:
#ifndef MAINTAIN_FREE_CLUSTER_COUNT
#define MAINTAIN_FREE_CLUSTER_COUNT 0
#endif  // MAINTAIN_FREE_CLUSTER_COUNT
I don't see anywhere in this config file where it has something like a __has_include.... to override, so my assumption (and from previous conversations with him), is that he is
expecting overrides to be done things like Makefiles.

Not sure what approach yoi may want to take...

But before I shoot myself in foot again, I think I will some big warning message to building certain files if that option is not set...
 
Aargh...

My Sublime project was looking at Arduino1.8.13, but I am using Arduino1.8.15 ... Double Argh!

...

Opps ... I just started using projects and now having new TD installs ... I was alert and copied the file "Teensy_18.15_154.sublime-project" for beta TD 1.55 and edited the path stored inside so I could open it with: "Teensy_18.15_155.sublime-project"

Now Beta #2 and IDE 1.8.16 pending ...
 
Secondary note in our current sets of code base

I now have in the code:
Code:
#include <SDMTPClass.h>
#include <mscFS.h>

#if defined(MAINTAIN_FREE_CLUSTER_COUNT) && (MAINTAIN_FREE_CLUSTER_COUNT == 0)
#warning "###############################################################"
#warning "# MAINTAIN_FREE_CLUSTER_COUNT is 0 in SdFatConfig.h           #"
#warning "# Large Fat32 SD cards will likely fail to work properly      #"
#warning "###############################################################"
#endif
So hopefully I (and others) wont chase it around again and again and again ...
 
Thanks, earlier I was experimenting with at least reading this... Through MSC stuff Also as mentioned, I had/have speed ups in the MSC case to reading in the FAT sectors, by read me in N sectors or the like and call me with each one, such that we can get the data as quickly as possible...

I will probably play with using some of these techniques. in this SD case as well.

However I first want to see why the asking for it multiple times the option in SD Library to keep this data is not...
That issSdFatConfig file has:
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.
 */
[/QUOTE]

Quick follow up here.  As I mentioned we experimented some with the Information sector. 
The code is in the MSC stuff: UsbMscFat\src\PFsLib\pfsvolume.cpp

[CODE]uint32_t PFsVolume::getFSInfoSectorFreeClusterCount() {
  uint8_t sector_buffer[512];
  if (fatType() != FAT_TYPE_FAT32) return (uint32_t)-1;

  // We could probably avoid this read if our class remembered the starting sector number for the partition...
  if (!m_blockDev->readSector(0, sector_buffer)) return (uint32_t)-1;
  MbrSector_t *mbr = reinterpret_cast<MbrSector_t*>(sector_buffer);
  MbrPart_t *pt = &mbr->part[m_part - 1];
  BpbFat32_t* bpb;
  if ((pt->type != 11) && (pt->type != 12))  return (uint32_t)-1;

  uint32_t volumeStartSector = getLe32(pt->relativeSectors);
  if (!m_blockDev->readSector(volumeStartSector, sector_buffer)) return (uint32_t)-1;
  pbs_t *pbs = reinterpret_cast<pbs_t*> (sector_buffer);
  bpb = reinterpret_cast<BpbFat32_t*>(pbs->bpb);
  
  //Serial.println("\nReadFat32InfoSectorFree BpbFat32_t sector");
  //dump_hexbytes(sector_buffer, 512);
  uint16_t infoSector = getLe16(bpb->fat32FSInfoSector); 

  // I am assuming this sector is based off of the volumeStartSector... So try reading from there.
  //Serial.printf("Try to read Info sector (%u)\n", infoSector); Serial.flush(); 
  if (!m_blockDev->readSector(volumeStartSector+infoSector, sector_buffer)) return (uint32_t)-1;
  //dump_hexbytes(sector_buffer, 512);
  FsInfo_t *pfsi = reinterpret_cast<FsInfo_t*>(sector_buffer);

  // check signatures:
  if (getLe32(pfsi->leadSignature) !=  FSINFO_LEAD_SIGNATURE) Serial.println("Lead Sig wrong");
  if (getLe32(pfsi->structSignature) !=  FSINFO_STRUCT_SIGNATURE) Serial.println("struct Sig wrong");    
  if (getLe32(pfsi->trailSignature) !=  FSINFO_TRAIL_SIGNATURE) Serial.println("Trail Sig wrong");    
  uint32_t free_count = getLe32(pfsi->freeCount);
  return free_count;


}

bool PFsVolume::setUpdateFSInfoSectorFreeClusterCount(uint32_t free_count) {
  uint8_t sector_buffer[512];
  if (fatType() != FAT_TYPE_FAT32) return (uint32_t)false;

  if (free_count == (uint32_t)-1) free_count = freeClusterCount();

  // We could probably avoid this read if our class remembered the starting sector number for the partition...
  if (!m_blockDev->readSector(0, sector_buffer)) return (uint32_t)-1;
  MbrSector_t *mbr = reinterpret_cast<MbrSector_t*>(sector_buffer);
  MbrPart_t *pt = &mbr->part[m_part - 1];
  BpbFat32_t* bpb;
  if ((pt->type != 11) && (pt->type != 12))  return (uint32_t)-1;

  uint32_t volumeStartSector = getLe32(pt->relativeSectors);
  if (!m_blockDev->readSector(volumeStartSector, sector_buffer)) return (uint32_t)-1;
  pbs_t *pbs = reinterpret_cast<pbs_t*> (sector_buffer);
  bpb = reinterpret_cast<BpbFat32_t*>(pbs->bpb);
  
  //Serial.println("\nReadFat32InfoSectorFree BpbFat32_t sector");
  //dump_hexbytes(sector_buffer, 512);
  uint16_t infoSector = getLe16(bpb->fat32FSInfoSector); 

  // OK we now need to fill in the the sector with the appropriate information...
  // Not sure if we should read it first or just blast out new data...
  FsInfo_t *pfsi = reinterpret_cast<FsInfo_t*>(sector_buffer);
  memset(sector_buffer, 0 , 512);

  // write FSINFO sector and backup
  setLe32(pfsi->leadSignature, FSINFO_LEAD_SIGNATURE);
  setLe32(pfsi->structSignature, FSINFO_STRUCT_SIGNATURE);
  setLe32(pfsi->freeCount, free_count);
  setLe32(pfsi->nextFree, 0XFFFFFFFF);
  setLe32(pfsi->trailSignature, FSINFO_TRAIL_SIGNATURE);
  if (!m_blockDev->writeSector(volumeStartSector+infoSector, sector_buffer)) return (uint32_t) false;
  return true;
}

Not sure if we have any place trying to use these currently...
 
@KurtE - I actually was playing with this this weekend before all of the recent updates. On a FAT32 formatted USB or SDIO drive I was getting the delay when using MSCFormatter or the Linux FAT32 formatting. Then I did all of the new updates with TD1.55B2 and no matter what I do including setting '#define MAINTAIN_FREE_CLUSTER_COUNT 0' I cannot duplicate the delay. Probably missing something. Tested with diskIOMB and diskIOTesting which actually would show the delay but now there is no delay, Really confused here:)

Edit: Not sure where all of you are with this but am quietly working a non-blocking 'MassStorageDriver.cpp'. Made some Interesting advancements today. Testing is next:)
 
Thanks will start playing/testing with the MSC stuff soon. I am seeing these issues with SD cards plugged in with SPI. Yes with MSC we played with a few different ways. Will see how hard it will be to try it here as well.

at a minimum will try deferring while the system is enumerating the drives.
 
Thanks will start playing/testing with the MSC stuff soon. I am seeing these issues with SD cards plugged in with SPI. Yes with MSC we played with a few different ways. Will see how hard it will be to try it here as well.

at a minimum will try deferring while the system is enumerating the drives.

Cool - Wait and watch:)

Edit: Help where I can...
 
Last edited:
@KurtE - Nice work on decoupling UsbMscFat:) With basically changing references from msController to msDevice everything seems to work. I have updated DiskIOV2 and it works.

One issue (typo) was found in msDevice.cpp that was causing a compile error:
Code:
#include "MSDevice.h"
needed to be changed to:
Code:
#include "msDevice.h"
.

This makes a good backup for any future eventualities in USBhost_t36.
 
@wwatson / KurtE - Having trouble getting anything to pass compile.
Teensy 4.1
Arduino 1.8.19 Teensyduino 1.56 - All Libraries
First I placed this - https://github.com/wwatson4506/UsbMscFat
in Teensy /avr/libraries. This is what I got when trying to verify/compile CardInfoUSB:

In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\examples\CardInfoUSB\CardInfoUSB.ino:16:0:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h:44:7: error: cannot derive from 'final' base 'File' in derived type 'MSCFile'
class MSCFile : public File
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h: In member function 'virtual File MSCFile::eek:penNextFile(uint8_t)':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h:122:42: error: no matching function for call to 'File::File(MSCFile*)'
if (file) return File(new MSCFile(file));
^
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h:35:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\examples\CardInfoUSB\CardInfoUSB.ino:16:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:134:2: note: candidate: File::File(const File&&)
File(const File&& file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:134:2: note: no known conversion for argument 1 from 'MSCFile*' to 'const File&&'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:127:2: note: candidate: File::File(const File&)
File(const File& file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:127:2: note: no known conversion for argument 1 from 'MSCFile*' to 'const File&'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:117:2: note: candidate: File::File(FileImpl*)
File(FileImpl *file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:117:2: note: no known conversion for argument 1 from 'MSCFile*' to 'FileImpl*'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:110:12: note: candidate: constexpr File::File()
constexpr File() : f(nullptr) { }
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:110:12: note: candidate expects 0 arguments, 1 provided
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\examples\CardInfoUSB\CardInfoUSB.ino:16:0:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h: In member function 'virtual File MSCClass::eek:pen(const char*, uint8_t)':
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h:166:42: error: no matching function for call to 'File::File(MSCFile*)'
if (file) return File(new MSCFile(file));
^
In file included from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\src/mscFS.h:35:0,
from C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\UsbMscFat_wwatson4506\examples\CardInfoUSB\CardInfoUSB.ino:16:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:134:2: note: candidate: File::File(const File&&)
File(const File&& file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:134:2: note: no known conversion for argument 1 from 'MSCFile*' to 'const File&&'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:127:2: note: candidate: File::File(const File&)
File(const File& file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:127:2: note: no known conversion for argument 1 from 'MSCFile*' to 'const File&'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:117:2: note: candidate: File::File(FileImpl*)
File(FileImpl *file) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:117:2: note: no known conversion for argument 1 from 'MSCFile*' to 'FileImpl*'
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:110:12: note: candidate: constexpr File::File()
constexpr File() : f(nullptr) { }
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/FS.h:110:12: note: candidate expects 0 arguments, 1 provided
Error compiling for board Teensy 4.1.

Can you please help with this?
It seems that it all boils down to two files - FS.H and MSCFS.H

This is a virgin load - New Teensy. Latest Arduino and Teensyduino - so just what youd expect from a newby like me.
 
Sorry not sure of the way with virgin builds right now. Mine is currently very convoluted.

Also we are in the process of hopefully merging the MSC functionality into the core files and hopefully an initial setup with it should be out with a new Beta Teensyduino. hopefully very near term.
 
@Case - These libraries are in a heavy state of change right now. With the upcoming TD1.57 Beta 1 all of the libraries that rely on USBHost_t36, UsbMscFat, SD, SdFat should be in a usable state. Anything before will probably be incompatible:)

Next, other than SD, SdFat, USBHost_t36 namely UsbMscFat should be in the Arduino/libraries/... folder. The current usable UsbMscFat version for use with Arduino 1.8.19 and TD1.56 is:
https://github.com/wwatson4506/UsbMscFat/tree/UsbMscFat-decouple

Some of the example sketches may not work.

What @KurtE said is basically what I am am saying:)
 
Indeed, things are changing quite a lot in just the last few days, in prep for 1.57-beta1, now more urgent due to this serious SdFat 2.1.0 bug recently discovered.

https://forum.pjrc.com/threads/7010...te-fails-after-256-kb-when-writing-to-2-files

Can confirm, incompatible changes for USB MSC are coming as part of the merge into USBHost_t36. Hopefully in just a matter of days we'll have a 1.57-beta1 installer with everything updated and using a soon-to-be-stable API.
 
Thank You - all three of you for responding so quickly. If I can, I'd like to be a tester for a virgin load of the progress. Recently bought the last four of your Teensy 4.1s off the site. Have a big project ahead, and have selected teensy, with its whopping 600mhz and usb host to do the job :)
If this isnt the thread for it, please let me know where,
Thanks again.
 
Thank You - all three of you for responding so quickly. If I can, I'd like to be a tester for a virgin load of the progress. Recently bought the last four of your Teensy 4.1s off the site. Have a big project ahead, and have selected teensy, with its whopping 600mhz and usb host to do the job :)
If this isnt the thread for it, please let me know where,
Thanks again.

Paul will announce the TD 1.57 beta 1 release.
Installing that to test will give access to the current code as incorporated.
That thread or this thread likely will end up being the place to track any changes as the Beta progresses.

Last seen here it was quite functional - except on the margins or edges of transfers.
 
Let's talk briefly about the public API for USBHost_t36 with UsbMscFat merged.

Currently we have a msController class which you create instances for each USB drive, and another class for the filesystem which has a static instance named MSC. You initialize the MSC instance by calling begin() with a pointer to a msController instance.

Initially I was thinking of just rolling everything into the msController class, and getting rid of begin() and going to a boolean check, similar to how Serial works. But that won't allow access to different partitions on the same drive. It seems we do need 2 public classes. I want to get away from a static class and follow the convention we're using for the USB device instances, where you give a list instances you want the host library to manage. So it might look something like this:
Code:
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
msController myDisk1(myusb);
MSCClass myFilesystem1(myDisk1);
MSCClass myFilesystem2(myDisk1);

Rather than call begin(), programs would use a boolean test like we do with Serial, such as:

Code:
  if (myFilesystem1) {
    File root = myFilesystem1.open("/");
    printDirectory(myFilesystem1, 0);
  }

I'm also considering renaming msController and MSCClass to fit better with the USBHost_t36 naming convention and be more readable for humans who don't instinctively know "MS" means Mass Storage.

msController -> USBStorage, USBDisk, USBDrive, USBMassStorage, ???

MSCClass -> USBFilesystem, USBDisk, USBDrive, USBDiskPartition, USBStorageVolume, USBFatFilesystem, ???

In choosing these names, my main hope is people familiar with computers & tech in general, but not necessarily the USB standards and USB terminology will be able to understand what the instances probably do when they glance at code for the first time. These lines are usually the first non-comment part of example programs, so choosing intuitive names can really help give a first impression.

Any suggestions on the class names? Once they're published in the 1.57 release, we'll probably never be able to change.
 
msController -> USBStorage, USBDisk, USBDrive, USBMassStorage, ???

MSCClass -> USBFilesystem, USBDisk, USBDrive, USBDiskPartition, USBStorageVolume, USBFatFilesystem, ???
Having both USBDisk and USBDrive in both msController and MSCClass might lead to some confusion.
 
Good morning Paul,

Quick comments:
Code:
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
msController myDisk1(myusb);
MSCClass myFilesystem1(myDisk1);
MSCClass myFilesystem2(myDisk1);

Not sure about having myFilesystem1 saying which drive it is on, as I may want to be able to handle
lets say 2 drives with max of 5FS, so would expect something like:

Code:
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);

USBDriveController myDisk1(myusb);
USBDriveController myDisk2(myusb);

USBFat myFilesystem1(myusb);
USBFat myFilesystem2(myusb);
USBFat myFilesystem3(myusb);
USBFat myFilesystem4(myusb);
USBFat myFilesystem5(myusb);

Sort of in the same way you specify HID parsers and the HID devices, but you don't
define which HIDParser for example a keyboard object will use.

Don't have strong opinion on names. I used a couple of random ones in above as needed to type something and lots of our classes have Controller in them.

As for cryptic names... what is a HID? ;)
 
Forgot to talk about:
Code:
  if (myFilesystem1) {
    File root = myFilesystem1.open("/");
    printDirectory(myFilesystem1, 0);
  }

I do like that, and was considering doing that as well.

We already have: if (myDisk1) {...

The concern I had was how long the operation may take: I too would like to get rid of:
Code:
  for (uint8_t i=0; i < CNT_DRIVES; i++) {
    if (*pdrives[i]) {
      if (!drive_previous_connected[i]) {
        Serial.println("\n@@@@@@@@@@@@@@@ NEW Drives @@@@@@@@@@@");
        if (mscDrive.begin(pdrives[i])) {
          Serial.println("\t ## new drive");
          Serial.printf("\nUSB Drive: %u connected\n", i);
          pfsLIB.mbrDmp(&mscDrive, (uint32_t)-1, Serial);
          Serial.println("\nTry Partition list");
          pfsLIB.listPartitions(&mscDrive, Serial);
          drive_previous_connected[i] = true;
        }
        Serial.println("\n@@@@@@@@@@@@@@@ NEW Drives  Completed. @@@@@@@@@@@");
      }
    } else {
      drive_previous_connected[i] = false;
    }
  }

But wondered how long this operation might take to complete. Especially if for example I plug in a hard disk with lets say 3 partitions...
Do you hold up the program until it completes and/or break it up and try to handle it in background calls... like myusb.Task() or timer or ...

Also was running into MTP startup issues, if you had drives plugged in and it started all of them up while we were not processing MTP
messages. Although initial timer hack took care of many of those issues.

But maybe we should try to remove the need and see!
 
Back
Top