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