Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 73 additions & 21 deletions can/interfaces/ics_neovi/neovi_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""
ICS NeoVi interface module.

python-ics is a Python wrapper around the API provided by Intrepid Control
python-ics is a Python wrapper around the API provided by Intrepid Control
Systems for communicating with their NeoVI range of devices.

Implementation references:
Expand Down Expand Up @@ -74,7 +74,6 @@ def __init__(self, channel, can_filters=None, **config):
The Channel id or name to create this bus with.
:param list can_filters:
See :meth:`can.BusABC.set_filters` for details.

:param use_system_timestamp:
Use system timestamp for can messages instead of the hardware time
stamp
Expand All @@ -84,6 +83,11 @@ def __init__(self, channel, can_filters=None, **config):
:param int bitrate:
Channel bitrate in bit/s. (optional, will enable the auto bitrate
feature if not supplied)
:param bool fd:
If CAN-FD frames should be supported.
:param int data_bitrate:
Which bitrate to use for data phase in CAN FD.
Defaults to arbitration bitrate.
"""
if ics is None:
raise ImportError('Please install python-ics')
Expand Down Expand Up @@ -115,6 +119,12 @@ def __init__(self, channel, can_filters=None, **config):
if 'bitrate' in config:
ics.set_bit_rate(self.dev, config.get('bitrate'), channel)

fd = config.get('fd', False)
if fd:
if 'data_bitrate' in config:
ics.set_fd_bit_rate(
self.dev, config.get('data_bitrate'), channel)

self.channel_info = '%s %s CH:%s' % (
self.dev.Name,
self.get_serial_number(self.dev),
Expand Down Expand Up @@ -222,19 +232,49 @@ def _get_timestamp_for_msg(self, ics_msg):
return ics.get_timestamp_for_msg(self.dev, ics_msg)

def _ics_msg_to_message(self, ics_msg):
return Message(
timestamp=self._get_timestamp_for_msg(ics_msg),
arbitration_id=ics_msg.ArbIDOrHeader,
data=ics_msg.Data[:ics_msg.NumberBytesData],
dlc=ics_msg.NumberBytesData,
extended_id=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_XTD_FRAME
),
is_remote_frame=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_REMOTE_FRAME
),
channel=ics_msg.NetworkID
)
is_fd = ics_msg.Protocol == ics.SPY_PROTOCOL_CANFD

if is_fd:
if ics_msg.ExtraDataPtrEnabled:
data = ics_msg.ExtraDataPtr[:ics_msg.NumberBytesData]
else:
data = ics_msg.Data[:ics_msg.NumberBytesData]

return Message(
timestamp=self._get_timestamp_for_msg(ics_msg),
arbitration_id=ics_msg.ArbIDOrHeader,
data=data,
dlc=ics_msg.NumberBytesData,
extended_id=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_XTD_FRAME
),
is_fd=is_fd,
is_remote_frame=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_REMOTE_FRAME
),
error_state_indicator=bool(
ics_msg.StatusBitField3 & ics.SPY_STATUS3_CANFD_ESI
),
bitrate_switch=bool(
ics_msg.StatusBitField3 & ics.SPY_STATUS3_CANFD_BRS
),
channel=ics_msg.NetworkID
)
else:
return Message(
timestamp=self._get_timestamp_for_msg(ics_msg),
arbitration_id=ics_msg.ArbIDOrHeader,
data=ics_msg.Data[:ics_msg.NumberBytesData],
dlc=ics_msg.NumberBytesData,
extended_id=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_XTD_FRAME
),
is_fd=is_fd,
is_remote_frame=bool(
ics_msg.StatusBitField & ics.SPY_STATUS_REMOTE_FRAME
),
channel=ics_msg.NetworkID
)

def _recv_internal(self, timeout=0.1):
if not self.rx_buffer:
Expand All @@ -249,19 +289,31 @@ def _recv_internal(self, timeout=0.1):
def send(self, msg, timeout=None):
if not ics.validate_hobject(self.dev):
raise CanError("bus not open")
message = ics.SpyMessage()

flags = 0
flag0 = 0
if msg.is_extended_id:
flags |= ics.SPY_STATUS_XTD_FRAME
flag0 |= ics.SPY_STATUS_XTD_FRAME
if msg.is_remote_frame:
flags |= ics.SPY_STATUS_REMOTE_FRAME
flag0 |= ics.SPY_STATUS_REMOTE_FRAME

flag3 = 0
if msg.is_fd:
message.Protocol = ics.SPY_PROTOCOL_CANFD
if msg.bitrate_switch:
flag3 |= ics.SPY_STATUS3_CANFD_BRS
if msg.error_state_indicator:
flag3 |= ics.SPY_STATUS3_CANFD_ESI

message = ics.SpyMessage()
message.ArbIDOrHeader = msg.arbitration_id
message.NumberBytesData = len(msg.data)
message.Data = tuple(msg.data)
message.StatusBitField = flags
message.Data = tuple(msg.data[:8])
if msg.is_fd and len(msg.data) > 8:
message.ExtraDataPtrEnabled = 1
message.ExtraDataPtr = tuple(msg.data)
message.StatusBitField = flag0
message.StatusBitField2 = 0
message.StatusBitField3 = flag3
message.NetworkID = self.network

try:
Expand Down