Skip to content

Commit 0066bb3

Browse files
committed
feat: allow bidirectional usb endpoint numbers
1 parent be33de1 commit 0066bb3

File tree

14 files changed

+226
-182
lines changed

14 files changed

+226
-182
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", 4580, 280, 0, 2264},
4646
{"microbit", "examples/serial", 2928, 388, 8, 2272},
47-
{"wioterminal", "examples/pininterrupt", 7387, 1489, 116, 6912},
47+
{"wioterminal", "examples/pininterrupt", 7442, 1502, 116, 6592},
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: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,6 @@ const (
1919

2020
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos = 14
2121
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask = 0x3FFF
22-
23-
NumberOfUSBEndpoints = 8
24-
)
25-
26-
var (
27-
endPoints = []uint32{
28-
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
29-
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
30-
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
31-
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
32-
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
33-
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
34-
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
35-
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
36-
}
3722
)
3823

3924
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
@@ -188,7 +173,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
188173

189174
// Now the actual transfer handlers, ignore endpoint number 0 (setup)
190175
var i uint32
191-
for i = 1; i < uint32(len(endPoints)); i++ {
176+
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
192177
// Check if endpoint has a pending interrupt
193178
epFlags := getEPINTFLAG(i)
194179
setEPINTFLAG(i, epFlags)
@@ -197,7 +182,8 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
197182
if usbRxHandler[i] == nil || usbRxHandler[i](buf) {
198183
AckUsbOutTransfer(i)
199184
}
200-
} else if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
185+
}
186+
if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
201187
if usbTxHandler[i] != nil {
202188
usbTxHandler[i]()
203189
}
@@ -215,8 +201,9 @@ func initEndpoint(ep, config uint32) {
215201
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
216202

217203
// set endpoint type
218-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
204+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))
219205

206+
// Set interrupt enable
220207
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
221208

222209
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
@@ -227,7 +214,7 @@ func initEndpoint(ep, config uint32) {
227214
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
228215

229216
// set endpoint type
230-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
217+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_BULK + 1))
231218

232219
// receive interrupts when current transfer complete
233220
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
@@ -246,7 +233,7 @@ func initEndpoint(ep, config uint32) {
246233
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
247234

248235
// set endpoint type
249-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
236+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))
250237

251238
// receive interrupts when current transfer complete
252239
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
@@ -265,11 +252,12 @@ func initEndpoint(ep, config uint32) {
265252
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
266253

267254
// set endpoint type
268-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
255+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_BULK + 1))
269256

270257
// NAK on endpoint IN, the bank is not yet filled in.
271258
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
272259

260+
// Set interrupt enable
273261
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
274262

275263
case usb.ENDPOINT_TYPE_CONTROL:
@@ -281,7 +269,7 @@ func initEndpoint(ep, config uint32) {
281269
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
282270

283271
// set endpoint type
284-
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
272+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_CONTROL + 1))
285273

286274
// Control IN
287275
// set packet size
@@ -291,7 +279,7 @@ func initEndpoint(ep, config uint32) {
291279
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
292280

293281
// set endpoint type
294-
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
282+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_CONTROL + 1))
295283

296284
// Prepare OUT endpoint for receive
297285
// set multi packet size for expected number of receive bytes on control OUT
@@ -426,7 +414,6 @@ func AckUsbOutTransfer(ep uint32) {
426414

427415
// set ready for next data
428416
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
429-
430417
}
431418

432419
func SendZlp() {
@@ -479,24 +466,49 @@ func getEPCFG(ep uint32) uint8 {
479466
}
480467
}
481468

