-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpio.go
186 lines (157 loc) · 4.33 KB
/
gpio.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package main
import (
"strconv"
"time"
"periph.io/x/conn/v3/gpio"
"periph.io/x/conn/v3/gpio/gpioreg"
"periph.io/x/host/v3"
)
// gpioProvider generates pins for the platform (used for testing)
var gpioProvider = xGpioProvider // For testing on non-test setups
// GpioState represents the current binary value of the pin. Is it High or Low Voltage
type GpioState bool
const (
// Low voltage registered on the pin (~0-1v)
Low GpioState = false
// High voltage registered on the pin (~1-3.3v)
High GpioState = true
)
// State returns whether the pin is in a High or Low voltage state
func (s GpioState) State() gpio.Level {
if s == Low {
return gpio.Low
}
return gpio.High
}
func (s GpioState) String() string {
return s.State().String()
}
// Edge refers to the rising or falling of a voltage value on the pin.
type Edge int
const (
// NoEdge means no change
NoEdge Edge = 0
// RisingEdge means that the voltage is moving from a low to a high voltage state.
RisingEdge Edge = 1
// FallingEdge means that the voltage is moving from a high to a low voltage state.
FallingEdge Edge = 2
// BothEdges means taht a change is occuring in either direction.
BothEdges Edge = 3
)
// Edge returns the current edge value.
func (e Edge) Edge() gpio.Edge {
switch e {
case NoEdge:
return gpio.NoEdge
case RisingEdge:
return gpio.RisingEdge
case FallingEdge:
return gpio.FallingEdge
case BothEdges:
return gpio.BothEdges
}
return gpio.NoEdge
}
func (e Edge) String() string {
return e.Edge().String()
}
// Pull refers to the configuration of the pin circuitry.
type Pull int
const (
// Float lets the input flow directly, resistance is handled elswhere.
Float Pull = 0
// PullDown applies pull-down resistance to the pin
PullDown Pull = 1
// PullUp applies pull-up resistance to the pin
PullUp Pull = 2
// PullNoChange does not change the previous pull resistor setting
PullNoChange Pull = 3
)
// Pull returns the current state of the pin's pull configuration
func (p Pull) Pull() gpio.Pull {
switch p {
case Float:
return gpio.Float
case PullDown:
return gpio.PullDown
case PullUp:
return gpio.PullUp
case PullNoChange:
return gpio.PullNoChange
}
return gpio.PullNoChange
}
func (p Pull) String() string { return p.Pull().String() }
// PiPin represnets a GPIO pin on the Raspberry Pi
type PiPin interface {
Input()
InputEdge(Pull, Edge)
Output(GpioState)
Read() GpioState
WaitForEdge(time.Duration) bool
Pin() uint8
}
// Gpio implements a PiPin interface for a Raspberry Pi system.
type Gpio struct {
gpio uint8
pin gpio.PinIO
}
// SetGpioProvider allows you to change the type of GPIO for the system (useful for testing)
func SetGpioProvider(p func(uint8) PiPin) {
gpioProvider = p
}
func xGpioProvider(gpio uint8) PiPin {
g := Gpio{
gpio: gpio,
pin: gpioreg.ByName(strconv.Itoa(int(gpio))),
}
gpioreg.Register(g.pin)
return (PiPin)(&g)
}
// NewGpio creates a new PiPin for a given gpio value.
func NewGpio(gpio uint8) PiPin {
return gpioProvider(gpio)
}
// GpioInit initializes the system
func GpioInit() error {
_, err := host.Init()
return err
}
// Input sets the pin to be read from.
func (g *Gpio) Input() {
Debug("Setting gpio(%d) to Input(%s, %s)", g.gpio, Float, NoEdge)
g.pin.In(gpio.Float, gpio.NoEdge)
}
// InputEdge sets the pin to be read from and to alert WaitForEdge when the given Edge is found.
func (g *Gpio) InputEdge(p Pull, e Edge) {
Debug("Setting gpio(%d) to Input(%s, %s)", g.gpio, p, e)
g.pin.In(p.Pull(), e.Edge())
}
// Output sets the pin to be written to.
func (g *Gpio) Output(s GpioState) {
Debug("Output setting gpio(%d) to %s", g.gpio, s)
g.pin.Out(s.State())
}
// Read returns the current state of the pin
func (g *Gpio) Read() GpioState {
if g.pin.Read() == gpio.High {
return High
}
return Low
}
// WaitForEdge blocks while waiting for a voltage change on the pin.
func (g *Gpio) WaitForEdge(timeout time.Duration) bool {
return g.pin.WaitForEdge(timeout)
}
// Pin returns the GPIO number of the pin.
func (g *Gpio) Pin() uint8 {
return g.gpio
}
// Direction refers to the usage of the pin. Is it being used for input or output?
type Direction bool
const (
// Input means that the value of the pin will be read and is controlled externally.
Input Direction = false
// Output means that the value of the pin will be written to and is controlled internally.
Output Direction = true
)