44"""
55ICS NeoVi interface module.
66
7- python-ics is a Python wrapper around the API provided by Intrepid Control
7+ python-ics is a Python wrapper around the API provided by Intrepid Control
88Systems for communicating with their NeoVI range of devices.
99
1010Implementation references:
@@ -74,7 +74,6 @@ def __init__(self, channel, can_filters=None, **config):
7474 The Channel id or name to create this bus with.
7575 :param list can_filters:
7676 See :meth:`can.BusABC.set_filters` for details.
77-
7877 :param use_system_timestamp:
7978 Use system timestamp for can messages instead of the hardware time
8079 stamp
@@ -84,6 +83,11 @@ def __init__(self, channel, can_filters=None, **config):
8483 :param int bitrate:
8584 Channel bitrate in bit/s. (optional, will enable the auto bitrate
8685 feature if not supplied)
86+ :param bool fd:
87+ If CAN-FD frames should be supported.
88+ :param int data_bitrate:
89+ Which bitrate to use for data phase in CAN FD.
90+ Defaults to arbitration bitrate.
8791 """
8892 if ics is None :
8993 raise ImportError ('Please install python-ics' )
@@ -115,6 +119,12 @@ def __init__(self, channel, can_filters=None, **config):
115119 if 'bitrate' in config :
116120 ics .set_bit_rate (self .dev , config .get ('bitrate' ), channel )
117121
122+ fd = config .get ('fd' , False )
123+ if fd :
124+ if 'data_bitrate' in config :
125+ ics .set_fd_bit_rate (
126+ self .dev , config .get ('data_bitrate' ), channel )
127+
118128 self .channel_info = '%s %s CH:%s' % (
119129 self .dev .Name ,
120130 self .get_serial_number (self .dev ),
@@ -222,19 +232,49 @@ def _get_timestamp_for_msg(self, ics_msg):
222232 return ics .get_timestamp_for_msg (self .dev , ics_msg )
223233
224234 def _ics_msg_to_message (self , ics_msg ):
225- return Message (
226- timestamp = self ._get_timestamp_for_msg (ics_msg ),
227- arbitration_id = ics_msg .ArbIDOrHeader ,
228- data = ics_msg .Data [:ics_msg .NumberBytesData ],
229- dlc = ics_msg .NumberBytesData ,
230- extended_id = bool (
231- ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
232- ),
233- is_remote_frame = bool (
234- ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
235- ),
236- channel = ics_msg .NetworkID
237- )
235+ is_fd = ics_msg .Protocol == ics .SPY_PROTOCOL_CANFD
236+
237+ if is_fd :
238+ if ics_msg .ExtraDataPtrEnabled :
239+ data = ics_msg .ExtraDataPtr [:ics_msg .NumberBytesData ]
240+ else :
241+ data = ics_msg .Data [:ics_msg .NumberBytesData ]
242+
243+ return Message (
244+ timestamp = self ._get_timestamp_for_msg (ics_msg ),
245+ arbitration_id = ics_msg .ArbIDOrHeader ,
246+ data = data ,
247+ dlc = ics_msg .NumberBytesData ,
248+ extended_id = bool (
249+ ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
250+ ),
251+ is_fd = is_fd ,
252+ is_remote_frame = bool (
253+ ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
254+ ),
255+ error_state_indicator = bool (
256+ ics_msg .StatusBitField3 & ics .SPY_STATUS3_CANFD_ESI
257+ ),
258+ bitrate_switch = bool (
259+ ics_msg .StatusBitField3 & ics .SPY_STATUS3_CANFD_BRS
260+ ),
261+ channel = ics_msg .NetworkID
262+ )
263+ else :
264+ return Message (
265+ timestamp = self ._get_timestamp_for_msg (ics_msg ),
266+ arbitration_id = ics_msg .ArbIDOrHeader ,
267+ data = ics_msg .Data [:ics_msg .NumberBytesData ],
268+ dlc = ics_msg .NumberBytesData ,
269+ extended_id = bool (
270+ ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
271+ ),
272+ is_fd = is_fd ,
273+ is_remote_frame = bool (
274+ ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
275+ ),
276+ channel = ics_msg .NetworkID
277+ )
238278
239279 def _recv_internal (self , timeout = 0.1 ):
240280 if not self .rx_buffer :
@@ -249,19 +289,31 @@ def _recv_internal(self, timeout=0.1):
249289 def send (self , msg , timeout = None ):
250290 if not ics .validate_hobject (self .dev ):
251291 raise CanError ("bus not open" )
292+ message = ics .SpyMessage ()
252293
253- flags = 0
294+ flag0 = 0
254295 if msg .is_extended_id :
255- flags |= ics .SPY_STATUS_XTD_FRAME
296+ flag0 |= ics .SPY_STATUS_XTD_FRAME
256297 if msg .is_remote_frame :
257- flags |= ics .SPY_STATUS_REMOTE_FRAME
298+ flag0 |= ics .SPY_STATUS_REMOTE_FRAME
299+
300+ flag3 = 0
301+ if msg .is_fd :
302+ message .Protocol = ics .SPY_PROTOCOL_CANFD
303+ if msg .bitrate_switch :
304+ flag3 |= ics .SPY_STATUS3_CANFD_BRS
305+ if msg .error_state_indicator :
306+ flag3 |= ics .SPY_STATUS3_CANFD_ESI
258307
259- message = ics .SpyMessage ()
260308 message .ArbIDOrHeader = msg .arbitration_id
261309 message .NumberBytesData = len (msg .data )
262- message .Data = tuple (msg .data )
263- message .StatusBitField = flags
310+ message .Data = tuple (msg .data [:8 ])
311+ if msg .is_fd and len (msg .data ) > 8 :
312+ message .ExtraDataPtrEnabled = 1
313+ message .ExtraDataPtr = tuple (msg .data )
314+ message .StatusBitField = flag0
264315 message .StatusBitField2 = 0
316+ message .StatusBitField3 = flag3
265317 message .NetworkID = self .network
266318
267319 try :
0 commit comments