Skip to content

Commit 4e3d290

Browse files
committed
Create "pico2-ice" target board
This board has an rp2350b chip on it, as well as a Lattice Semiconductor iCE40UP5K FPGA. More details of this open hardware board here: https://pico2-ice.tinyvision.ai/ Tested on a pico2-ice board with: ~/go/bin/tinygo flash -target=pico2-ice src/examples/blinky1/blinky1.go which blinks the GREEN LED (connected to GPIO0) on this board. Signed-off-by: Tinkerer <tinkerer@zappem.net>
1 parent aedaf7d commit 4e3d290

File tree

6 files changed

+244
-20
lines changed

6 files changed

+244
-20
lines changed

src/machine/board_pico2_ice.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//go:build pico2_ice
2+
3+
// Most of the info is from
4+
// https://pico2-ice.tinyvision.ai/md_pinout.html although
5+
// (2025-09-07) RP4 appears twice in that pinout - the schematic is
6+
// more clear. Consistent with other RPi boards, we use GPn instead of
7+
// RPn to reference the RPi connected pins.
8+
9+
package machine
10+
11+
// GPIO pins
12+
const (
13+
GP0 Pin = GPIO0
14+
GP1 Pin = GPIO1
15+
GP2 Pin = GPIO2
16+
GP3 Pin = GPIO3
17+
GP4 Pin = GPIO4
18+
GP5 Pin = GPIO5
19+
GP6 Pin = GPIO6
20+
GP7 Pin = GPIO7
21+
GP8 Pin = GPIO8
22+
GP9 Pin = GPIO9
23+
GP10 Pin = GPIO10
24+
GP11 Pin = GPIO11
25+
GP12 Pin = GPIO12
26+
GP13 Pin = GPIO13
27+
GP14 Pin = GPIO14
28+
GP15 Pin = GPIO15
29+
GP16 Pin = GPIO16
30+
GP17 Pin = GPIO17
31+
GP18 Pin = GPIO18
32+
GP19 Pin = GPIO19
33+
GP20 Pin = GPIO20
34+
GP21 Pin = GPIO21
35+
GP22 Pin = GPIO22
36+
GP23 Pin = GPIO23
37+
GP24 Pin = GPIO24
38+
GP25 Pin = GPIO25
39+
GP26 Pin = GPIO26
40+
GP27 Pin = GPIO27
41+
GP28 Pin = GPIO28
42+
GP29 Pin = GPIO29
43+
GP30 Pin = 30
44+
GP31 Pin = 31
45+
GP32 Pin = 32
46+
GP33 Pin = 33
47+
GP34 Pin = 34
48+
GP35 Pin = 35
49+
GP36 Pin = 36
50+
GP37 Pin = 37
51+
GP38 Pin = 38
52+
GP39 Pin = 39
53+
GP40 Pin = 40
54+
GP41 Pin = 41
55+
GP42 Pin = 42
56+
GP43 Pin = 43
57+
GP44 Pin = 44
58+
GP45 Pin = 45
59+
GP46 Pin = 46
60+
GP47 Pin = 47
61+
62+
// RPi pins shared with ICE
63+
ICE9 = GP28
64+
ICE11 = GP29
65+
ICE14 = GP7
66+
ICE15 = GP6
67+
ICE16 = GP5
68+
ICE17 = GP4
69+
ICE18 = GP27
70+
ICE19 = GP23
71+
ICE20 = GP22
72+
ICE21 = GP26
73+
ICE23 = GP25
74+
ICE25 = GP30
75+
ICE26 = GP24
76+
ICE27 = GP20
77+
78+
// FPGA Clock pin.
79+
ICE35_G0 = GP21
80+
81+
// Silkscreen & Pinout names
82+
ICE_SSN = ICE16
83+
ICE_SO = ICE14
84+
ICE_SI = ICE17
85+
ICE_CK = ICE15
86+
FPGA_RSTN = GP31
87+
ICE_DONE = GP40
88+
USB_BOOT = GP42
89+
90+
// Button
91+
SW1 = GP42
92+
BOOTSEL = GP42
93+
94+
// Tricolor LEDs
95+
RED Pin = GP1
96+
GREEN Pin = GP0
97+
BLUE Pin = GP9
98+
99+
// Onboard LED
100+
LED Pin = GREEN
101+
102+
// Onboard crystal oscillator frequency, in MHz.
103+
xoscFreq = 12 // MHz
104+
)
105+
106+
// This board does not define default i2c pins.
107+
const (
108+
I2C0_SDA_PIN Pin = 0
109+
I2C0_SCL_PIN Pin = 0
110+
I2C1_SDA_PIN Pin = 0
111+
I2C1_SCL_PIN Pin = 0
112+
)
113+
114+
// SPI default pins
115+
const (
116+
// Default Serial Clock Bus 0 for SPI communications
117+
SPI0_SCK_PIN = GPIO18
118+
// Default Serial Out Bus 0 for SPI communications
119+
SPI0_SDO_PIN = GPIO19 // Tx
120+
// Default Serial In Bus 0 for SPI communications
121+
SPI0_SDI_PIN = GPIO16 // Rx
122+
123+
// Default Serial Clock Bus 1 for SPI communications
124+
SPI1_SCK_PIN = GPIO10
125+
// Default Serial Out Bus 1 for SPI communications
126+
SPI1_SDO_PIN = GPIO11 // Tx
127+
// Default Serial In Bus 1 for SPI communications
128+
SPI1_SDI_PIN = GPIO12 // Rx
129+
)
130+
131+
// UART pins
132+
const (
133+
UART0_TX_PIN = GPIO0
134+
UART0_RX_PIN = GPIO1
135+
UART1_TX_PIN = GPIO8
136+
UART1_RX_PIN = GPIO9
137+
UART_TX_PIN = UART0_TX_PIN
138+
UART_RX_PIN = UART0_RX_PIN
139+
)
140+
141+
var DefaultUART = UART0
142+
143+
// USB identifiers
144+
const (
145+
usb_STRING_PRODUCT = "Pico2"
146+
usb_STRING_MANUFACTURER = "Raspberry Pi"
147+
)
148+
149+
var (
150+
usb_VID uint16 = 0x2E8A
151+
usb_PID uint16 = 0x000A
152+
)

