chegewara / EspTinyUSB

ESP32S2 native USB library. Implemented few common classes, like MIDI, CDC, HID or DFU (update).
MIT License
473 stars 70 forks source link

Stop or end USB classes #121

Closed applefreak closed 1 year ago

applefreak commented 1 year ago

Hi, I'm wondering if there's a way to stop a USB class once the .begin() method has been called.

Reason for this is, I want to have a mode switching button (or something that can be called pragmatically) that can toggle between enabling the FlashUSB class and reading the files written off of the FAT partition. But I notice that once I called FlashUSB::begin() I'm having problems when calling FFat.begin() and then FFat.open().

I can get around this by setting a "mode" flag using the Preferences API, then reset the chip to whatever mode. But I want to know if there's a better way to go about this.

Or maybe this has to do more with the FAT part than the USB part, in that case I'll try to look into that direction.

Thank you!

chegewara commented 1 year ago

This class is designed to use as pendrive and FFat arduino class at the same time. You dont have to switch mode nor to use FFat.begin(), and probably FFat.end() will brake MSC functionality. If you really need option to switch mode then you need to write class similar to included in this library.

applefreak commented 1 year ago

Hmm I see. I modified the example code in this repo and example from the FFat library, see below.

It falls into the if(!root) block giving me failed to open directory message.

I can see the disk mounted on my computer and I can read and write files to it.

Any ideas?

/**
 * Simple MSC device, use fat partition
 * author: chegewara
 */
#include "arduino.h"
#include "flashdisk.h"
#include "cdcusb.h"

#include "FFat.h"

#if CFG_TUD_MSC

FlashUSB dev;
CDCusb CDCUSBSerial;

char *l1 = "ffat";
uint8_t cnt = 0;

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\r\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("- failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println(" - not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("\tSIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void setup()
{
    Serial.begin(115200);

    if (!CDCUSBSerial.begin())
        Serial.println("Failed to start CDC USB stack");

    if (dev.init("/fat1", "ffat"))
    {
        if (dev.begin())
        {
            Serial.println("MSC lun 1 begin");
        }
        else
            log_e("LUN 1 failed");
    }
}
void loop()
{
    Serial.println("Hello world serial");

    if (cnt == 5) {
        /* FFat.begin(true, "/fat1", 5, "ffat"); */
        listDir(FFat, "/", 0);
        while (1);
    }

    delay(1000);
    cnt++;
}

#endif
chegewara commented 1 year ago

https://github.com/chegewara/EspTinyUSB/blob/master/examples/device/msc/sd_msc/sd_msc.ino this example is using FFat class to list dirs and other tests.

applefreak commented 1 year ago

Hey thanks for your help, as far as I can tell what I did should work, but it's not :)

And what you said make sense too, both the FlashUSB and FFat class is using the underlying ESP-IDF vfat implementation. So I must be missing something.

I'll have to take a look another time, it's getting late here. Will report back once I figured it out.

applefreak commented 1 year ago

I figured it out! Turns out for some reason, the label parameter in FlashUSB::init(const char* path, char* label) has to be NULL for it to work. I also have to call FFat.begin() otherwise I would get open(): File system is not mounted error.

It's weird, but that works for me. I also noticed that if I write some files to the disk via USB, I have to called FFat.end() and then FFat.begin() again to see the new files with FFat.

Anyway, hopefully this is helpful for other people. I'll be closing this issue.