Skip to content

Commit 6287783

Browse files
committed
Add new filter API's and implementations
1 parent 290db7a commit 6287783

File tree

8 files changed

+194
-11
lines changed

8 files changed

+194
-11
lines changed

API.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,33 @@ Returns the next byte in the packet or `-1` if no bytes are available.
220220

221221
**Note:** Other Arduino [`Stream` API's](https://www.arduino.cc/en/Reference/Stream) can also be used to read data from the packet
222222

223+
### Filtering
224+
225+
Filter packets that meet the desired criteria.
226+
227+
```
228+
CAN.filter(id);
229+
CAN.filter(id, mask);
230+
231+
CAN.filterExtended(id);
232+
CAN.filterExtended(id, mask);
233+
```
234+
235+
* `id` - 11-bit id (standard packet) or 29-bit packet id (extended packet)
236+
* `mask` - (optional) 11-bit mask (standard packet) or 29-bit mask (extended packet), defaults to `0x7ff` or `0x1fffffff` (extended)
237+
238+
Only packets that meet the following criteria are acknowleged and received, other packets are ignored:
239+
240+
```
241+
if ((packetId & mask) == id) {
242+
// acknowleged and received
243+
} else {
244+
// ignored
245+
}
246+
```
247+
248+
Returns `1` on success, `0` on failure.
249+
223250
## Other modes
224251

225252
### Loopback mode

keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ peek KEYWORD2
3333
flush KEYWORD2
3434

3535
onReceive KEYWORD2
36+
filter KEYWORD2
37+
filterExtended KEYWORD2
3638
loopback KEYWORD2
3739
sleep KEYWORD2
3840
wakeup KEYWORD2

src/CANController.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ void CANControllerClass::onReceive(void(*callback)(int))
185185
_onReceive = callback;
186186
}
187187

188+
int CANControllerClass::filter(int /*id*/, int /*mask*/)
189+
{
190+
return 0;
191+
}
192+
193+
int CANControllerClass::filterExtended(long /*id*/, long /*mask*/)
194+
{
195+
return 0;
196+
}
197+
188198
int CANControllerClass::observe()
189199
{
190200
return 0;

src/CANController.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ class CANControllerClass : public Stream {
3434

3535
virtual void onReceive(void(*callback)(int));
3636

37+
virtual int filter(int id) { return filter(id, 0x7ff); }
38+
virtual int filter(int id, int mask);
39+
virtual int filterExtended(long id) { return filterExtended(id, 0x1fffffff); }
40+
virtual int filterExtended(long id, long mask);
41+
3742
virtual int observe();
3843
virtual int loopback();
3944
virtual int sleep();

src/ESP32SJA1000.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ int ESP32SJA1000Class::begin(long baudRate)
155155
readRegister(REG_IR);
156156

157157
// normal mode
158-
modifyRegister(REG_MOD, 0x1f, 0x00);
158+
modifyRegister(REG_MOD, 0x08, 0x08);
159+
modifyRegister(REG_MOD, 0x17, 0x00);
159160

160161
return 1;
161162
}
@@ -283,10 +284,54 @@ void ESP32SJA1000Class::onReceive(void(*callback)(int))
283284
}
284285
}
285286

287+
int ESP32SJA1000Class::filter(int id, int mask)
288+
{
289+
id &= 0x7ff;
290+
mask = ~(mask & 0x7ff);
291+
292+
modifyRegister(REG_MOD, 0x17, 0x01); // reset
293+
294+
writeRegister(REG_ACRn(0), id >> 3);
295+
writeRegister(REG_ACRn(1), id << 5);
296+
writeRegister(REG_ACRn(2), 0x00);
297+
writeRegister(REG_ACRn(3), 0x00);
298+
299+
writeRegister(REG_AMRn(0), mask >> 3);
300+
writeRegister(REG_AMRn(1), (mask << 5) | 0x1f);
301+
writeRegister(REG_AMRn(2), 0xff);
302+
writeRegister(REG_AMRn(3), 0xff);
303+
304+
modifyRegister(REG_MOD, 0x17, 0x00); // normal
305+
306+
return 1;
307+
}
308+
309+
int ESP32SJA1000Class::filterExtended(long id, long mask)
310+
{
311+
id &= 0x1FFFFFFF;
312+
mask &= ~(mask & 0x1FFFFFFF);
313+
314+
modifyRegister(REG_MOD, 0x17, 0x01); // reset
315+
316+
writeRegister(REG_ACRn(0), id >> 21);
317+
writeRegister(REG_ACRn(1), id >> 13);
318+
writeRegister(REG_ACRn(2), id >> 5);
319+
writeRegister(REG_ACRn(3), id << 5);
320+
321+
writeRegister(REG_AMRn(0), mask >> 21);
322+
writeRegister(REG_AMRn(1), mask >> 13);
323+
writeRegister(REG_AMRn(2), mask >> 5);
324+
writeRegister(REG_AMRn(3), (mask << 5) | 0x1f);
325+
326+
modifyRegister(REG_MOD, 0x17, 0x00); // normal
327+
328+
return 1;
329+
}
330+
286331
int ESP32SJA1000Class::observe()
287332
{
288-
modifyRegister(REG_MOD, 0x1f, 0x01); // reset
289-
modifyRegister(REG_MOD, 0x1f, 0x02); // observe
333+
modifyRegister(REG_MOD, 0x17, 0x01); // reset
334+
modifyRegister(REG_MOD, 0x17, 0x02); // observe
290335

291336
return 1;
292337
}
@@ -295,8 +340,8 @@ int ESP32SJA1000Class::loopback()
295340
{
296341
_loopback = true;
297342

298-
modifyRegister(REG_MOD, 0x1f, 0x01); // reset
299-
modifyRegister(REG_MOD, 0x1f, 0x04); // self test mode
343+
modifyRegister(REG_MOD, 0x17, 0x01); // reset
344+
modifyRegister(REG_MOD, 0x17, 0x04); // self test mode
300345

301346
return 1;
302347
}

