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:
@@ -84,6 +84,8 @@ def __init__(self, channel, can_filters=None, **config):
8484 :param int bitrate:
8585 Channel bitrate in bit/s. (optional, will enable the auto bitrate
8686 feature if not supplied)
87+ :param int fd_bitrate:
88+ Channel CAN FD bitrate in bit/s.
8789 """
8890 if ics is None :
8991 raise ImportError ('Please install python-ics' )
@@ -110,6 +112,9 @@ def __init__(self, channel, can_filters=None, **config):
110112 if 'bitrate' in config :
111113 ics .set_bit_rate (self .dev , config .get ('bitrate' ), channel )
112114
115+ if 'fd_bitrate' in config :
116+ ics .set_fd_bit_rate (self .dev , config .get ('fd_bitrate' ), channel )
117+
113118 self .channel_info = '%s %s CH:%s' % (
114119 self .dev .Name ,
115120 self .get_serial_number (self .dev ),
@@ -217,19 +222,49 @@ def _get_timestamp_for_msg(self, ics_msg):
217222 return ics .get_timestamp_for_msg (self .dev , ics_msg )
218223
219224 def _ics_msg_to_message (self , ics_msg ):
220- return Message (
221- timestamp = self ._get_timestamp_for_msg (ics_msg ),
222- arbitration_id = ics_msg .ArbIDOrHeader ,
223- data = ics_msg .Data [:ics_msg .NumberBytesData ],
224- dlc = ics_msg .NumberBytesData ,
225- extended_id = bool (
226- ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
227- ),
228- is_remote_frame = bool (
229- ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
230- ),
231- channel = ics_msg .NetworkID
232- )
225+ is_fd = ics_msg .Protocol == ics .SPY_PROTOCOL_CANFD
226+
227+ if is_fd :
228+ if ics_msg .ExtraDataPtrEnabled :
229+ data = ics_msg .ExtraDataPtr [:ics_msg .NumberBytesData ]
230+ else :
231+ data = ics_msg .Data [:ics_msg .NumberBytesData ]
232+
233+ return Message (
234+ timestamp = self ._get_timestamp_for_msg (ics_msg ),
235+ arbitration_id = ics_msg .ArbIDOrHeader ,
236+ data = data ,
237+ dlc = ics_msg .NumberBytesData ,
238+ extended_id = bool (
239+ ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
240+ ),
241+ is_fd = is_fd ,
242+ is_remote_frame = bool (
243+ ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
244+ ),
245+ error_state_indicator = bool (
246+ ics_msg .StatusBitField3 & ics .SPY_STATUS3_CANFD_ESI
247+ ),
248+ bitrate_switch = bool (
249+ ics_msg .StatusBitField3 & ics .SPY_STATUS3_CANFD_BRS
250+ ),
251+ channel = ics_msg .NetworkID
252+ )
253+ else :
254+ return Message (
255+ timestamp = self ._get_timestamp_for_msg (ics_msg ),
256+ arbitration_id = ics_msg .ArbIDOrHeader ,
257+ data = ics_msg .Data [:ics_msg .NumberBytesData ],
258+ dlc = ics_msg .NumberBytesData ,
259+ extended_id = bool (
260+ ics_msg .StatusBitField & ics .SPY_STATUS_XTD_FRAME
261+ ),
262+ is_fd = is_fd ,
263+ is_remote_frame = bool (
264+ ics_msg .StatusBitField & ics .SPY_STATUS_REMOTE_FRAME
265+ ),
266+ channel = ics_msg .NetworkID
267+ )
233268
234269 def _recv_internal (self , timeout = 0.1 ):
235270 if not self .rx_buffer :
@@ -244,19 +279,31 @@ def _recv_internal(self, timeout=0.1):
244279 def send (self , msg , timeout = None ):
245280 if not ics .validate_hobject (self .dev ):
246281 raise CanError ("bus not open" )
282+ message = ics .SpyMessage ()
247283
248- flags = 0
284+ flag0 = 0
249285 if msg .is_extended_id :
250- flags |= ics .SPY_STATUS_XTD_FRAME
286+ flag0 |= ics .SPY_STATUS_XTD_FRAME
251287 if msg .is_remote_frame :
252- flags |= ics .SPY_STATUS_REMOTE_FRAME
288+ flag0 |= ics .SPY_STATUS_REMOTE_FRAME
289+
290+ flag3 = 0
291+ if msg .is_fd :
292+ message .Protocol = ics .SPY_PROTOCOL_CANFD
293+ if msg .bitrate_switch :
294+ flag3 |= ics .SPY_STATUS3_CANFD_BRS
295+ if msg .error_state_indicator :
296+ flag3 |= ics .SPY_STATUS3_CANFD_ESI
253297
254- message = ics .SpyMessage ()
255298 message .ArbIDOrHeader = msg .arbitration_id
256299 message .NumberBytesData = len (msg .data )
257- message .Data = tuple (msg .data )
258- message .StatusBitField = flags
300+ message .Data = tuple (msg .data [:8 ])
301+ if msg .is_fd and len (msg .data ) > 8 :
302+ message .ExtraDataPtrEnabled = 1
303+ message .ExtraDataPtr = tuple (msg .data )
304+ message .StatusBitField = flag0
259305 message .StatusBitField2 = 0
306+ message .StatusBitField3 = flag3
260307 message .NetworkID = self .network
261308
262309 try :
0 commit comments