Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/machine/machine_atsamd21_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (dev *USBDevice) Configure(config UARTConfig) {
sam.USB_DEVICE.CTRLB.SetBits(sam.USB_DEVICE_CTRLB_SPDCONF_FS << sam.USB_DEVICE_CTRLB_SPDCONF_Pos)

// attach
sam.USB_DEVICE.CTRLB.ClearBits(sam.USB_DEVICE_CTRLB_DETACH)
dev.Attach()

// enable interrupt for end of reset
sam.USB_DEVICE.INTENSET.SetBits(sam.USB_DEVICE_INTENSET_EORST)
Expand All @@ -68,6 +68,20 @@ func (dev *USBDevice) Configure(config UARTConfig) {
dev.initcomplete = true
}

// Attach connects the device to the USB bus, allowing the host to detect and
// enumerate it. It can be used together with Detach to delay enumeration
// until the USB configuration (device identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
sam.USB_DEVICE.CTRLB.ClearBits(sam.USB_DEVICE_CTRLB_DETACH)
}

// Detach disconnects the device from the USB bus. To the host this appears
// as if the device was unplugged. A subsequent Attach makes the host
// enumerate the device again.
func (dev *USBDevice) Detach() {
sam.USB_DEVICE.CTRLB.SetBits(sam.USB_DEVICE_CTRLB_DETACH)
}

