def send(self, msg, timeout=None): if not ics.validate_hobject(self.dev): raise CanError("bus not open") message = ics.SpyMessage() flag0 = 0 if msg.is_extended_id: flag0 |= ics.SPY_STATUS_XTD_FRAME if msg.is_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.ArbIDOrHeader = msg.arbitration_id msg_data = msg.data message.NumberBytesData = len(msg_data) 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 if msg.channel is not None: message.NetworkID = msg.channel elif len(self.channels) == 1: message.NetworkID = self.channels[0] else: raise ValueError( "msg.channel must be set when using multiple channels.") try: ics.transmit_messages(self.dev, message) except ics.RuntimeError: raise ICSApiError(*ics.get_last_api_error(self.dev))
def send(self, msg, timeout=None): if not self.dev.IsOpen: raise CanError("bus not open") flags = 0 if msg.is_extended_id: flags |= ics.SPY_STATUS_XTD_FRAME if msg.is_remote_frame: flags |= ics.SPY_STATUS_REMOTE_FRAME message = ics.SpyMessage() message.ArbIDOrHeader = msg.arbitration_id message.NumberBytesData = len(msg.data) message.Data = tuple(msg.data) message.StatusBitField = flags message.StatusBitField2 = 0 message.NetworkID = self.network try: ics.transmit_messages(self.dev, message) except ics.RuntimeError: raise ICSApiError(*ics.get_last_api_error(self.dev))
def send(self, msg, timeout=0): """Transmit a message to the CAN bus. :param Message msg: A message object. :param float timeout: If > 0, wait up to this many seconds for message to be ACK'ed. If timeout is exceeded, an exception will be raised. None blocks indefinitely. :raises can.CanError: if the message could not be sent """ if not ics.validate_hobject(self.dev): raise CanError("bus not open") message = ics.SpyMessage() flag0 = 0 if msg.is_extended_id: flag0 |= ics.SPY_STATUS_XTD_FRAME if msg.is_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.ArbIDOrHeader = msg.arbitration_id msg_data = msg.data message.NumberBytesData = len(msg_data) 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 if msg.channel is not None: message.NetworkID = msg.channel elif len(self.channels) == 1: message.NetworkID = self.channels[0] else: raise ValueError( "msg.channel must be set when using multiple channels.") msg_desc_id = next(description_id) message.DescriptionID = msg_desc_id receipt_key = (msg.arbitration_id, msg_desc_id) if timeout != 0: self.message_receipts[receipt_key].clear() try: ics.transmit_messages(self.dev, message) except ics.RuntimeError: raise ICSApiError(*ics.get_last_api_error(self.dev)) # If timeout is set, wait for ACK # This requires a notifier for the bus or # some other thread calling recv periodically if timeout != 0 and not self.message_receipts[receipt_key].wait( timeout): raise CanError("Transmit timeout")
def __init__(self, channel, can_filters=None, **kwargs): """ :param channel: The channel ids to create this bus with. Can also be a single integer, netid name or a comma separated string. :type channel: int or str or list(int) or list(str) :param list can_filters: See :meth:`can.BusABC.set_filters` for details. :param bool receive_own_messages: If transmitted messages should also be received by this bus. :param bool use_system_timestamp: Use system timestamp for can messages instead of the hardware time stamp :param str serial: Serial to connect (optional, will use the first found if not supplied) :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. :param override_library_name: Absolute path or relative path to the library including filename. """ if ics is None: raise ImportError("Please install python-ics") super().__init__(channel=channel, can_filters=can_filters, **kwargs) logger.info("CAN Filters: {}".format(can_filters)) logger.info("Got configuration of: {}".format(kwargs)) if "override_library_name" in kwargs: ics.override_library_name(kwargs.get("override_library_name")) if isinstance(channel, (list, tuple)): self.channels = channel elif isinstance(channel, int): self.channels = [channel] else: # Assume comma separated string of channels self.channels = [ch.strip() for ch in channel.split(",")] self.channels = [NeoViBus.channel_to_netid(ch) for ch in self.channels] type_filter = kwargs.get("type_filter") serial = kwargs.get("serial") self.dev = self._find_device(type_filter, serial) with open_lock: ics.open_device(self.dev) try: if "bitrate" in kwargs: for channel in self.channels: ics.set_bit_rate(self.dev, kwargs.get("bitrate"), channel) if kwargs.get("fd", False): if "data_bitrate" in kwargs: for channel in self.channels: ics.set_fd_bit_rate(self.dev, kwargs.get("data_bitrate"), channel) except ics.RuntimeError as re: logger.error(re) err = ICSApiError(*ics.get_last_api_error(self.dev)) try: self.shutdown() finally: raise err self._use_system_timestamp = bool( kwargs.get("use_system_timestamp", False)) self._receive_own_messages = kwargs.get("receive_own_messages", True) self.channel_info = "%s %s CH:%s" % ( self.dev.Name, self.get_serial_number(self.dev), self.channels, ) logger.info("Using device: {}".format(self.channel_info)) self.rx_buffer = deque() self.message_receipts = defaultdict(Event)