Skip to content

Commit 133e32c

Browse files
authored
machine/rp2: merge common usb code (#4856)
* machine/rp2: merge common usb code * chore: add note on noinline reason
1 parent 41e501a commit 133e32c

File tree

6 files changed

+255
-465
lines changed

6 files changed

+255
-465
lines changed

src/machine/machine_atsamd21_usb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
334334
return true
335335
}
336336

337+
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
338+
//
337339
//go:noinline
338340
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
339341
l := uint16(len(data))

src/machine/machine_atsamd51_usb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
337337
return true
338338
}
339339

340+
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
341+
//
340342
//go:noinline
341343
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
342344
l := uint16(len(data))

src/machine/machine_nrf52840_usb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
252252
return true
253253
}
254254

255+
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
256+
//
255257
//go:noinline
256258
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
257259
count := len(data)

src/machine/machine_rp2040_usb.go

Lines changed: 2 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,6 @@ import (
66
"device/rp"
77
"machine/usb"
88
"runtime/interrupt"
9-
"runtime/volatile"
10-
"unsafe"
11-
)
12-
13-
var (
14-
sendOnEP0DATADONE struct {
15-
offset int
16-
data []byte
17-
pid uint32
18-
}
199
)
2010

2111
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
@@ -134,40 +124,6 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
134124
}
135125
}
136126

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-
171127
func handleUSBSetAddress(setup usb.Setup) bool {
172128
// Using 570μs timeout which is exactly the same as SAMD21.
173129
const ackTimeout = 570
@@ -188,191 +144,6 @@ func handleUSBSetAddress(setup usb.Setup) bool {
188144
return true
189145
}
190146

191-
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
192-
func SendUSBInPacket(ep uint32, data []byte) bool {
193-
sendUSBPacket(ep, data, 0)
194-
return true
195-
}
196-
197-
//go:noinline
198-
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
199-
count := len(data)
200-
if 0 < int(maxsize) && int(maxsize) < count {
201-
count = int(maxsize)
202-
}
203-
204-
if ep == 0 {
205-
if count > usb.EndpointPacketSize {
206-
count = usb.EndpointPacketSize
207-
208-
sendOnEP0DATADONE.offset = count
209-
sendOnEP0DATADONE.data = data
210-
} else {
211-
sendOnEP0DATADONE.offset = 0
212-
}
213-
epXdata0[ep] = true
214-
}
215-
216-
sendViaEPIn(ep, data, count)
217-
}
218-
219-
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {
220-
var b [cdcLineInfoSize]byte
221-
ep := 0
222-
223-
for !_usbDPSRAM.EPxBufferControl[ep].Out.HasBits(usbBuf0CtrlFull) {
224-
// TODO: timeout
225-
}
226-
227-
ctrl := _usbDPSRAM.EPxBufferControl[ep].Out.Get()
228-
_usbDPSRAM.EPxBufferControl[ep].Out.Set(usbBufferLen & usbBuf0CtrlLenMask)
229-
sz := ctrl & usbBuf0CtrlLenMask
230-
231-
copy(b[:], _usbDPSRAM.EPxBuffer[ep].Buffer0[:sz])
232-
233-
_usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid)
234-
_usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail)
235-
236-
return b, nil
237-
}
238-
239-
func handleEndpointRx(ep uint32) []byte {
240-
ctrl := _usbDPSRAM.EPxBufferControl[ep].Out.Get()
241-
_usbDPSRAM.EPxBufferControl[ep].Out.Set(usbBufferLen & usbBuf0CtrlLenMask)
242-
sz := ctrl & usbBuf0CtrlLenMask
243-
244-
return _usbDPSRAM.EPxBuffer[ep].Buffer0[:sz]
245-
}
246-
247-
func handleEndpointRxComplete(ep uint32) {
248-
epXdata0[ep] = !epXdata0[ep]
249-
if epXdata0[ep] || ep == 0 {
250-
_usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlData1Pid)
251-
}
252-
253-
_usbDPSRAM.EPxBufferControl[ep].Out.SetBits(usbBuf0CtrlAvail)
147+
func armEPZeroStall() {
148+
rp.USBCTRL_REGS.EP_STALL_ARM.Set(rp.USBCTRL_REGS_EP_STALL_ARM_EP0_IN)
254149
}
255-
256-
func SendZlp() {
257-
sendUSBPacket(0, []byte{}, 0)
258-
}
259-
260-
func sendViaEPIn(ep uint32, data []byte, count int) {
261-
// Prepare buffer control register value
262-
val := uint32(count) | usbBuf0CtrlAvail
263-
264-
// DATA0 or DATA1
265-
epXdata0[ep&0x7F] = !epXdata0[ep&0x7F]
266-
if !epXdata0[ep&0x7F] {
267-
val |= usbBuf0CtrlData1Pid
268-
}
269-
270-
// Mark as full
271-
val |= usbBuf0CtrlFull
272-
273-
copy(_usbDPSRAM.EPxBuffer[ep&0x7F].Buffer0[:], data[:count])
274-
_usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val)
275-
}
276-
277-
func sendStallViaEPIn(ep uint32) {
278-
// Prepare buffer control register value
279-
if ep == 0 {
280-
rp.USBCTRL_REGS.EP_STALL_ARM.Set(rp.USBCTRL_REGS_EP_STALL_ARM_EP0_IN)
281-
}
282-
val := uint32(usbBuf0CtrlFull)
283-
_usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val)
284-
val |= uint32(usbBuf0CtrlStall)
285-
_usbDPSRAM.EPxBufferControl[ep&0x7F].In.Set(val)
286-
}
287-
288-
type usbDPSRAM struct {
289-
// Note that EPxControl[0] is not EP0Control but 8-byte setup data.
290-
EPxControl [16]usbEndpointControlRegister
291-
292-
EPxBufferControl [16]usbBufferControlRegister
293-
294-
EPxBuffer [16]usbBuffer
295-
}
296-
297-
type usbEndpointControlRegister struct {
298-
In volatile.Register32
299-
Out volatile.Register32
300-
}
301-
type usbBufferControlRegister struct {
302-
In volatile.Register32
303-
Out volatile.Register32
304-
}
305-
306-
type usbBuffer struct {
307-
Buffer0 [usbBufferLen]byte
308-
Buffer1 [usbBufferLen]byte
309-
}
310-
311-
var (
312-
_usbDPSRAM = (*usbDPSRAM)(unsafe.Pointer(uintptr(0x50100000)))
313-
epXdata0 [16]bool
314-
setupBytes [8]byte
315-
)
316-
317-
func (d *usbDPSRAM) setupBytes() []byte {
318-
319-
data := d.EPxControl[usb.CONTROL_ENDPOINT].In.Get()
320-
setupBytes[0] = byte(data)
321-
setupBytes[1] = byte(data >> 8)
322-
setupBytes[2] = byte(data >> 16)
323-
setupBytes[3] = byte(data >> 24)
324-
325-
data = d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get()
326-
setupBytes[4] = byte(data)
327-
setupBytes[5] = byte(data >> 8)
328-
setupBytes[6] = byte(data >> 16)
329-
setupBytes[7] = byte(data >> 24)
330-
331-
return setupBytes[:]
332-
}
333-
334-
func (d *usbDPSRAM) clear() {
335-
for i := 0; i < len(d.EPxControl); i++ {
336-
d.EPxControl[i].In.Set(0)
337-
d.EPxControl[i].Out.Set(0)
338-
d.EPxBufferControl[i].In.Set(0)
339-
d.EPxBufferControl[i].Out.Set(0)
340-
}
341-
}
342-
343-
const (
344-
// DPRAM : Endpoint control register
345-
usbEpControlEnable = 0x80000000
346-
usbEpControlDoubleBuffered = 0x40000000
347-
usbEpControlInterruptPerBuff = 0x20000000
348-
usbEpControlInterruptPerDoubleBuff = 0x10000000
349-
usbEpControlEndpointType = 0x0c000000
350-
usbEpControlInterruptOnStall = 0x00020000
351-
usbEpControlInterruptOnNak = 0x00010000
352-
usbEpControlBufferAddress = 0x0000ffff
353-
354-
usbEpControlEndpointTypeControl = 0x00000000
355-
usbEpControlEndpointTypeISO = 0x04000000
356-
usbEpControlEndpointTypeBulk = 0x08000000
357-
usbEpControlEndpointTypeInterrupt = 0x0c000000
358-
359-
// Endpoint buffer control bits
360-
usbBuf1CtrlFull = 0x80000000
361-
usbBuf1CtrlLast = 0x40000000
362-
usbBuf1CtrlData0Pid = 0x20000000
363-
usbBuf1CtrlData1Pid = 0x00000000
364-
usbBuf1CtrlSel = 0x10000000
365-
usbBuf1CtrlStall = 0x08000000
366-
usbBuf1CtrlAvail = 0x04000000
367-
usbBuf1CtrlLenMask = 0x03FF0000
368-
usbBuf0CtrlFull = 0x00008000
369-
usbBuf0CtrlLast = 0x00004000
370-
usbBuf0CtrlData0Pid = 0x00000000
371-
usbBuf0CtrlData1Pid = 0x00002000
372-
usbBuf0CtrlSel = 0x00001000
373-
usbBuf0CtrlStall = 0x00000800
374-
usbBuf0CtrlAvail = 0x00000400
375-
usbBuf0CtrlLenMask = 0x000003FF
376-
377-
usbBufferLen = 64
378-
)

0 commit comments

Comments
 (0)