func handlePadCalibration() {
// Load Pad Calibration data from non-volatile memory
// This requires registers that are not included in the SVD file.
Expand Down
16 changes: 15 additions & 1 deletion src/machine/machine_atsamd51_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (dev *USBDevice) Configure(config UARTConfig) {
sam.USB_DEVICE.CTRLB.SetBits(sam.USB_DEVICE_CTRLB_SPDCONF_FS << sam.USB_DEVICE_CTRLB_SPDCONF_Pos)

// attach
sam.USB_DEVICE.CTRLB.ClearBits(sam.USB_DEVICE_CTRLB_DETACH)
dev.Attach()

// enable interrupt for end of reset
sam.USB_DEVICE.INTENSET.SetBits(sam.USB_DEVICE_INTENSET_EORST)
Expand All @@ -71,6 +71,20 @@ func (dev *USBDevice) Configure(config UARTConfig) {
dev.initcomplete = true
}

// Attach connects the device to the USB bus, allowing the host to detect and
// enumerate it. It can be used together with Detach to delay enumeration
// until the USB configuration (device identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
sam.USB_DEVICE.CTRLB.ClearBits(sam.USB_DEVICE_CTRLB_DETACH)
}

// Detach disconnects the device from the USB bus. To the host this appears
// as if the device was unplugged. A subsequent Attach makes the host
// enumerate the device again.
func (dev *USBDevice) Detach() {
sam.USB_DEVICE.CTRLB.SetBits(sam.USB_DEVICE_CTRLB_DETACH)
}

func handlePadCalibration() {
// Load Pad Calibration data from non-volatile memory
// This requires registers that are not included in the SVD file.
Expand Down
5 changes: 5 additions & 0 deletions src/machine/machine_esp32c3_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ func (dev *USBDevice) SetStallEPOut(ep uint32) {}
func (dev *USBDevice) ClearStallEPIn(ep uint32) {}
func (dev *USBDevice) ClearStallEPOut(ep uint32) {}

// Attach and Detach are no-ops: the USB Serial/JTAG controller has no
// software-controlled soft-connect, it is always attached to the bus.
func (dev *USBDevice) Attach() {}
func (dev *USBDevice) Detach() {}

// initUSB is intentionally empty — the interp phase evaluates init()
// functions at compile time and cannot access hardware registers.
// Actual hardware setup is deferred to the first Configure() call.
Expand Down
5 changes: 5 additions & 0 deletions src/machine/machine_esp32c6_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ func (dev *USBDevice) SetStallEPOut(ep uint32) {}
func (dev *USBDevice) ClearStallEPIn(ep uint32) {}
func (dev *USBDevice) ClearStallEPOut(ep uint32) {}

// Attach and Detach are no-ops: the USB Serial/JTAG controller has no
// software-controlled soft-connect, it is always attached to the bus.
func (dev *USBDevice) Attach() {}
func (dev *USBDevice) Detach() {}

// initUSB is intentionally empty — the interp phase evaluates init()
// functions at compile time and cannot access hardware registers.
// Actual hardware setup is deferred to the first Configure() call.
Expand Down
5 changes: 5 additions & 0 deletions src/machine/machine_esp32xx_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ func (dev *USBDevice) SetStallEPOut(ep uint32) {}
func (dev *USBDevice) ClearStallEPIn(ep uint32) {}
func (dev *USBDevice) ClearStallEPOut(ep uint32) {}

// Attach and Detach are no-ops: the USB Serial/JTAG controller has no
// software-controlled soft-connect, it is always attached to the bus.
func (dev *USBDevice) Attach() {}
func (dev *USBDevice) Detach() {}

// initUSB is intentionally empty — the interp phase evaluates init()
// functions at compile time and cannot access hardware registers.
// Actual hardware setup is deferred to the first Configure() call.
Expand Down
26 changes: 25 additions & 1 deletion src/machine/machine_nrf52840_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ var (
epinen uint32
epouten uint32
easyDMABusy volatile.Register8

// usbDetached keeps the device detached from the bus after Detach: the
// USB IRQ handler re-enables the DP pull-up on every power-ready event,
// which would otherwise silently undo a Detach.
usbDetached bool
)

// enterCriticalSection is used to protect access to easyDMA - only one thing
Expand Down Expand Up @@ -89,6 +94,23 @@ func (dev *USBDevice) Configure(config UARTConfig) {
dev.initcomplete = true
}

// Attach connects the device to the USB bus by enabling the DP pull-up,
// allowing the host to detect and enumerate it. It can be used together with
// Detach to delay enumeration until the USB configuration (device
// identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
usbDetached = false
nrf.USBD.USBPULLUP.Set(1)
}

// Detach disconnects the device from the USB bus by disabling the DP pull-up.
// To the host this appears as if the device was unplugged. A subsequent
// Attach makes the host enumerate the device again.
func (dev *USBDevice) Detach() {
usbDetached = true
nrf.USBD.USBPULLUP.Set(0)
}

func handleUSBIRQ(interrupt.Interrupt) {
if nrf.USBD.EVENTS_SOF.Get() == 1 {
nrf.USBD.EVENTS_SOF.Set(0)
Expand All @@ -103,7 +125,9 @@ func handleUSBIRQ(interrupt.Interrupt) {

// Configure control endpoint
initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
nrf.USBD.USBPULLUP.Set(1)
if !usbDetached {
nrf.USBD.USBPULLUP.Set(1)
}

usbConfiguration = 0
}
Expand Down
15 changes: 15 additions & 0 deletions src/machine/machine_rp2040_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,24 @@ func (dev *USBDevice) Configure(config UARTConfig) {
rp.USBCTRL_REGS_INTE_SETUP_REQ)

// Present full speed device by enabling pull up on DP
dev.Attach()
}

// Attach connects the device to the USB bus by enabling the DP pull-up,
// allowing the host to detect and enumerate it. It can be used together with
// Detach to delay enumeration until the USB configuration (device
// identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
rp.USBCTRL_REGS.SIE_CTRL.SetBits(rp.USBCTRL_REGS_SIE_CTRL_PULLUP_EN)
Comment thread
sago35 marked this conversation as resolved.
}

// Detach disconnects the device from the USB bus by disabling the DP pull-up.
// To the host this appears as if the device was unplugged. A subsequent
// Attach makes the host enumerate the device again.
func (dev *USBDevice) Detach() {
rp.USBCTRL_REGS.SIE_CTRL.ClearBits(rp.USBCTRL_REGS_SIE_CTRL_PULLUP_EN)
}

func handleUSBIRQ(intr interrupt.Interrupt) {
status := rp.USBCTRL_REGS.INTS.Get()

Expand Down
17 changes: 16 additions & 1 deletion src/machine/machine_rp2350_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,27 @@ func (dev *USBDevice) Configure(config UARTConfig) {
rp.USB_INTE_SETUP_REQ)

// Present full speed device by enabling pull up on DP
rp.USB.SIE_CTRL.SetBits(rp.USB_SIE_CTRL_PULLUP_EN)
dev.Attach()

// 12.7.2 Disable phy isolation
rp.USB.SetMAIN_CTRL_PHY_ISO(0x0)
}

// Attach connects the device to the USB bus by enabling the DP pull-up,
// allowing the host to detect and enumerate it. It can be used together with
// Detach to delay enumeration until the USB configuration (device
// identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
rp.USB.SIE_CTRL.SetBits(rp.USB_SIE_CTRL_PULLUP_EN)
}

