@@ -58,6 +58,23 @@ def is_critical(self):
5858 return self .severity == self .ICS_SPY_ERR_CRITICAL
5959
6060
61+ BAUDRATE_SETTING = {
62+ 20000 : 0 ,
63+ 33333 : 1 ,
64+ 50000 : 2 ,
65+ 62500 : 3 ,
66+ 83333 : 4 ,
67+ 100000 : 5 ,
68+ 125000 : 6 ,
69+ 250000 : 7 ,
70+ 500000 : 8 ,
71+ 800000 : 9 ,
72+ 1000000 : 10 ,
73+ }
74+ VALID_BITRATES = list (BAUDRATE_SETTING .keys ())
75+ VALID_BITRATES .sort ()
76+
77+
6178class NeoViBus (BusABC ):
6279 """
6380 The CAN Bus implemented for the python_ics interface
@@ -71,12 +88,18 @@ def __init__(self, channel=None, can_filters=None, **config):
7188 The Channel id to create this bus with.
7289 :param list can_filters:
7390 A list of dictionaries each containing a "can_id" and a "can_mask".
91+
92+ >>> [{"can_id": 0x11, "can_mask": 0x21}]
93+
7494 :param use_system_timestamp:
7595 Use system timestamp for can messages instead of the hardware time
7696 stamp
77-
78- >>> [{"can_id": 0x11, "can_mask": 0x21}]
79-
97+ :param str serial:
98+ Serial to connect (optional, will use the first found if not
99+ supplied)
100+ :param int bitrate:
101+ Channel bitrate in bit/s. (optional, will enable the auto bitrate
102+ feature if not supplied)
80103 """
81104 super (NeoViBus , self ).__init__ (channel , can_filters , ** config )
82105 if ics is None :
@@ -97,7 +120,32 @@ def __init__(self, channel=None, can_filters=None, **config):
97120
98121 type_filter = config .get ('type_filter' )
99122 serial = config .get ('serial' )
100- self .dev = self ._open_device (type_filter , serial )
123+ self .dev = self ._find_device (type_filter , serial )
124+ ics .open_device (self .dev )
125+
126+ bitrate = config .get ('bitrate' )
127+
128+ # Default auto baud setting
129+ settings = {
130+ 'SetBaudrate' : ics .AUTO ,
131+ 'Baudrate' : BAUDRATE_SETTING [500000 ], # Default baudrate setting
132+ 'auto_baud' : 1
133+ }
134+
135+ if bitrate is not None :
136+ if int (bitrate ) not in VALID_BITRATES :
137+ raise ValueError (
138+ 'Invalid bitrate. Valid bitrates are {}' .format (
139+ VALID_BITRATES
140+ )
141+ )
142+ baud_rate_setting = BAUDRATE_SETTING [int (bitrate )]
143+ settings = {
144+ 'SetBaudrate' : ics .AUTO ,
145+ 'Baudrate' : baud_rate_setting ,
146+ 'auto_baud' : 0 ,
147+ }
148+ self ._set_can_settings (channel , settings )
101149
102150 self .channel_info = '%s %s CH:%s' % (
103151 self .dev .Name ,
@@ -126,21 +174,17 @@ def get_serial_number(device):
126174 :return: ics device serial string
127175 :rtype: str
128176 """
129- def to_base36 (n , alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ):
130- return (to_base36 (n // 36 ) + alphabet [n % 36 ]).lstrip ("0" ) \
131- if n > 0 else "0"
132-
133177 a0000 = 604661760
134178 if device .SerialNumber >= a0000 :
135- return to_base36 (device .SerialNumber )
179+ return ics . base36enc (device .SerialNumber )
136180 return str (device .SerialNumber )
137181
138182 def shutdown (self ):
139183 super (NeoViBus , self ).shutdown ()
140184 self .opened = False
141185 ics .close_device (self .dev )
142186
143- def _open_device (self , type_filter = None , serial = None ):
187+ def _find_device (self , type_filter = None , serial = None ):
144188 if type_filter is not None :
145189 devices = ics .find_devices (type_filter )
146190 else :
@@ -159,9 +203,30 @@ def _open_device(self, type_filter=None, serial=None):
159203 msg .append ('with serial {}' .format (serial ))
160204 msg .append ('found.' )
161205 raise Exception (' ' .join (msg ))
162- ics .open_device (dev )
163206 return dev
164207
208+ def _get_can_settings (self , channel ):
209+ """Return the CanSettings for channel
210+
211+ :param channel: can channel number
212+ :return: ics.CanSettings
213+ """
214+ device_settings = ics .get_device_settings (self .dev )
215+ return getattr (device_settings , 'can{}' .format (channel ))
216+
217+ def _set_can_settings (self , channel , setting ):
218+ """Applies can settings to channel
219+
220+ :param channel: can channel number
221+ :param setting: settings dictionary (only the settings to update)
222+ :return: None
223+ """
224+ device_settings = ics .get_device_settings (self .dev )
225+ channel_settings = getattr (device_settings , 'can{}' .format (channel ))
226+ for setting , value in setting .items ():
227+ setattr (channel_settings , setting , value )
228+ ics .set_device_settings (self .dev , device_settings )
229+
165230 def _process_msg_queue (self , timeout = None ):
166231 try :
167232 messages , errors = ics .get_messages (self .dev , False , timeout )
0 commit comments