Files
tinygo/src/machine/machine_stm32_moder_gpio.go
T
2020-07-23 22:45:23 +02:00

129 lines
3.8 KiB
Go

// +build stm32,!stm32f103xx
package machine
import (
"device/stm32"
)
// GPIO for the stm32 families except the stm32f1xx which uses a simpler but
// less flexible mechanism. Extend the +build directive above to exclude other
// models in the stm32f1xx series as necessary
const (
// Mode Flag
PinOutput PinMode = 0
PinInput PinMode = PinInputFloating
PinInputFloating PinMode = 1
PinInputPulldown PinMode = 2
PinInputPullup PinMode = 3
// for UART
PinModeUARTTX PinMode = 4
PinModeUARTRX PinMode = 5
// for I2C
PinModeI2CSCL PinMode = 6
PinModeI2CSDA PinMode = 7
// for SPI
PinModeSPICLK PinMode = 8
PinModeSPISDO PinMode = 9
PinModeSPISDI PinMode = 10
// for analog/ADC
PinInputAnalog PinMode = 11
// for PWM
// TBD
)
// Configure this pin with the given configuration
func (p Pin) Configure(config PinConfig) {
// Use the default system alternate function; this
// will only be used if you try to call this with
// one of the peripheral modes instead of vanilla GPIO.
p.ConfigureAltFunc(config, stm32.AF0_SYSTEM)
}
// Configure this pin with the given configuration including alternate
// function mapping if necessary.
func (p Pin) ConfigureAltFunc(config PinConfig, altFunc stm32.AltFunc) {
// Configure the GPIO pin.
p.enableClock()
port := p.getPort()
pin := uint8(p) % 16
pos := pin * 2
switch config.Mode {
// GPIO
case PinInputFloating:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
case PinInputPulldown:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullDown, 0x3, pos)
case PinInputPullup:
port.MODER.ReplaceBits(stm32.GPIOModeInput, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos)
case PinOutput:
port.MODER.ReplaceBits(stm32.GPIOModeOutputGeneral, 0x3, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos)
// UART
case PinModeUARTTX:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedHigh, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRPullUp, 0x3, pos)
p.SetAltFunc(altFunc)
case PinModeUARTRX:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
// I2C
case PinModeI2CSCL:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
case PinModeI2CSDA:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OTYPER.ReplaceBits(stm32.GPIOOutputTypeOpenDrain, 0x1, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
// SPI
case PinModeSPICLK:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
case PinModeSPISDO:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
case PinModeSPISDI:
port.MODER.ReplaceBits(stm32.GPIOModeOutputAltFunc, 0x3, pos)
port.OSPEEDR.ReplaceBits(stm32.GPIOSpeedLow, 0x3, pos)
port.PUPDR.ReplaceBits(stm32.GPIOPUPDRFloating, 0x3, pos)
p.SetAltFunc(altFunc)
}
}
// SetAltFunc maps the given alternative function to the I/O pin
func (p Pin) SetAltFunc(af stm32.AltFunc) {
port := p.getPort()
pin := uint8(p) % 16
pos := (pin % 8) * 4
if pin < 8 {
port.AFRL.ReplaceBits(uint32(af), 0xf, pos)
} else {
port.AFRH.ReplaceBits(uint32(af), 0xf, pos)
}
}