/
loop.go
97 lines (82 loc) · 1.74 KB
/
loop.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
// MCP2515 Stand-Alone CAN Interface
package mcp2515
import (
"os"
"os/signal"
"time"
)
type MsgChan chan *Message
type ErrChan chan error
func RunMessageLoop(d *MCP2515, rxChan MsgChan, txChan MsgChan,
errChan ErrChan) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
defer d.reset()
for {
status, err := d.readStatus()
reportError(err, errChan)
tryReceiveMessage(d, status, rxChan, errChan)
tryTransmitMessage(d, status, txChan, errChan)
select {
case <-c:
// Program done
return
default:
}
}
}
func tryReceiveMessage(d *MCP2515, status uint8,
rxChan MsgChan, errChan ErrChan) {
var rxBuffer uint8
switch {
case status&(1<<bits["RX0IF"]) != 0:
rxBuffer = 0
case status&(1<<bits["RX1IF"]) != 0:
rxBuffer = 1
default:
// no message received; carry on
return
}
rxMessage, err := d.receiveMessage(rxBuffer)
reportError(err, errChan)
select {
case rxChan <- rxMessage:
// Message forwarded for processing
default:
// Message channel full; carry on
}
}
func tryTransmitMessage(d *MCP2515, status uint8,
txChan MsgChan, errChan ErrChan) {
var txBuffer uint8
switch {
case status&(1<<statusBits["TX0REQ"]) == 0:
txBuffer = 0
case status&(1<<statusBits["TX1REQ"]) == 0:
txBuffer = 1
case status&(1<<statusBits["TX2REQ"]) == 0:
txBuffer = 2
default:
// No empty message buffers. Retry transmitting later
return
}
select {
case txMessage := <-txChan:
err := d.transmitMessage(txBuffer, txMessage)
reportError(err, errChan)
default:
// nothing to send; carry on
}
}
func reportError(err error, errChan ErrChan) {
if err == nil {
return
}
select {
case errChan <- err:
// Error reported
default:
// Error channel full; carry on
}
time.Sleep(100 * time.Millisecond)
}