feat: USB OTG CDC-ACM with custom VID:PID, disconnect UX
Switch all ESP32-S3 boards from UsbSerialJtag to USB OTG CDC-ACM via embassy-usb. The USB device stack is now shared code — boards only provide the platform-specific embassy-usb Driver. - Custom VID:PID 1209:5741 (open-source VID, "WA" PID) - CDC-ACM class with proper device enumeration - COBS+postcard protocol over CDC-ACM packet read/write - Concurrent USB device loop + protocol loop via join() - On disconnect: sends DisplayCommand::Reset to show "Waiting for host..." - Justfile: espflash no longer uses --monitor (OTG steals PHY) - Test script updated to detect by new VID:PID Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
9 files changed
+113
-46
No files matched your search
+12
-6
@@ -21,8 +21,7 @@ type Iv = GenericSx126xInterfaceVariant<Output<'static>, Input<'static>>;
|
||||
type RadioSpiDevice = SpiDevice<'static, NoopRawMutex, SpiBus, Nss>;
|
||||
pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
||||
|
||||
// V3 has CP2102 on UART0 but also has USB-Serial-JTAG on the ESP32-S3
|
||||
pub type UsbDriver = esp_hal::usb_serial_jtag::UsbSerialJtag<'static, esp_hal::Async>;
|
||||
pub type UsbDriver = esp_hal::otg_fs::asynch::Driver<'static>;
|
||||
|
||||
pub type DisplayI2c = I2c<'static, esp_hal::Async>;
|
||||
|
||||
@@ -111,10 +110,17 @@ impl Board {
|
||||
delay: Delay,
|
||||
};
|
||||
|
||||
// ── USB Serial (via USB-Serial-JTAG) ───────────────────────
|
||||
let usb_serial = esp_hal::usb_serial_jtag::UsbSerialJtag::new(p.USB_DEVICE)
|
||||
.into_async();
|
||||
let usb = UsbParts { driver: usb_serial };
|
||||
// ── USB OTG CDC-ACM driver ──────────────────────────────
|
||||
let usb_inst = esp_hal::otg_fs::Usb::new(p.USB0, p.GPIO20, p.GPIO19);
|
||||
static EP_OUT_BUF: StaticCell<[u8; 1024]> = StaticCell::new();
|
||||
let ep_out_buf = EP_OUT_BUF.init([0u8; 1024]);
|
||||
let usb = UsbParts {
|
||||
driver: esp_hal::otg_fs::asynch::Driver::new(
|
||||
usb_inst,
|
||||
ep_out_buf,
|
||||
esp_hal::otg_fs::asynch::Config::default(),
|
||||
),
|
||||
};
|
||||
|
||||
// ── Display (SSD1306 OLED on I2C, 0x3C) ───────────────────
|
||||
let i2c = I2c::new(p.I2C0, I2cConfig::default())
|
||||
|
||||
+14
-4
@@ -21,7 +21,7 @@ type Iv = GenericSx126xInterfaceVariant<Output<'static>, Input<'static>>;
|
||||
type RadioSpiDevice = SpiDevice<'static, NoopRawMutex, SpiBus, Nss>;
|
||||
pub type RadioDriver = Sx126x<RadioSpiDevice, Iv, Sx1262>;
|
||||
|
||||
pub type UsbDriver = esp_hal::usb_serial_jtag::UsbSerialJtag<'static, esp_hal::Async>;
|
||||
pub type UsbDriver = esp_hal::otg_fs::asynch::Driver<'static>;
|
||||
|
||||
pub type DisplayI2c = I2c<'static, esp_hal::Async>;
|
||||
|
||||
@@ -112,9 +112,19 @@ impl Board {
|
||||
};
|
||||
|
||||
// ── USB Serial (via USB-Serial-JTAG, shares PHY safely) ───
|
||||
let usb_serial = esp_hal::usb_serial_jtag::UsbSerialJtag::new(p.USB_DEVICE)
|
||||
.into_async();
|
||||
let usb = UsbParts { driver: usb_serial };
|
||||
// ── USB OTG CDC-ACM driver ──────────────────────────────
|
||||
// Note: this switches the internal USB PHY from Serial-JTAG to OTG.
|
||||
// espflash --monitor will stop working after this point.
|
||||
let usb_inst = esp_hal::otg_fs::Usb::new(p.USB0, p.GPIO20, p.GPIO19);
|
||||
static EP_OUT_BUF: StaticCell<[u8; 1024]> = StaticCell::new();
|
||||
let ep_out_buf = EP_OUT_BUF.init([0u8; 1024]);
|
||||
let usb = UsbParts {
|
||||
driver: esp_hal::otg_fs::asynch::Driver::new(
|
||||
usb_inst,
|
||||
ep_out_buf,
|
||||
esp_hal::otg_fs::asynch::Config::default(),
|
||||
),
|
||||
};
|
||||
|
||||
// ── Display (SSD1315 OLED on I2C, 0x3C) ───────────────────
|
||||
// Reset display controller
|
||||
|
||||
Reference in new issue
Block a user