Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add notes/kvaser support for non-iso support #1752

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion can/bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class CanProtocol(Enum):
"""The CAN protocol type supported by a :class:`can.BusABC` instance"""

CAN_20 = auto()
CAN_FD = auto()
CAN_FD = auto() # ISO Mode
CAN_FD_NON_ISO = auto()
CAN_XL = auto()


Expand Down
16 changes: 14 additions & 2 deletions can/interfaces/kvaser/canlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ def __init__(
computer, set this to True or set single_handle to True.
:param bool fd:
If CAN-FD frames should be supported.
:param bool fd_non_iso:
Open the channel in Non-ISO (Bosch) FD mode. Only applies for FD buses.
This changes the handling of the stuff-bit counter and the CRC. Defaults
to False (ISO mode)
:param bool exclusive:
Don't allow sharing of this CANlib channel.
:param bool override_exclusive:
Expand All @@ -454,6 +458,7 @@ def __init__(
accept_virtual = kwargs.get("accept_virtual", True)
fd = isinstance(timing, BitTimingFd) if timing else kwargs.get("fd", False)
data_bitrate = kwargs.get("data_bitrate", None)
fd_non_iso = kwargs.get("fd_non_iso", False)

try:
channel = int(channel)
Expand All @@ -462,7 +467,11 @@ def __init__(

self.channel = channel
self.single_handle = single_handle
self._can_protocol = CanProtocol.CAN_FD if fd else CanProtocol.CAN_20
self._can_protocol = CanProtocol.CAN_20
if fd_non_iso:
self._can_protocol = CanProtocol.CAN_FD_NON_ISO
elif fd:
self._can_protocol = CanProtocol.CAN_FD

log.debug("Initialising bus instance")
num_channels = ctypes.c_int(0)
Expand All @@ -483,7 +492,10 @@ def __init__(
if accept_virtual:
flags |= canstat.canOPEN_ACCEPT_VIRTUAL
if fd:
flags |= canstat.canOPEN_CAN_FD
if fd_non_iso:
flags |= canstat.canOPEN_CAN_FD_NONISO
else:
flags |= canstat.canOPEN_CAN_FD

log.debug("Creating read handle to bus channel: %s", channel)
self._read_handle = canOpenChannel(channel, flags)
Expand Down
7 changes: 7 additions & 0 deletions doc/interfaces/pcan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ Here is an example configuration file for using `PCAN-USB <https://www.peak-syst
``bitrate`` (default ``500000``)
Channel bitrate

ISO/Non-ISO CAN FD Mode
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heading here also looks out of place. IMO the paragraph is not necessary.

~~~~~~~~~~~~~~~~~~~~~~~

The PCAN basic driver doesn't presently allow toggling the ISO/Non-ISO FD modes directly.
The default mode is stored on the device and can be controlled using the PCANView Windows application.
See: https://forum.peak-system.com/viewtopic.php?t=6496

This restriction does not apply to the socket-can driver.

.. _pcandoc linux installation:

Expand Down
5 changes: 5 additions & 0 deletions doc/interfaces/socketcan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ to ensure usage of SocketCAN Linux API. The most important differences are:
:members:
:inherited-members:

ISO/Non-ISO CAN FD Mode
-----------------------

Socket CAN devices can (for supported hardware) control ISO vs Non-ISO FD during creation with the ``ip`` command using the ``fd-non-iso`` flag.

.. External references

.. _Linux kernel docs: https://www.kernel.org/doc/Documentation/networking/can.txt
Expand Down
27 changes: 27 additions & 0 deletions test/test_kvaser.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ def test_can_timing(self):
def test_canfd_timing(self):
canlib.canSetBusParams.reset_mock()
canlib.canSetBusParamsFd.reset_mock()
canlib.canOpenChannel.reset_mock()
timing = can.BitTimingFd.from_bitrate_and_segments(
f_clock=80_000_000,
nom_bitrate=500_000,
Expand All @@ -210,6 +211,32 @@ def test_canfd_timing(self):
can.Bus(channel=0, interface="kvaser", timing=timing)
canlib.canSetBusParams.assert_called_once_with(0, 500_000, 68, 11, 10, 1, 0)
canlib.canSetBusParamsFd.assert_called_once_with(0, 2_000_000, 10, 9, 8)
canlib.canOpenChannel.assert_called_with(
0, constants.canOPEN_CAN_FD | constants.canOPEN_ACCEPT_VIRTUAL
)

def test_canfd_non_iso(self):
canlib.canSetBusParams.reset_mock()
canlib.canSetBusParamsFd.reset_mock()
canlib.canOpenChannel.reset_mock()
timing = can.BitTimingFd.from_bitrate_and_segments(
f_clock=80_000_000,
nom_bitrate=500_000,
nom_tseg1=68,
nom_tseg2=11,
nom_sjw=10,
data_bitrate=2_000_000,
data_tseg1=10,
data_tseg2=9,
data_sjw=8,
)
bus = can.Bus(channel=0, interface="kvaser", timing=timing, fd_non_iso=True)
self.assertEqual(bus.protocol, can.CanProtocol.CAN_FD_NON_ISO)
canlib.canSetBusParams.assert_called_once_with(0, 500_000, 68, 11, 10, 1, 0)
canlib.canSetBusParamsFd.assert_called_once_with(0, 2_000_000, 10, 9, 8)
canlib.canOpenChannel.assert_called_with(
0, constants.canOPEN_CAN_FD_NONISO | constants.canOPEN_ACCEPT_VIRTUAL
)

def test_canfd_nondefault_data_bitrate(self):
canlib.canSetBusParams.reset_mock()
Expand Down