Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builder/sizes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) {
// microcontrollers
{"hifive1b", "examples/echo", 4580, 280, 0, 2264},
{"microbit", "examples/serial", 2928, 388, 8, 2272},
{"wioterminal", "examples/pininterrupt", 7387, 1489, 116, 6912},
{"wioterminal", "examples/pininterrupt", 7442, 1502, 116, 6592},

// TODO: also check wasm. Right now this is difficult, because
// wasm binaries are run through wasm-opt and therefore the
Expand Down
78 changes: 45 additions & 33 deletions src/machine/machine_atsamd21_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,6 @@ const (

usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos = 14
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask = 0x3FFF

NumberOfUSBEndpoints = 8
)

var (
endPoints = []uint32{
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
}
)

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

// Now the actual transfer handlers, ignore endpoint number 0 (setup)
var i uint32
for i = 1; i < uint32(len(endPoints)); i++ {
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
// Check if endpoint has a pending interrupt
epFlags := getEPINTFLAG(i)
setEPINTFLAG(i, epFlags)
Expand All @@ -197,7 +182,8 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
if usbRxHandler[i] == nil || usbRxHandler[i](buf) {
AckUsbOutTransfer(i)
}
} else if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
}
if (epFlags & sam.USB_DEVICE_EPINTFLAG_TRCPT1) > 0 {
if usbTxHandler[i] != nil {
usbTxHandler[i]()
}
Expand All @@ -215,8 +201,9 @@ func initEndpoint(ep, config uint32) {
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))

// Set interrupt enable
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_BULK + 1))

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_BULK + 1))

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

// Set interrupt enable
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)

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

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

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

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

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

// set ready for next data
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)

}

func SendZlp() {
Expand Down Expand Up @@ -479,24 +466,49 @@ func getEPCFG(ep uint32) uint8 {
}
}

func setEPCFG(ep uint32, val uint8) {
// Configure output endpoint in EPCFG
func setEPCFGEPType0(ep uint32, val uint8) {
switch ep {
case 0:
sam.USB_DEVICE.SetEPCFG0_EPTYPE0(val)
case 1:
sam.USB_DEVICE.SetEPCFG1_EPTYPE0(val)
case 2:
sam.USB_DEVICE.SetEPCFG2_EPTYPE0(val)
case 3:
sam.USB_DEVICE.SetEPCFG3_EPTYPE0(val)
case 4:
sam.USB_DEVICE.SetEPCFG4_EPTYPE0(val)
case 5:
sam.USB_DEVICE.SetEPCFG5_EPTYPE0(val)
case 6:
sam.USB_DEVICE.SetEPCFG6_EPTYPE0(val)
case 7:
sam.USB_DEVICE.SetEPCFG7_EPTYPE0(val)
default:
return
}
}

// Configure input endpoint in EPCFG
func setEPCFGEPType1(ep uint32, val uint8) {
switch ep {
case 0:
sam.USB_DEVICE.EPCFG0.Set(val)
sam.USB_DEVICE.SetEPCFG0_EPTYPE1(val)
case 1:
sam.USB_DEVICE.EPCFG1.Set(val)
sam.USB_DEVICE.SetEPCFG1_EPTYPE1(val)
case 2:
sam.USB_DEVICE.EPCFG2.Set(val)
sam.USB_DEVICE.SetEPCFG2_EPTYPE1(val)
case 3:
sam.USB_DEVICE.EPCFG3.Set(val)
sam.USB_DEVICE.SetEPCFG3_EPTYPE1(val)
case 4:
sam.USB_DEVICE.EPCFG4.Set(val)
sam.USB_DEVICE.SetEPCFG4_EPTYPE1(val)
case 5:
sam.USB_DEVICE.EPCFG5.Set(val)
sam.USB_DEVICE.SetEPCFG5_EPTYPE1(val)
case 6:
sam.USB_DEVICE.EPCFG6.Set(val)
sam.USB_DEVICE.SetEPCFG6_EPTYPE1(val)
case 7:
sam.USB_DEVICE.EPCFG7.Set(val)
sam.USB_DEVICE.SetEPCFG7_EPTYPE1(val)
default:
return
}
Expand Down
44 changes: 19 additions & 25 deletions src/machine/machine_atsamd51_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,6 @@ const (

usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Pos = 14
usb_DEVICE_PCKSIZE_MULTI_PACKET_SIZE_Mask = 0x3FFF

NumberOfUSBEndpoints = 8
)

var (
endPoints = []uint32{
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
}
)

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

// Now the actual transfer handlers, ignore endpoint number 0 (setup)
var i uint32
for i = 1; i < uint32(len(endPoints)); i++ {
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
// Check if endpoint has a pending interrupt
epFlags := getEPINTFLAG(i)
setEPINTFLAG(i, epFlags)
Expand All @@ -200,7 +185,8 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
if usbRxHandler[i] == nil || usbRxHandler[i](buf) {
AckUsbOutTransfer(i)
}
} else if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) > 0 {
}
if (epFlags & sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1) > 0 {
if usbTxHandler[i] != nil {
usbTxHandler[i]()
}
Expand All @@ -218,8 +204,9 @@ func initEndpoint(ep, config uint32) {
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))

// Set interrupt enable
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_BULK + 1))

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
setEPCFGEPType0(ep, (usb.ENDPOINT_TYPE_INTERRUPT + 1))

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

