forked from google/periph
/
registers.go
111 lines (93 loc) · 2.34 KB
/
registers.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
// Copyright 2020 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package mcp23xxx
import (
"periph.io/x/periph/conn/i2c"
"periph.io/x/periph/conn/spi"
)
type registerAccess interface {
define(address uint8) registerCache
readRegister(address uint8) (uint8, error)
writeRegister(address uint8, value uint8) error
}
type i2cRegisterAccess struct {
*i2c.Dev
}
func (ra *i2cRegisterAccess) readRegister(address uint8) (uint8, error) {
r := make([]byte, 1)
err := ra.Tx([]byte{address}, r)
return r[0], err
}
func (ra *i2cRegisterAccess) writeRegister(address uint8, value uint8) error {
return ra.Tx([]byte{address, value}, nil)
}
func (ra *i2cRegisterAccess) define(address uint8) registerCache {
return newRegister(ra, address)
}
type spiRegisterAccess struct {
spi.Conn
}
func (ra *spiRegisterAccess) readRegister(address uint8) (uint8, error) {
r := make([]byte, 1)
err := ra.Tx([]byte{0x41, address}, r)
return r[0], err
}
func (ra *spiRegisterAccess) writeRegister(address uint8, value uint8) error {
return ra.Tx([]byte{0x40, address, value}, nil)
}
func (ra *spiRegisterAccess) define(address uint8) registerCache {
return newRegister(ra, address)
}
type registerCache struct {
registerAccess
address uint8
got bool
cache uint8
}
func newRegister(ra registerAccess, address uint8) registerCache {
return registerCache{
registerAccess: ra,
address: address,
got: false,
}
}
func (r *registerCache) readValue(cached bool) (uint8, error) {
if cached && r.got {
return r.cache, nil
}
v, err := r.readRegister(r.address)
if err == nil {
r.got = true
r.cache = v
}
return v, err
}
func (r *registerCache) writeValue(value uint8, cached bool) error {
if cached && r.got && value == r.cache {
return nil
}
err := r.writeRegister(r.address, value)
if err != nil {
return err
}
r.got = true
r.cache = value
return nil
}
func (r *registerCache) getAndSetBit(bit uint8, value bool, cached bool) error {
v, err := r.readValue(cached)
if err != nil {
return err
}
if value {
v |= 1 << bit
} else {
v &= ^(1 << bit)
}
return r.writeValue(v, cached)
}
func (r *registerCache) getBit(bit uint8, cached bool) (bool, error) {
v, err := r.readValue(cached)
return (v & (1 << bit)) != 0, err
}