github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_stm32.go (about) 1 //go:build stm32 2 3 package machine 4 5 import ( 6 "device/stm32" 7 8 "runtime/volatile" 9 "unsafe" 10 ) 11 12 const deviceName = stm32.Device 13 14 // Peripheral abstraction layer for the stm32. 15 16 const ( 17 portA Pin = iota * 16 18 portB 19 portC 20 portD 21 portE 22 portF 23 portG 24 portH 25 portI 26 portJ 27 portK 28 ) 29 30 // Peripheral operations sequence: 31 // 1. Enable the clock to the alternate function. 32 // 2. Enable clock to corresponding GPIO 33 // 3. Attach the alternate function. 34 // 4. Configure the input-output port and pins (of the corresponding GPIOx) to match the AF . 35 // 5. If desired enable the nested vector interrupt control to generate interrupts. 36 // 6. Program the AF/peripheral for the required configuration (eg baud rate for a USART) . 37 38 // Given that the stm32 family has the AF and GPIO on different registers based on the chip, 39 // use the main function here for configuring, and use hooks in the more specific chip 40 // definition files 41 // Also, the stm32f1xx series handles things differently from the stm32f0/2/3/4 42 43 // ---------- General pin operations ---------- 44 type PinChange uint8 45 46 const ( 47 PinRising PinChange = 1 << iota 48 PinFalling 49 PinToggle = PinRising | PinFalling 50 ) 51 52 // Set the pin to high or low. 53 // Warning: only use this on an output pin! 54 func (p Pin) Set(high bool) { 55 port := p.getPort() 56 pin := uint8(p) % 16 57 if high { 58 port.BSRR.Set(1 << pin) 59 } else { 60 port.BSRR.Set(1 << (pin + 16)) 61 } 62 } 63 64 // Get returns the current value of a GPIO pin when the pin is configured as an 65 // input or as an output. 66 func (p Pin) Get() bool { 67 port := p.getPort() 68 pin := uint8(p) % 16 69 val := port.IDR.Get() & (1 << pin) 70 return (val > 0) 71 } 72 73 // PortMaskSet returns the register and mask to enable a given GPIO pin. This 74 // can be used to implement bit-banged drivers. 75 func (p Pin) PortMaskSet() (*uint32, uint32) { 76 port := p.getPort() 77 pin := uint8(p) % 16 78 return &port.BSRR.Reg, 1 << pin 79 } 80 81 // PortMaskClear returns the register and mask to disable a given port. This can 82 // be used to implement bit-banged drivers. 83 func (p Pin) PortMaskClear() (*uint32, uint32) { 84 port := p.getPort() 85 pin := uint8(p) % 16 86 return &port.BSRR.Reg, 1 << (pin + 16) 87 } 88 89 var deviceID [12]byte 90 91 // DeviceID returns an identifier that is unique within 92 // a particular chipset. 93 // 94 // The identity is one burnt into the MCU itself. 95 // 96 // The length of the device ID for STM32 is 12 bytes (96 bits). 97 func DeviceID() []byte { 98 for i := 0; i < len(deviceID); i++ { 99 word := (*volatile.Register32)(unsafe.Pointer(deviceIDAddr[i/4])).Get() 100 deviceID[i] = byte(word >> ((i % 4) * 8)) 101 } 102 103 return deviceID[:] 104 }