// Detach disconnects the device from the USB bus by disabling the DP pull-up.
// To the host this appears as if the device was unplugged. A subsequent
// Attach makes the host enumerate the device again.
func (dev *USBDevice) Detach() {
rp.USB.SIE_CTRL.ClearBits(rp.USB_SIE_CTRL_PULLUP_EN)
}

func handleUSBIRQ(intr interrupt.Interrupt) {
status := rp.USB.INTS.Get()

Expand Down
19 changes: 17 additions & 2 deletions src/machine/machine_stm32_otgfs_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func (dev *USBDevice) Configure(config UARTConfig) {
otgPower.PCGCCTL.Set(0)

// Soft-disconnect now (after CSRST reset DCTL to its default connected state).
otgDevice.DCTL.SetBits(dctlSDIS)
dev.Detach()

// ---- 7. Configure data FIFOs --------------------------------------------

Expand Down Expand Up @@ -311,11 +311,26 @@ func (dev *USBDevice) Configure(config UARTConfig) {

// ---- 12. Connect to host (clear soft-disconnect) -----------------------

otgDevice.DCTL.ClearBits(dctlSDIS)
dev.Attach()

dev.initcomplete = true
}

// Attach connects the device to the USB bus by releasing soft disconnect,
// allowing the host to detect and enumerate it. It can be used together with
// Detach to delay enumeration until the USB configuration (device
// identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
otgDevice.DCTL.ClearBits(dctlSDIS)
}

// Detach disconnects the device from the USB bus by asserting soft
// disconnect. To the host this appears as if the device was unplugged. A
// subsequent Attach makes the host enumerate the device again.
func (dev *USBDevice) Detach() {
otgDevice.DCTL.SetBits(dctlSDIS)
}

// handleUSBIRQ is the OTG FS interrupt handler, dispatching on GINTSTS bits.
func handleUSBIRQ(intr interrupt.Interrupt) {
status := stm32.OTG_FS_GLOBAL.GINTSTS.Get() &
Expand Down
17 changes: 16 additions & 1 deletion src/machine/machine_stm32h7_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (dev *USBDevice) Configure(config UARTConfig) {

// Stay soft-disconnected until configuration is complete; CSRST left
// DCTL at its default "connected" state.
usbOTG.DCTL.SetBits(DCTL_SDIS)
dev.Detach()

// 5. Force device mode now that the core is out of reset. The mode
// change takes effect only after up to 25 ms (RM0433); poll GINTSTS.CMOD
Expand Down Expand Up @@ -265,9 +265,24 @@ func (dev *USBDevice) Configure(config UARTConfig) {
dev.initcomplete = true

// Release soft-disconnect: pulls D+ high, making device visible to host.
dev.Attach()
}

// Attach connects the device to the USB bus by releasing soft disconnect,
// allowing the host to detect and enumerate it. It can be used together with
// Detach to delay enumeration until the USB configuration (device
// identifiers, classes, ...) is complete.
func (dev *USBDevice) Attach() {
usbOTG.DCTL.ClearBits(DCTL_SDIS)
}

// Detach disconnects the device from the USB bus by asserting soft
// disconnect. To the host this appears as if the device was unplugged. A
// subsequent Attach makes the host enumerate the device again.
func (dev *USBDevice) Detach() {
usbOTG.DCTL.SetBits(DCTL_SDIS)
}

func initEndpoint(ep, config uint32) {
if ep == 0 {
// Control endpoint
Expand Down
Loading