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
66 changes: 66 additions & 0 deletions src/machine/machine_nrf52840_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,69 @@ func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {

return b, nil
}

// Set the USB endpoint Packet ID to DATA0 or DATA1.
// In endpoints must have bit 7 (0x80) set.
func setEPDataPID(ep uint32, dataOne bool) {
val := ep
if dataOne {
val |= nrf.USBD_DTOGGLE_VALUE_Data1 << nrf.USBD_DTOGGLE_VALUE_Pos
} else {
val |= nrf.USBD_DTOGGLE_VALUE_Data0 << nrf.USBD_DTOGGLE_VALUE_Pos
}
nrf.USBD.DTOGGLE.Set(val)
}

// Set ENDPOINT_HALT/stall status on a USB IN endpoint.
func (dev *USBDevice) SetStallEPIn(ep uint32) {
if ep&0x7F == 0 {
nrf.USBD.TASKS_EP0STALL.Set(1)
} else if ep&0x7F < NumberOfUSBEndpoints {
// Stall In Endpoint
val := 0x100 | 0x80 | ep
nrf.USBD.EPSTALL.Set(val)
}
}

// Set ENDPOINT_HALT/stall status on a USB OUT endpoint.
func (dev *USBDevice) SetStallEPOut(ep uint32) {
if ep == 0 {
nrf.USBD.TASKS_EP0STALL.Set(1)
} else if ep < NumberOfUSBEndpoints {
// Stall Out Endpoint
val := 0x100 | 0x00 | ep
nrf.USBD.EPSTALL.Set(val)
}
}

// Clear the ENDPOINT_HALT/stall on a USB IN endpoint.
func (dev *USBDevice) ClearStallEPIn(ep uint32) {
if ep&0x7F == 0 {
nrf.USBD.TASKS_EP0STALL.Set(0)
} else if ep&0x7F < NumberOfUSBEndpoints {
// Reset the endpoint data PID to DATA0
ep |= 0x80 // Set endpoint direction bit
setEPDataPID(ep, false)

// No-stall In Endpoint
val := 0x000 | 0x80 | ep
nrf.USBD.EPSTALL.Set(val)
}
}

// Clear the ENDPOINT_HALT/stall on a USB OUT endpoint.
func (dev *USBDevice) ClearStallEPOut(ep uint32) {
if ep == 0 {
nrf.USBD.TASKS_EP0STALL.Set(0)
} else if ep < NumberOfUSBEndpoints {
// Reset the endpoint data PID to DATA0
setEPDataPID(ep, false)

// No-stall Out Endpoint
val := 0x000 | 0x00 | ep
nrf.USBD.EPSTALL.Set(val)

// Write a value to the SIZE register to allow nRF to ACK/accept data
nrf.USBD.SIZE.EPOUT[ep].Set(0)
}
}
5 changes: 3 additions & 2 deletions src/machine/usb/msc/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"machine"
"machine/usb"
"time"
)

Expand All @@ -17,8 +18,8 @@ func (m *msc) RegisterBlockDevice(dev machine.BlockDevice) {
m.dev = dev

if cap(m.blockCache) != int(dev.WriteBlockSize()) {
m.blockCache = make([]byte, dev.WriteBlockSize())
m.buf = make([]byte, dev.WriteBlockSize())
m.blockCache = make([]byte, max(usb.EndpointPacketSize, dev.WriteBlockSize()))
m.buf = make([]byte, max(usb.EndpointPacketSize, dev.WriteBlockSize()))
}

m.blockSizeRaw = uint32(m.dev.WriteBlockSize())
Expand Down
4 changes: 2 additions & 2 deletions src/machine/usb/msc/msc.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ func newMSC(dev machine.BlockDevice) *msc {
maxPacketSize := descriptor.EndpointMSCIN.GetMaxPacketSize()
m := &msc{
// Some platforms require reads/writes to be aligned to the full underlying hardware block
blockCache: make([]byte, dev.WriteBlockSize()),
blockCache: make([]byte, max(usb.EndpointPacketSize, dev.WriteBlockSize())),
blockSizeUSB: 512,
buf: make([]byte, dev.WriteBlockSize()),
buf: make([]byte, max(usb.EndpointPacketSize, dev.WriteBlockSize())),
cswBuf: make([]byte, csw.MsgLen),
cbw: &CBW{Data: make([]byte, 31)},
maxPacketSize: uint32(maxPacketSize),
Expand Down
Loading