From 5331e408e3bbe21ef8fab1a6784cf824cbe36f0b Mon Sep 17 00:00:00 2001 From: Sebastian Holzapfel Date: Wed, 27 May 2026 08:05:40 +0200 Subject: [PATCH 1/2] top/polysyn/tusb322i: enable VBUS when enumerating as Accessory/DebugDfp --- gateware/src/rs/hal/src/tusb322.rs | 4 ++- gateware/src/top/polysyn/fw/src/main.rs | 33 +++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/gateware/src/rs/hal/src/tusb322.rs b/gateware/src/rs/hal/src/tusb322.rs index 9de7d392..79d7c29f 100644 --- a/gateware/src/rs/hal/src/tusb322.rs +++ b/gateware/src/rs/hal/src/tusb322.rs @@ -200,6 +200,8 @@ impl TUSB322Driver { } pub fn soft_reset(&mut self) -> Result<(), I2C::Error> { - self.write_register(0x0A, 0x08) + // Read-modify-write so the reset bit doesn't clobber MODE_SELECT in the same register. + let reg = self.read_register(0x0A)?; + self.write_register(0x0A, reg | 0x08) } } diff --git a/gateware/src/top/polysyn/fw/src/main.rs b/gateware/src/top/polysyn/fw/src/main.rs index cf2e4f01..38dbf20a 100644 --- a/gateware/src/top/polysyn/fw/src/main.rs +++ b/gateware/src/top/polysyn/fw/src/main.rs @@ -30,7 +30,7 @@ use tiliqua_hal::embedded_graphics::prelude::*; use opts::persistence::*; use hal::pca9635::Pca9635Driver; -use hal::tusb322::{TUSB322Driver, TUSB322Mode, AttachedState}; +use hal::tusb322::{TUSB322Driver, TUSB322Mode, AttachedState, AccessoryType}; use tiliqua_fw::wavetable; @@ -365,6 +365,7 @@ fn main() -> ! { let mut last_jack = pmod.jack(); let mut usb_cc_attached_as_src = false; + let mut last_attached_state = AttachedState::NotAttached; loop { @@ -380,17 +381,33 @@ fn main() -> ! { // Type-C hotplugging detection // - // Only enable VBUS if the TUSB322 Type-C controller says we are attached as a source. - // This is an extra safeguard against applying VBUS if we're accidentally connecting host<->host. + // Only enable VBUS if the TUSB322 Type-C controller says we are attached as: + // - Attached.SRC + // - Attached.ACCESSORY && AccessoryType.DebugDfp + // + // It seems some USB-C adapters will enumerate as a DebugDfp accessory. Enabling VBUS + // is still safe in this situation, as we can only land in DebugDfp if the CC + // controller is sure we are a DFP. It's not sufficient to just check + // Attached.ACCESSORY as we could also enumerate as an UFP accessory against a host! + // + // This is essentially a safeguard against applying VBUS if we're accidentally connecting host<->host. // - if let Ok(status) = tusb322.read_connection_status_control() { + if let Ok(ctrl) = tusb322.read_connection_status_control() { // Only update on valid reads to reduce risk of unintended toggling mid-stream - let new_state = status.attached_state == AttachedState::AttachedSrc; - if new_state != usb_cc_attached_as_src { - info!("USB CC hotplug: {:?}", status); - usb_cc_attached_as_src = new_state; + // TODO: move read_connection_status() into above gate. + let conn = tusb322.read_connection_status().ok(); + if ctrl.attached_state != last_attached_state { + match &conn { + Some(c) => info!("USB CC change: {:?} | {:?}", ctrl, c), + None => info!("USB CC change: {:?} | ", ctrl), + } + last_attached_state = ctrl.attached_state; } + + let debug_dfp = ctrl.attached_state == AttachedState::AttachedAccessory + && conn.as_ref().map_or(false, |c| c.accessory == AccessoryType::DebugDfp); + usb_cc_attached_as_src = ctrl.attached_state == AttachedState::AttachedSrc || debug_dfp; } let usb_vbus_enabled = usb_cc_attached_as_src && (app.ui.opts.misc.usb_host.value == UsbHost::On); app.synth.usb_midi_host(usb_vbus_enabled, 1, 1); From 09c220b068b8ba382580a1cd4538fb1f73e06854 Mon Sep 17 00:00:00 2001 From: Sebastian Holzapfel Date: Sat, 30 May 2026 15:16:36 +0200 Subject: [PATCH 2/2] top/polysyn/tusb322i: only update hotplug if both reg reads succeed, undo hal layer change --- gateware/src/rs/hal/src/tusb322.rs | 4 +--- gateware/src/top/polysyn/fw/src/main.rs | 20 ++++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/gateware/src/rs/hal/src/tusb322.rs b/gateware/src/rs/hal/src/tusb322.rs index 79d7c29f..9de7d392 100644 --- a/gateware/src/rs/hal/src/tusb322.rs +++ b/gateware/src/rs/hal/src/tusb322.rs @@ -200,8 +200,6 @@ impl TUSB322Driver { } pub fn soft_reset(&mut self) -> Result<(), I2C::Error> { - // Read-modify-write so the reset bit doesn't clobber MODE_SELECT in the same register. - let reg = self.read_register(0x0A)?; - self.write_register(0x0A, reg | 0x08) + self.write_register(0x0A, 0x08) } } diff --git a/gateware/src/top/polysyn/fw/src/main.rs b/gateware/src/top/polysyn/fw/src/main.rs index 38dbf20a..07a9c153 100644 --- a/gateware/src/top/polysyn/fw/src/main.rs +++ b/gateware/src/top/polysyn/fw/src/main.rs @@ -394,20 +394,16 @@ fn main() -> ! { // if let Ok(ctrl) = tusb322.read_connection_status_control() { - // Only update on valid reads to reduce risk of unintended toggling mid-stream - // TODO: move read_connection_status() into above gate. - let conn = tusb322.read_connection_status().ok(); - if ctrl.attached_state != last_attached_state { - match &conn { - Some(c) => info!("USB CC change: {:?} | {:?}", ctrl, c), - None => info!("USB CC change: {:?} | ", ctrl), + if let Ok(conn) = tusb322.read_connection_status() { + // Only update on valid reads to reduce risk of unintended toggling mid-stream + if ctrl.attached_state != last_attached_state { + info!("USB hotplug: {:?} | {:?}", ctrl, conn); + last_attached_state = ctrl.attached_state; } - last_attached_state = ctrl.attached_state; + let debug_dfp = (ctrl.attached_state == AttachedState::AttachedAccessory) && + (conn.accessory == AccessoryType::DebugDfp); + usb_cc_attached_as_src = ctrl.attached_state == AttachedState::AttachedSrc || debug_dfp; } - - let debug_dfp = ctrl.attached_state == AttachedState::AttachedAccessory - && conn.as_ref().map_or(false, |c| c.accessory == AccessoryType::DebugDfp); - usb_cc_attached_as_src = ctrl.attached_state == AttachedState::AttachedSrc || debug_dfp; } let usb_vbus_enabled = usb_cc_attached_as_src && (app.ui.opts.misc.usb_host.value == UsbHost::On); app.synth.usb_midi_host(usb_vbus_enabled, 1, 1);