/
driver.go
86 lines (74 loc) · 2.24 KB
/
driver.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
package buttonshim
import (
"time"
"periph.io/x/periph/conn"
"periph.io/x/periph/conn/i2c"
"periph.io/x/periph/devices"
)
// New returns a new Button SHIM hardware driver. The driver encapsulates a set of buttons
// and a single RGB LED, handling interaction with the actual device.
// Connects to the device on the given I2C bus at its standard address.
func New(bus i2c.Bus, opts ...Option) (*Driver, error) {
return NewWithConn(&i2c.Dev{Bus: bus, Addr: addr}, opts...)
}
// NewWithConn returns a new Button SHIM hardware driver, using the given periph.io
// conn.Conn object. Typically New should be used instead, but this may be useful for
// testing using mocks, or a custom I2C connection with a different address than the
// default.
func NewWithConn(periphConn conn.Conn, opts ...Option) (*Driver, error) {
options := defaultOptions
for _, opt := range opts {
opt(&options)
}
d := &Driver{
options: options,
pressHandlers: map[Button][]chan<- struct{}{},
releaseHandlers: map[Button][]chan<- time.Duration{},
i2c: periphConn,
buttonState: map[Button]time.Time{},
ledColor: make(chan color),
brightness: 255,
}
if err := d.setup(); err != nil {
return nil, err
}
return d, nil
}
// Driver is the primary struct for interacting with the Button SHIM device.
type Driver struct {
options options
// Device handle for I2C bus
i2c conn.Conn
pressHandlers map[Button][]chan<- struct{}
releaseHandlers map[Button][]chan<- time.Duration
// Indicates the pressed time if the button is currently pressed
buttonState map[Button]time.Time
// Communicates new colors to the LED color goroutine
ledColor chan color
brightness byte
}
type color struct {
r, g, b byte
}
func (d *Driver) setup() error {
// Initialize the hardware
if err := d.i2c.Tx([]byte{regConfig, 0x1f}, nil); err != nil {
return err
}
if err := d.i2c.Tx([]byte{regPolarity, 0x00}, nil); err != nil {
return err
}
if err := d.i2c.Tx([]byte{regOutput, 0x00}, nil); err != nil {
return err
}
go d.updateLed()
go d.pollButtons()
d.ledColor <- color{0, 0, 0}
return nil
}
// Halt implements devices.Device.
func (d *Driver) Halt() error {
// TODO: Clear the LED
return nil
}
var _ devices.Device = &Driver{}