diff options
author | sago35 <[email protected]> | 2022-07-07 19:06:47 +0900 |
---|---|---|
committer | Ron Evans <[email protected]> | 2022-07-07 21:04:41 +0200 |
commit | f1e699701801f020ce87e3afa1fc53de52fe000d (patch) | |
tree | 0b3174b6cfa04cf2736bcb4ecf8ba5dfa31f56d7 | |
parent | 335a7ad0b72aa5b5248c79bd77cc5e1ed6e1c183 (diff) | |
download | tinygo-f1e699701801f020ce87e3afa1fc53de52fe000d.tar.gz tinygo-f1e699701801f020ce87e3afa1fc53de52fe000d.zip |
atsamd21,atsamd51,nrf52840: improve usb-device initialization
-rw-r--r-- | src/machine/machine_atsamd21_usb.go | 6 | ||||
-rw-r--r-- | src/machine/machine_atsamd51_usb.go | 6 | ||||
-rw-r--r-- | src/machine/machine_nrf52840_usb.go | 47 | ||||
-rw-r--r-- | src/machine/usb.go | 1 |
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 ( |