github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32_moder_gpio.go (about) 1 //go:build stm32 && !stm32f103 2 3 package machine 4 5 import ( 6 "device/stm32" 7 ) 8 9 // GPIO for the stm32 families except the stm32f1xx which uses a simpler but 10 // less flexible mechanism. Extend the go:build directive above to exclude other 11 // models in the stm32f1xx series as necessary 12 13 const ( 14 // Mode Flag 15 PinOutput PinMode = 0 16 PinInput PinMode = PinInputFloating 17 PinInputFloating PinMode = 1 18 PinInputPulldown PinMode = 2 19 PinInputPullup PinMode = 3 20 21 // for UART 22 PinModeUARTTX PinMode = 4 23 PinModeUARTRX PinMode = 5 24 25 // for I2C 26 PinModeI2CSCL PinMode = 6 27 PinModeI2CSDA PinMode = 7 28 29 // for SPI 30 PinModeSPICLK PinMode = 8 31 PinModeSPISDO PinMode = 9 32 PinModeSPISDI PinMode = 10 33 34 // for analog/ADC 35 PinInputAnalog PinMode = 11 36 37 // for PWM 38 PinModePWMOutput PinMode = 12 39 ) 40 41 // Define several bitfields that have different names across chip families but 42 // essentially have the same meaning. 43 const ( 44 // MODER bitfields. 45 gpioModeInput = 0 46 gpioModeOutput = 1 47 gpioModeAlternate = 2 48 gpioModeAnalog = 3 49 gpioModeMask = 0x3 50 51 // PUPDR bitfields. 52 gpioPullFloating = 0 53 gpioPullUp = 1 54 gpioPullDown = 2 55 gpioPullMask = 0x3 56 57 // OSPEED bitfields. 58 gpioOutputSpeedVeryHigh = 3 59 gpioOutputSpeedHigh = 2 60 gpioOutputSpeedMedium = 1 61 gpioOutputSpeedLow = 0 62 gpioOutputSpeedMask = 0x3 63 ) 64 65 // Configure this pin with the given configuration 66 func (p Pin) Configure(config PinConfig) { 67 // Use the default system alternate function; this 68 // will only be used if you try to call this with 69 // one of the peripheral modes instead of vanilla GPIO. 70 p.ConfigureAltFunc(config, 0) 71 } 72 73 // Configure this pin with the given configuration including alternate 74 // 75 // function mapping if necessary. 76 func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) { 77 // Configure the GPIO pin. 78 p.enableClock() 79 port := p.getPort() 80 pos := (uint8(p) % 16) * 2 // assume each field is two bits in size (with mask 0x3) 81 82 switch config.Mode { 83 84 // GPIO 85 case PinInputFloating: 86 port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) 87 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 88 case PinInputPulldown: 89 port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) 90 port.PUPDR.ReplaceBits(gpioPullDown, gpioPullMask, pos) 91 case PinInputPullup: 92 port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos) 93 port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) 94 case PinOutput: 95 port.MODER.ReplaceBits(gpioModeOutput, gpioModeMask, pos) 96 port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) 97 98 // UART 99 case PinModeUARTTX: 100 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 101 port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) 102 port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) 103 p.SetAltFunc(altFunc) 104 case PinModeUARTRX: 105 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 106 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 107 p.SetAltFunc(altFunc) 108 109 // I2C 110 case PinModeI2CSCL: 111 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 112 port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2) 113 port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos) 114 port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) 115 p.SetAltFunc(altFunc) 116 case PinModeI2CSDA: 117 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 118 port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2) 119 port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos) 120 port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos) 121 p.SetAltFunc(altFunc) 122 123 // SPI 124 case PinModeSPICLK: 125 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 126 port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) 127 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 128 p.SetAltFunc(altFunc) 129 case PinModeSPISDO: 130 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 131 port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos) 132 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 133 p.SetAltFunc(altFunc) 134 case PinModeSPISDI: 135 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 136 port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos) 137 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 138 p.SetAltFunc(altFunc) 139 140 // PWM 141 case PinModePWMOutput: 142 port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos) 143 port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos) 144 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 145 p.SetAltFunc(altFunc) 146 147 // ADC 148 case PinInputAnalog: 149 port.MODER.ReplaceBits(gpioModeAnalog, gpioModeMask, pos) 150 port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos) 151 } 152 } 153 154 // SetAltFunc maps the given alternative function to the I/O pin 155 func (p Pin) SetAltFunc(af uint8) { 156 port := p.getPort() 157 pin := uint8(p) % 16 158 pos := (pin % 8) * 4 159 if pin < 8 { 160 port.AFRL.ReplaceBits(uint32(af), 0xf, pos) 161 } else { 162 port.AFRH.ReplaceBits(uint32(af), 0xf, pos) 163 } 164 }