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", 3680, 280, 0, 2252},
{"microbit", "examples/serial", 2694, 342, 8, 2248},
{"wioterminal", "examples/pininterrupt", 7074, 1510, 120, 7248},
{"wioterminal", "examples/pininterrupt", 7090, 1510, 120, 7248},

// TODO: also check wasm. Right now this is difficult, because
// wasm binaries are run through wasm-opt and therefore the
Expand Down
1 change: 1 addition & 0 deletions src/examples/hid-keyboard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func main() {
button.Configure(machine.PinConfig{Mode: machine.PinInputPullup})

kb := keyboard.Port()
machine.USBDev.Configure(machine.UARTConfig{}) // no-op if already init'd by serial.usb

for {
if !button.Get() {
Expand Down
79 changes: 78 additions & 1 deletion src/examples/usb-storage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,85 @@ import (
"time"
)

// Disk geometry.
const (
sectorSize = 512
diskSectors = 128 // 64 KB total
)

var diskData [diskSectors * sectorSize]byte

type ramDisk struct{}

func (r *ramDisk) ReadAt(p []byte, off int64) (int, error) {
return copy(p, diskData[off:]), nil
}

func (r *ramDisk) WriteAt(p []byte, off int64) (int, error) {
return copy(diskData[off:], p), nil
}

func (r *ramDisk) Size() int64 { return int64(diskSectors * sectorSize) }
func (r *ramDisk) WriteBlockSize() int64 { return sectorSize }
func (r *ramDisk) EraseBlockSize() int64 { return sectorSize }
func (r *ramDisk) EraseBlocks(start, len int64) error { return nil }

func init() {
formatFAT12(diskData[:])
}

// formatFAT12 writes a minimal FAT12 volume boot record and FAT tables so the
// host OS can mount the disk without reformatting.
func formatFAT12(d []byte) {
// --- Sector 0: Volume Boot Record ---
s := d[0:]
s[0] = 0xEB
s[1] = 0x3C
s[2] = 0x90 // short JMP + NOP
copy(s[3:11], "MSDOS5.0")
// BPB fields (little-endian)
s[11] = 0x00
s[12] = 0x02 // bytesPerSector = 512
s[13] = 0x01 // sectorsPerCluster = 1
s[14] = 0x01
s[15] = 0x00 // reservedSectors = 1
s[16] = 0x02 // numFATs = 2
s[17] = 0x20
s[18] = 0x00 // rootEntryCount = 32
s[19] = 0x80
s[20] = 0x00 // totalSectors16 = 128
s[21] = 0xF8 // mediaType = fixed disk
s[22] = 0x01
s[23] = 0x00 // sectorsPerFAT = 1
s[24] = 0x80
s[25] = 0x00 // sectorsPerTrack = 128
s[26] = 0x01
s[27] = 0x00 // numHeads = 1
// hiddenSectors[28:32] = 0
// totalSectors32[32:36] = 0
s[38] = 0x29 // extBootSig
s[39] = 0x47
s[40] = 0x4F
s[41] = 0x30
s[42] = 0x31 // volumeID "GO01"
copy(s[43:54], "TINYGO ") // volumeLabel (11 bytes)
copy(s[54:62], "FAT12 ") // fsType
s[510] = 0x55
s[511] = 0xAA // boot sector signature

// --- Sector 1: FAT1 ---
// Entry 0 = 0xFF8 (media byte), entry 1 = 0xFFF (EOC); all others = free.
d[512] = 0xF8
d[513] = 0xFF
d[514] = 0xFF

// --- Sector 2: FAT2 (identical copy) ---
copy(d[1024:1027], d[512:515])
}

func main() {
msc.Port(machine.Flash)
msc.Port(&ramDisk{})
machine.USBDev.Configure(machine.UARTConfig{})

for {
time.Sleep(2 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion src/machine/flash.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build esp32c3 || nrf || nrf51 || nrf52 || nrf528xx || stm32f4 || stm32l0 || stm32l4 || stm32wlx || atsamd21 || atsamd51 || atsame5x || rp2040 || rp2350
//go:build esp32c3 || nrf || nrf51 || nrf52 || nrf528xx || stm32f4 || stm32f7 || stm32l0 || stm32l4 || stm32wlx || atsamd21 || atsamd51 || atsame5x || rp2040 || rp2350

package machine

Expand Down
8 changes: 8 additions & 0 deletions src/machine/machine_atsamd21_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,11 @@ func setEPINTENSET(ep uint32, val uint8) {
return
}
}

func (dev *USBDevice) SetStallEPIn(ep uint32) {
setEPSTATUSSET(ep, sam.USB_DEVICE_EPSTATUSSET_STALLRQ1)
}

func (dev *USBDevice) SetStallEPOut(ep uint32) {
setEPSTATUSSET(ep, sam.USB_DEVICE_EPSTATUSSET_STALLRQ0)
}
8 changes: 8 additions & 0 deletions src/machine/machine_atsamd51_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,11 @@ func setEPINTENCLR(ep uint32, val uint8) {
func setEPINTENSET(ep uint32, val uint8) {
sam.USB_DEVICE.DEVICE_ENDPOINT[ep].EPINTENSET.Set(val)
}

func (dev *USBDevice) SetStallEPIn(ep uint32) {
setEPSTATUSSET(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_STALLRQ1)
}

func (dev *USBDevice) SetStallEPOut(ep uint32) {
setEPSTATUSSET(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_STALLRQ0)
}
16 changes: 16 additions & 0 deletions src/machine/machine_nrf52840_usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,19 @@ func ReceiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {

return b, nil
}

func (dev *USBDevice) SetStallEPIn(ep uint32) {
if ep == 0 {
nrf.USBD.TASKS_EP0STALL.Set(1)
return
}
nrf.USBD.EPSTALL.Set(uint32(ep) | nrf.USBD_EPSTALL_IO_In<<7 | nrf.USBD_EPSTALL_STALL_Stall<<8)
}

func (dev *USBDevice) SetStallEPOut(ep uint32) {
if ep == 0 {
nrf.USBD.TASKS_EP0STALL.Set(1)
return
}
nrf.USBD.EPSTALL.Set(uint32(ep) | nrf.USBD_EPSTALL_IO_Out<<7 | nrf.USBD_EPSTALL_STALL_Stall<<8)
}
5 changes: 5 additions & 0 deletions src/machine/machine_stm32.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ func (p Pin) PortMaskClear() (*uint32, uint32) {
return &port.BSRR.Reg, 1 << (pin + 16)
}

// EnterBootloader resets the chip into the bootloader.
// This is currently a stub for STM32.
func EnterBootloader() {
}

var deviceID [12]byte

// DeviceID returns an identifier that is unique within
Expand Down
Loading