// set endpoint type
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
setEPCFGEPType1(ep, (usb.ENDPOINT_TYPE_BULK + 1))

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

// Set interrupt enable
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)

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

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

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

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

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

func setEPCFG(ep uint32, val uint8) {
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPCFG.Set(val)
// Configure output endpoint in EPCFG
func setEPCFGEPType0(ep uint32, val uint8) {
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].SetEPCFG_EPTYPE0(val)
}

// Configure input endpoint in EPCFG
func setEPCFGEPType1(ep uint32, val uint8) {
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].SetEPCFG_EPTYPE1(val)
}

func setEPSTATUSCLR(ep uint32, val uint8) {
Expand Down
20 changes: 4 additions & 16 deletions src/machine/machine_nrf52840_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"unsafe"
)

const NumberOfUSBEndpoints = 8

var (
sendOnEP0DATADONE struct {
ptr *byte
Expand All @@ -22,17 +20,6 @@ var (
epinen uint32
epouten uint32
easyDMABusy volatile.Register8

endPoints = []uint32{
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
}
)

// enterCriticalSection is used to protect access to easyDMA - only one thing
Expand Down Expand Up @@ -183,15 +170,16 @@ func handleUSBIRQ(interrupt.Interrupt) {
epDataStatus := nrf.USBD.EPDATASTATUS.Get()
nrf.USBD.EPDATASTATUS.Set(epDataStatus)
var i uint32
for i = 1; i < uint32(len(endPoints)); i++ {
for i = 1; i < uint32(NumberOfUSBEndpoints); i++ {
// Check if endpoint has a pending interrupt
inDataDone := epDataStatus&(nrf.USBD_EPDATASTATUS_EPIN1<<(i-1)) > 0
outDataDone := epDataStatus&(nrf.USBD_EPDATASTATUS_EPOUT1<<(i-1)) > 0
if inDataDone {
if usbTxHandler[i] != nil {
usbTxHandler[i]()
}
} else if outDataDone {
}
if outDataDone {
enterCriticalSection()
nrf.USBD.EPOUT[i].PTR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[i]))))
count := nrf.USBD.SIZE.EPOUT[i].Get()
Expand All @@ -202,7 +190,7 @@ func handleUSBIRQ(interrupt.Interrupt) {
}

// ENDEPOUT[n] events
for i := 0; i < len(endPoints); i++ {
for i := 0; i < len(outEndpoints); i++ {
if nrf.USBD.EVENTS_ENDEPOUT[i].Get() > 0 {
nrf.USBD.EVENTS_ENDEPOUT[i].Set(0)
buf := handleEndpointRx(uint32(i))
Expand Down
Loading
Loading