-
Notifications
You must be signed in to change notification settings - Fork 11
/
device.go
146 lines (123 loc) · 3.12 KB
/
device.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
package rfm69
import (
"bytes"
"time"
"github.com/ecc1/gpio"
"github.com/ecc1/radio"
)
const (
hwVersion = 0x0204
)
type hwFlavor struct{}
// SPIDevice returns the pathname of the radio's SPI device.
func (hwFlavor) SPIDevice() string {
return spiDevice
}
// Speed returns the radio's SPI speed.
func (hwFlavor) Speed() int {
return spiSpeed
}
// CustomCS returns the GPIO pin number to use as a custom chip-select for the radio.
func (hwFlavor) CustomCS() int {
return customCS
}
// InterruptPin returns the GPIO pin number to use for receive interrupts.
func (hwFlavor) InterruptPin() int {
return interruptPin
}
// ReadSingleAddress returns the (identity) encoding of an address for SPI read operations.
func (hwFlavor) ReadSingleAddress(addr byte) byte {
return addr
}
// ReadBurstAddress returns the (identity) encoding of an address for SPI burst-read operations.
func (hwFlavor) ReadBurstAddress(addr byte) byte {
return addr
}
// WriteSingleAddress returns the encoding of an address for SPI write operations.
func (hwFlavor) WriteSingleAddress(addr byte) byte {
return SPIWriteMode | addr
}
// WriteBurstAddress returns the encoding of an address for SPI burst-write operations.
func (hwFlavor) WriteBurstAddress(addr byte) byte {
return SPIWriteMode | addr
}
// Radio represents an open radio device.
type Radio struct {
hw *radio.Hardware
resetPin gpio.OutputPin
receiveBuffer bytes.Buffer
txPacket []byte
err error
}
// Open opens the radio device.
func Open() *Radio {
r := &Radio{hw: radio.Open(hwFlavor{})}
v := r.Version()
if r.Error() != nil {
r.hw.Close()
return r
}
if v != hwVersion {
r.hw.Close()
r.SetError(radio.HardwareVersionError{Actual: v, Expected: hwVersion})
return r
}
r.resetPin, r.err = gpio.Output(resetPin, false, false)
if r.Error() != nil {
r.hw.Close()
return r
}
r.txPacket = make([]byte, maxPacketSize+1)
return r
}
// Close closes the radio device.
func (r *Radio) Close() {
r.setMode(SleepMode)
r.hw.Close()
}
// Name returns the radio's name.
func (r *Radio) Name() string {
return "RFM69HCW"
}
// Device returns the pathname of the radio's device.
func (*Radio) Device() string {
return spiDevice
}
// Version returns the radio's hardware version.
func (r *Radio) Version() uint16 {
v := r.hw.ReadRegister(RegVersion)
return uint16(v>>4)<<8 | uint16(v&0xF)
}
// Reset resets the radio device. See section 7.2.2 of data sheet.
func (r *Radio) Reset() {
if r.Error() != nil {
return
}
r.resetPin.Write(true)
time.Sleep(100 * time.Microsecond)
r.err = r.resetPin.Write(false)
time.Sleep(5 * time.Millisecond)
}
// Init initializes the radio device.
func (r *Radio) Init(frequency uint32) {
r.Reset()
r.InitRF(frequency)
r.setMode(SleepMode)
}
// Error returns the error state of the radio device.
func (r *Radio) Error() error {
err := r.hw.Error()
if err != nil {
return err
}
return r.err
}
// SetError sets the error state of the radio device.
func (r *Radio) SetError(err error) {
r.hw.SetError(err)
r.err = err
}
// Hardware returns the radio's hardware information.
func (r *Radio) Hardware() *radio.Hardware {
return r.hw
}