482-
func setEPCFG(ep uint32, val uint8) {
469+
// Configure output endpoint in EPCFG
470+
func setEPCFGEPType0(ep uint32, val uint8) {
471+
switch ep {
472+
case 0:
473+
sam.USB_DEVICE.SetEPCFG0_EPTYPE0(val)
474+
case 1:
475+
sam.USB_DEVICE.SetEPCFG1_EPTYPE0(val)
476+
case 2:
477+
sam.USB_DEVICE.SetEPCFG2_EPTYPE0(val)
478+
case 3:
479+
sam.USB_DEVICE.SetEPCFG3_EPTYPE0(val)
480+
case 4:
481+
sam.USB_DEVICE.SetEPCFG4_EPTYPE0(val)
482+
case 5:
483+
sam.USB_DEVICE.SetEPCFG5_EPTYPE0(val)
484+
case 6:
485+
sam.USB_DEVICE.SetEPCFG6_EPTYPE0(val)
486+
case 7:
487+
sam.USB_DEVICE.SetEPCFG7_EPTYPE0(val)
488+
default:
489+
return
490+
}
491+
}
492+
493+
// Configure input endpoint in EPCFG
494+
func setEPCFGEPType1(ep uint32, val uint8) {
483495
switch ep {
484496
case 0:
485-
sam.USB_DEVICE.EPCFG0.Set(val)
497+
sam.USB_DEVICE.SetEPCFG0_EPTYPE1(val)
486498
case 1:
487-
sam.USB_DEVICE.EPCFG1.Set(val)
499+
sam.USB_DEVICE.SetEPCFG1_EPTYPE1(val)
488500
case 2:
489-
sam.USB_DEVICE.EPCFG2.Set(val)
501+
sam.USB_DEVICE.SetEPCFG2_EPTYPE1(val)
490502
case 3:
491-
sam.USB_DEVICE.EPCFG3.Set(val)
503+
sam.USB_DEVICE.SetEPCFG3_EPTYPE1(val)
492504
case 4:
493-
sam.USB_DEVICE.EPCFG4.Set(val)
505+
sam.USB_DEVICE.SetEPCFG4_EPTYPE1(val)
494506
case 5:
495-
sam.USB_DEVICE.EPCFG5.Set(val)
507+
sam.USB_DEVICE.SetEPCFG5_EPTYPE1(val)
496508
case 6:
497-
sam.USB_DEVICE.EPCFG6.Set(val)
509+
sam.USB_DEVICE.SetEPCFG6_EPTYPE1(val)
498510
case 7:
499-
sam.USB_DEVICE.EPCFG7.Set(val)
511+
sam.USB_DEVICE.SetEPCFG7_EPTYPE1(val)
500512
default:
501513
return
502514
}

src/machine/machine_atsamd51_usb.go

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,6 @@ const (
1919

2020
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos = 14
2121
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask = 0x3FFF
22-
23-
NumberOfUSBEndpoints = 8
24-
)
25-
26-
var (
27-
endPoints = []uint32{
28-
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
29-
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
30-
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
31-
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
32-
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
33-
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
34-
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
35-
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
36-
}
3722
)
3823

3924
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
@@ -191,7 +176,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
191176

192177
// Now the actual transfer handlers, ignore endpoint number 0 (setup)
193178
var i uint32
194-
for i = 1; i < uint32(len(endPoints)); i++ {
179+
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
195180
// Check if endpoint has a pending interrupt
196181
epFlags := getEPINTFLAG(i)
197182
setEPINTFLAG(i, epFlags)
@@ -200,7 +185,8 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
200185
if usbRxHandler[i] == nil || usbRxHandler[i](buf) {
201186
AckUsbOutTransfer(i)
202187
}
203-
} else if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) > 0 {
188+
}
189+
if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) > 0 {
204190
if usbTxHandler[i] != nil {
205191
usbTxHandler[i]()
206192
}
@@ -218,8 +204,9 @@ func initEndpoint(ep, config uint32) {
218204
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
219205

220206
// set endpoint type
221-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
207+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))
222208

209+
// Set interrupt enable
223210
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
224211

225212
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
@@ -230,7 +217,7 @@ func initEndpoint(ep, config uint32) {
230217
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
231218

232219
// set endpoint type
233-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
220+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_BULK + 1))
234221

235222
// receive interrupts when current transfer complete
236223
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
@@ -249,7 +236,7 @@ func initEndpoint(ep, config uint32) {
249236
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
250237

251238
// set endpoint type
252-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
239+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))
253240

