Skip to content

Commit b4d5094

Browse files
SeedBus: Added can_filters parameter in SeedBus.__init__ method (#1999)
* Added hardware filter support for SeeedBus during initialization * Implement software fallback for can_filters in SeedBus - Updated the __init__ function in SeedBus - Implemented software fallback, if the user passes multiple filters in can_filters dict. * updated changelog for PR #1999 * Updated _recv_internal method of SeedBus - updated _recv_internal method of SeedBus to return also the Boolean value based on whether hw filter is enabled or not
1 parent efd4de5 commit b4d5094

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

can/interfaces/seeedstudio/seeedstudio.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ def __init__(
6363
frame_type="STD",
6464
operation_mode="normal",
6565
bitrate=500000,
66+
can_filters=None,
6667
**kwargs,
6768
):
6869
"""
@@ -85,6 +86,12 @@ def __init__(
8586
:param bitrate
8687
CAN bus bit rate, selected from available list.
8788
89+
:param can_filters:
90+
A list of CAN filter dictionaries. If one filter is provided,
91+
it will be used by the high-performance hardware filter. If
92+
zero or more than one filter is provided, software-based
93+
filtering will be used. Defaults to None (no filtering).
94+
8895
:raises can.CanInitializationError: If the given parameters are invalid.
8996
:raises can.CanInterfaceNotImplementedError: If the serial module is not installed.
9097
"""
@@ -94,11 +101,21 @@ def __init__(
94101
"the serial module is not installed"
95102
)
96103

104+
can_id = 0x00
105+
can_mask = 0x00
106+
self._is_filtered = False
107+
108+
if can_filters and len(can_filters) == 1:
109+
self._is_filtered = True
110+
hw_filter = can_filters[0]
111+
can_id = hw_filter["can_id"]
112+
can_mask = hw_filter["can_mask"]
113+
97114
self.bit_rate = bitrate
98115
self.frame_type = frame_type
99116
self.op_mode = operation_mode
100-
self.filter_id = bytearray([0x00, 0x00, 0x00, 0x00])
101-
self.mask_id = bytearray([0x00, 0x00, 0x00, 0x00])
117+
self.filter_id = struct.pack("<I", can_id)
118+
self.mask_id = struct.pack("<I", can_mask)
102119
self._can_protocol = CanProtocol.CAN_20
103120

104121
if not channel:
@@ -114,7 +131,7 @@ def __init__(
114131
"could not create the serial device"
115132
) from error
116133

117-
super().__init__(channel=channel, **kwargs)
134+
super().__init__(channel=channel, can_filters=can_filters, **kwargs)
118135
self.init_frame()
119136

120137
def shutdown(self):
@@ -237,8 +254,9 @@ def _recv_internal(self, timeout):
237254
This parameter will be ignored. The timeout value of the
238255
channel is used.
239256
240-
:returns:
241-
Received message and False (because not filtering as taken place).
257+
:return:
258+
1. a message that was read or None on timeout
259+
2. a bool that is True if hw_filter is enabled, else False
242260
243261
:rtype:
244262
can.Message, bool
@@ -251,7 +269,7 @@ def _recv_internal(self, timeout):
251269
except serial.PortNotOpenError as error:
252270
raise can.CanOperationError("reading from closed port") from error
253271
except serial.SerialException:
254-
return None, False
272+
return None, self._is_filtered
255273

256274
if rx_byte_1 and ord(rx_byte_1) == 0xAA:
257275
try:
@@ -287,10 +305,10 @@ def _recv_internal(self, timeout):
287305
data=data,
288306
)
289307
logger.debug("recv message: %s", str(msg))
290-
return msg, False
308+
return msg, self._is_filtered
291309

292310
else:
293-
return None, False
311+
return None, self._is_filtered
294312

295313
except serial.PortNotOpenError as error:
296314
raise can.CanOperationError("reading from closed port") from error
@@ -299,7 +317,7 @@ def _recv_internal(self, timeout):
299317
"failed to read message information"
300318
) from error
301319

302-
return None, None
320+
return None, self._is_filtered
303321

304322
def fileno(self):
305323
try:

doc/changelog.d/1995.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added hardware filter support for SeeedBus during initialization, with a software fallback.

doc/interfaces/seeedstudio.rst

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ Configuration
4444
timeout=0.1,
4545
frame_type='STD',
4646
operation_mode='normal',
47-
bitrate=500000)
47+
bitrate=500000,
48+
can_filters=None)
4849

4950
CHANNEL
5051
The serial port created by the USB device when connected.
@@ -75,3 +76,17 @@ BITRATE
7576
- 20000
7677
- 10000
7778
- 5000
79+
80+
CAN_FILTERS
81+
A list of can filter dictionaries. Defaults to None (i.e. no filtering).
82+
Each filter dictionary should have the following keys:
83+
- ``can_id``: The CAN ID to filter on.
84+
- ``can_mask``: The mask to apply to the ID.
85+
86+
Example: ``[{"can_id": 0x11, "can_mask": 0x21},]``
87+
88+
If one filter is provided, it will be used by the high-performance
89+
hardware filter. If zero or more than one filter is provided,
90+
software-based filtering will be used.
91+
92+

0 commit comments

Comments
 (0)