esp32: configure the I/O matrix for GPIO pins
Only some pins (notably including GPIO2 aka machine.LED) have GPIO for the default function 1. Other pins (such as GPIO 15) had a different function by default. Function 3 means GPIO for all the pins, so always use that when configuring a pin to use as a GPIO pin. In the future, the mux configuration will need to be updated for other functions such as SPI, I2C, etc.
Этот коммит содержится в:
родитель
9e599bac49
коммит
19d5e05e37
1 изменённых файлов: 110 добавлений и 2 удалений
|
@ -20,18 +20,43 @@ type PinMode uint8
|
||||||
const (
|
const (
|
||||||
PinOutput PinMode = iota
|
PinOutput PinMode = iota
|
||||||
PinInput
|
PinInput
|
||||||
|
PinInputPullup
|
||||||
|
PinInputPulldown
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure this pin with the given configuration.
|
// Configure this pin with the given configuration.
|
||||||
func (p Pin) Configure(config PinConfig) {
|
func (p Pin) Configure(config PinConfig) {
|
||||||
if config.Mode == PinOutput {
|
var muxConfig uint32 // The mux configuration.
|
||||||
|
|
||||||
|
// Configure this pin as a GPIO pin.
|
||||||
|
const function = 3 // function 3 is GPIO for every pin
|
||||||
|
muxConfig |= (function - 1) << esp.IO_MUX_GPIO0_MCU_SEL_Pos
|
||||||
|
|
||||||
|
// Make this pin an input pin (always).
|
||||||
|
muxConfig |= esp.IO_MUX_GPIO0_FUN_IE
|
||||||
|
|
||||||
|
// Set drive strength: 0 is lowest, 3 is highest.
|
||||||
|
muxConfig |= 2 << esp.IO_MUX_GPIO0_FUN_DRV_Pos
|
||||||
|
|
||||||
|
// Select pull mode.
|
||||||
|
if config.Mode == PinInputPullup {
|
||||||
|
muxConfig |= esp.IO_MUX_GPIO0_FUN_WPU
|
||||||
|
} else if config.Mode == PinInputPulldown {
|
||||||
|
muxConfig |= esp.IO_MUX_GPIO0_FUN_WPD
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the pad with the given IO mux configuration.
|
||||||
|
p.mux().Set(muxConfig)
|
||||||
|
|
||||||
|
switch config.Mode {
|
||||||
|
case PinOutput:
|
||||||
// Set the 'output enable' bit.
|
// Set the 'output enable' bit.
|
||||||
if p < 32 {
|
if p < 32 {
|
||||||
esp.GPIO.ENABLE_W1TS.Set(1 << p)
|
esp.GPIO.ENABLE_W1TS.Set(1 << p)
|
||||||
} else {
|
} else {
|
||||||
esp.GPIO.ENABLE1_W1TS.Set(1 << (p - 32))
|
esp.GPIO.ENABLE1_W1TS.Set(1 << (p - 32))
|
||||||
}
|
}
|
||||||
} else {
|
case PinInput, PinInputPullup, PinInputPulldown:
|
||||||
// Clear the 'output enable' bit.
|
// Clear the 'output enable' bit.
|
||||||
if p < 32 {
|
if p < 32 {
|
||||||
esp.GPIO.ENABLE_W1TC.Set(1 << p)
|
esp.GPIO.ENABLE_W1TC.Set(1 << p)
|
||||||
|
@ -97,6 +122,89 @@ func (p Pin) Get() bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mux returns the I/O mux configuration register corresponding to the given
|
||||||
|
// GPIO pin.
|
||||||
|
func (p Pin) mux() *volatile.Register32 {
|
||||||
|
// I have no idea whether there is any pattern in the GPIO <-> pad mapping.
|
||||||
|
// I couldn't find it.
|
||||||
|
switch p {
|
||||||
|
case 36:
|
||||||
|
return &esp.IO_MUX.GPIO36
|
||||||
|
case 37:
|
||||||
|
return &esp.IO_MUX.GPIO37
|
||||||
|
case 38:
|
||||||
|
return &esp.IO_MUX.GPIO38
|
||||||
|
case 39:
|
||||||
|
return &esp.IO_MUX.GPIO39
|
||||||
|
case 34:
|
||||||
|
return &esp.IO_MUX.GPIO34
|
||||||
|
case 35:
|
||||||
|
return &esp.IO_MUX.GPIO35
|
||||||
|
case 32:
|
||||||
|
return &esp.IO_MUX.GPIO32
|
||||||
|
case 33:
|
||||||
|
return &esp.IO_MUX.GPIO33
|
||||||
|
case 25:
|
||||||
|
return &esp.IO_MUX.GPIO25
|
||||||
|
case 26:
|
||||||
|
return &esp.IO_MUX.GPIO26
|
||||||
|
case 27:
|
||||||
|
return &esp.IO_MUX.GPIO27
|
||||||
|
case 14:
|
||||||
|
return &esp.IO_MUX.MTMS
|
||||||
|
case 12:
|
||||||
|
return &esp.IO_MUX.MTDI
|
||||||
|
case 13:
|
||||||
|
return &esp.IO_MUX.MTCK
|
||||||
|
case 15:
|
||||||
|
return &esp.IO_MUX.MTDO
|
||||||
|
case 2:
|
||||||
|
return &esp.IO_MUX.GPIO2
|
||||||
|
case 0:
|
||||||
|
return &esp.IO_MUX.GPIO0
|
||||||
|
case 4:
|
||||||
|
return &esp.IO_MUX.GPIO4
|
||||||
|
case 16:
|
||||||
|
return &esp.IO_MUX.GPIO16
|
||||||
|
case 17:
|
||||||
|
return &esp.IO_MUX.GPIO17
|
||||||
|
case 9:
|
||||||
|
return &esp.IO_MUX.SD_DATA2
|
||||||
|
case 10:
|
||||||
|
return &esp.IO_MUX.SD_DATA3
|
||||||
|
case 11:
|
||||||
|
return &esp.IO_MUX.SD_CMD
|
||||||
|
case 6:
|
||||||
|
return &esp.IO_MUX.SD_CLK
|
||||||
|
case 7:
|
||||||
|
return &esp.IO_MUX.SD_DATA0
|
||||||
|
case 8:
|
||||||
|
return &esp.IO_MUX.SD_DATA1
|
||||||
|
case 5:
|
||||||
|
return &esp.IO_MUX.GPIO5
|
||||||
|
case 18:
|
||||||
|
return &esp.IO_MUX.GPIO18
|
||||||
|
case 19:
|
||||||
|
return &esp.IO_MUX.GPIO19
|
||||||
|
case 20:
|
||||||
|
return &esp.IO_MUX.GPIO20
|
||||||
|
case 21:
|
||||||
|
return &esp.IO_MUX.GPIO21
|
||||||
|
case 22:
|
||||||
|
return &esp.IO_MUX.GPIO22
|
||||||
|
case 3:
|
||||||
|
return &esp.IO_MUX.U0RXD
|
||||||
|
case 1:
|
||||||
|
return &esp.IO_MUX.U0TXD
|
||||||
|
case 23:
|
||||||
|
return &esp.IO_MUX.GPIO23
|
||||||
|
case 24:
|
||||||
|
return &esp.IO_MUX.GPIO24
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
UART0 = UART{Bus: esp.UART0, Buffer: NewRingBuffer()}
|
UART0 = UART{Bus: esp.UART0, Buffer: NewRingBuffer()}
|
||||||
UART1 = UART{Bus: esp.UART1, Buffer: NewRingBuffer()}
|
UART1 = UART{Bus: esp.UART1, Buffer: NewRingBuffer()}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче