Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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))
Ejemplo n.º 3
0
    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")
Ejemplo n.º 4
0
    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)