Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch between CDC and MSC device on esp32-s3 #2926

Open
1 task done
marchingband opened this issue Jan 2, 2025 · 5 comments
Open
1 task done

switch between CDC and MSC device on esp32-s3 #2926

marchingband opened this issue Jan 2, 2025 · 5 comments

Comments

@marchingband
Copy link

Related area

device stack?

Hardware specification

ESP32-S3

Is your feature request related to a problem?

I am working on a device where most of the time, the ESP32 is a USB serial device, but then sometimes, it needs to change into a MSC device for a while, and then back to serial again.
This is to allow users to upload config files, which they will only do sometimes, and which should not be active all the time.
I see the example in the esp-idf for composite cdc and msc device, but if I do not initialize the msc, then then the driver crashes.

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x420046d8  PS      : 0x00060f30  A0      : 0x82023cb2  A1      : 0x3fc9ff70  
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00060120  A5      : 0x3fca000c  
A6      : 0x0000001f  A7      : 0x00000003  A8      : 0x00000000  A9      : 0x3fc9ff60  
A10     : 0x00000000  A11     : 0x00000002  A12     : 0x00000000  A13     : 0x00060d23  
A14     : 0xb33fffff  A15     : 0xb33fffff  SAR     : 0x00000020  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x40056f5c  LEND    : 0x40056f72  LCOUNT  : 0xffffffff  


Backtrace: 0x420046d5:0x3fc9ff70 0x42023caf:0x3fc9ff90 0x420245b6:0x3fc9ffe0 0x42025e61:0x3fca0000 0x420039c3:0x3fca0030 0x4037d1bd:0x3fca0050

  #0  0x420046d5:0x3fc9ff70 in tud_msc_test_unit_ready_cb at components/espressif_esp_tinyusb_1.4.2_2/tusb_msc_storage.c:525
  #1  0x42023caf:0x3fc9ff90 in proc_builtin_scsi at managed_components/espressif__tinyusb/src/class/msc/msc_device.c:658
  #2  0x420245b6:0x3fc9ffe0 in mscd_xfer_cb at managed_components/espressif__tinyusb/src/class/msc/msc_device.c:471
  #3  0x42025e61:0x3fca0000 in tud_task_ext at managed_components/espressif__tinyusb/src/device/usbd.c:567 (discriminator 2)
  #4  0x420039c3:0x3fca0030 in tud_task at managed_components/espressif__tinyusb/src/device/usbd.h:55 (discriminator 1)
      (inlined by) tusb_device_task at components/espressif_esp_tinyusb_1.4.2_2/tusb_tasks.c:41 (discriminator 1)
  #5  0x4037d1bd:0x3fca0050 in vPortTaskWrapper at /Users/andy/.platformio/packages/framework-espidf@3.50102.0/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162

Describe the solution you'd like

Is there a way to either
a) register as a composite device, but defer initialization of the msc device, and then later deinit it?
b) register as a CDC, then later deinit the CDC device, register as an MSC, init the MSC, and then back again?

Example code for this on ESP32, where menuconfig is so intimately connected to USB driver, would be deeply appreciated.
any tips appreciated really, I have not been able to find any info online, thank you!

I have checked existing issues, dicussion and documentation

  • I confirm I have checked existing issues, dicussion and documentation.
@marchingband
Copy link
Author

I have worked on the individual initialization sequences such that I can start either the CDC or the MSC, without having to adjust sdkconfig.
However the teardown process is not working.
Digging through the source code I did find

// TODO
// bool tusb_teardown(void);

Is there a way i can accomplish this teardown without restarting the MCU?

@roma-jam
Copy link
Contributor

roma-jam commented Jan 2, 2025

Hi @marchingband,

The esp-idf is using the esp-tinyusb wrapper, which provides the configuration and and other things for the classes and simplify the final usage.
In the example for the composite device both classes must be initialized.

For the MSC device there is also a way to insert and remove the media (without a media your device will be represented in the system as a SD card reader without a card). But for that, if you still want to use esp-idf, you need to use tinyusb component directly, as to provide media you need to use bool tud_msc_test_unit_ready_cb(uint8_t lun) and return true in this callback.
In suvh case you will have both classes all the time, but the media in MSC class will be available (as well and READ/WRITE SCSI commands) only when you need it.

Otherwise, there is a version of tusb_teardown() implementation awaiting for the review in here: #2904

So, there are several options to try it out. Maybe it will help you with your idea.

@marchingband
Copy link
Author

@roma-jam thank you so much for your help.
Using tud_msc_test_unit_ready_cb and friends worked well.
I had to comment-out tud_msc_test_unit_ready_cb from tusb_msc_storage.c, so I am no longer in sync with the repo, but that's ok, it works :)

@marchingband
Copy link
Author

There is one bug(?) where the driver does not respect tud_msc_test_unit_ready_cb at initialization time.
I can set it to always return false and it still takes the drive. This only happens once, during init, later it respects tud_msc_test_unit_ready_cb.
I setup a workaround to just always unmount from the MSC following initialization, but I think it will be pretty common for user to want to initialize the USB driver at boot (because they are doing a composite device for example), but not mount the drive to the MSC.
My workaround is fine for me, just reporting this incase you want to look into it.

@marchingband
Copy link
Author

just realized this may simply be because of

// // Invoked when device is mounted (configured)
void tud_mount_cb(void)
{
    tinyusb_msc_storage_unmount();
}

In which case just ignore me heh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants