1010import logging
1111import time
1212import os
13- from typing import Optional , Tuple
13+ from typing import List , Optional , Tuple
1414
1515import typing
1616
3232# Import Modules
3333# ==============
3434from can import BusABC , Message
35- from can .util import len2dlc , dlc2len
35+ from can .util import len2dlc , dlc2len , deprecated_args_alias
3636from .exceptions import VectorError
3737
3838# Define Module Logger
5454class VectorBus (BusABC ):
5555 """The CAN Bus implemented for the Vector interface."""
5656
57+ deprecated_args = dict (
58+ sjwAbr = "sjw_abr" ,
59+ tseg1Abr = "tseg1_abr" ,
60+ tseg2Abr = "tseg2_abr" ,
61+ sjwDbr = "sjw_dbr" ,
62+ tseg1Dbr = "tseg1_dbr" ,
63+ tseg2Dbr = "tseg2_dbr" ,
64+ )
65+
66+ @deprecated_args_alias (** deprecated_args )
5767 def __init__ (
5868 self ,
5969 channel ,
@@ -66,12 +76,12 @@ def __init__(
6676 serial = None ,
6777 fd = False ,
6878 data_bitrate = None ,
69- sjwAbr = 2 ,
70- tseg1Abr = 6 ,
71- tseg2Abr = 3 ,
72- sjwDbr = 2 ,
73- tseg1Dbr = 6 ,
74- tseg2Dbr = 3 ,
79+ sjw_abr = 2 ,
80+ tseg1_abr = 6 ,
81+ tseg2_abr = 3 ,
82+ sjw_dbr = 2 ,
83+ tseg1_dbr = 6 ,
84+ tseg2_dbr = 3 ,
7585 ** kwargs ,
7686 ):
7787 """
@@ -98,6 +108,18 @@ def __init__(
98108 :param int data_bitrate:
99109 Which bitrate to use for data phase in CAN FD.
100110 Defaults to arbitration bitrate.
111+ :param int sjw_abr:
112+ Bus timing value sample jump width (arbitration).
113+ :param int tseg1_abr:
114+ Bus timing value tseg1 (arbitration)
115+ :param int tseg2_abr:
116+ Bus timing value tseg2 (arbitration)
117+ :param int sjw_dbr:
118+ Bus timing value sample jump width (data)
119+ :param int tseg1_dbr:
120+ Bus timing value tseg1 (data)
121+ :param int tseg2_dbr:
122+ Bus timing value tseg2 (data)
101123 """
102124 if os .name != "nt" and not kwargs .get ("_testing" , False ):
103125 raise OSError (
@@ -152,29 +174,19 @@ def __init__(
152174 for channel in self .channels :
153175 if app_name :
154176 # Get global channel index from application channel
155- hw_type = ctypes .c_uint (0 )
156- hw_index = ctypes .c_uint (0 )
157- hw_channel = ctypes .c_uint (0 )
158- xldriver .xlGetApplConfig (
159- self ._app_name ,
160- channel ,
161- hw_type ,
162- hw_index ,
163- hw_channel ,
164- xldefine .XL_BusTypes .XL_BUS_TYPE_CAN .value ,
177+ hw_type , hw_index , hw_channel = self .get_application_config (
178+ app_name , channel , xldefine .XL_BusTypes .XL_BUS_TYPE_CAN
165179 )
166180 LOG .debug ("Channel index %d found" , channel )
167- idx = xldriver .xlGetChannelIndex (
168- hw_type .value , hw_index .value , hw_channel .value
169- )
181+ idx = xldriver .xlGetChannelIndex (hw_type .value , hw_index , hw_channel )
170182 if idx < 0 :
171183 # Undocumented behavior! See issue #353.
172184 # If hardware is unavailable, this function returns -1.
173185 # Raise an exception as if the driver
174186 # would have signalled XL_ERR_HW_NOT_PRESENT.
175187 raise VectorError (
176188 xldefine .XL_Status .XL_ERR_HW_NOT_PRESENT .value ,
177- " XL_ERR_HW_NOT_PRESENT" ,
189+ xldefine . XL_Status . XL_ERR_HW_NOT_PRESENT . name ,
178190 "xlGetChannelIndex" ,
179191 )
180192 else :
@@ -219,19 +231,19 @@ def __init__(
219231 if fd :
220232 self .canFdConf = xlclass .XLcanFdConf ()
221233 if bitrate :
222- self .canFdConf .arbitrationBitRate = ctypes . c_uint (bitrate )
234+ self .canFdConf .arbitrationBitRate = int (bitrate )
223235 else :
224- self .canFdConf .arbitrationBitRate = ctypes . c_uint ( 500000 )
225- self .canFdConf .sjwAbr = ctypes . c_uint ( sjwAbr )
226- self .canFdConf .tseg1Abr = ctypes . c_uint ( tseg1Abr )
227- self .canFdConf .tseg2Abr = ctypes . c_uint ( tseg2Abr )
236+ self .canFdConf .arbitrationBitRate = 500000
237+ self .canFdConf .sjwAbr = int ( sjw_abr )
238+ self .canFdConf .tseg1Abr = int ( tseg1_abr )
239+ self .canFdConf .tseg2Abr = int ( tseg2_abr )
228240 if data_bitrate :
229- self .canFdConf .dataBitRate = ctypes . c_uint (data_bitrate )
241+ self .canFdConf .dataBitRate = int (data_bitrate )
230242 else :
231243 self .canFdConf .dataBitRate = self .canFdConf .arbitrationBitRate
232- self .canFdConf .sjwDbr = ctypes . c_uint ( sjwDbr )
233- self .canFdConf .tseg1Dbr = ctypes . c_uint ( tseg1Dbr )
234- self .canFdConf .tseg2Dbr = ctypes . c_uint ( tseg2Dbr )
244+ self .canFdConf .sjwDbr = int ( sjw_dbr )
245+ self .canFdConf .tseg1Dbr = int ( tseg1_dbr )
246+ self .canFdConf .tseg2Dbr = int ( tseg2_dbr )
235247
236248 xldriver .xlCanFdSetConfiguration (
237249 self .port_handle , self .mask , self .canFdConf
@@ -634,15 +646,99 @@ def popup_vector_hw_configuration(wait_for_finish: int = 0) -> None:
634646 """
635647 xldriver .xlPopupHwConfig (ctypes .c_char_p (), ctypes .c_uint (wait_for_finish ))
636648
649+ @staticmethod
650+ def get_application_config (
651+ app_name : str , app_channel : int , bus_type : xldefine .XL_BusTypes
652+ ) -> Tuple [xldefine .XL_HardwareType , int , int ]:
653+ """Retrieve information for an application in Vector Hardware Configuration.
654+
655+ :param app_name:
656+ The name of the application.
657+ :param app_channel:
658+ The channel of the application.
659+ :param bus_type:
660+ The bus type Enum e.g. `XL_BusTypes.XL_BUS_TYPE_CAN`
661+ :return:
662+ Returns a tuple of the hardware type, the hardware index and the
663+ hardware channel.
664+ :raises VectorError:
665+ Raises a VectorError when the application name does not exist in
666+ Vector Hardware Configuration.
667+ """
668+ hw_type = ctypes .c_uint ()
669+ hw_index = ctypes .c_uint ()
670+ hw_channel = ctypes .c_uint ()
671+
672+ xldriver .xlGetApplConfig (
673+ app_name .encode (),
674+ app_channel ,
675+ hw_type ,
676+ hw_index ,
677+ hw_channel ,
678+ bus_type .value ,
679+ )
680+ return xldefine .XL_HardwareType (hw_type .value ), hw_index .value , hw_channel .value
681+
682+ @staticmethod
683+ def set_application_config (
684+ app_name : str ,
685+ app_channel : int ,
686+ hw_type : xldefine .XL_HardwareType ,
687+ hw_index : int ,
688+ hw_channel : int ,
689+ bus_type : xldefine .XL_BusTypes ,
690+ ) -> None :
691+ """Modify the application settings in Vector Hardware Configuration.
692+
693+ :param app_name:
694+ The name of the application. Creates a new application if it does
695+ not exist yet.
696+ :param app_channel:
697+ The channel of the application.
698+ :param hw_type:
699+ The hardware type of the interface.
700+ E.g XL_HardwareType.XL_HWTYPE_VIRTUAL
701+ :param hw_index:
702+ The index of the interface if multiple interface with the same
703+ hardware type are present.
704+ :param hw_channel:
705+ The channel index of the interface.
706+ :param bus_type:
707+ The bus type of the interfaces, which should be
708+ XL_BusTypes.XL_BUS_TYPE_CAN for most cases.
709+ """
710+ xldriver .xlSetApplConfig (
711+ app_name .encode (),
712+ app_channel ,
713+ hw_type .value ,
714+ hw_index ,
715+ hw_channel ,
716+ bus_type .value ,
717+ )
718+
719+ def set_timer_rate (self , timer_rate_ms : int ) -> None :
720+ """Set the cyclic event rate of the port.
721+
722+ Once set, the port will generate a cyclic event with the tag XL_EventTags.XL_TIMER.
723+ This timer can be used to keep an application alive. See XL Driver Library Description
724+ for more information
725+
726+ :param timer_rate_ms:
727+ The timer rate in ms. The minimal timer rate is 1ms, a value of 0 deactivates
728+ the timer events.
729+ """
730+ timer_rate_10us = timer_rate_ms * 100
731+ xldriver .xlSetTimerRate (self .port_handle , timer_rate_10us )
732+
637733
638- def get_channel_configs ():
734+ def get_channel_configs () -> List [ xlclass . XLchannelConfig ] :
639735 if xldriver is None :
640736 return []
641737 driver_config = xlclass .XLdriverConfig ()
642738 try :
643739 xldriver .xlOpenDriver ()
644740 xldriver .xlGetDriverConfig (driver_config )
645741 xldriver .xlCloseDriver ()
646- except Exception :
742+ except VectorError :
647743 pass
648744 return [driver_config .channel [i ] for i in range (driver_config .channelCount )]
0 commit comments