254241
// receive interrupts when current transfer complete
255242
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
@@ -268,11 +255,12 @@ func initEndpoint(ep, config uint32) {
268255
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
269256

270257
// set endpoint type
271-
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
258+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_BULK + 1))
272259

273260
// NAK on endpoint IN, the bank is not yet filled in.
274261
setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK1RDY)
275262

263+
// Set interrupt enable
276264
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
277265

278266
case usb.ENDPOINT_TYPE_CONTROL:
@@ -284,7 +272,7 @@ func initEndpoint(ep, config uint32) {
284272
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
285273

286274
// set endpoint type
287-
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
275+
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_CONTROL + 1))
288276

289277
// Control IN
290278
// set packet size
@@ -294,7 +282,7 @@ func initEndpoint(ep, config uint32) {
294282
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
295283

296284
// set endpoint type
297-
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
285+
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_CONTROL + 1))
298286

299287
// Prepare OUT endpoint for receive
300288
// set multi packet size for expected number of receive bytes on control OUT
@@ -462,8 +450,14 @@ func getEPCFG(ep uint32) uint8 {
462450
return sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPCFG.Get()
463451
}
464452

465-
func setEPCFG(ep uint32, val uint8) {
466-
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPCFG.Set(val)
453+
// Configure output endpoint in EPCFG
454+
func setEPCFGEPType0(ep uint32, val uint8) {
455+
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].SetEPCFG_EPTYPE0(val)
456+
}
457+
458+
// Configure input endpoint in EPCFG
459+
func setEPCFGEPType1(ep uint32, val uint8) {
460+
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].SetEPCFG_EPTYPE1(val)
467461
}
468462

469463
func setEPSTATUSCLR(ep uint32, val uint8) {

src/machine/machine_nrf52840_usb.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import (
1111
"unsafe"
1212
)
1313

14-
const NumberOfUSBEndpoints = 8
15-
1614
var (
1715
sendOnEP0DATADONE struct {
1816
ptr *byte
@@ -22,17 +20,6 @@ var (
2220
epinen uint32
2321
epouten uint32
2422
easyDMABusy volatile.Register8
25-
26-
endPoints = []uint32{
27-
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
28-
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
29-
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
30-
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
31-
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
32-
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
33-
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
34-
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
35-
}
3623
)
3724

3825
// enterCriticalSection is used to protect access to easyDMA - only one thing
@@ -183,15 +170,16 @@ func handleUSBIRQ(interrupt.Interrupt) {
183170
epDataStatus := nrf.USBD.EPDATASTATUS.Get()
184171
nrf.USBD.EPDATASTATUS.Set(epDataStatus)
185172
var i uint32
186-
for i = 1; i < uint32(len(endPoints)); i++ {
173+
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
187174
// Check if endpoint has a pending interrupt
188175
inDataDone := epDataStatus&(nrf.USBD_EPDATASTATUS_EPIN1<<(i-1)) > 0
189176
outDataDone := epDataStatus&(nrf.USBD_EPDATASTATUS_EPOUT1<<(i-1)) > 0
190177
if inDataDone {
191178
if usbTxHandler[i] != nil {
192179
usbTxHandler[i]()
193180
}
194-
} else if outDataDone {
181+
}
182+
if outDataDone {
195183
enterCriticalSection()
196184
nrf.USBD.EPOUT[i].PTR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[i]))))
197185
count := nrf.USBD.SIZE.EPOUT[i].Get()
@@ -202,7 +190,7 @@ func handleUSBIRQ(interrupt.Interrupt) {
202190
}
203191

204192
// ENDEPOUT[n] events
205-
for i := 0; i < len(endPoints); i++ {
193+
for i := 0; i < len(outEndpoints); i++ {
206194
if nrf.USBD.EVENTS_ENDEPOUT[i].Get() > 0 {
207195
nrf.USBD.EVENTS_ENDEPOUT[i].Set(0)
208196
buf := handleEndpointRx(uint32(i))

0 commit comments

Comments
 (0)