github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_rp2040_usb.go (about) 1 //go:build rp2040 2 3 package machine 4 5 import ( 6 "device/rp" 7 "machine/usb" 8 "runtime/interrupt" 9 "runtime/volatile" 10 "unsafe" 11 ) 12 13 var ( 14 sendOnEP0DATADONE struct { 15 offset int 16 data []byte 17 pid uint32 18 } 19 ) 20 21 // Configure the USB peripheral. The config is here for compatibility with the UART interface. 22 func (dev *USBDevice) Configure(config UARTConfig) { 23 // Reset usb controller 24 resetBlock(rp.RESETS_RESET_USBCTRL) 25 unresetBlockWait(rp.RESETS_RESET_USBCTRL) 26 27 // Clear any previous state in dpram just in case 28 usbDPSRAM.clear() 29 30 // Enable USB interrupt at processor 31 rp.USBCTRL_REGS.INTE.Set(0) 32 intr := interrupt.New(rp.IRQ_USBCTRL_IRQ, handleUSBIRQ) 33 intr.SetPriority(0x00) 34 intr.Enable() 35 irqSet(rp.IRQ_USBCTRL_IRQ, true) 36 37 // Mux the controller to the onboard usb phy 38 rp.USBCTRL_REGS.USB_MUXING.Set(rp.USBCTRL_REGS_USB_MUXING_TO_PHY | rp.USBCTRL_REGS_USB_MUXING_SOFTCON) 39 40 // Force VBUS detect so the device thinks it is plugged into a host 41 rp.USBCTRL_REGS.USB_PWR.Set(rp.USBCTRL_REGS_USB_PWR_VBUS_DETECT | rp.USBCTRL_REGS_USB_PWR_VBUS_DETECT_OVERRIDE_EN) 42 43 // Enable the USB controller in device mode. 44 rp.USBCTRL_REGS.MAIN_CTRL.Set(rp.USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN) 45 46 // Enable an interrupt per EP0 transaction 47 rp.USBCTRL_REGS.SIE_CTRL.Set(rp.USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF) 48 49 // Enable interrupts for when a buffer is done, when the bus is reset, 50 // and when a setup packet is received 51 rp.USBCTRL_REGS.INTE.Set(rp.USBCTRL_REGS_INTE_BUFF_STATUS | 52 rp.USBCTRL_REGS_INTE_BUS_RESET | 53 rp.USBCTRL_REGS_INTE_SETUP_REQ) 54 55 // Present full speed device by enabling pull up on DP 56 rp.USBCTRL_REGS.SIE_CTRL.SetBits(rp.USBCTRL_REGS_SIE_CTRL_PULLUP_EN) 57 } 58 59 func handleUSBIRQ(intr interrupt.Interrupt) { 60 status := rp.USBCTRL_REGS.INTS.Get() 61 62 // Setup packet received 63 if (status & rp.USBCTRL_REGS_INTS_SETUP_REQ) > 0 { 64 rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_SETUP_REC) 65 setup := usb.NewSetup(usbDPSRAM.setupBytes()) 66 67 ok := false 68 if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD { 69 // Standard Requests 70 ok = handleStandardSetup(setup) 71 } else { 72 // Class Interface Requests 73 if setup.WIndex < uint16(len(usbSetupHandler)) && usbSetupHandler[setup.WIndex] != nil { 74 ok = usbSetupHandler[setup.WIndex](setup) 75 } 76 } 77 78 if !ok { 79 // Stall endpoint? 80 sendStallViaEPIn(0) 81 } 82 83 } 84 85 // Buffer status, one or more buffers have completed 86 if (status & rp.USBCTRL_REGS_INTS_BUFF_STATUS) > 0 { 87 if sendOnEP0DATADONE.offset > 0 { 88 ep := uint32(0) 89 data := sendOnEP0DATADONE.data 90 count := len(data) - sendOnEP0DATADONE.offset 91 if ep == 0 && count > usb.EndpointPacketSize { 92 count = usb.EndpointPacketSize 93 } 94 95 sendViaEPIn(ep, data[sendOnEP0DATADONE.offset:], count) 96 sendOnEP0DATADONE.offset += count 97 if sendOnEP0DATADONE.offset == len(data) { 98 sendOnEP0DATADONE.offset = 0 99 } 100 } 101 102 s2 := rp.USBCTRL_REGS.BUFF_STATUS.Get() 103 104 // OUT (PC -> rp2040) 105 for i := 0; i < 16; i++ { 106 if s2&(1<<(i*2+1)) > 0 { 107 buf := handleEndpointRx(uint32(i)) 108 if usbRxHandler[i] != nil { 109 usbRxHandler[i](buf) 110 } 111 handleEndpointRxComplete(uint32(i)) 112 } 113 } 114 115 // IN (rp2040 -> PC) 116 for i := 0; i < 16; i++ { 117 if s2&(1<<(i*2)) > 0 { 118 if usbTxHandler[i] != nil { 119 usbTxHandler[i]() 120 } 121 } 122 } 123 124 rp.USBCTRL_REGS.BUFF_STATUS.Set(s2) 125 } 126 127 // Bus is reset 128 if (status & rp.USBCTRL_REGS_INTS_BUS_RESET) > 0 { 129 rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_BUS_RESET) 130 fixRP2040UsbDeviceEnumeration() 131 132 rp.USBCTRL_REGS.ADDR_ENDP.Set(0) 133 initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL) 134 } 135 } 136 137 func initEndpoint(ep, config uint32) { 138 val := uint32(usbEpControlEnable) | uint32(usbEpControlInterruptPerBuff) 139 offset := ep*2*USBBufferLen + 0x100 140 val |= offset 141 142 switch config { 143 case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn: 144 val |= usbEpControlEndpointTypeInterrupt 145 usbDPSRAM.EPxControl[ep].In.Set(val) 146 147 case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut: 148 val |= usbEpControlEndpointTypeBulk 149 usbDPSRAM.EPxControl[ep].Out.Set(val) 150 usbDPSRAM.EPxBufferControl[ep].Out.Set(USBBufferLen & usbBuf0CtrlLenMask) 151 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail) 152 153 case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut: 154 val |= usbEpControlEndpointTypeInterrupt 155 usbDPSRAM.EPxControl[ep].Out.Set(val) 156 usbDPSRAM.EPxBufferControl[ep].Out.Set(USBBufferLen & usbBuf0CtrlLenMask) 157 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail) 158 159 case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn: 160 val |= usbEpControlEndpointTypeBulk 161 usbDPSRAM.EPxControl[ep].In.Set(val) 162 163 case usb.ENDPOINT_TYPE_CONTROL: 164 val |= usbEpControlEndpointTypeControl 165 usbDPSRAM.EPxBufferControl[ep].Out.Set(usbBuf0CtrlData1Pid) 166 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail) 167 168 } 169 } 170 171 func handleUSBSetAddress(setup usb.Setup) bool { 172 sendUSBPacket(0, []byte{}, 0) 173 174 // last, set the device address to that requested by host 175 // wait for transfer to complete 176 timeout := 3000 177 rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_ACK_REC) 178 for (rp.USBCTRL_REGS.SIE_STATUS.Get() & rp.USBCTRL_REGS_SIE_STATUS_ACK_REC) == 0 { 179 timeout-- 180 if timeout == 0 { 181 return true 182 } 183 } 184 185 rp.USBCTRL_REGS.ADDR_ENDP.Set(uint32(setup.WValueL) & rp.USBCTRL_REGS_ADDR_ENDP_ADDRESS_Msk) 186 187 return true 188 } 189 190 // SendUSBInPacket sends a packet for USB (interrupt in / bulk in). 191 func SendUSBInPacket(ep uint32, data []byte) bool { 192 sendUSBPacket(ep, data, 0) 193 return true 194 } 195 196 //go:noinline 197 func sendUSBPacket(ep uint32, data []byte, maxsize uint16) { 198 count := len(data) 199 if 0 < int(maxsize) && int(maxsize) < count { 200 count = int(maxsize) 201 } 202 203 if ep == 0 { 204 if count > usb.EndpointPacketSize { 205 count = usb.EndpointPacketSize 206 207 sendOnEP0DATADONE.offset = count 208 sendOnEP0DATADONE.data = data 209 } else { 210 sendOnEP0DATADONE.offset = 0 211 } 212 epXdata0[ep] = true 213 } 214 215 sendViaEPIn(ep, data, count) 216 } 217 218 func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) { 219 var b [cdcLineInfoSize]byte 220 ep := 0 221 222 for !usbDPSRAM.EPxBufferControl[ep].Out.HasBits(usbBuf0CtrlFull) { 223 // TODO: timeout 224 } 225 226 ctrl := usbDPSRAM.EPxBufferControl[ep].Out.Get() 227 usbDPSRAM.EPxBufferControl[ep].Out.Set(USBBufferLen & usbBuf0CtrlLenMask) 228 sz := ctrl & usbBuf0CtrlLenMask 229 230 copy(b[:], usbDPSRAM.EPxBuffer[ep].Buffer0[:sz]) 231 232 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid) 233 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail) 234 235 return b, nil 236 } 237 238 func handleEndpointRx(ep uint32) []byte { 239 ctrl := usbDPSRAM.EPxBufferControl[ep].Out.Get() 240 usbDPSRAM.EPxBufferControl[ep].Out.Set(USBBufferLen & usbBuf0CtrlLenMask) 241 sz := ctrl & usbBuf0CtrlLenMask 242 243 return usbDPSRAM.EPxBuffer[ep].Buffer0[:sz] 244 } 245 246 func handleEndpointRxComplete(ep uint32) { 247 epXdata0[ep] = !epXdata0[ep] 248 if epXdata0[ep] || ep == 0 { 249 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid) 250 } 251 252 usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail) 253 } 254 255 func SendZlp() { 256 sendUSBPacket(0, []byte{}, 0) 257 } 258 259 func sendViaEPIn(ep uint32, data []byte, count int) { 260 // Prepare buffer control register value 261 val := uint32(count) | usbBuf0CtrlAvail 262 263 // DATA0 or DATA1 264 epXdata0[ep&0x7F] = !epXdata0[ep&0x7F] 265 if !epXdata0[ep&0x7F] { 266 val |= usbBuf0CtrlData1Pid 267 } 268 269 // Mark as full 270 val |= usbBuf0CtrlFull 271 272 copy(usbDPSRAM.EPxBuffer[ep&0x7F].Buffer0[:], data[:count]) 273 usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val) 274 } 275 276 func sendStallViaEPIn(ep uint32) { 277 // Prepare buffer control register value 278 if ep == 0 { 279 rp.USBCTRL_REGS.EP_STALL_ARM.Set(rp.USBCTRL_REGS_EP_STALL_ARM_EP0_IN) 280 } 281 val := uint32(usbBuf0CtrlFull) 282 usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val) 283 val |= uint32(usbBuf0CtrlStall) 284 usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val) 285 } 286 287 type USBDPSRAM struct { 288 // Note that EPxControl[0] is not EP0Control but 8-byte setup data. 289 EPxControl [16]USBEndpointControlRegister 290 291 EPxBufferControl [16]USBBufferControlRegister 292 293 EPxBuffer [16]USBBuffer 294 } 295 296 type USBEndpointControlRegister struct { 297 In volatile.Register32 298 Out volatile.Register32 299 } 300 type USBBufferControlRegister struct { 301 In volatile.Register32 302 Out volatile.Register32 303 } 304 305 type USBBuffer struct { 306 Buffer0 [USBBufferLen]byte 307 Buffer1 [USBBufferLen]byte 308 } 309 310 var ( 311 usbDPSRAM = (*USBDPSRAM)(unsafe.Pointer(uintptr(0x50100000))) 312 epXdata0 [16]bool 313 setupBytes [8]byte 314 ) 315 316 func (d *USBDPSRAM) setupBytes() []byte { 317 318 data := d.EPxControl[usb.CONTROL_ENDPOINT].In.Get() 319 setupBytes[0] = byte(data) 320 setupBytes[1] = byte(data >> 8) 321 setupBytes[2] = byte(data >> 16) 322 setupBytes[3] = byte(data >> 24) 323 324 data = d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get() 325 setupBytes[4] = byte(data) 326 setupBytes[5] = byte(data >> 8) 327 setupBytes[6] = byte(data >> 16) 328 setupBytes[7] = byte(data >> 24) 329 330 return setupBytes[:] 331 } 332 333 func (d *USBDPSRAM) clear() { 334 for i := 0; i < len(d.EPxControl); i++ { 335 d.EPxControl[i].In.Set(0) 336 d.EPxControl[i].Out.Set(0) 337 d.EPxBufferControl[i].In.Set(0) 338 d.EPxBufferControl[i].Out.Set(0) 339 } 340 } 341 342 const ( 343 // DPRAM : Endpoint control register 344 usbEpControlEnable = 0x80000000 345 usbEpControlDoubleBuffered = 0x40000000 346 usbEpControlInterruptPerBuff = 0x20000000 347 usbEpControlInterruptPerDoubleBuff = 0x10000000 348 usbEpControlEndpointType = 0x0c000000 349 usbEpControlInterruptOnStall = 0x00020000 350 usbEpControlInterruptOnNak = 0x00010000 351 usbEpControlBufferAddress = 0x0000ffff 352 353 usbEpControlEndpointTypeControl = 0x00000000 354 usbEpControlEndpointTypeISO = 0x04000000 355 usbEpControlEndpointTypeBulk = 0x08000000 356 usbEpControlEndpointTypeInterrupt = 0x0c000000 357 358 // Endpoint buffer control bits 359 usbBuf1CtrlFull = 0x80000000 360 usbBuf1CtrlLast = 0x40000000 361 usbBuf1CtrlData0Pid = 0x20000000 362 usbBuf1CtrlData1Pid = 0x00000000 363 usbBuf1CtrlSel = 0x10000000 364 usbBuf1CtrlStall = 0x08000000 365 usbBuf1CtrlAvail = 0x04000000 366 usbBuf1CtrlLenMask = 0x03FF0000 367 usbBuf0CtrlFull = 0x00008000 368 usbBuf0CtrlLast = 0x00004000 369 usbBuf0CtrlData0Pid = 0x00000000 370 usbBuf0CtrlData1Pid = 0x00002000 371 usbBuf0CtrlSel = 0x00001000 372 usbBuf0CtrlStall = 0x00000800 373 usbBuf0CtrlAvail = 0x00000400 374 usbBuf0CtrlLenMask = 0x000003FF 375 376 USBBufferLen = 64 377 )