Describe the bug
The BitTiming class unconditionally requires that the bitrate prescaler brp is within the interval [1,64]; this is checked in the _validate function, which is unconditionally called from __init__ even when strict=False:
def _validate(self) -> None:
if not 1 <= self.brp <= 64:
raise ValueError(f"bitrate prescaler (={self.brp}) must be in [1...64].")
# other checks omitted
I was using python-can with a FYSETC UCAN transceiver running candleLight firmware, which speaks the gs_usb protocol. The transceiver uses a clock frequency of fclock=48MHz, but it also supports a large range of possible brp values from 1 to 1024 to implement lower bitrates (see bxcan.c ).
I need to configure a baud rate of 33333 bit/s and want to use the default sample point of 87.5%, which requires a prescaler value > 64 to keep the other paramters (specifically tseg1 within their valid range). This is currently not possible without patching the code of python-can directly, since the gs_usb interface kind does not allow direct specification of the BitTimings, and the validation check will reject the prescaler value, so the automatic parameter finding does not work. However, the device supports higher prescaler values just fine; and removing the bitrate prescaler check in _validate allows me to configure the device and send CAN messages.
To Reproduce
The following code will raise ValueError("No suitable bit timings found.") from BitTimings.from_sample_point
import can
can_bus = can.Bus(interface='gs_usb', channel=0, bitrate=33333)
Note: this requires a suitable board with candleLight firmware to be present and attached. Internally, the device configuration routine retrieves the CAN clock speed and calls BitTiming.from_sample_point with those values:
from can.bit_timing import BitTiming
BitTiming.from_sample_point(f_clock=48000000,bitrate=33333,sample_point=87.5)
This can be called without hardware to reproduce the issue.
Expected behavior
Ideally, the parameter validation takes the valid parameter range of the attached device into account (if known), so that the code above just works as-is. The gs_usb protocol allows the host to query valid timing parameters, including the CAN clock frequency and the range of allowed brp values (start, stop, increment).
Alternatively, having an option to pass a raw BitTimings object to the can.Bus method would work as well, although it would be less convenient.
Additional context
OS and version: Linux 6.17.0-23-generic (Ubuntu 25.10)
Python version: 3.13.7
python-can version: 4.6.1
python-can interface/s (if applicable): gs_usb
Traceback and logs
Traceback (most recent call last):
File "/home/user/Development/canbus/./gs_usb_bitrate_test.py", line 3, in <module>
can_bus = can.Bus(interface='gs_usb', channel=0, bitrate=33333)
File "/home/user/Development/canbus/venv/lib/python3.13/site-packages/can/util.py", line 392, in wrapper
return f(*args, **kwargs)
File "/home/user/Development/canbus/venv/lib/python3.13/site-packages/can/interface.py", line 137, in Bus
bus = cls(channel, **kwargs)
File "/home/user/Development/canbus/venv/lib/python3.13/site-packages/can/interfaces/gs_usb.py", line 63, in __init__
bit_timing = can.BitTiming.from_sample_point(
f_clock=self.gs_usb.device_capability.fclk_can,
bitrate=bitrate,
sample_point=87.5,
)
File "/home/user/Development/canbus/venv/lib/python3.13/site-packages/can/bit_timing.py", line 295, in from_sample_point
raise ValueError("No suitable bit timings found.")
ValueError: No suitable bit timings found.
Describe the bug
The
BitTimingclass unconditionally requires that the bitrate prescalerbrpis within the interval[1,64]; this is checked in the_validatefunction, which is unconditionally called from__init__even whenstrict=False:I was using
python-canwith a FYSETC UCAN transceiver running candleLight firmware, which speaks thegs_usbprotocol. The transceiver uses a clock frequency offclock=48MHz, but it also supports a large range of possiblebrpvalues from 1 to 1024 to implement lower bitrates (see bxcan.c ).I need to configure a baud rate of 33333 bit/s and want to use the default sample point of 87.5%, which requires a prescaler value > 64 to keep the other paramters (specifically
tseg1within their valid range). This is currently not possible without patching the code ofpython-candirectly, since thegs_usbinterface kind does not allow direct specification of theBitTimings, and the validation check will reject the prescaler value, so the automatic parameter finding does not work. However, the device supports higher prescaler values just fine; and removing the bitrate prescaler check in_validateallows me to configure the device and send CAN messages.To Reproduce
The following code will raise
ValueError("No suitable bit timings found.")fromBitTimings.from_sample_pointNote: this requires a suitable board with candleLight firmware to be present and attached. Internally, the device configuration routine retrieves the CAN clock speed and calls
BitTiming.from_sample_pointwith those values:This can be called without hardware to reproduce the issue.
Expected behavior
Ideally, the parameter validation takes the valid parameter range of the attached device into account (if known), so that the code above just works as-is. The
gs_usbprotocol allows the host to query valid timing parameters, including the CAN clock frequency and the range of allowedbrpvalues (start, stop, increment).Alternatively, having an option to pass a raw
BitTimingsobject to thecan.Busmethod would work as well, although it would be less convenient.Additional context
OS and version: Linux 6.17.0-23-generic (Ubuntu 25.10)
Python version: 3.13.7
python-can version: 4.6.1
python-can interface/s (if applicable): gs_usb
Traceback and logs