aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorsago35 <[email protected]>2022-07-07 19:06:47 +0900
committerRon Evans <[email protected]>2022-07-07 21:04:41 +0200
commitf1e699701801f020ce87e3afa1fc53de52fe000d (patch)
tree0b3174b6cfa04cf2736bcb4ecf8ba5dfa31f56d7
parent335a7ad0b72aa5b5248c79bd77cc5e1ed6e1c183 (diff)
downloadtinygo-f1e699701801f020ce87e3afa1fc53de52fe000d.tar.gz
tinygo-f1e699701801f020ce87e3afa1fc53de52fe000d.zip
atsamd21,atsamd51,nrf52840: improve usb-device initialization
-rw-r--r--src/machine/machine_atsamd21_usb.go6
-rw-r--r--src/machine/machine_atsamd51_usb.go6
-rw-r--r--src/machine/machine_nrf52840_usb.go47
-rw-r--r--src/machine/usb.go1
4 files changed, 49 insertions, 11 deletions
diff --git a/src/machine/machine_atsamd21_usb.go b/src/machine/machine_atsamd21_usb.go
index 2155ccf77..d79a52d5c 100644
--- a/src/machine/machine_atsamd21_usb.go
+++ b/src/machine/machine_atsamd21_usb.go
@@ -150,6 +150,10 @@ const (
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
func (dev *USBDevice) Configure(config UARTConfig) {
+ if dev.initcomplete {
+ return
+ }
+
// reset USB interface
sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_SWRST)
for sam.USB_DEVICE.SYNCBUSY.HasBits(sam.USB_DEVICE_SYNCBUSY_SWRST) ||
@@ -185,6 +189,8 @@ func (dev *USBDevice) Configure(config UARTConfig) {
// enable IRQ
interrupt.New(sam.IRQ_USB, handleUSBIRQ).Enable()
+
+ dev.initcomplete = true
}
func (usbcdc *USBCDC) Configure(config UARTConfig) {
diff --git a/src/machine/machine_atsamd51_usb.go b/src/machine/machine_atsamd51_usb.go
index 5af924a45..a7d9e8910 100644
--- a/src/machine/machine_atsamd51_usb.go
+++ b/src/machine/machine_atsamd51_usb.go
@@ -151,6 +151,10 @@ const (
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
func (dev *USBDevice) Configure(config UARTConfig) {
+ if dev.initcomplete {
+ return
+ }
+
// reset USB interface
sam.USB_DEVICE.CTRLA.SetBits(sam.USB_DEVICE_CTRLA_SWRST)
for sam.USB_DEVICE.SYNCBUSY.HasBits(sam.USB_DEVICE_SYNCBUSY_SWRST) ||
@@ -189,6 +193,8 @@ func (dev *USBDevice) Configure(config UARTConfig) {
interrupt.New(sam.IRQ_USB_SOF_HSOF, handleUSBIRQ).Enable()
interrupt.New(sam.IRQ_USB_TRCPT0, handleUSBIRQ).Enable()
interrupt.New(sam.IRQ_USB_TRCPT1, handleUSBIRQ).Enable()
+
+ dev.initcomplete = true
}
func (usbcdc *USBCDC) Configure(config UARTConfig) {
diff --git a/src/machine/machine_nrf52840_usb.go b/src/machine/machine_nrf52840_usb.go
index 86cbf6a5d..2193e1430 100644
--- a/src/machine/machine_nrf52840_usb.go
+++ b/src/machine/machine_nrf52840_usb.go
@@ -153,6 +153,15 @@ func exitCriticalSection() {
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
func (dev *USBDevice) Configure(config UARTConfig) {
+ if dev.initcomplete {
+ return
+ }
+
+ state := interrupt.Disable()
+ defer interrupt.Restore(state)
+
+ nrf.USBD.USBPULLUP.Set(0)
+
// Enable IRQ. Make sure this is higher than the SWI2 interrupt handler so
// that it is possible to print to the console from a BLE interrupt. You
// shouldn't generally do that but it is useful for debugging and panic
@@ -161,19 +170,33 @@ func (dev *USBDevice) Configure(config UARTConfig) {
intr.SetPriority(0x40) // interrupt priority 2 (lower number means more important)
intr.Enable()
+ // enable interrupt for end of reset and start of frame
+ nrf.USBD.INTEN.Set(nrf.USBD_INTENSET_USBEVENT | nrf.USBD_INTENSET_SOF)
+
+ // errata 187
+ // https://infocenter.nordicsemi.com/topic/errata_nRF52840_EngB/ERR/nRF52840/EngineeringB/latest/anomaly_840_187.html
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006EC00))).Set(0x00009375)
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006ED14))).Set(0x00000003)
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006EC00))).Set(0x00009375)
+
// enable USB
nrf.USBD.ENABLE.Set(1)
- // enable interrupt for end of reset and start of frame
- nrf.USBD.INTENSET.Set(
- nrf.USBD_INTENSET_EPDATA |
- nrf.USBD_INTENSET_EP0DATADONE |
- nrf.USBD_INTENSET_USBEVENT |
- nrf.USBD_INTENSET_SOF |
- nrf.USBD_INTENSET_EP0SETUP,
- )
+ timeout := 300000
+ for !nrf.USBD.EVENTCAUSE.HasBits(nrf.USBD_EVENTCAUSE_READY) {
+ timeout--
+ if timeout == 0 {
+ return
+ }
+ }
+ nrf.USBD.EVENTCAUSE.ClearBits(nrf.USBD_EVENTCAUSE_READY)
- nrf.USBD.USBPULLUP.Set(0)
+ // errata 187
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006EC00))).Set(0x00009375)
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006ED14))).Set(0x00000000)
+ (*volatile.Register32)(unsafe.Pointer(uintptr(0x4006EC00))).Set(0x00009375)
+
+ dev.initcomplete = true
}
func (usbcdc *USBCDC) Configure(config UARTConfig) {
@@ -350,10 +373,12 @@ func initEndpoint(ep, config uint32) {
enableEPIn(ep)
case usb_ENDPOINT_TYPE_CONTROL:
- nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_ENDEPOUT0)
- nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_EP0SETUP)
enableEPIn(0)
enableEPOut(0)
+ nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_ENDEPOUT0 |
+ nrf.USBD_INTENSET_EP0SETUP |
+ nrf.USBD_INTENSET_EPDATA |
+ nrf.USBD_INTENSET_EP0DATADONE)
SendZlp() // nrf.USBD.TASKS_EP0STATUS.Set(1)
}
}
diff --git a/src/machine/usb.go b/src/machine/usb.go
index bff0f7153..ebdacfdaf 100644
--- a/src/machine/usb.go
+++ b/src/machine/usb.go
@@ -9,6 +9,7 @@ import (
)
type USBDevice struct {
+ initcomplete bool
}
var (