Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions can/interfaces/seeedstudio/seeedstudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def __init__(
frame_type="STD",
operation_mode="normal",
bitrate=500000,
can_filters=None,
**kwargs,
):
"""
Expand All @@ -85,6 +86,12 @@ def __init__(
:param bitrate
CAN bus bit rate, selected from available list.

:param can_filters:
A list of CAN filter dictionaries. If one filter is provided,
it will be used by the high-performance hardware filter. If
zero or more than one filter is provided, software-based
filtering will be used. Defaults to None (no filtering).

:raises can.CanInitializationError: If the given parameters are invalid.
:raises can.CanInterfaceNotImplementedError: If the serial module is not installed.
"""
Expand All @@ -94,11 +101,21 @@ def __init__(
"the serial module is not installed"
)

can_id = 0x00
can_mask = 0x00
self._is_filtered = False

if can_filters and len(can_filters) == 1:
self._is_filtered = True
hw_filter = can_filters[0]
can_id = hw_filter["can_id"]
can_mask = hw_filter["can_mask"]

self.bit_rate = bitrate
self.frame_type = frame_type
self.op_mode = operation_mode
self.filter_id = bytearray([0x00, 0x00, 0x00, 0x00])
self.mask_id = bytearray([0x00, 0x00, 0x00, 0x00])
self.filter_id = struct.pack("<I", can_id)
self.mask_id = struct.pack("<I", can_mask)
self._can_protocol = CanProtocol.CAN_20

if not channel:
Expand All @@ -114,7 +131,7 @@ def __init__(
"could not create the serial device"
) from error

super().__init__(channel=channel, **kwargs)
super().__init__(channel=channel, can_filters=can_filters, **kwargs)
self.init_frame()

def shutdown(self):
Expand Down Expand Up @@ -237,8 +254,9 @@ def _recv_internal(self, timeout):
This parameter will be ignored. The timeout value of the
channel is used.

:returns:
Received message and False (because not filtering as taken place).
:return:
1. a message that was read or None on timeout
2. a bool that is True if hw_filter is enabled, else False

:rtype:
can.Message, bool
Expand All @@ -251,7 +269,7 @@ def _recv_internal(self, timeout):
except serial.PortNotOpenError as error:
raise can.CanOperationError("reading from closed port") from error
except serial.SerialException:
return None, False
return None, self._is_filtered

if rx_byte_1 and ord(rx_byte_1) == 0xAA:
try:
Expand Down Expand Up @@ -287,10 +305,10 @@ def _recv_internal(self, timeout):
data=data,
)
logger.debug("recv message: %s", str(msg))
return msg, False
return msg, self._is_filtered

else:
return None, False
return None, self._is_filtered

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

return None, None
return None, self._is_filtered

def fileno(self):
try:
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/1995.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added hardware filter support for SeeedBus during initialization, with a software fallback.
17 changes: 16 additions & 1 deletion doc/interfaces/seeedstudio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ Configuration
timeout=0.1,
frame_type='STD',
operation_mode='normal',
bitrate=500000)
bitrate=500000,
can_filters=None)

CHANNEL
The serial port created by the USB device when connected.
Expand Down Expand Up @@ -75,3 +76,17 @@ BITRATE
- 20000
- 10000
- 5000

CAN_FILTERS
A list of can filter dictionaries. Defaults to None (i.e. no filtering).
Each filter dictionary should have the following keys:
- ``can_id``: The CAN ID to filter on.
- ``can_mask``: The mask to apply to the ID.

Example: ``[{"can_id": 0x11, "can_mask": 0x21},]``

If one filter is provided, it will be used by the high-performance
hardware filter. If zero or more than one filter is provided,
software-based filtering will be used.


Loading