Skip to content

Commit d2971bf

Browse files
committed
esp32s3: enable basic gpio support
1 parent 1c87416 commit d2971bf

File tree

1 file changed

+70
-7
lines changed

1 file changed

+70
-7
lines changed

src/machine/machine_esp32s3.go

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func SetCPUFrequency(frequency uint32) error {
4343
// clock source, but this will change the behavior of APB clock and Crypto PWM
4444
// clock
4545
//esp.SYSTEM.SetSYSCLK_CONF_SOC_CLK_SEL(1)
46-
46+
4747
switch frequency {
4848
case 80_000000:
4949
esp.SYSTEM.SetCPU_PER_CONF_CPUPERIOD_SEL(0)
@@ -94,12 +94,14 @@ const (
9494
GPIO17 Pin = 17
9595
GPIO18 Pin = 18
9696
GPIO19 Pin = 19
97+
GPIO20 Pin = 20
9798
GPIO21 Pin = 21
98-
GPIO22 Pin = 22
99-
GPIO23 Pin = 23
100-
GPIO25 Pin = 25
10199
GPIO26 Pin = 26
102100
GPIO27 Pin = 27
101+
GPIO28 Pin = 28
102+
GPIO29 Pin = 29
103+
GPIO30 Pin = 30
104+
GPIO31 Pin = 31
103105
GPIO32 Pin = 32
104106
GPIO33 Pin = 33
105107
GPIO34 Pin = 34
@@ -115,6 +117,8 @@ const (
115117
GPIO44 Pin = 44
116118
GPIO45 Pin = 45
117119
GPIO46 Pin = 46
120+
GPIO47 Pin = 47
121+
GPIO48 Pin = 48
118122
)
119123

120124
// Configure this pin with the given configuration.
@@ -137,7 +141,68 @@ func (p Pin) configure(config PinConfig, signal uint32) {
137141
return
138142
}
139143

140-
// TODO: Mux config
144+
ioConfig := uint32(0)
145+
146+
// MCU_SEL: Function 1 is always GPIO
147+
ioConfig |= (1 << esp.IO_MUX_GPIO_MCU_SEL_Pos)
148+
149+
// FUN_IE: Make this pin an input pin (always set for GPIO operation)
150+
ioConfig |= esp.IO_MUX_GPIO_FUN_IE
151+
152+
// DRV: Set drive strength to 20 mA as a default. Pins 17 and 18 are special
153+
var drive uint32
154+
if p == GPIO17 || p == GPIO18 {
155+
drive = 1 // 20 mA
156+
} else {
157+
drive = 2 // 20 mA
158+
}
159+
ioConfig |= (drive << esp.IO_MUX_GPIO_FUN_DRV_Pos)
160+
161+
// WPU/WPD: Select pull mode.
162+
if config.Mode == PinInputPullup {
163+
ioConfig |= esp.IO_MUX_GPIO_FUN_WPU
164+
} else if config.Mode == PinInputPulldown {
165+
ioConfig |= esp.IO_MUX_GPIO_FUN_WPD
166+
}
167+
168+
// Set configuration
169+
ioRegister := p.ioMuxReg()
170+
ioRegister.Set(ioConfig)
171+
172+
switch config.Mode {
173+
case PinOutput:
174+
// Set the 'output enable' bit.
175+
if p < 32 {
176+
esp.GPIO.ENABLE_W1TS.Set(1 << p)
177+
} else {
178+
esp.GPIO.ENABLE1_W1TS.Set(1 << (p - 32))
179+
}
180+
// Set the signal to read the output value from. It can be a peripheral
181+
// output signal, or the special value 256 which indicates regular GPIO
182+
// usage.
183+
p.outFunc().Set(signal)
184+
case PinInput, PinInputPullup, PinInputPulldown:
185+
// Clear the 'output enable' bit.
186+
if p < 32 {
187+
esp.GPIO.ENABLE_W1TC.Set(1 << p)
188+
} else {
189+
esp.GPIO.ENABLE1_W1TC.Set(1 << (p - 32))
190+
}
191+
if signal != 256 {
192+
// Signal is a peripheral function (not a simple GPIO). Connect this
193+
// signal to the pin.
194+
// Note that outFunc and inFunc work in the opposite direction.
195+
// outFunc configures a pin to use a given output signal, while
196+
// inFunc specifies a pin to use to read the signal from.
197+
inFunc(signal).Set(esp.GPIO_FUNC_IN_SEL_CFG_SEL | uint32(p)<<esp.GPIO_FUNC_IN_SEL_CFG_IN_SEL_Pos)
198+
}
199+
}
200+
}
201+
202+
// ioMuxReg returns the IO_MUX_n_REG register used for configuring the io mux for
203+
// this pin
204+
func (p Pin) ioMuxReg() *volatile.Register32 {
205+
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.IO_MUX.GPIO0), uintptr(p)*4))
141206
}
142207

143208
// outFunc returns the FUNCx_OUT_SEL_CFG register used for configuring the
@@ -208,8 +273,6 @@ func (p Pin) Get() bool {
208273
}
209274
}
210275

211-
// TODO: Mux
212-
213276
var DefaultUART = UART0
214277

215278
var (

0 commit comments

Comments
 (0)