Skip to content

Commit 4b831af

Browse files
authored
w5500: initial version the driver (#788)
Thank you, @nrwiersma for working on this and @soypat for review. Now merging.
1 parent 09fd013 commit 4b831af

File tree

6 files changed

+923
-0
lines changed

6 files changed

+923
-0
lines changed

examples/w5500/main.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"machine"
5+
"net"
6+
"net/netip"
7+
"time"
8+
9+
"tinygo.org/x/drivers/netdev"
10+
"tinygo.org/x/drivers/w5500"
11+
)
12+
13+
func main() {
14+
machine.SPI0.Configure(machine.SPIConfig{
15+
Frequency: 33 * machine.MHz,
16+
})
17+
machine.GPIO17.Configure(machine.PinConfig{Mode: machine.PinOutput})
18+
19+
eth := w5500.New(machine.SPI0, machine.GPIO17)
20+
eth.Configure(w5500.Config{
21+
MAC: net.HardwareAddr{0xee, 0xbe, 0xe9, 0xa9, 0xb6, 0x4f},
22+
IP: netip.AddrFrom4([4]byte{192, 168, 1, 2}),
23+
SubnetMask: netip.AddrFrom4([4]byte{255, 255, 255, 0}),
24+
Gateway: netip.AddrFrom4([4]byte{192, 168, 1, 1}),
25+
})
26+
netdev.UseNetdev(eth)
27+
28+
for {
29+
if eth.LinkStatus() != w5500.LinkStatusUp {
30+
println("Waiting for link to be up")
31+
32+
time.Sleep(1 * time.Second)
33+
continue
34+
}
35+
break
36+
}
37+
}

smoketest.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ tinygo build -size short -o ./build/test.uf2 -target=nicenano ./examples/sharpme
146146
tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/max6675/main.go
147147
tinygo build -size short -o ./build/test.hex -target=pico ./examples/ens160/main.go
148148
tinygo build -size short -o ./build/test.hex -target=pico ./examples/si5351/main.go
149+
tinygo build -size short -o ./build/test.hex -target=pico ./examples/w5500/main.go
149150
# network examples (espat)
150151
tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
151152
# network examples (wifinina)

w5500/io.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package w5500
2+
3+
import "time"
4+
5+
func (d *Device) irqPoll(sockn uint8, state uint8, deadline time.Time) uint8 {
6+
waitTime := 500 * time.Microsecond
7+
for {
8+
if !deadline.IsZero() && time.Now().After(deadline) {
9+
// If a deadline is set and it has passed, return 0.
10+
return sockIntUnknown
11+
}
12+
13+
irq := d.readByte(sockInt, sockAddr(sockn)) & 0b00011111
14+
if got := irq & state; got != 0 {
15+
// Acknowledge the interrupt.
16+
d.writeByte(sockInt, sockAddr(sockn), got)
17+
18+
return got
19+
}
20+
21+
d.mu.Unlock()
22+
23+
time.Sleep(waitTime)
24+
25+
// Exponential backoff for polling.
26+
waitTime *= 2
27+
if waitTime > 10*time.Millisecond {
28+
waitTime = 10 * time.Millisecond
29+
}
30+
31+
d.mu.Lock()
32+
}
33+
}
34+
35+
func (d *Device) read(addr uint16, bsb uint8, p []byte) {
36+
d.cs(false)
37+
if len(p) == 0 {
38+
return
39+
}
40+
41+
d.sendReadHeader(addr, bsb)
42+
_ = d.bus.Tx(nil, p)
43+
d.cs(true)
44+
}
45+
46+
func (d *Device) readUint16(addr uint16, bsb uint8) uint16 {
47+
d.cs(false)
48+
d.sendReadHeader(addr, bsb)
49+
buf := d.cmdBuf
50+
_ = d.bus.Tx(nil, buf[:2])
51+
d.cs(true)
52+
return uint16(buf[1]) | uint16(buf[0])<<8
53+
}
54+
55+
func (d *Device) readByte(addr uint16, bsb uint8) byte {
56+
d.cs(false)
57+
d.sendReadHeader(addr, bsb)
58+
r, _ := d.bus.Transfer(byte(0))
59+
d.cs(true)
60+
return r
61+
}
62+
63+
func (d *Device) write(addr uint16, bsb uint8, p []byte) {
64+
d.cs(false)
65+
if len(p) == 0 {
66+
return
67+
}
68+
d.sendWriteHeader(addr, bsb)
69+
_ = d.bus.Tx(p, nil)
70+
d.cs(true)
71+
}
72+
73+
func (d *Device) writeUint16(addr uint16, bsb uint8, v uint16) {
74+
d.cs(false)
75+
d.sendWriteHeader(addr, bsb)
76+
buf := d.cmdBuf
77+
buf[0] = byte(v >> 8)
78+
buf[1] = byte(v & 0xff)
79+
_ = d.bus.Tx(buf[:2], nil)
80+
d.cs(true)
81+
}
82+
83+
func (d *Device) writeByte(addr uint16, bsb uint8, b byte) {
84+
d.cs(false)
85+
d.sendWriteHeader(addr, bsb)
86+
_, _ = d.bus.Transfer(b)
87+
d.cs(true)
88+
}
89+
90+
func (d *Device) sendReadHeader(addr uint16, bsb uint8) {
91+
buf := d.cmdBuf
92+
buf[0] = byte(addr >> 8)
93+
buf[1] = byte(addr & 0xff)
94+
buf[2] = bsb << 3
95+
_ = d.bus.Tx(buf[:], nil)
96+
}
97+
98+
func (d *Device) sendWriteHeader(addr uint16, bsb uint8) {
99+
buf := d.cmdBuf
100+
buf[0] = byte(addr >> 8)
101+
buf[1] = byte(addr & 0xff)
102+
buf[2] = bsb<<3 | 0b100
103+
_ = d.bus.Tx(buf[:], nil)
104+
}

0 commit comments

Comments
 (0)