src/ESP32SJA1000.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class ESP32SJA1000Class : public CANControllerClass {
2626

2727
virtual void onReceive(void(*callback)(int));
2828

29+
using CANControllerClass::filter;
30+
virtual int filter(int id, int mask);
31+
using CANControllerClass::filterExtended;
32+
virtual int filterExtended(long id, long mask);
33+
2934
virtual int observe();
3035
virtual int loopback();
3136
virtual int sleep();

src/MCP2515.cpp

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
#define FLAG_RXnIF(n) (0x01 << n)
2222
#define FLAG_TXnIF(n) (0x04 << n)
2323

24+
#define REG_RXFnSIDH(n) (0x00 + (n * 4))
25+
#define REG_RXFnSIDL(n) (0x01 + (n * 4))
26+
#define REG_RXFnEID8(n) (0x02 + (n * 4))
27+
#define REG_RXFnEID0(n) (0x03 + (n * 4))
28+
29+
#define REG_RXMnSIDH(n) (0x20 + (n * 0x04))
30+
#define REG_RXMnSIDL(n) (0x21 + (n * 0x04))
31+
#define REG_RXMnEID8(n) (0x22 + (n * 0x04))
32+
#define REG_RXMnEID0(n) (0x23 + (n * 0x04))
33+
2434
#define REG_TXBnCTRL(n) (0x30 + (n * 0x10))
2535
#define REG_TXBnSIDH(n) (0x31 + (n * 0x10))
2636
#define REG_TXBnSIDL(n) (0x32 + (n * 0x10))
@@ -45,8 +55,6 @@
4555
#define FLAG_RXM0 0x20
4656
#define FLAG_RXM1 0x40
4757

48-
#define REG_RXB0CTRL 0x60
49-
#define REG_RXB1CTRL 0x70
5058

5159
MCP2515Class::MCP2515Class() :
5260
CANControllerClass(),
@@ -129,8 +137,8 @@ int MCP2515Class::begin(long baudRate)
129137
writeRegister(REG_CANINTE, FLAG_RXnIE(1) | FLAG_RXnIE(0));
130138
writeRegister(REG_BFPCTRL, 0x00);
131139
writeRegister(REG_TXRTSCTRL, 0x00);
132-
writeRegister(REG_RXB0CTRL, FLAG_RXM1 | FLAG_RXM0);
133-
writeRegister(REG_RXB1CTRL, FLAG_RXM1 | FLAG_RXM0);
140+
writeRegister(REG_RXBnCTRL(0), FLAG_RXM1 | FLAG_RXM0);
141+
writeRegister(REG_RXBnCTRL(1), FLAG_RXM1 | FLAG_RXM0);
134142

135143
writeRegister(REG_CANCTRL, 0x00);
136144
if (readRegister(REG_CANCTRL) != 0x00) {
@@ -157,7 +165,7 @@ int MCP2515Class::endPacket()
157165

158166
if (_txExtended) {
159167
writeRegister(REG_TXBnSIDH(n), _txId >> 21);
160-
writeRegister(REG_TXBnSIDL(n), (((_txId >> 18) & 0x03) << 5) | FLAG_EXIDE | ((_txId >> 16) & 0x03));
168+
writeRegister(REG_TXBnSIDL(n), (((_txId >> 18) & 0x07) << 5) | FLAG_EXIDE | ((_txId >> 16) & 0x03));
161169
writeRegister(REG_TXBnEID8(n), (_txId >> 8) & 0xff);
162170
writeRegister(REG_TXBnEID0(n), _txId & 0xff);
163171
} else {
@@ -213,7 +221,7 @@ int MCP2515Class::parsePacket()
213221

214222
_rxExtended = (readRegister(REG_RXBnSIDL(n)) & FLAG_IDE) ? true : false;
215223

216-
uint32_t idA = ((readRegister(REG_RXBnSIDH(n)) << 3) & 0xf8) | ((readRegister(REG_RXBnSIDL(n)) >> 5) & 0x07);
224+
uint32_t idA = ((readRegister(REG_RXBnSIDH(n)) << 3) & 0x07f8) | ((readRegister(REG_RXBnSIDL(n)) >> 5) & 0x07);
217225
if (_rxExtended) {
218226
uint32_t idB = (((uint32_t)(readRegister(REG_RXBnSIDL(n)) & 0x03) << 16) & 0x30000) | ((readRegister(REG_RXBnEID8(n)) << 8) & 0xff00) | readRegister(REG_RXBnEID0(n));
219227

@@ -258,6 +266,82 @@ void MCP2515Class::onReceive(void(*callback)(int))
258266
}
259267
}
260268

269+
int MCP2515Class::filter(int id, int mask)
270+
{
271+
id &= 0x7ff;
272+
mask &= 0x7ff;
273+
274+
// config mode
275+
writeRegister(REG_CANCTRL, 0x80);
276+
if (readRegister(REG_CANCTRL) != 0x80) {
277+
return 0;
278+
}
279+
280+
for (int n = 0; n < 2; n++) {
281+
// standard only
282+
writeRegister(REG_RXBnCTRL(n), FLAG_RXM0);
283+
writeRegister(REG_RXBnCTRL(n), FLAG_RXM0);
284+
285+
writeRegister(REG_RXMnSIDH(n), mask >> 3);
286+
writeRegister(REG_RXMnSIDL(n), mask << 5);
287+
writeRegister(REG_RXMnEID8(n), 0);
288+
writeRegister(REG_RXMnEID0(n), 0);
289+
}
290+
291+
for (int n = 0; n < 6; n++) {
292+
writeRegister(REG_RXFnSIDH(n), id >> 3);
293+
writeRegister(REG_RXFnSIDL(n), id << 5);
294+
writeRegister(REG_RXFnEID8(n), 0);
295+
writeRegister(REG_RXFnEID0(n), 0);
296+
}
297+
298+
// normal mode
299+
writeRegister(REG_CANCTRL, 0x00);
300+
if (readRegister(REG_CANCTRL) != 0x00) {
301+
return 0;
302+
}
303+
304+
return 1;
305+
}
306+
307+
int MCP2515Class::filterExtended(long id, long mask)
308+
{
309+
id &= 0x1FFFFFFF;
310+
mask &= 0x1FFFFFFF;
311+
312+
// config mode
313+
writeRegister(REG_CANCTRL, 0x80);
314+
if (readRegister(REG_CANCTRL) != 0x80) {
315+
return 0;
316+
}
317+
318+
for (int n = 0; n < 2; n++) {
319+
// extended only
320+
writeRegister(REG_RXBnCTRL(n), FLAG_RXM1);
321+
writeRegister(REG_RXBnCTRL(n), FLAG_RXM1);
322+
323+
writeRegister(REG_RXMnSIDH(n), mask >> 21);
324+
writeRegister(REG_RXMnSIDL(n), (((mask >> 18) & 0x03) << 5) | FLAG_EXIDE | ((mask >> 16) & 0x03));
325+
writeRegister(REG_RXMnEID8(n), (mask >> 8) & 0xff);
326+
writeRegister(REG_RXMnEID0(n), mask & 0xff);
327+
}
328+
329+
for (int n = 0; n < 6; n++) {
330+
writeRegister(REG_RXFnSIDH(n), id >> 21);
331+
writeRegister(REG_RXFnSIDL(n), (((id >> 18) & 0x03) << 5) | FLAG_EXIDE | ((id >> 16) & 0x03));
332+
writeRegister(REG_RXFnEID8(n), (id >> 8) & 0xff);
333+
writeRegister(REG_RXFnEID0(n), id & 0xff);
334+
}
335+
336+
// normal mode
337+
writeRegister(REG_CANCTRL, 0x00);
338+
if (readRegister(REG_CANCTRL) != 0x00) {
339+
return 0;
340+
}
341+
342+
return 1;
343+
}
344+
261345
int MCP2515Class::observe()
262346
{
263347
writeRegister(REG_CANCTRL, 0x80);

src/MCP2515.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class MCP2515Class : public CANControllerClass {
2929

3030
virtual void onReceive(void(*callback)(int));
3131

32+
using CANControllerClass::filter;
33+
virtual int filter(int id, int mask);
34+
using CANControllerClass::filterExtended;
35+
virtual int filterExtended(long id, long mask);
36+
3237
virtual int observe();
3338
virtual int loopback();
3439
virtual int sleep();

0 commit comments

Comments
 (0)