chegewara / EspTinyUSB

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

On-board external Flash as USB Mass Storage #50

Closed mihkel615 closed 2 years ago

mihkel615 commented 2 years ago

Hi, I know this question already got raised but just pointing out that the flash that ESP32 modules are equipped with would be great to access through this library. The Ramdisk option - just too little space for practical value. The SD card option - great but requires additional hardware.

If anyone have time, a "flash_msc" would be just great. Perhaps using the LittleFS filesystem :). What do you think.

chegewara commented 2 years ago

Hi, the problem is that tinyusb has to access flash with raw data access, using wear leveling API, which means we cant use regular libraries like LittleFS to expose it to host. Ive been trying to write this functionality today, but i failed: https://esp32.com/viewtopic.php?f=13&t=22580&p=82359#p82359

When i find solution i will add it for sure.

chegewara commented 2 years ago

I have solved some problems with flash to USB and code is ready. There is still 1 more performance issue.

It may be somehow related to wear leveling sector size 4096 bytes and tinyusb buffer size 512 bytes (but i may be doing it wrong).

chegewara commented 2 years ago

I will share files here, for testing, because i dont feel it is ready to post in library: flashdisk.ino flashdisk.h flashdisk.cpp

mihkel615 commented 2 years ago

This is awesome, U rock Chegewara! Speed is low, yes, but it works. I can commit to it as the files I need to transfer are only 100-200 kB. Thanks

nikthefix commented 2 years ago

@mihkel615 @chegewara

I had this working with earlier versions of the core and EspTinyUSB using Adafruit SpiFlash lib. With a little modification to the adafruit example and combined with EspTinyUSB I could expose internal flash, external spi Winbond flash and external spi FRAM as usb MSD fat16 partitions (fat12 for the low capacity FRAM). It was pretty fast too. I'll check to see if it still works with the current releases. The Adafruit SAMD21/51 SpiFlash/msd example code is a good guide to get it working, but obviously you can't use Adafruit's TinyUSB (yet). The ESP32-S2 would always use the first found FAT partition so if I wanted to target an external SPI device I needed to ensure that the internal flash partition was either unformatted or left as SPIFFS. I couldn't see a way of programmatically selecting partitions without modifying the HAL.

chegewara commented 2 years ago

My implementation is using esp-idf wear leveling and tinyusb buffer is only 512 bytes. I hope @me-no-dev will increase tinyusb MSC buffer to 4096, which is internal flash block size. That way only 1 write operation will be required instead of 8 4096/512. It will not only speed up write operations, but also will increase flash live.

nikthefix commented 2 years ago

My experiments also used the idf wear levelling and I decided to start with external Winbond and FRAM to avoid wear of the esp flash in case my implementation was bad. The FRAM is great not needing any erase cycles but the capacity is too small.

mihkel615 commented 2 years ago

I'm trying to get the flashdisk example code working on the S2 but having difficulties. I'm getting the "Error compiling for board ESP32S2 Dev Module" error, even tho I'm using the master branch from https://github.com/espressif/arduino-esp32. What could be the issue? Thanks

nikthefix commented 2 years ago

Have you got "USB CDC on boot" enabled in boards manager? I found this had to be enabled even if you're using UART upload.

BTW Adafruits tinyusb is now working with the S2 and it plays nicely with their SPIflash lib so we have a lot of choice now.

mihkel615 commented 2 years ago

Hi Chegewara, I see you closed the issue but I have few more comments. Since Adafruit library only works with their own bootloader, I'm still looking into your solution. After just copying the three files into a sketch folder, I managed to compile and upload but after booting up nothing happens (no device appears on Device Manager or port on Arduino IDE). My board is still ESP32S2 WROOM on custom made PCB and I tried different board settings and board definitions 2.0.1-RC1, 2.0.1 and 2.0.0 with "ESP32S2 Dev Module" selected from the boards list and 2.0.0 with "ESP32S2 Native USB" also different physical boards (everything factory soldered btw). The ramdisc example works fine but flashdisk does not. Thanks.

chegewara commented 2 years ago

I closed issue because it is working fine to me. There is flashdisk example, with 2 FatFS partitions, which will show in OS as 2 disks.

https://github.com/chegewara/EspTinyUSB/tree/master/examples/device/msc/flashdisk

mihkel615 commented 2 years ago

Success! It is working, I was missing the "Partition Scheme: Default 4MB with ffat" part. I hope someone can get a fast forward through this thread. Awesome.

ahmedmibrahim commented 1 year ago

@chegewara , @mihkel615 Does this flashdisk example really use the on-board flash on ESP32-S3 ? or is it using the on-die one? I'm probing the SPI interface pins as I'm running the flashdisk example, I see the 2 USB drives, when I copy and paste a file to the MSC drive I don't see the SPI pins toggling.

chegewara commented 1 year ago

It works with the same flash on which you have firmware.

ahmedmibrahim commented 1 year ago

I appreciate your response. If the MSC device mounts as 2 USB drives, each of size ~1MB. I wonder how I have 2MB that is not the external Flash? (I'm using ESP32-S3-N8R2)? Moreover:

chegewara commented 1 year ago

To be honest i didnt study S3 yet, so i cant help you with those questions. Also i dont have plans to use S3 with both, on die and external flash, but i believe it is possible to do it.