forked from kidoman/embd
-
Notifications
You must be signed in to change notification settings - Fork 3
/
gpiodriver.go
122 lines (93 loc) · 2.49 KB
/
gpiodriver.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
// Generic GPIO driver.
package embd
import (
"errors"
"fmt"
)
type pin interface {
Close() error
}
type digitalPinFactory func(pd *PinDesc, drv GPIODriver) DigitalPin
type analogPinFactory func(pd *PinDesc, drv GPIODriver) AnalogPin
type pwmPinFactory func(pd *PinDesc, drv GPIODriver) PWMPin
type gpioDriver struct {
pinMap PinMap
dpf digitalPinFactory
apf analogPinFactory
ppf pwmPinFactory
initializedPins map[string]pin
}
// NewGPIODriver returns a GPIODriver interface which allows control
// over the GPIO subsystem.
func NewGPIODriver(pinMap PinMap, dpf digitalPinFactory, apf analogPinFactory, ppf pwmPinFactory) GPIODriver {
return &gpioDriver{
pinMap: pinMap,
dpf: dpf,
apf: apf,
ppf: ppf,
initializedPins: map[string]pin{},
}
}
func (io *gpioDriver) Unregister(id string) error {
if _, ok := io.initializedPins[id]; !ok {
return fmt.Errorf("gpio: pin %v is not registered yet, cannot unregister", id)
}
delete(io.initializedPins, id)
return nil
}
func (io *gpioDriver) DigitalPin(key interface{}) (DigitalPin, error) {
if io.dpf == nil {
return nil, errors.New("gpio: digital io not supported on this host")
}
pd, found := io.pinMap.Lookup(key, CapDigital)
if !found {
return nil, fmt.Errorf("gpio: could not find pin matching %v", key)
}
if p, ok := io.initializedPins[pd.ID]; ok {
return p.(DigitalPin), nil
}
p := io.dpf(pd, io)
io.initializedPins[pd.ID] = p
return p, nil
}
func (io *gpioDriver) AnalogPin(key interface{}) (AnalogPin, error) {
if io.apf == nil {
return nil, errors.New("gpio: analog io not supported on this host")
}
pd, found := io.pinMap.Lookup(key, CapAnalog)
if !found {
return nil, fmt.Errorf("gpio: could not find pin matching %v", key)
}
if p, ok := io.initializedPins[pd.ID]; ok {
return p.(AnalogPin), nil
}
p := io.apf(pd, io)
io.initializedPins[pd.ID] = p
return p, nil
}
func (io *gpioDriver) PWMPin(key interface{}) (PWMPin, error) {
if io.ppf == nil {
return nil, errors.New("gpio: pwm not supported on this host")
}
pd, found := io.pinMap.Lookup(key, CapPWM)
if !found {
return nil, fmt.Errorf("gpio: could not find pin matching %v", key)
}
if p, ok := io.initializedPins[pd.ID]; ok {
return p.(PWMPin), nil
}
p := io.ppf(pd, io)
io.initializedPins[pd.ID] = p
return p, nil
}
func (io *gpioDriver) PinMap() PinMap {
return io.pinMap
}
func (io *gpioDriver) Close() error {
for _, p := range io.initializedPins {
if err := p.Close(); err != nil {
return err
}
}
return nil
}