-
Notifications
You must be signed in to change notification settings - Fork 0
/
BURT_can.cpp
94 lines (83 loc) · 2.85 KB
/
BURT_can.cpp
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
#include "BURT_can.h"
/// The number of the next available mailbox.
static int mailbox = MB0;
template <class CanType>
BurtCan<CanType>::BurtCan(uint32_t id, ProtoHandler onMessage, bool useExtendedIds) :
id(id),
onMessage(onMessage),
useExtendedIds(useExtendedIds)
{ }
template <class CanType>
void BurtCan<CanType>::handleCanFrame(const CanMessage& message) {
onMessage(message.buf, message.len);
}
template <class CanType>
void BurtCan<CanType>::setup() {
// Sets the baud rate and default message policy.
can.begin();
can.setBaudRate(CAN_BAUD_RATE);
can.setMBFilter(REJECT_ALL);
// Creates a new mailbox set to handle [id] with [handler].
FLEXCAN_MAILBOX mb = FLEXCAN_MAILBOX(mailbox);
can.setMBFilter(mb, id);
mailbox += 1;
}
template <class CanType>
void BurtCan<CanType>::update() {
int count = 0;
while (true) {
CanMessage message;
int success = can.read(message); // 0=no message, 1=message read
if (success == 0) return;
count++;
if (count == 10) {
Serial.println("[BurtCan] Warning: More than 10 messages are being read in loop().");
Serial.println("[BurtCan] Warning: Consider calling can.update() more often, reduce the");
Serial.println("[BurtCan] Warning: amount of messages on the CAN bus, or consider increasing");
Serial.println("[BurtCan] Warning: this limit. Your messages are still being processed.");
}
onMessage(message.buf, message.len);
}
}
template <class CanType>
void BurtCan<CanType>::sendRaw(uint32_t id, uint8_t data[8], int length) {
if (length > 8) {
Serial.println("Message is too long");
return;
}
// Initializes a CAN frame with the given data and sends it.
CanMessage frame = {};
if (useExtendedIds) frame.flags.extended = 1;
frame.id = id;
frame.len = length;
memset(frame.buf, 0, 8);
memcpy(frame.buf, data, length);
can.write(frame);
}
template <class CanType>
bool BurtCan<CanType>::send(uint32_t id, const void* message, const pb_msgdesc_t* fields) {
// Encodes a Protobuf message and then sends it using #sendRaw.
uint8_t data[8];
int length = BurtProto::encode(data, fields, message, 8);
if (length == -1) {
Serial.println("[BurtCan] Error: Failed to encode message");
return false;
} else if (length > 8) {
Serial.println("[BurtCan] Error: Encoded message is too long");
return false;
}
sendRaw(id, data, length);
return true;
}
template <class CanType>
void BurtCan<CanType>::showDebugInfo() {
Serial.println("[BurtCan] Debug: Showing debug info...");
can.mailboxStatus();
}
// ----- DO NOT REMOVE -----
// The following tells C++ which concrete implementations of "CanType" we will need.
// Without this, the BurtCan class will compile but you cannot use it since it's never seen
// a "real" CanType (ie, Can1, Can2, Can3) in this file. We have to use all three CAN types here.
template class BurtCan<Can1>;
template class BurtCan<Can2>;
template class BurtCan<Can3>;