Skip to content

Commit f23e13d

Browse files
Add option to disable bit rate switching for socket can
When running in CAN-FD mode, but with same nominal and data baudrate, BRS bit has to remain at zero. That indicates that there is no bitrate switch happening for data and data is transmitted at same speed.
1 parent 811e2eb commit f23e13d

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

pycyphal/application/_transport_factory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ def init(name: str, default: RelaxedValue) -> ValueProxy:
283283
iface_list = str(init("iface", "")).split()
284284
mtu = int(init("mtu", Natural16([64])))
285285
br_arb, br_data = init("bitrate", Natural32([1_000_000, 4_000_000])).ints
286+
disable_brs = bool(init("disable_brs", br_arb == br_data))
286287

287288
if iface_list:
288289
from pycyphal.transport.can import CANTransport
@@ -292,7 +293,7 @@ def init(name: str, default: RelaxedValue) -> ValueProxy:
292293
if iface.lower().startswith("socketcan:"):
293294
from pycyphal.transport.can.media.socketcan import SocketCANMedia
294295

295-
media = SocketCANMedia(iface.split(":", 1)[-1], mtu=mtu)
296+
media = SocketCANMedia(iface.split(":", 1)[-1], mtu=mtu, disable_brs=disable_brs)
296297
elif iface.lower().startswith("candump:"):
297298
from pycyphal.transport.can.media.candump import CandumpMedia
298299

pycyphal/transport/can/media/socketcan/_socketcan.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@ class SocketCANMedia(Media):
4141
SocketCAN documentation: https://www.kernel.org/doc/Documentation/networking/can.txt
4242
"""
4343

44-
def __init__(self, iface_name: str, mtu: int, loop: typing.Optional[asyncio.AbstractEventLoop] = None) -> None:
44+
def __init__(
45+
self,
46+
iface_name: str,
47+
mtu: int,
48+
disable_brs: bool = False,
49+
loop: typing.Optional[asyncio.AbstractEventLoop] = None,
50+
) -> None:
4551
"""
4652
CAN Classic/FD is selected automatically based on the MTU. It is not possible to use CAN FD with MTU of 8 bytes.
4753
@@ -50,6 +56,9 @@ def __init__(self, iface_name: str, mtu: int, loop: typing.Optional[asyncio.Abst
5056
:param mtu: The maximum data field size in bytes. CAN FD is used if this value > 8, Classic CAN otherwise.
5157
This value must belong to Media.VALID_MTU_SET.
5258
59+
:param disable_brs: When true, will disabele bitrate switching for CAN FD frames. Meaning that the data bitrate
60+
will be the same as the nominal bitrate.
61+
5362
:param loop: Deprecated.
5463
"""
5564
# This can't be made a class attribute because these errnos are only available on GNU/Linux.
@@ -68,6 +77,8 @@ def __init__(self, iface_name: str, mtu: int, loop: typing.Optional[asyncio.Abst
6877
self._mtu = int(mtu)
6978
if self._mtu not in self.VALID_MTU_SET:
7079
raise ValueError(f"Invalid MTU: {self._mtu} not in {self.VALID_MTU_SET}")
80+
self._disable_brs: bool = disable_brs
81+
7182
if loop:
7283
warnings.warn("The loop argument is deprecated", DeprecationWarning)
7384

@@ -260,7 +271,7 @@ def _read_frame(self, ts_mono_ns: int) -> typing.Tuple[Timestamp, Envelope]:
260271
return timestamp, Envelope(out, loopback=loopback)
261272

262273
def _compile_native_frame(self, source: DataFrame) -> bytes:
263-
flags = _CANFD_BRS if self._is_fd else 0
274+
flags = _CANFD_BRS if (self._is_fd and not self._disable_brs) else 0
264275
ident = source.identifier | (_CAN_EFF_FLAG if source.format == FrameFormat.EXTENDED else 0)
265276
header = _FRAME_HEADER_STRUCT.pack(ident, len(source.data), flags)
266277
out = header + source.data.ljust(self._native_frame_data_capacity, b"\x00")

0 commit comments

Comments
 (0)