-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
i2c.go
204 lines (168 loc) · 5.03 KB
/
i2c.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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package i2c
import (
"errors"
"io"
"sync"
)
const (
// Error event
Error = "error"
)
const (
// BusNotInitialized is the initial value for a bus
BusNotInitialized = -1
// AddressNotInitialized is the initial value for an address
AddressNotInitialized = -1
)
var (
ErrEncryptedBytes = errors.New("Encrypted bytes")
ErrNotEnoughBytes = errors.New("Not enough bytes read")
ErrNotReady = errors.New("Device is not ready")
ErrInvalidPosition = errors.New("Invalid position value")
)
type bitState uint8
const (
clear bitState = 0x00
set = 0x01
)
type I2cOperations interface {
io.ReadWriteCloser
ReadByte() (val byte, err error)
ReadByteData(reg uint8) (val uint8, err error)
ReadWordData(reg uint8) (val uint16, err error)
WriteByte(val byte) (err error)
WriteByteData(reg uint8, val uint8) (err error)
WriteWordData(reg uint8, val uint16) (err error)
WriteBlockData(reg uint8, b []byte) (err error)
}
// I2cDevice is the interface to a specific i2c bus
type I2cDevice interface {
I2cOperations
SetAddress(int) error
}
// Connector lets Adaptors provide the interface for Drivers
// to get access to the I2C buses on platforms that support I2C.
type Connector interface {
// GetConnection returns a connection to device at the specified address
// and bus. Bus numbering starts at index 0, the range of valid buses is
// platform specific.
GetConnection(address int, bus int) (device Connection, err error)
// GetDefaultBus returns the default I2C bus index
GetDefaultBus() int
}
// Connection is a connection to an I2C device with a specified address
// on a specific bus. Used as an alternative to the I2c interface.
// Implements I2cOperations to talk to the device, wrapping the
// calls in SetAddress to always target the specified device.
// Provided by an Adaptor by implementing the I2cConnector interface.
type Connection I2cOperations
type i2cConnection struct {
bus I2cDevice
address int
mutex *sync.Mutex
}
// NewConnection creates and returns a new connection to a specific
// i2c device on a bus and address.
func NewConnection(bus I2cDevice, address int) (connection *i2cConnection) {
return &i2cConnection{bus: bus, address: address, mutex: &sync.Mutex{}}
}
// Read data from an i2c device.
func (c *i2cConnection) Read(data []byte) (read int, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err = c.bus.SetAddress(c.address); err != nil {
return 0, err
}
read, err = c.bus.Read(data)
return
}
// Write data to an i2c device.
func (c *i2cConnection) Write(data []byte) (written int, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err = c.bus.SetAddress(c.address); err != nil {
return 0, err
}
written, err = c.bus.Write(data)
return
}
// Close connection to i2c device.
func (c *i2cConnection) Close() error {
c.mutex.Lock()
defer c.mutex.Unlock()
return c.bus.Close()
}
// ReadByte reads a single byte from the i2c device.
func (c *i2cConnection) ReadByte() (val byte, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadByte()
}
// ReadByteData reads a byte value for a register on the i2c device.
func (c *i2cConnection) ReadByteData(reg uint8) (val uint8, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadByteData(reg)
}
// ReadWordData reads a word value for a register on the i2c device.
func (c *i2cConnection) ReadWordData(reg uint8) (val uint16, err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return 0, err
}
return c.bus.ReadWordData(reg)
}
// WriteByte writes a single byte to the i2c device.
func (c *i2cConnection) WriteByte(val byte) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteByte(val)
}
// WriteByteData writes a byte value to a register on the i2c device.
func (c *i2cConnection) WriteByteData(reg uint8, val uint8) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteByteData(reg, val)
}
// WriteWordData writes a word value to a register on the i2c device.
func (c *i2cConnection) WriteWordData(reg uint8, val uint16) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteWordData(reg, val)
}
// WriteBlockData writes a block of bytes to a register on the i2c device.
func (c *i2cConnection) WriteBlockData(reg uint8, b []byte) (err error) {
c.mutex.Lock()
defer c.mutex.Unlock()
if err := c.bus.SetAddress(c.address); err != nil {
return err
}
return c.bus.WriteBlockData(reg, b)
}
// setBit is used to set a bit at a given position to 1.
func setBit(n uint8, pos uint8) uint8 {
n |= (1 << pos)
return n
}
// clearBit is used to set a bit at a given position to 0.
func clearBit(n uint8, pos uint8) uint8 {
mask := ^uint8(1 << pos)
n &= mask
return n
}