github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_avrtiny.go (about) 1 //go:build avrtiny 2 3 package machine 4 5 import ( 6 "device/avr" 7 "runtime/volatile" 8 "unsafe" 9 ) 10 11 const deviceName = avr.DEVICE 12 13 const ( 14 PinInput PinMode = iota 15 PinInputPullup 16 PinOutput 17 ) 18 19 // Configure sets the pin to input or output. 20 func (p Pin) Configure(config PinConfig) { 21 port, mask := p.getPortMask() 22 23 if config.Mode == PinOutput { 24 // set output bit 25 port.DIRSET.Set(mask) 26 27 // Note: the output state (high or low) is as it was before. 28 } else { 29 // Configure the pin as an input. 30 // First set up the configuration that will be used when it is an input. 31 pinctrl := uint8(0) 32 if config.Mode == PinInputPullup { 33 pinctrl |= avr.PORT_PIN0CTRL_PULLUPEN 34 } 35 // Find the PINxCTRL register for this pin. 36 ctrlAddress := (*volatile.Register8)(unsafe.Add(unsafe.Pointer(&port.PIN0CTRL), p%8)) 37 ctrlAddress.Set(pinctrl) 38 39 // Configure the pin as input (if it wasn't an input pin before). 40 port.DIRCLR.Set(mask) 41 } 42 } 43 44 // Get returns the current value of a GPIO pin when the pin is configured as an 45 // input or as an output. 46 func (p Pin) Get() bool { 47 port, mask := p.getPortMask() 48 // As noted above, the PINx register is always two registers below the PORTx 49 // register, so we can find it simply by subtracting two from the PORTx 50 // register address. 51 return (port.IN.Get() & mask) > 0 52 } 53 54 // Set changes the value of the GPIO pin. The pin must be configured as output. 55 func (p Pin) Set(high bool) { 56 port, mask := p.getPortMask() 57 if high { 58 port.OUTSET.Set(mask) 59 } else { 60 port.OUTCLR.Set(mask) 61 } 62 }