Skip to content

Commit 8ef36ed

Browse files
niaowdeadprogram
authored andcommitted
machine: fix usb truncation?
Remove the sendUSBPacket maxLen param because this greatly confused the compiler. It also fixes a bug where the length provided to the hardware may not match the length of the packet. sendUSBPacket now panics if the sent packet is too big. I also fixed some of the string descriptor logic where we could create a packet without fully populating it. RP2* systems might require some more work since they are implemented very differently? I don't have any of those to test with yet, so maybe someone can deal with them in a seperate PR?
1 parent c7f62ba commit 8ef36ed

File tree

8 files changed

+130
-98
lines changed

8 files changed

+130
-98
lines changed

builder/sizes_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) {
4444
// microcontrollers
4545
{"hifive1b", "examples/echo", 3668, 280, 0, 2244},
4646
{"microbit", "examples/serial", 2694, 342, 8, 2248},
47-
{"wioterminal", "examples/pininterrupt", 7187, 1489, 116, 6888},
47+
{"wioterminal", "examples/pininterrupt", 6833, 1491, 120, 6888},
4848

4949
// TODO: also check wasm. Right now this is difficult, because
5050
// wasm binaries are run through wasm-opt and therefore the

src/machine/machine_atsamd21_usb.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
337337

338338
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
339339
func SendUSBInPacket(ep uint32, data []byte) bool {
340-
sendUSBPacket(ep, data, 0)
340+
sendUSBPacket(ep, data)
341341

342342
// clear transfer complete flag
343343
setEPINTFLAG(ep, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
@@ -351,27 +351,28 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
351351
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
352352
//
353353
//go:noinline
354-
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
355-
l := uint16(len(data))
356-
if 0 < maxsize && maxsize < l {
357-
l = maxsize
354+
func sendUSBPacket(ep uint32, data []byte) {
355+
// Select the corresponding buffer.
356+
buffer := udd_ep_control_cache_buffer[:]
357+
if ep != 0 {
358+
buffer = udd_ep_in_cache_buffer[ep][:]
358359
}
359360

360-
// Set endpoint address for sending data
361-
if ep == 0 {
362-
copy(udd_ep_control_cache_buffer[:], data[:l])
363-
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
364-
} else {
365-
copy(udd_ep_in_cache_buffer[ep][:], data[:l])
366-
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
367-
}
361+
// Copy the packet to the buffer.
362+
copy(buffer[:len(data)], data)
363+
364+
// Select the corresponding endpoint descriptor.
365+
endpoint := &usbEndpointDescriptors[ep].DeviceDescBank[1]
366+
367+
// Set the endpoint address.
368+
endpoint.ADDR.Set(uint32(uintptr(unsafe.Pointer(unsafe.SliceData(buffer)))))
368369

369370
// clear multi-packet size which is total bytes already sent
370-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
371+
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
371372

372373
// set byte count, which is total number of bytes to be sent
373-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
374-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
374+
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
375+
endpoint.PCKSIZE.SetBits((uint32(len(data)) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
375376
}
376377

377378
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {

src/machine/machine_atsamd51_usb.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
340340

341341
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
342342
func SendUSBInPacket(ep uint32, data []byte) bool {
343-
sendUSBPacket(ep, data, 0)
343+
sendUSBPacket(ep, data)
344344

345345
// clear transfer complete flag
346346
setEPINTFLAG(ep, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
@@ -354,27 +354,28 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
354354
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
355355
//
356356
//go:noinline
357-
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
358-
l := uint16(len(data))
359-
if 0 < maxsize && maxsize < l {
360-
l = maxsize
357+
func sendUSBPacket(ep uint32, data []byte) {
358+
// Select the corresponding buffer.
359+
buffer := udd_ep_control_cache_buffer[:]
360+
if ep != 0 {
361+
buffer = udd_ep_in_cache_buffer[ep][:]
361362
}
362363

363-
// Set endpoint address for sending data
364-
if ep == 0 {
365-
copy(udd_ep_control_cache_buffer[:], data[:l])
366-
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_control_cache_buffer))))
367-
} else {
368-
copy(udd_ep_in_cache_buffer[ep][:], data[:l])
369-
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
370-
}
364+
// Copy the packet to the buffer.
365+
copy(buffer[:len(data)], data)
366+
367+
// Select the corresponding endpoint descriptor.
368+
endpoint := &usbEndpointDescriptors[ep].DeviceDescBank[1]
369+
370+
// Set the endpoint address.
371+
endpoint.ADDR.Set(uint32(uintptr(unsafe.Pointer(unsafe.SliceData(buffer)))))
371372

372373
// clear multi-packet size which is total bytes already sent
373-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
374+
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask << usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos)
374375

375376
// set byte count, which is total number of bytes to be sent
376-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
377-
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
377+
endpoint.PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
378+
endpoint.PCKSIZE.SetBits((uint32(len(data)) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
378379
}
379380

380381
func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {

src/machine/machine_nrf52840_usb.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ func initEndpoint(ep, config uint32) {
256256

257257
// SendUSBInPacket sends a packet for USBHID (interrupt in / bulk in).
258258
func SendUSBInPacket(ep uint32, data []byte) bool {
259-
sendUSBPacket(ep, data, 0)
259+
sendUSBPacket(ep, data)
260260

261261
// clear transfer complete flag
262262
nrf.USBD.INTENCLR.Set(nrf.USBD_INTENCLR_ENDEPOUT0 << 4)
@@ -267,33 +267,32 @@ func SendUSBInPacket(ep uint32, data []byte) bool {
267267
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
268268
//
269269
//go:noinline
270-
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
270+
func sendUSBPacket(ep uint32, data []byte) {
271+
// Select the corresponding buffer.
271272
count := len(data)
272-
if 0 < int(maxsize) && int(maxsize) < count {
273-
count = int(maxsize)
274-
}
275-
273+
var buffer []byte
276274
if ep == 0 {
277-
copy(udd_ep_control_cache_buffer[:], data[:count])
275+
buffer = udd_ep_control_cache_buffer[:]
278276
if count > usb.EndpointPacketSize {
277+
// The packet must be sent in chunks.
279278
sendOnEP0DATADONE.offset = usb.EndpointPacketSize
280-
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[sendOnEP0DATADONE.offset]
279+
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[usb.EndpointPacketSize]
281280
sendOnEP0DATADONE.count = count - usb.EndpointPacketSize
282281
count = usb.EndpointPacketSize
283282
}
284-
sendViaEPIn(
285-
ep,
286-
&udd_ep_control_cache_buffer[0],
287-
count,
288-
)
289283
} else {
290-
copy(udd_ep_in_cache_buffer[ep][:], data[:count])
291-
sendViaEPIn(
292-
ep,
293-
&udd_ep_in_cache_buffer[ep][0],
294-
count,
295-
)
284+
buffer = udd_ep_in_cache_buffer[ep][:]
296285
}
286+
287+
// Copy the packet to the buffer.
288+
copy(buffer[:len(data)], data)
289+
290+
// Send the first chunk of the packet.
291+
sendViaEPIn(
292+
ep,
293+
&buffer[0],
294+
count,
295+
)
297296
}
298297

299298
func handleEndpointRx(ep uint32) []byte {

src/machine/machine_rp2040_usb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
128128
const ackTimeout = 570
129129

130130
rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_ACK_REC)
131-
sendUSBPacket(0, []byte{}, 0)
131+
sendUSBPacket(0, []byte{})
132132

133133
// Wait for transfer to complete with a timeout.
134134
t := timer.timeElapsed()

src/machine/machine_rp2350_usb.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func handleUSBSetAddress(setup usb.Setup) bool {
131131
const ackTimeout = 570
132132

133133
rp.USB.SIE_STATUS.Set(rp.USB_SIE_STATUS_ACK_REC)
134-
sendUSBPacket(0, []byte{}, 0)
134+
sendUSBPacket(0, []byte{})
135135

136136
// Wait for transfer to complete with a timeout.
137137
t := timer.timeElapsed()

src/machine/machine_rp2_usb.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,15 @@ func initEndpoint(ep, config uint32) {
7272

7373
// SendUSBInPacket sends a packet for USB (interrupt in / bulk in).
7474
func SendUSBInPacket(ep uint32, data []byte) bool {
75-
sendUSBPacket(ep, data, 0)
75+
sendUSBPacket(ep, data)
7676
return true
7777
}
7878

7979
// Prevent file size increases: https://github.com/tinygo-org/tinygo/pull/998
8080
//
8181
//go:noinline
82-
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
82+
func sendUSBPacket(ep uint32, data []byte) {
8383
count := len(data)
84-
if 0 < int(maxsize) && int(maxsize) < count {
85-
count = int(maxsize)
86-
}
87-
8884
if ep == 0 {
8985
if count > usb.EndpointPacketSize {
9086
count = usb.EndpointPacketSize
@@ -145,7 +141,7 @@ func setEPDataPID(ep uint32, dataOne bool) {
145141
}
146142

147143
func SendZlp() {
148-
sendUSBPacket(0, []byte{}, 0)
144+
sendUSBPacket(0, []byte{})
149145
}
150146

151147
func sendViaEPIn(ep uint32, data []byte, count int) {

0 commit comments

Comments
 (0)