10
10
import logging
11
11
import sys
12
12
import time
13
+ from typing import Optional , Union
13
14
14
- from can import BusABC , CanProtocol , Message
15
- from can .util import time_perfcounter_correlation
15
+ from can import BitTiming , BitTimingFd , BusABC , CanProtocol , Message
16
+ from can .exceptions import CanError , CanInitializationError , CanOperationError
17
+ from can .typechecking import CanFilters
18
+ from can .util import check_or_adjust_timing_clock , time_perfcounter_correlation
16
19
17
- from ...exceptions import CanError , CanInitializationError , CanOperationError
18
20
from . import constants as canstat
19
21
from . import structures
20
22
@@ -199,6 +201,17 @@ def __check_bus_handle_validity(handle, function, arguments):
199
201
errcheck = __check_status_initialization ,
200
202
)
201
203
204
+ canSetBusParamsC200 = __get_canlib_function (
205
+ "canSetBusParamsC200" ,
206
+ argtypes = [
207
+ c_canHandle ,
208
+ ctypes .c_byte ,
209
+ ctypes .c_byte ,
210
+ ],
211
+ restype = canstat .c_canStatus ,
212
+ errcheck = __check_status_initialization ,
213
+ )
214
+
202
215
canSetBusParamsFd = __get_canlib_function (
203
216
"canSetBusParamsFd" ,
204
217
argtypes = [
@@ -360,7 +373,13 @@ class KvaserBus(BusABC):
360
373
The CAN Bus implemented for the Kvaser interface.
361
374
"""
362
375
363
- def __init__ (self , channel , can_filters = None , ** kwargs ):
376
+ def __init__ (
377
+ self ,
378
+ channel : int ,
379
+ can_filters : Optional [CanFilters ] = None ,
380
+ timing : Optional [Union [BitTiming , BitTimingFd ]] = None ,
381
+ ** kwargs ,
382
+ ):
364
383
"""
365
384
:param int channel:
366
385
The Channel id to create this bus with.
@@ -370,6 +389,12 @@ def __init__(self, channel, can_filters=None, **kwargs):
370
389
371
390
Backend Configuration
372
391
392
+ :param timing:
393
+ An instance of :class:`~can.BitTiming` or :class:`~can.BitTimingFd`
394
+ to specify the bit timing parameters for the Kvaser interface. If provided, it
395
+ takes precedence over the all other timing-related parameters.
396
+ Note that the `f_clock` property of the `timing` instance must be 16_000_000 (16MHz)
397
+ for standard CAN or 80_000_000 (80MHz) for CAN FD.
373
398
:param int bitrate:
374
399
Bitrate of channel in bit/s
375
400
:param bool accept_virtual:
@@ -427,7 +452,7 @@ def __init__(self, channel, can_filters=None, **kwargs):
427
452
exclusive = kwargs .get ("exclusive" , False )
428
453
override_exclusive = kwargs .get ("override_exclusive" , False )
429
454
accept_virtual = kwargs .get ("accept_virtual" , True )
430
- fd = kwargs .get ("fd" , False )
455
+ fd = isinstance ( timing , BitTimingFd ) if timing else kwargs .get ("fd" , False )
431
456
data_bitrate = kwargs .get ("data_bitrate" , None )
432
457
433
458
try :
@@ -468,22 +493,43 @@ def __init__(self, channel, can_filters=None, **kwargs):
468
493
ctypes .byref (ctypes .c_long (TIMESTAMP_RESOLUTION )),
469
494
4 ,
470
495
)
471
-
472
- if fd :
473
- if "tseg1" not in kwargs and bitrate in BITRATE_FD :
474
- # Use predefined bitrate for arbitration
475
- bitrate = BITRATE_FD [bitrate ]
476
- if data_bitrate in BITRATE_FD :
477
- # Use predefined bitrate for data
478
- data_bitrate = BITRATE_FD [data_bitrate ]
479
- elif not data_bitrate :
480
- # Use same bitrate for arbitration and data phase
481
- data_bitrate = bitrate
482
- canSetBusParamsFd (self ._read_handle , data_bitrate , tseg1 , tseg2 , sjw )
496
+ if isinstance (timing , BitTimingFd ):
497
+ timing = check_or_adjust_timing_clock (timing , [80_000_000 ])
498
+ canSetBusParams (
499
+ self ._read_handle ,
500
+ timing .nom_bitrate ,
501
+ timing .nom_tseg1 ,
502
+ timing .nom_tseg2 ,
503
+ timing .nom_sjw ,
504
+ 1 ,
505
+ 0 ,
506
+ )
507
+ canSetBusParamsFd (
508
+ self ._read_handle ,
509
+ timing .data_bitrate ,
510
+ timing .data_tseg1 ,
511
+ timing .data_tseg2 ,
512
+ timing .data_sjw ,
513
+ )
514
+ elif isinstance (timing , BitTiming ):
515
+ timing = check_or_adjust_timing_clock (timing , [16_000_000 ])
516
+ canSetBusParamsC200 (self ._read_handle , timing .btr0 , timing .btr1 )
483
517
else :
484
- if "tseg1" not in kwargs and bitrate in BITRATE_OBJS :
485
- bitrate = BITRATE_OBJS [bitrate ]
486
- canSetBusParams (self ._read_handle , bitrate , tseg1 , tseg2 , sjw , no_samp , 0 )
518
+ if fd :
519
+ if "tseg1" not in kwargs and bitrate in BITRATE_FD :
520
+ # Use predefined bitrate for arbitration
521
+ bitrate = BITRATE_FD [bitrate ]
522
+ if data_bitrate in BITRATE_FD :
523
+ # Use predefined bitrate for data
524
+ data_bitrate = BITRATE_FD [data_bitrate ]
525
+ elif not data_bitrate :
526
+ # Use same bitrate for arbitration and data phase
527
+ data_bitrate = bitrate
528
+ canSetBusParamsFd (self ._read_handle , data_bitrate , tseg1 , tseg2 , sjw )
529
+ else :
530
+ if "tseg1" not in kwargs and bitrate in BITRATE_OBJS :
531
+ bitrate = BITRATE_OBJS [bitrate ]
532
+ canSetBusParams (self ._read_handle , bitrate , tseg1 , tseg2 , sjw , no_samp , 0 )
487
533
488
534
# By default, use local echo if single handle is used (see #160)
489
535
local_echo = single_handle or receive_own_messages
0 commit comments