src/machine/machine_rp2_2040.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,31 @@ const (
124124
fnXIP pinFunc = 0
125125
)
126126

127+
// validPins confirms that the SPI pin selection is a legitimate one
128+
// for the the 2040 chip.
129+
func (spi *SPI) validPins(config SPIConfig) error {
130+
var okSDI, okSDO, okSCK bool
131+
switch spi.Bus {
132+
case rp.SPI0:
133+
okSDI = config.SDI == 0 || config.SDI == 4 || config.SDI == 16 || config.SDI == 20
134+
okSDO = config.SDO == 3 || config.SDO == 7 || config.SDO == 19 || config.SDO == 23
135+
okSCK = config.SCK == 2 || config.SCK == 6 || config.SCK == 18 || config.SCK == 22
136+
case rp.SPI1:
137+
okSDI = config.SDI == 8 || config.SDI == 12 || config.SDI == 24 || config.SDI == 28
138+
okSDO = config.SDO == 11 || config.SDO == 15 || config.SDO == 27
139+
okSCK = config.SCK == 10 || config.SCK == 14 || config.SCK == 26
140+
}
141+
switch {
142+
case !okSDI:
143+
return errSPIInvalidSDI
144+
case !okSDO:
145+
return errSPIInvalidSDO
146+
case !okSCK:
147+
return errSPIInvalidSCK
148+
}
149+
return nil
150+
}
151+
127152
// Configure configures the gpio pin as per mode.
128153
func (p Pin) Configure(config PinConfig) {
129154
if p == NoPin {

src/machine/machine_rp2_2350a.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
package machine
44

5+
import "device/rp"
6+
57
// Analog pins on RP2350a.
68
const (
79
ADC0 Pin = GPIO26
@@ -12,3 +14,28 @@ const (
1214
// fifth ADC channel.
1315
thermADC = 30
1416
)
17+
18+
// validPins confirms that the SPI pin selection is a legitimate one
19+
// for the the 2350a chip.
20+
func (spi *SPI) validPins(config SPIConfig) error {
21+
var okSDI, okSDO, okSCK bool
22+
switch spi.Bus {
23+
case rp.SPI0:
24+
okSDI = config.SDI == 0 || config.SDI == 4 || config.SDI == 16 || config.SDI == 20
25+
okSDO = config.SDO == 3 || config.SDO == 7 || config.SDO == 19 || config.SDO == 23
26+
okSCK = config.SCK == 2 || config.SCK == 6 || config.SCK == 18 || config.SCK == 22
27+
case rp.SPI1:
28+
okSDI = config.SDI == 8 || config.SDI == 12 || config.SDI == 24 || config.SDI == 28
29+
okSDO = config.SDO == 11 || config.SDO == 15 || config.SDO == 27
30+
okSCK = config.SCK == 10 || config.SCK == 14 || config.SCK == 26
31+
}
32+
switch {
33+
case !okSDI:
34+
return errSPIInvalidSDI
35+
case !okSDO:
36+
return errSPIInvalidSDO
37+
case !okSCK:
38+
return errSPIInvalidSCK
39+
}
40+
return nil
41+
}

src/machine/machine_rp2_2350b.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
package machine
44

5+
import "device/rp"
6+
57
// RP2350B has additional pins.
68

79
const (
@@ -46,3 +48,28 @@ var (
4648
PWM10 = getPWMGroup(10)
4749
PWM11 = getPWMGroup(11)
4850
)
51+
52+
// validPins confirms that the SPI pin selection is a legitimate one
53+
// for the the 2350b chip.
54+
func (spi *SPI) validPins(config SPIConfig) error {
55+
var okSDI, okSDO, okSCK bool
56+
switch spi.Bus {
57+
case rp.SPI0:
58+
okSDI = config.SDI == 0 || config.SDI == 4 || config.SDI == 16 || config.SDI == 20 || config.SDI == 32 || config.SDI == 36
59+
okSDO = config.SDO == 3 || config.SDO == 7 || config.SDO == 19 || config.SDO == 23 || config.SDO == 35 || config.SDO == 39
60+
okSCK = config.SCK == 2 || config.SCK == 6 || config.SCK == 18 || config.SCK == 22 || config.SCK == 34 || config.SCK == 38
61+
case rp.SPI1:
62+
okSDI = config.SDI == 8 || config.SDI == 12 || config.SDI == 24 || config.SDI == 28 || config.SDI == 40 || config.SDI == 44
63+
okSDO = config.SDO == 11 || config.SDO == 15 || config.SDO == 27 || config.SDO == 31 || config.SDO == 43 || config.SDO == 47
64+
okSCK = config.SCK == 10 || config.SCK == 14 || config.SCK == 26 || config.SCK == 30 || config.SCK == 42 || config.SCK == 46
65+
}
66+
switch {
67+
case !okSDI:
68+
return errSPIInvalidSDI
69+
case !okSDO:
70+
return errSPIInvalidSDO
71+
case !okSCK:
72+
return errSPIInvalidSCK
73+
}
74+
return nil
75+
}

src/machine/machine_rp2_spi.go

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -165,27 +165,9 @@ func (spi *SPI) Configure(config SPIConfig) error {
165165
config.SDI = SPI1_SDI_PIN
166166
}
167167
}
168-
var okSDI, okSDO, okSCK bool
169-
switch spi.Bus {
170-
case rp.SPI0:
171-
okSDI = config.SDI == 0 || config.SDI == 4 || config.SDI == 16 || config.SDI == 20
172-
okSDO = config.SDO == 3 || config.SDO == 7 || config.SDO == 19 || config.SDO == 23
173-
okSCK = config.SCK == 2 || config.SCK == 6 || config.SCK == 18 || config.SCK == 22
174-
case rp.SPI1:
175-
okSDI = config.SDI == 8 || config.SDI == 12 || config.SDI == 24 || config.SDI == 28
176-
okSDO = config.SDO == 11 || config.SDO == 15 || config.SDO == 27
177-
okSCK = config.SCK == 10 || config.SCK == 14 || config.SCK == 26
168+
if err := spi.validPins(config); err != nil {
169+
return err
178170
}
179-
180-
switch {
181-
case !okSDI:
182-
return errSPIInvalidSDI
183-
case !okSDO:
184-
return errSPIInvalidSDO
185-
case !okSCK:
186-
return errSPIInvalidSCK
187-
}
188-
189171
if config.Frequency == 0 {
190172
config.Frequency = defaultBaud
191173
}

targets/pico2-ice.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"inherits": [
3+
"rp2350b"
4+
],
5+
"build-tags": ["pico2_ice"],
6+
"serial-port": ["2e8a:000A"],
7+
"default-stack-size": 8192,
8+
"ldflags": [
9+
"--defsym=__flash_size=4M"
10+
]
11+
}

0 commit comments

Comments
 (0)