From e53a3739771e1c817415147cd52e83bb67ab817e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Tue, 26 Jul 2022 16:40:54 +0800 Subject: [PATCH 01/30] add tosun and zlg can driver --- can/interfaces/__init__.py | 2 + can/interfaces/tosun.py | 257 ++++++++++++++++++++++++++ can/interfaces/zlgcan.py | 362 +++++++++++++++++++++++++++++++++++++ 3 files changed, 621 insertions(+) create mode 100644 can/interfaces/tosun.py create mode 100644 can/interfaces/zlgcan.py diff --git a/can/interfaces/__init__.py b/can/interfaces/__init__.py index 90a05d7bc..91163520f 100644 --- a/can/interfaces/__init__.py +++ b/can/interfaces/__init__.py @@ -27,6 +27,8 @@ "neousys": ("can.interfaces.neousys", "NeousysBus"), "etas": ("can.interfaces.etas", "EtasBus"), "socketcand": ("can.interfaces.socketcand", "SocketCanDaemonBus"), + "zlgcan": ("can.interfaces.zlgcan", "ZCanBus"), + "tosun": ("can.interfaces.tosun", "TosuBus"), } try: diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py new file mode 100644 index 000000000..e1de6cf07 --- /dev/null +++ b/can/interfaces/tosun.py @@ -0,0 +1,257 @@ +import collections +import warnings +from typing import List, Optional, Tuple, Any, Union + +import can +import can.typechecking +import ctypes +from can import CanInitializationError +from can.bus import LOG + +from tosun import TSCanMessage, TSCanFdMessage, TSMasterException, TosunDevice, TSMasterMessageType, \ + TSReadTxRxMode + + +def tosun_convert_msg(msg): + if isinstance(msg, TSCanMessage): + return can.Message( + timestamp=msg.FTimeUs, + arbitration_id=msg.FIdentifier, + is_extended_id=msg.FProperties & 0x04, + is_remote_frame=msg.FProperties & 0x02, + channel=msg.FIdxChn, + dlc=msg.FDLC, + data=bytes(msg.FData), + is_fd=False, + is_rx=False if msg.FProperties & 0x01 else True, + ) + elif isinstance(msg, TSCanFdMessage): + return can.Message( + timestamp=msg.FTimeUs, + arbitration_id=msg.FIdentifier, + is_extended_id=msg.FProperties & 0x04, + is_remote_frame=msg.FProperties & 0x02, + channel=msg.FIdxChn, + dlc=msg.FDLC, + data=bytes(msg.FData), + is_fd=False, + is_rx=False if msg.FProperties & 0x01 else True, + bitrate_switch=msg.FFDProperties & 0x02, + error_state_indicator=msg.FFDProperties & 0x04, + ) + elif isinstance(msg, can.Message): + if msg.is_fd: + result = TSCanFdMessage() + result.FFDProperties = 0x00 | (0x02 if msg.bitrate_switch else 0x00) | \ + (0x04 if msg.error_state_indicator else 0x00) + else: + result = TSCanMessage() + result.FIdxChn = msg.channel + result.FProperties = 0x00 | (0x00 if msg.is_rx else 0x01) | \ + (0x02 if msg.is_remote_frame else 0x00) | \ + (0x04 if msg.is_extended_id else 0x00) + result.FDLC = msg.dlc + result.FIdentifier = msg.arbitration_id + result.FTimeUs = msg.timestamp + for index, item in enumerate(msg.data): + result.FData[index] = item + return result + else: + raise TSMasterException(f'Unknown message type: {type(msg)}') + + +class TosunBus(can.BusABC): + + def __init__(self, mappings: list[dict], + configs: Union[List[dict], Tuple[dict]], + fifo_status: str = 'enable', + turbo_enable: bool = False, + channel: Any = None, + rx_queue_size: Optional[int] = None, + can_filters: Optional[can.typechecking.CanFilters] = None, + **kwargs: object): + super().__init__(channel, can_filters, **kwargs) + + if isinstance(channel, list): + self.channels = channel + else: + self.channels = [] + if 'with_com' not in kwargs: + kwargs['with_com'] = False + self.device = TosunDevice(self.channels, **kwargs) + count = self.device.channel_count('can', len(mappings)) + assert count == len(mappings) + self.available = [] + for _mapping in mappings: + _mapping = self.device.mapping_instance(**_mapping) + self.device.set_mapping(_mapping) + if _mapping.FMappingDisabled is False: + chl_index = _mapping.FAppChannelIndex + if isinstance(chl_index, ctypes.c_int): + self.available.append(chl_index.value) + else: + self.available.append(chl_index) + + for index, chl in enumerate(self.available): + try: + config: dict = configs[index] + except IndexError: + LOG.warn(f'TOSUN-CAN: channel:{chl} not initialized.') + return + + baudrate = config.get('baudrate', None) + if baudrate is None: + raise CanInitializationError('TOSUN-CAN: baudrate is required.') + + del config['baudrate'] + baudrate = int(baudrate / 1000) + config['kbaudrate'] = baudrate + + arb_baudrate = config.get('arb_baudrate', None) + if arb_baudrate is None: + arb_kbaudrate = baudrate + else: + del config['arb_baudrate'] + arb_kbaudrate = int(arb_baudrate / 1000) + config['arb_kbaudrate'] = arb_kbaudrate + + self.device.configure_baudrate(chl, **config) + + self.device.turbo_mode(turbo_enable) + try: + self.device.set_receive_fifo_status(fifo_status) + except TSMasterException as e: + LOG.warning(e) + # self.device.connect() + self.rx_queue = collections.deque( + maxlen=rx_queue_size + ) # type: Deque[Any] # channel, raw_msg + + def _recv_from_queue(self) -> Tuple[can.Message, bool]: + """Return a message from the internal receive queue""" + raw_msg = self.rx_queue.popleft() + if isinstance(raw_msg, can.Message): + return raw_msg, False + return tosun_convert_msg(raw_msg), False + + def poll_received_messages(self, timeout, buffer_size=50): + for channel in self.available: + if self.device.com_enabled: + success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, TSReadTxRxMode.TX_RX_MESSAGES, TSMasterMessageType.CAN) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=False, + ) + ) + success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, TSReadTxRxMode.TX_RX_MESSAGES, TSMasterMessageType.CAN_FD) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=True, + bitrate_switch=is_brs, + + ) + ) + can_msg, can_num = self.device.tsfifo_receive_msgs(channel, buffer_size, TSReadTxRxMode.TX_RX_MESSAGES, + TSMasterMessageType.CAN) + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, buffer_size, TSReadTxRxMode.TX_RX_MESSAGES, + TSMasterMessageType.CAN_FD) + if can_num: + LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') + self.rx_queue.extend( + can_msg[i] for i in range(can_num) + ) + if canfd_num: + LOG.debug(f'ZLG-CAN: canfd message received: {canfd_num}.') + self.rx_queue.extend( + can_msgfd[i] for i in range(canfd_num) + ) + + def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: + + if self.rx_queue: + return self._recv_from_queue() + + deadline = None + while deadline is None or time.time() < deadline: + if deadline is None and timeout is not None: + deadline = time.time() + timeout + + self.poll_received_messages(timeout) + + if self.rx_queue: + return self._recv_from_queue() + + return None, False + + def send(self, msg: can.Message, timeout: Optional[float] = None, sync: bool = True) -> None: + msg = tosun_convert_msg(msg) + self.device.transmit(msg, sync, timeout=timeout) + + @staticmethod + def _detect_available_configs() -> List[can.typechecking.AutoDetectedConfig]: + warnings.warn('Not supported by Tosun device.', DeprecationWarning, 2) + + def fileno(self) -> int: + warnings.warn('Not supported by Tosun device.', DeprecationWarning, 2) + + def cyclic_send(self, msg: can.Message, period: int): + pass + + def del_cyclic_send(self, msg: can.Message): + pass + + def configure_can_regs(self): + self.device.tsapp_configure_can_register() + + def __enter__(self): + self.device.connect() + return self + + def shutdown(self) -> None: + super().shutdown() + self.device.finalize() + + +if __name__ == '__main__': + from tosun import TSChannelIndex, TSAppChannelType, TSDeviceType, TSDeviceSubType + import time + mapping = {'app_name': 'TSMaster', + 'app_chl_idx': TSChannelIndex.CHN1, + 'app_chl_type': TSAppChannelType.APP_CAN, + 'hw_type': TSDeviceType.TS_USB_DEVICE, + 'hw_idx': 0, + 'hw_chl_idx': TSChannelIndex.CHN1, + 'hw_subtype': TSDeviceSubType.TC1016, + 'hw_name': 'TC1016'} + with TosunBus([mapping, ], configs=[ + {'baudrate': 500_000, 'initenal_resistance': 1} + ], + # with_com=True + ) as bus: + # while True: + # print(bus.device.tsfifo_receive_msgs(0, 100, TSReadTxRxMode.TX_RX_MESSAGES, TSMasterMessageType.CAN)) + # time.sleep(0.5) + while True: + print(bus.recv()) + time.sleep(0.01) + + + diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py new file mode 100644 index 000000000..6acca2552 --- /dev/null +++ b/can/interfaces/zlgcan.py @@ -0,0 +1,362 @@ +import collections +import ctypes +import logging +import platform +import time +import warnings + +from can.bus import LOG + +import can.typechecking +from can.exceptions import ( + CanError, + CanInterfaceNotImplementedError, + CanOperationError, + CanInitializationError, +) +from typing import Optional, Tuple, Sequence, Union, Deque, Any +from can import BusABC, Message +from zlgcan import ZCAN, ZCANDeviceType, ZCAN_Transmit_Data, ZCAN_TransmitFD_Data, ZCAN_Receive_Data, \ + ZCAN_ReceiveFD_Data, ZCANDataObj, ZCANException, ZCANMessageType, ZCANCanTransType + +logger = logging.getLogger(__name__) + +# AFTER_OPEN_DEVICE = [ +# 'tx_timeout', +# ] +# +# BEFORE_INIT_CAN = [ +# 'canfd_standard', +# 'protocol', +# 'canfd_abit_baud_rate', +# 'canfd_dbit_baud_rate', +# 'baud_rate_custom', +# ] +# +# AFTER_INIT_CAN = [ +# 'initenal_resistance', +# 'filter_mode', +# 'filter_start', +# 'filter_end', +# 'filter_ack', +# 'filter_clear', +# ] +# +# BEFOR_START_CAN = [ +# 'set_bus_usage_enable', +# 'set_bus_usage_period', +# ] +# +# AFTER_START_CAN = [ +# 'auto_send', +# 'auto_send_canfd', +# 'auto_send_param', +# 'clear_auto_send', +# 'apply_auto_send', +# 'set_send_mode', +# ] +ZCAN_Transmit_Data_1 = (ZCAN_Transmit_Data * 1) +ZCAN_TransmitFD_Data_1 = (ZCAN_TransmitFD_Data * 1) +ZCANDataObj_1 = (ZCANDataObj * 1) + + +def zlg_convert_msg(msg, **kwargs): # channel=None, trans_type=0, is_merge=False, **kwargs): + + if isinstance(msg, Message): # 发送报文转换 + is_merge = kwargs.get('is_merge', None) + trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL) + assert is_merge is not None, 'is_merge required when convert to ZLG.' + # assert trans_type is not None, 'trans_type required when convert to ZLG.' + if not is_merge: + if msg.is_fd: + result = ZCAN_TransmitFD_Data_1() + result[0].frame.len = msg.dlc + result[0].frame.brs = msg.bitrate_switch + result[0].frame.data = (ctypes.c_ubyte * 64)(*msg.data) + else: + result = ZCAN_Transmit_Data_1() + result[0].frame.can_dlc = msg.dlc + result[0].frame.data = (ctypes.c_ubyte * msg.dlc)(*msg.data) + result[0].transmit_type = trans_type + + result[0].frame.can_id = msg.arbitration_id + result[0].frame.err = msg.is_error_frame + result[0].frame.rtr = msg.is_remote_frame + result[0].frame.eff = msg.is_extended_id + return result + else: + channel = kwargs.get('channel', None) + assert channel is not None, 'channel required when merge send recv.' + result = ZCANDataObj_1() + result[0].dataType = 1 # can device always equal 1 + assert channel is not None + result[0].chnl = channel + result[0].data.zcanCANFDData.frame.can_id = msg.arbitration_id + result[0].data.zcanCANFDData.frame.err = msg.is_error_frame + result[0].data.zcanCANFDData.frame.rtr = msg.is_remote_frame + result[0].data.zcanCANFDData.frame.eff = msg.is_extended_id + + result[0].data.zcanCANFDData.flag.transmitType = trans_type + echo = kwargs.get('is_echo', False) + result[0].data.zcanCANFDData.flag.txEchoRequest = echo + delay = kwargs.get('delay_mode', 0) + if delay: + result[0].data.zcanCANFDData.flag.txDelay = delay + result[0].data.zcanCANFDData.timeStamp = kwargs['delay_time'] + return result + elif isinstance(msg, ZCAN_Receive_Data): # 接收CAN报文转换 + channel = kwargs.get('channel', None) + assert channel is not None, 'channel required when convert ZLG CAN msg to std msg.' + return Message( + timestamp=msg.timestamp, + arbitration_id=msg.frame.can_id, + is_extended_id=msg.frame.eff, + is_remote_frame=msg.frame.rtr, + is_error_frame=msg.frame.err, + channel=channel, + dlc=msg.frame.can_dlc, + data=bytes(msg.frame.data), + ) + elif isinstance(msg, ZCAN_ReceiveFD_Data): # 接收CANFD报文转换 + channel = kwargs.get('channel', None) + assert channel is not None, 'channel required when convert ZLG CANFD msg to std msg.' + return Message( + timestamp=msg.timestamp, + arbitration_id=msg.frame.can_id, + is_extended_id=msg.frame.eff, + is_remote_frame=msg.frame.rtr, + is_error_frame=msg.frame.err, + channel=channel, + dlc=msg.frame.len, + data=bytes(msg.frame.data), + is_fd=True, + # is_rx=True, + bitrate_switch=msg.frame.brs, + error_state_indicator=msg.frame.esi, + ) + elif isinstance(msg, ZCANDataObj): # 合并接收CAN|CANFD报文转换 + data = msg.data.zcanCANFDData + return Message( + timestamp=data.timeStamp, + arbitration_id=data.frame.can_id, + is_extended_id=data.frame.eff, + is_remote_frame=data.frame.rtr, + is_error_frame=data.frame.err, + channel=msg.chnl, + dlc=data.frame.len, + data=bytes(data.frame.data), + is_fd=data.flag.frameType, + bitrate_switch=data.frame.brs, + error_state_indicator=data.frame.esi, + ), data.flag.txEchoed + else: + raise ZCANException(f'Unknown message type: {type(msg)}') + + +class ZCanBus(BusABC): + + def __init__(self, + device_type: ZCANDeviceType, + channel: Union[int, Sequence[int], str] = None, + device_index: int = 0, + rx_queue_size: Optional[int] = None, + configs: Union[list, tuple] = None, + can_filters: Optional[can.typechecking.CanFilters] = None, + **kwargs: object): + """ + Init ZLG CAN Bus device. + :param device_type: The device type in ZCANDeviceType. + :param channel: A channel list(such as [0, 1]) or str split by ","(such as "0, 1") index cont from 0. + :param device_index: The ZLG device index, default 0. + :param rx_queue_size: The size of received queue. + :param configs: The channel configs, is a list of dict: + The index 0 is configuration for channel 0, index 1 is configuration for channel 1, and so on. + When the system is Windows, the config key is: + clock: [Optional] The clock of channel. + arb_baudrate: [Must] The arbitration phase baudrate. + data_baudrate: [Optional] The data phase baudrate, default is arb_baudrate. + initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable} + mode: [Optional] The can mode, defined in ZCANCanMode, default is NORMAL + filter: [Optional] The filter mode, defined in ZCANCanFilter, default is DOUBLE + acc_code: [Optional] The frame filter acceptance code of SJA1000. + acc_mask: [Optional] The frame mask code of SJA1000. + brp: [Optional] The bit rate prescaler + abit_timing: [Optional] The arbitration phase timing, ignored. + dbit_timing: [Optional] The data phase timing, ignored. + Other property value: please see: https://manual.zlg.cn/web/#/152/6364->设备属性, with out head "n/". + When the system is Linux, the config key is: + clock: [Must] The clock of channel. + arb_tseg1: [Must] The phase buffer time segment1 of arbitration phase. + arb_tseg2: [Must] The phase buffer time segment2 of arbitration phase. + arb_sjw: [Must] The synchronization jump width of arbitration phase. + arb_smp: [Optional] Sample rate of arbitration phase, default is 0, Ignored. + arb_brp: [Must] The bit rate prescaler of arbitration phase. + data_tseg1: [Optional] The phase buffer time segment1 of data phase, default is arb_tseg1. + data_tseg2: [Optional] The phase buffer time segment2 of data phase, default is arb_tseg2. + data_sjw: [Optional] The synchronization jump width of data phase, default is arb_sjw. + data_smp: [Optional] Sample rate of data phase, default is arb_smp, Ignored. + data_brp: [Optional] The bit rate prescaler of data phase, default is arb_brp. + :param can_filters: Not used. + :param kwargs: Not used. + """ + super().__init__(channel=channel, can_filters=can_filters, **kwargs) + + cfg_length = len(configs) + if cfg_length == 0: + raise CanInitializationError('ZLG-CAN: Configuration list or tuple of dict is required.') + + self.rx_queue = collections.deque( + maxlen=rx_queue_size + ) # type: Deque[Tuple[int, Any]] # channel, raw_msg + + self.device = ZCAN() + self.device.OpenDevice(device_type, device_index) + self.channels = self.device.channels + self.available = [] + self.channel_info = f"ZLG-CAN: device {device_index}, channels {self.channels}" + # {'mode': 0|1(NORMAL|LISTEN_ONLY), 'filter': 0|1(DOUBLE|SINGLE), 'acc_code': 0x0, 'acc_mask': 0xFFFFFFFF, + # 'brp': 0, 'abit_timing': 0, 'dbit_timing': 0} + + for index, channel in enumerate(self.channels): + try: + config: dict = configs[index] + except IndexError: + LOG.warn(f'ZLG-CAN: channel:{channel} not initialized.') + return + init_config = {} + if platform.system().lower() == 'windows': + mode = config.get('mode', None) + if mode: + init_config['mode'] = mode + del config['mode'] + filter = config.get('filter', None) + if filter: + init_config['filter'] = filter + del config['filter'] + acc_code = config.get('acc_code', None) + if acc_code: + init_config['acc_code'] = acc_code + del config['acc_code'] + acc_mask = config.get('acc_mask', None) + if acc_mask: + init_config['acc_mask'] = acc_mask + del config['acc_mask'] + brp = config.get('brp', None) + if brp: + init_config['brp'] = brp + del config['brp'] + abit_timing = config.get('dbit_timing', None) + if abit_timing: + init_config['abit_timing'] = abit_timing + del config['abit_timing'] + dbit_timing = config.get('dbit_timing', None) + if dbit_timing: + init_config['dbit_timing'] = dbit_timing + del config['dbit_timing'] + + baudrate = config.get('baudrate', None) + if baudrate is None: + raise CanInitializationError('ZLG-CAN: baudrate is required.') + del config['baudrate'] + config['canfd_dbit_baud_rate'] = baudrate + + arb_baudrate = config.get('arb_baudrate', None) + if arb_baudrate is None: + config['canfd_abit_baud_rate'] = baudrate + else: + del config['arb_baudrate'] + config['canfd_abit_baud_rate'] = arb_baudrate + + self.device.SetValue(channel, **config) + self.device.InitCAN(channel, **init_config) + self.device.StartCAN(channel) + self.available.append(channel) + + # def _apply_filters(self, filters: Optional[can.typechecking.CanFilters]) -> None: + # pass + + def _recv_from_queue(self) -> Tuple[Message, bool]: + """Return a message from the internal receive queue""" + channel, raw_msg = self.rx_queue.popleft() + + return zlg_convert_msg(raw_msg, channel=channel), False + + def poll_received_messages(self, timeout): + for channel in self.available: + can_num = self.device.GetReceiveNum(channel, ZCANMessageType.CAN) + canfd_num = self.device.GetReceiveNum(channel, ZCANMessageType.CANFD) + if can_num: + LOG.debug(f'ZLG-CAN: can message received: {can_num}.') + self.rx_queue.extend( + (channel, raw_msg) for raw_msg in self.device.Receive(channel, can_num, timeout) + ) + if canfd_num: + LOG.debug(f'ZLG-CAN: canfd message received: {canfd_num}.') + self.rx_queue.extend( + (channel, raw_msg) for raw_msg in self.device.ReceiveFD(channel, canfd_num, timeout) + ) + + def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], bool]: + + if self.rx_queue: + return self._recv_from_queue() + + deadline = None + while deadline is None or time.time() < deadline: + if deadline is None and timeout is not None: + deadline = time.time() + timeout + + self.poll_received_messages(timeout) + + if self.rx_queue: + return self._recv_from_queue() + + return None, False + + def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: + channel = msg.channel + if channel not in self.available: + raise CanOperationError(f'Channel: {channel} not in {self.available}') + is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False + if is_merge: + return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + else: + if msg.is_fd: + return self.device.TransmitFD(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + return self.device.Transmit(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + + @staticmethod + def _detect_available_configs(): # -> List[can.typechecking.AutoDetectedConfig]: + warnings.warn('Not supported by ZLG-CAN device.', DeprecationWarning, 2) + + def fileno(self): + warnings.warn('Not supported by ZLG-CAN device.', DeprecationWarning, 2) + + def shutdown(self) -> None: + super().shutdown() + self.device.CloseDevice() + + def clear_rx_buffer(self, channel=None): + if channel: + assert channel in self.available + self.device.ClearBuffer(channel) + else: + for channel in self.available: + self.device.ClearBuffer(channel) + + def set_hardware_filters(self, channel, filters: Optional[can.typechecking.CanFilters]): + assert channel in self.available, f'channel: {channel} is not initialized!' + _filters = [] + for flt in filters: + can_id = flt.get('can_id') + can_mask = flt.get('can_mask') + extended = False + if isinstance(flt, can.typechecking.CanFilterExtended): + extended = flt.get('extended') + end = ~(can_id ^ can_mask) + if end < 0: + end = -end + LOG.debug(f'~(can_id ^ can_mask): {bin(end)}') + _filters.append((1 if extended else 0, can_id, end)) + + self.device.SetFilters(channel, _filters) From 5f52ae5f909db72d31cd908f9a71f01f0b419f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Tue, 26 Jul 2022 16:49:11 +0800 Subject: [PATCH 02/30] TosunBus add receive_own_messages parameter --- can/interfaces/tosun.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index e1de6cf07..bbe049008 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -8,8 +8,7 @@ from can import CanInitializationError from can.bus import LOG -from tosun import TSCanMessage, TSCanFdMessage, TSMasterException, TosunDevice, TSMasterMessageType, \ - TSReadTxRxMode +from tosun import TSCanMessage, TSCanFdMessage, TSMasterException, TosunDevice, TSMasterMessageType def tosun_convert_msg(msg): @@ -66,11 +65,13 @@ def __init__(self, mappings: list[dict], configs: Union[List[dict], Tuple[dict]], fifo_status: str = 'enable', turbo_enable: bool = False, + receive_own_messages=True, channel: Any = None, rx_queue_size: Optional[int] = None, can_filters: Optional[can.typechecking.CanFilters] = None, **kwargs: object): super().__init__(channel, can_filters, **kwargs) + self.receive_own_messages = receive_own_messages if isinstance(channel, list): self.channels = channel @@ -138,7 +139,7 @@ def poll_received_messages(self, timeout, buffer_size=50): for channel in self.available: if self.device.com_enabled: success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, TSReadTxRxMode.TX_RX_MESSAGES, TSMasterMessageType.CAN) + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) if success: self.rx_queue.append( can.Message( @@ -153,7 +154,7 @@ def poll_received_messages(self, timeout, buffer_size=50): ) ) success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, TSReadTxRxMode.TX_RX_MESSAGES, TSMasterMessageType.CAN_FD) + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) if success: self.rx_queue.append( can.Message( @@ -169,9 +170,9 @@ def poll_received_messages(self, timeout, buffer_size=50): ) ) - can_msg, can_num = self.device.tsfifo_receive_msgs(channel, buffer_size, TSReadTxRxMode.TX_RX_MESSAGES, + can_msg, can_num = self.device.tsfifo_receive_msgs(channel, buffer_size, self.receive_own_messages, TSMasterMessageType.CAN) - can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, buffer_size, TSReadTxRxMode.TX_RX_MESSAGES, + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, buffer_size, self.receive_own_messages, TSMasterMessageType.CAN_FD) if can_num: LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') From b2568b7b0fe8949a7bba35eb02fdcf136960d644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Tue, 26 Jul 2022 17:08:26 +0800 Subject: [PATCH 03/30] rename keyword parameter name --- can/interfaces/zlgcan.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 6acca2552..2bd8939b0 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -173,8 +173,8 @@ def __init__(self, The index 0 is configuration for channel 0, index 1 is configuration for channel 1, and so on. When the system is Windows, the config key is: clock: [Optional] The clock of channel. - arb_baudrate: [Must] The arbitration phase baudrate. - data_baudrate: [Optional] The data phase baudrate, default is arb_baudrate. + baudrate: [Must] The data phase baudrate. + arb_baudrate: [Optional] The arbitration phase baudrate, default is baudrate. initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable} mode: [Optional] The can mode, defined in ZCANCanMode, default is NORMAL filter: [Optional] The filter mode, defined in ZCANCanFilter, default is DOUBLE From cd9b777ae3c8f8a73660ad9192e0004683f73c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 27 Jul 2022 11:46:05 +0800 Subject: [PATCH 04/30] fix tosun device buffer count, remove unimplement method. --- can/interfaces/tosun.py | 92 +++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index bbe049008..a233e08f0 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -51,7 +51,7 @@ def tosun_convert_msg(msg): (0x04 if msg.is_extended_id else 0x00) result.FDLC = msg.dlc result.FIdentifier = msg.arbitration_id - result.FTimeUs = msg.timestamp + result.FTimeUs = int(msg.timestamp) for index, item in enumerate(msg.data): result.FData[index] = item return result @@ -135,51 +135,55 @@ def _recv_from_queue(self) -> Tuple[can.Message, bool]: return raw_msg, False return tosun_convert_msg(raw_msg), False - def poll_received_messages(self, timeout, buffer_size=50): + def poll_received_messages(self, timeout): for channel in self.available: + can_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN) + canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) if self.device.com_enabled: - success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) - if success: - self.rx_queue.append( - can.Message( - timestamp=timestamp, - arbitration_id=can_id, - is_extended_id=is_extend, - is_remote_frame=is_remote, - channel=chl_index, - dlc=dlc, - data=[int(i) for i in data.split(',')], - is_fd=False, + if can_num: + success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=False, + ) ) - ) - success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) - if success: - self.rx_queue.append( - can.Message( - timestamp=timestamp, - arbitration_id=can_id, - is_extended_id=is_extend, - is_remote_frame=is_remote, - channel=chl_index, - dlc=dlc, - data=[int(i) for i in data.split(',')], - is_fd=True, - bitrate_switch=is_brs, - + if canfd_num: + success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=True, + bitrate_switch=is_brs, + + ) ) - ) - can_msg, can_num = self.device.tsfifo_receive_msgs(channel, buffer_size, self.receive_own_messages, - TSMasterMessageType.CAN) - can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, buffer_size, self.receive_own_messages, - TSMasterMessageType.CAN_FD) if can_num: + can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, + TSMasterMessageType.CAN) LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') self.rx_queue.extend( can_msg[i] for i in range(can_num) ) if canfd_num: + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, self.receive_own_messages, + TSMasterMessageType.CAN_FD) LOG.debug(f'ZLG-CAN: canfd message received: {canfd_num}.') self.rx_queue.extend( can_msgfd[i] for i in range(canfd_num) @@ -213,14 +217,14 @@ def _detect_available_configs() -> List[can.typechecking.AutoDetectedConfig]: def fileno(self) -> int: warnings.warn('Not supported by Tosun device.', DeprecationWarning, 2) - def cyclic_send(self, msg: can.Message, period: int): - pass - - def del_cyclic_send(self, msg: can.Message): - pass - - def configure_can_regs(self): - self.device.tsapp_configure_can_register() + # def cyclic_send(self, msg: can.Message, period: int): + # pass + # + # def del_cyclic_send(self, msg: can.Message): + # pass + # + # def configure_can_regs(self): + # self.device.tsapp_configure_can_register() def __enter__(self): self.device.connect() From 6a0eceb4d561493c422159e1f94ff655de30815a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Fri, 29 Jul 2022 16:51:29 +0800 Subject: [PATCH 05/30] rename the keyword params to fit python-can style --- can/interfaces/tosun.py | 26 +++++++++++++------------- can/interfaces/zlgcan.py | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index a233e08f0..7b7701196 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -100,21 +100,21 @@ def __init__(self, mappings: list[dict], LOG.warn(f'TOSUN-CAN: channel:{chl} not initialized.') return - baudrate = config.get('baudrate', None) - if baudrate is None: - raise CanInitializationError('TOSUN-CAN: baudrate is required.') - + bitrate = config.get('bitrate', None) + if bitrate is None: + raise CanInitializationError('TOSUN-CAN: bitrate is required.') + # data_bitrate del config['baudrate'] - baudrate = int(baudrate / 1000) - config['kbaudrate'] = baudrate + bitrate = int(bitrate / 1000) + config['kbaudrate'] = bitrate - arb_baudrate = config.get('arb_baudrate', None) - if arb_baudrate is None: - arb_kbaudrate = baudrate + data_bitrate = config.get('data_bitrate', None) + if data_bitrate is None: + data_bitrate = bitrate else: - del config['arb_baudrate'] - arb_kbaudrate = int(arb_baudrate / 1000) - config['arb_kbaudrate'] = arb_kbaudrate + del config['data_bitrate'] + data_bitrate = int(data_bitrate / 1000) + config['db_kbaudrate'] = data_bitrate self.device.configure_baudrate(chl, **config) @@ -247,7 +247,7 @@ def shutdown(self) -> None: 'hw_subtype': TSDeviceSubType.TC1016, 'hw_name': 'TC1016'} with TosunBus([mapping, ], configs=[ - {'baudrate': 500_000, 'initenal_resistance': 1} + {'bitrate': 500_000, 'initenal_resistance': 1} ], # with_com=True ) as bus: diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 2bd8939b0..abb7b737f 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -173,8 +173,8 @@ def __init__(self, The index 0 is configuration for channel 0, index 1 is configuration for channel 1, and so on. When the system is Windows, the config key is: clock: [Optional] The clock of channel. - baudrate: [Must] The data phase baudrate. - arb_baudrate: [Optional] The arbitration phase baudrate, default is baudrate. + bitrate: [Must] The arbitration phase baudrate. + data_bitrate: [Optional] The data phase baudrate, default is baudrate. initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable} mode: [Optional] The can mode, defined in ZCANCanMode, default is NORMAL filter: [Optional] The filter mode, defined in ZCANCanFilter, default is DOUBLE @@ -254,18 +254,18 @@ def __init__(self, init_config['dbit_timing'] = dbit_timing del config['dbit_timing'] - baudrate = config.get('baudrate', None) - if baudrate is None: - raise CanInitializationError('ZLG-CAN: baudrate is required.') - del config['baudrate'] - config['canfd_dbit_baud_rate'] = baudrate + bitrate = config.get('bitrate', None) + if bitrate is None: + raise CanInitializationError('ZLG-CAN: bitrate is required.') + del config['bitrate'] + config['canfd_abit_baud_rate'] = bitrate - arb_baudrate = config.get('arb_baudrate', None) - if arb_baudrate is None: - config['canfd_abit_baud_rate'] = baudrate + data_bitrate = config.get('data_bitrate', None) + if data_bitrate is None: + config['canfd_dbit_baud_rate'] = bitrate else: - del config['arb_baudrate'] - config['canfd_abit_baud_rate'] = arb_baudrate + del config['data_bitrate'] + config['canfd_dbit_baud_rate'] = data_bitrate self.device.SetValue(channel, **config) self.device.InitCAN(channel, **init_config) From 30268e98a94d3eab845d8797fe70d9bf4eb8f134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Tue, 2 Aug 2022 13:45:25 +0800 Subject: [PATCH 06/30] add default channel for message. --- can/interfaces/tosun.py | 5 ++++- can/interfaces/zlgcan.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 7b7701196..09a530ee2 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -1,4 +1,5 @@ import collections +import time import warnings from typing import List, Optional, Tuple, Any, Union @@ -206,7 +207,9 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message return None, False - def send(self, msg: can.Message, timeout: Optional[float] = None, sync: bool = True) -> None: + def send(self, msg: can.Message, timeout: Optional[float] = 50, sync: bool = True) -> None: + if msg.channel is None: + msg.channel = self.available[0] msg = tosun_convert_msg(msg) self.device.transmit(msg, sync, timeout=timeout) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index abb7b737f..afaac7ec2 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -316,7 +316,10 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], b def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: channel = msg.channel if channel not in self.available: - raise CanOperationError(f'Channel: {channel} not in {self.available}') + if len(self.available) == 0: + raise CanOperationError(f'Channel: {channel} not in {self.available}') + if channel is None: + channel = self.available[0] is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False if is_merge: return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) From eef93835d9634e6fcc02343e52a0f334b787b514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 3 Aug 2022 16:41:12 +0800 Subject: [PATCH 07/30] fix some errors. --- can/interfaces/tosun.py | 47 +++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 09a530ee2..e901009d4 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -34,10 +34,11 @@ def tosun_convert_msg(msg): channel=msg.FIdxChn, dlc=msg.FDLC, data=bytes(msg.FData), - is_fd=False, + is_fd=msg.FFDProperties & 0x01, is_rx=False if msg.FProperties & 0x01 else True, bitrate_switch=msg.FFDProperties & 0x02, error_state_indicator=msg.FFDProperties & 0x04, + is_error_frame=msg.FProperties & 0x80 ) elif isinstance(msg, can.Message): if msg.is_fd: @@ -105,7 +106,7 @@ def __init__(self, mappings: list[dict], if bitrate is None: raise CanInitializationError('TOSUN-CAN: bitrate is required.') # data_bitrate - del config['baudrate'] + del config['bitrate'] bitrate = int(bitrate / 1000) config['kbaudrate'] = bitrate @@ -141,7 +142,10 @@ def poll_received_messages(self, timeout): can_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN) canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) if self.device.com_enabled: - if can_num: + # if can_num: + LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') + while can_num > 0: + can_num -= 1 success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) if success: @@ -157,7 +161,10 @@ def poll_received_messages(self, timeout): is_fd=False, ) ) - if canfd_num: + # if canfd_num: + LOG.debug(f'TOSUN-CAN: canfd message received: {canfd_num}.') + while canfd_num > 0: + canfd_num -= 1 success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) if success: @@ -175,20 +182,24 @@ def poll_received_messages(self, timeout): ) ) - if can_num: - can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, - TSMasterMessageType.CAN) - LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') - self.rx_queue.extend( - can_msg[i] for i in range(can_num) - ) - if canfd_num: - can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, self.receive_own_messages, - TSMasterMessageType.CAN_FD) - LOG.debug(f'ZLG-CAN: canfd message received: {canfd_num}.') - self.rx_queue.extend( - can_msgfd[i] for i in range(canfd_num) - ) + else: + if can_num or canfd_num: + print('can_num:', can_num, 'canfd_num:', canfd_num) + if can_num < canfd_num: + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, + self.receive_own_messages, + TSMasterMessageType.CAN_FD) + LOG.debug(f'TOSUN-CAN: canfd message received: {canfd_num}.') + self.rx_queue.extend( + can_msgfd[i] for i in range(canfd_num) + ) + else: + can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, + TSMasterMessageType.CAN) + LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') + self.rx_queue.extend( + can_msg[i] for i in range(can_num) + ) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: From b437c0b669a7c08e20a69a659c53493cf5a653ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 3 Aug 2022 18:01:54 +0800 Subject: [PATCH 08/30] fix some errors. --- can/interfaces/tosun.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index e901009d4..9ef4f9005 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -125,7 +125,7 @@ def __init__(self, mappings: list[dict], self.device.set_receive_fifo_status(fifo_status) except TSMasterException as e: LOG.warning(e) - # self.device.connect() + self.device.connect() self.rx_queue = collections.deque( maxlen=rx_queue_size ) # type: Deque[Any] # channel, raw_msg @@ -184,7 +184,6 @@ def poll_received_messages(self, timeout): ) else: if can_num or canfd_num: - print('can_num:', can_num, 'canfd_num:', canfd_num) if can_num < canfd_num: can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, self.receive_own_messages, @@ -200,6 +199,8 @@ def poll_received_messages(self, timeout): self.rx_queue.extend( can_msg[i] for i in range(can_num) ) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: @@ -241,7 +242,6 @@ def fileno(self) -> int: # self.device.tsapp_configure_can_register() def __enter__(self): - self.device.connect() return self def shutdown(self) -> None: From 0f2c57af950628f555eaa22e5e0ed5b26eb0e667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sat, 6 Aug 2022 12:55:07 +0800 Subject: [PATCH 09/30] fix arg channel location --- can/interfaces/tosun.py | 4 ++-- can/interfaces/zlgcan.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 9ef4f9005..6c34bc53d 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -63,12 +63,12 @@ def tosun_convert_msg(msg): class TosunBus(can.BusABC): - def __init__(self, mappings: list[dict], + def __init__(self, channel: Any = None, *, + mappings: list[dict], configs: Union[List[dict], Tuple[dict]], fifo_status: str = 'enable', turbo_enable: bool = False, receive_own_messages=True, - channel: Any = None, rx_queue_size: Optional[int] = None, can_filters: Optional[can.typechecking.CanFilters] = None, **kwargs: object): diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index afaac7ec2..a6d144324 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -156,8 +156,8 @@ def zlg_convert_msg(msg, **kwargs): # channel=None, trans class ZCanBus(BusABC): def __init__(self, + channel: Union[int, Sequence[int], str] = None, *, device_type: ZCANDeviceType, - channel: Union[int, Sequence[int], str] = None, device_index: int = 0, rx_queue_size: Optional[int] = None, configs: Union[list, tuple] = None, From 5b14b4f3f4ab8863d2b56a58ef606ca5bba224f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sat, 6 Aug 2022 14:12:03 +0800 Subject: [PATCH 10/30] change log head --- can/interfaces/tosun.py | 12 ++++++------ can/interfaces/zlgcan.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 6c34bc53d..b799a8c1d 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -99,12 +99,12 @@ def __init__(self, channel: Any = None, *, try: config: dict = configs[index] except IndexError: - LOG.warn(f'TOSUN-CAN: channel:{chl} not initialized.') + LOG.warn(f'TOSUN-CAN - channel:{chl} not initialized.') return bitrate = config.get('bitrate', None) if bitrate is None: - raise CanInitializationError('TOSUN-CAN: bitrate is required.') + raise CanInitializationError('TOSUN-CAN - bitrate is required.') # data_bitrate del config['bitrate'] bitrate = int(bitrate / 1000) @@ -143,7 +143,7 @@ def poll_received_messages(self, timeout): canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) if self.device.com_enabled: # if can_num: - LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') + LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') while can_num > 0: can_num -= 1 success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ @@ -162,7 +162,7 @@ def poll_received_messages(self, timeout): ) ) # if canfd_num: - LOG.debug(f'TOSUN-CAN: canfd message received: {canfd_num}.') + LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') while canfd_num > 0: canfd_num -= 1 success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ @@ -188,14 +188,14 @@ def poll_received_messages(self, timeout): can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, self.receive_own_messages, TSMasterMessageType.CAN_FD) - LOG.debug(f'TOSUN-CAN: canfd message received: {canfd_num}.') + LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') self.rx_queue.extend( can_msgfd[i] for i in range(canfd_num) ) else: can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, TSMasterMessageType.CAN) - LOG.debug(f'TOSUN-CAN: can message received: {can_num}.') + LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') self.rx_queue.extend( can_msg[i] for i in range(can_num) ) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index a6d144324..5ff9d5847 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -203,7 +203,7 @@ def __init__(self, cfg_length = len(configs) if cfg_length == 0: - raise CanInitializationError('ZLG-CAN: Configuration list or tuple of dict is required.') + raise CanInitializationError('ZLG-CAN - Configuration list or tuple of dict is required.') self.rx_queue = collections.deque( maxlen=rx_queue_size @@ -213,7 +213,7 @@ def __init__(self, self.device.OpenDevice(device_type, device_index) self.channels = self.device.channels self.available = [] - self.channel_info = f"ZLG-CAN: device {device_index}, channels {self.channels}" + self.channel_info = f"ZLG-CAN - device {device_index}, channels {self.channels}" # {'mode': 0|1(NORMAL|LISTEN_ONLY), 'filter': 0|1(DOUBLE|SINGLE), 'acc_code': 0x0, 'acc_mask': 0xFFFFFFFF, # 'brp': 0, 'abit_timing': 0, 'dbit_timing': 0} @@ -221,7 +221,7 @@ def __init__(self, try: config: dict = configs[index] except IndexError: - LOG.warn(f'ZLG-CAN: channel:{channel} not initialized.') + LOG.warn(f'ZLG-CAN - channel:{channel} not initialized.') return init_config = {} if platform.system().lower() == 'windows': @@ -256,7 +256,7 @@ def __init__(self, bitrate = config.get('bitrate', None) if bitrate is None: - raise CanInitializationError('ZLG-CAN: bitrate is required.') + raise CanInitializationError('ZLG-CAN - bitrate is required.') del config['bitrate'] config['canfd_abit_baud_rate'] = bitrate @@ -286,12 +286,12 @@ def poll_received_messages(self, timeout): can_num = self.device.GetReceiveNum(channel, ZCANMessageType.CAN) canfd_num = self.device.GetReceiveNum(channel, ZCANMessageType.CANFD) if can_num: - LOG.debug(f'ZLG-CAN: can message received: {can_num}.') + LOG.debug(f'ZLG-CAN - can message received: {can_num}.') self.rx_queue.extend( (channel, raw_msg) for raw_msg in self.device.Receive(channel, can_num, timeout) ) if canfd_num: - LOG.debug(f'ZLG-CAN: canfd message received: {canfd_num}.') + LOG.debug(f'ZLG-CAN - canfd message received: {canfd_num}.') self.rx_queue.extend( (channel, raw_msg) for raw_msg in self.device.ReceiveFD(channel, canfd_num, timeout) ) From 2d6e999849eebfd3d4739072c6e29aeb591ed624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sun, 7 Aug 2022 00:36:50 +0800 Subject: [PATCH 11/30] add shutdown log, fix tosun order of connect and enable fifo. --- can/interfaces/tosun.py | 8 +++++--- can/interfaces/zlgcan.py | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index b799a8c1d..49662c5e5 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -121,11 +121,12 @@ def __init__(self, channel: Any = None, *, self.device.configure_baudrate(chl, **config) self.device.turbo_mode(turbo_enable) + self.device.connect() try: self.device.set_receive_fifo_status(fifo_status) - except TSMasterException as e: - LOG.warning(e) - self.device.connect() + except TSMasterException: + self.device.set_receive_fifo_status(fifo_status) + self.rx_queue = collections.deque( maxlen=rx_queue_size ) # type: Deque[Any] # channel, raw_msg @@ -245,6 +246,7 @@ def __enter__(self): return self def shutdown(self) -> None: + LOG.debug('TSMaster - shutdown.') super().shutdown() self.device.finalize() diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 5ff9d5847..255d24174 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -336,6 +336,7 @@ def fileno(self): warnings.warn('Not supported by ZLG-CAN device.', DeprecationWarning, 2) def shutdown(self) -> None: + LOG.debug('ZLG-CAN - shutdown.') super().shutdown() self.device.CloseDevice() From c97966a1df4f55df86fec6052cc780643fef6ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 10 Aug 2022 21:57:14 +0800 Subject: [PATCH 12/30] conver TSMasterException, ZCANException to CanError. --- can/interfaces/tosun.py | 229 ++++++++++++++++++++------------------- can/interfaces/zlgcan.py | 186 ++++++++++++++++--------------- 2 files changed, 216 insertions(+), 199 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 49662c5e5..301abbbbb 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -81,55 +81,58 @@ def __init__(self, channel: Any = None, *, self.channels = [] if 'with_com' not in kwargs: kwargs['with_com'] = False - self.device = TosunDevice(self.channels, **kwargs) - count = self.device.channel_count('can', len(mappings)) - assert count == len(mappings) - self.available = [] - for _mapping in mappings: - _mapping = self.device.mapping_instance(**_mapping) - self.device.set_mapping(_mapping) - if _mapping.FMappingDisabled is False: - chl_index = _mapping.FAppChannelIndex - if isinstance(chl_index, ctypes.c_int): - self.available.append(chl_index.value) + try: + self.device = TosunDevice(self.channels, **kwargs) + count = self.device.channel_count('can', len(mappings)) + assert count == len(mappings) + self.available = [] + for _mapping in mappings: + _mapping = self.device.mapping_instance(**_mapping) + self.device.set_mapping(_mapping) + if _mapping.FMappingDisabled is False: + chl_index = _mapping.FAppChannelIndex + if isinstance(chl_index, ctypes.c_int): + self.available.append(chl_index.value) + else: + self.available.append(chl_index) + + for index, chl in enumerate(self.available): + try: + config: dict = configs[index] + except IndexError: + LOG.warn(f'TOSUN-CAN - channel:{chl} not initialized.') + return + + bitrate = config.get('bitrate', None) + if bitrate is None: + raise CanInitializationError('TOSUN-CAN - bitrate is required.') + # data_bitrate + del config['bitrate'] + bitrate = int(bitrate / 1000) + config['kbaudrate'] = bitrate + + data_bitrate = config.get('data_bitrate', None) + if data_bitrate is None: + data_bitrate = bitrate else: - self.available.append(chl_index) + del config['data_bitrate'] + data_bitrate = int(data_bitrate / 1000) + config['db_kbaudrate'] = data_bitrate + + self.device.configure_baudrate(chl, **config) - for index, chl in enumerate(self.available): + self.device.turbo_mode(turbo_enable) + self.device.connect() try: - config: dict = configs[index] - except IndexError: - LOG.warn(f'TOSUN-CAN - channel:{chl} not initialized.') - return - - bitrate = config.get('bitrate', None) - if bitrate is None: - raise CanInitializationError('TOSUN-CAN - bitrate is required.') - # data_bitrate - del config['bitrate'] - bitrate = int(bitrate / 1000) - config['kbaudrate'] = bitrate - - data_bitrate = config.get('data_bitrate', None) - if data_bitrate is None: - data_bitrate = bitrate - else: - del config['data_bitrate'] - data_bitrate = int(data_bitrate / 1000) - config['db_kbaudrate'] = data_bitrate - - self.device.configure_baudrate(chl, **config) - - self.device.turbo_mode(turbo_enable) - self.device.connect() - try: - self.device.set_receive_fifo_status(fifo_status) - except TSMasterException: - self.device.set_receive_fifo_status(fifo_status) + self.device.set_receive_fifo_status(fifo_status) + except TSMasterException: + self.device.set_receive_fifo_status(fifo_status) - self.rx_queue = collections.deque( - maxlen=rx_queue_size - ) # type: Deque[Any] # channel, raw_msg + self.rx_queue = collections.deque( + maxlen=rx_queue_size + ) # type: Deque[Any] # channel, raw_msg + except TSMasterException as e: + raise can.CanOperationError(e) def _recv_from_queue(self) -> Tuple[can.Message, bool]: """Return a message from the internal receive queue""" @@ -139,69 +142,72 @@ def _recv_from_queue(self) -> Tuple[can.Message, bool]: return tosun_convert_msg(raw_msg), False def poll_received_messages(self, timeout): - for channel in self.available: - can_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN) - canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) - if self.device.com_enabled: - # if can_num: - LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') - while can_num > 0: - can_num -= 1 - success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) - if success: - self.rx_queue.append( - can.Message( - timestamp=timestamp, - arbitration_id=can_id, - is_extended_id=is_extend, - is_remote_frame=is_remote, - channel=chl_index, - dlc=dlc, - data=[int(i) for i in data.split(',')], - is_fd=False, + try: + for channel in self.available: + can_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN) + canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) + if self.device.com_enabled: + # if can_num: + LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') + while can_num > 0: + can_num -= 1 + success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=False, + ) ) - ) - # if canfd_num: - LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') - while canfd_num > 0: - canfd_num -= 1 - success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) - if success: - self.rx_queue.append( - can.Message( - timestamp=timestamp, - arbitration_id=can_id, - is_extended_id=is_extend, - is_remote_frame=is_remote, - channel=chl_index, - dlc=dlc, - data=[int(i) for i in data.split(',')], - is_fd=True, - bitrate_switch=is_brs, - + # if canfd_num: + LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') + while canfd_num > 0: + canfd_num -= 1 + success, chl_index, is_remote, is_extend, is_edl, is_brs, dlc, can_id, timestamp, data = \ + self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN_FD) + if success: + self.rx_queue.append( + can.Message( + timestamp=timestamp, + arbitration_id=can_id, + is_extended_id=is_extend, + is_remote_frame=is_remote, + channel=chl_index, + dlc=dlc, + data=[int(i) for i in data.split(',')], + is_fd=True, + bitrate_switch=is_brs, + + ) ) - ) - else: - if can_num or canfd_num: - if can_num < canfd_num: - can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, - self.receive_own_messages, - TSMasterMessageType.CAN_FD) - LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') - self.rx_queue.extend( - can_msgfd[i] for i in range(canfd_num) - ) - else: - can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, - TSMasterMessageType.CAN) - LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') - self.rx_queue.extend( - can_msg[i] for i in range(can_num) - ) - self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) - self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) + else: + if can_num or canfd_num: + if can_num < canfd_num: + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, + self.receive_own_messages, + TSMasterMessageType.CAN_FD) + LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') + self.rx_queue.extend( + can_msgfd[i] for i in range(canfd_num) + ) + else: + can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, + TSMasterMessageType.CAN) + LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') + self.rx_queue.extend( + can_msg[i] for i in range(can_num) + ) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) + except TSMasterException as e: + raise can.CanOperationError(e) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: @@ -221,10 +227,13 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message return None, False def send(self, msg: can.Message, timeout: Optional[float] = 50, sync: bool = True) -> None: - if msg.channel is None: - msg.channel = self.available[0] - msg = tosun_convert_msg(msg) - self.device.transmit(msg, sync, timeout=timeout) + try: + if msg.channel is None: + msg.channel = self.available[0] + msg = tosun_convert_msg(msg) + self.device.transmit(msg, sync, timeout=timeout) + except TSMasterException as e: + raise can.CanOperationError(e) @staticmethod def _detect_available_configs() -> List[can.typechecking.AutoDetectedConfig]: diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 255d24174..88ca6db4c 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -208,69 +208,71 @@ def __init__(self, self.rx_queue = collections.deque( maxlen=rx_queue_size ) # type: Deque[Tuple[int, Any]] # channel, raw_msg - - self.device = ZCAN() - self.device.OpenDevice(device_type, device_index) - self.channels = self.device.channels - self.available = [] - self.channel_info = f"ZLG-CAN - device {device_index}, channels {self.channels}" - # {'mode': 0|1(NORMAL|LISTEN_ONLY), 'filter': 0|1(DOUBLE|SINGLE), 'acc_code': 0x0, 'acc_mask': 0xFFFFFFFF, - # 'brp': 0, 'abit_timing': 0, 'dbit_timing': 0} - - for index, channel in enumerate(self.channels): - try: - config: dict = configs[index] - except IndexError: - LOG.warn(f'ZLG-CAN - channel:{channel} not initialized.') - return - init_config = {} - if platform.system().lower() == 'windows': - mode = config.get('mode', None) - if mode: - init_config['mode'] = mode - del config['mode'] - filter = config.get('filter', None) - if filter: - init_config['filter'] = filter - del config['filter'] - acc_code = config.get('acc_code', None) - if acc_code: - init_config['acc_code'] = acc_code - del config['acc_code'] - acc_mask = config.get('acc_mask', None) - if acc_mask: - init_config['acc_mask'] = acc_mask - del config['acc_mask'] - brp = config.get('brp', None) - if brp: - init_config['brp'] = brp - del config['brp'] - abit_timing = config.get('dbit_timing', None) - if abit_timing: - init_config['abit_timing'] = abit_timing - del config['abit_timing'] - dbit_timing = config.get('dbit_timing', None) - if dbit_timing: - init_config['dbit_timing'] = dbit_timing - del config['dbit_timing'] - - bitrate = config.get('bitrate', None) - if bitrate is None: - raise CanInitializationError('ZLG-CAN - bitrate is required.') - del config['bitrate'] - config['canfd_abit_baud_rate'] = bitrate - - data_bitrate = config.get('data_bitrate', None) - if data_bitrate is None: - config['canfd_dbit_baud_rate'] = bitrate - else: - del config['data_bitrate'] - config['canfd_dbit_baud_rate'] = data_bitrate - - self.device.SetValue(channel, **config) - self.device.InitCAN(channel, **init_config) - self.device.StartCAN(channel) - self.available.append(channel) + try: + self.device = ZCAN() + self.device.OpenDevice(device_type, device_index) + self.channels = self.device.channels + self.available = [] + self.channel_info = f"ZLG-CAN - device {device_index}, channels {self.channels}" + # {'mode': 0|1(NORMAL|LISTEN_ONLY), 'filter': 0|1(DOUBLE|SINGLE), 'acc_code': 0x0, 'acc_mask': 0xFFFFFFFF, + # 'brp': 0, 'abit_timing': 0, 'dbit_timing': 0} + + for index, channel in enumerate(self.channels): + try: + config: dict = configs[index] + except IndexError: + LOG.warn(f'ZLG-CAN - channel:{channel} not initialized.') + return + init_config = {} + if platform.system().lower() == 'windows': + mode = config.get('mode', None) + if mode: + init_config['mode'] = mode + del config['mode'] + filter = config.get('filter', None) + if filter: + init_config['filter'] = filter + del config['filter'] + acc_code = config.get('acc_code', None) + if acc_code: + init_config['acc_code'] = acc_code + del config['acc_code'] + acc_mask = config.get('acc_mask', None) + if acc_mask: + init_config['acc_mask'] = acc_mask + del config['acc_mask'] + brp = config.get('brp', None) + if brp: + init_config['brp'] = brp + del config['brp'] + abit_timing = config.get('dbit_timing', None) + if abit_timing: + init_config['abit_timing'] = abit_timing + del config['abit_timing'] + dbit_timing = config.get('dbit_timing', None) + if dbit_timing: + init_config['dbit_timing'] = dbit_timing + del config['dbit_timing'] + + bitrate = config.get('bitrate', None) + if bitrate is None: + raise CanInitializationError('ZLG-CAN - bitrate is required.') + del config['bitrate'] + config['canfd_abit_baud_rate'] = bitrate + + data_bitrate = config.get('data_bitrate', None) + if data_bitrate is None: + config['canfd_dbit_baud_rate'] = bitrate + else: + del config['data_bitrate'] + config['canfd_dbit_baud_rate'] = data_bitrate + + self.device.SetValue(channel, **config) + self.device.InitCAN(channel, **init_config) + self.device.StartCAN(channel) + self.available.append(channel) + except ZCANException as e: + raise CanInitializationError(e) # def _apply_filters(self, filters: Optional[can.typechecking.CanFilters]) -> None: # pass @@ -282,19 +284,22 @@ def _recv_from_queue(self) -> Tuple[Message, bool]: return zlg_convert_msg(raw_msg, channel=channel), False def poll_received_messages(self, timeout): - for channel in self.available: - can_num = self.device.GetReceiveNum(channel, ZCANMessageType.CAN) - canfd_num = self.device.GetReceiveNum(channel, ZCANMessageType.CANFD) - if can_num: - LOG.debug(f'ZLG-CAN - can message received: {can_num}.') - self.rx_queue.extend( - (channel, raw_msg) for raw_msg in self.device.Receive(channel, can_num, timeout) - ) - if canfd_num: - LOG.debug(f'ZLG-CAN - canfd message received: {canfd_num}.') - self.rx_queue.extend( - (channel, raw_msg) for raw_msg in self.device.ReceiveFD(channel, canfd_num, timeout) - ) + try: + for channel in self.available: + can_num = self.device.GetReceiveNum(channel, ZCANMessageType.CAN) + canfd_num = self.device.GetReceiveNum(channel, ZCANMessageType.CANFD) + if can_num: + LOG.debug(f'ZLG-CAN - can message received: {can_num}.') + self.rx_queue.extend( + (channel, raw_msg) for raw_msg in self.device.Receive(channel, can_num, timeout) + ) + if canfd_num: + LOG.debug(f'ZLG-CAN - canfd message received: {canfd_num}.') + self.rx_queue.extend( + (channel, raw_msg) for raw_msg in self.device.ReceiveFD(channel, canfd_num, timeout) + ) + except ZCANException as e: + raise CanOperationError(e) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], bool]: @@ -314,19 +319,22 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], b return None, False def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: - channel = msg.channel - if channel not in self.available: - if len(self.available) == 0: - raise CanOperationError(f'Channel: {channel} not in {self.available}') - if channel is None: - channel = self.available[0] - is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False - if is_merge: - return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) - else: - if msg.is_fd: - return self.device.TransmitFD(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) - return self.device.Transmit(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + try: + channel = msg.channel + if channel not in self.available: + if len(self.available) == 0: + raise CanOperationError(f'Channel: {channel} not in {self.available}') + if channel is None: + channel = self.available[0] + is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False + if is_merge: + return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + else: + if msg.is_fd: + return self.device.TransmitFD(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + return self.device.Transmit(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + except ZCANException as e: + raise CanOperationError(e) @staticmethod def _detect_available_configs(): # -> List[can.typechecking.AutoDetectedConfig]: From 9633fd4e67a8abea3ac8b5239fde31a1f836161b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 11 Aug 2022 08:44:05 +0800 Subject: [PATCH 13/30] fix spell error. --- can/interfaces/__init__.py | 2 +- can/interfaces/tosun.py | 8 ++++---- can/interfaces/zlgcan.py | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/can/interfaces/__init__.py b/can/interfaces/__init__.py index 91163520f..49ab0b057 100644 --- a/can/interfaces/__init__.py +++ b/can/interfaces/__init__.py @@ -28,7 +28,7 @@ "etas": ("can.interfaces.etas", "EtasBus"), "socketcand": ("can.interfaces.socketcand", "SocketCanDaemonBus"), "zlgcan": ("can.interfaces.zlgcan", "ZCanBus"), - "tosun": ("can.interfaces.tosun", "TosuBus"), + "tosun": ("can.interfaces.tosun", "TosunBus"), } try: diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 301abbbbb..13701f404 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -1,7 +1,7 @@ import collections import time import warnings -from typing import List, Optional, Tuple, Any, Union +from typing import List, Optional, Tuple, Union, Deque, Any import can import can.typechecking @@ -132,7 +132,7 @@ def __init__(self, channel: Any = None, *, maxlen=rx_queue_size ) # type: Deque[Any] # channel, raw_msg except TSMasterException as e: - raise can.CanOperationError(e) + raise can.CanOperationError(str(e)) def _recv_from_queue(self) -> Tuple[can.Message, bool]: """Return a message from the internal receive queue""" @@ -207,7 +207,7 @@ def poll_received_messages(self, timeout): self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) except TSMasterException as e: - raise can.CanOperationError(e) + raise can.CanOperationError(str(e)) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: @@ -271,7 +271,7 @@ def shutdown(self) -> None: 'hw_chl_idx': TSChannelIndex.CHN1, 'hw_subtype': TSDeviceSubType.TC1016, 'hw_name': 'TC1016'} - with TosunBus([mapping, ], configs=[ + with TosunBus(mappings=[mapping, ], configs=[ {'bitrate': 500_000, 'initenal_resistance': 1} ], # with_com=True diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 88ca6db4c..74286abc8 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -272,7 +272,7 @@ def __init__(self, self.device.StartCAN(channel) self.available.append(channel) except ZCANException as e: - raise CanInitializationError(e) + raise CanInitializationError(str(e)) # def _apply_filters(self, filters: Optional[can.typechecking.CanFilters]) -> None: # pass @@ -299,7 +299,7 @@ def poll_received_messages(self, timeout): (channel, raw_msg) for raw_msg in self.device.ReceiveFD(channel, canfd_num, timeout) ) except ZCANException as e: - raise CanOperationError(e) + raise CanOperationError(str(e)) def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], bool]: @@ -334,7 +334,7 @@ def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: return self.device.TransmitFD(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) return self.device.Transmit(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) except ZCANException as e: - raise CanOperationError(e) + raise CanOperationError(str(e)) @staticmethod def _detect_available_configs(): # -> List[can.typechecking.AutoDetectedConfig]: From 2b56cd7012526aaa6e2dc7ea990519f16bf66071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sat, 13 Aug 2022 16:45:45 +0800 Subject: [PATCH 14/30] tosun drivce enable turbo mode by default --- can/interfaces/tosun.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 13701f404..20c7d8c93 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -67,7 +67,7 @@ def __init__(self, channel: Any = None, *, mappings: list[dict], configs: Union[List[dict], Tuple[dict]], fifo_status: str = 'enable', - turbo_enable: bool = False, + turbo_enable: bool = True, receive_own_messages=True, rx_queue_size: Optional[int] = None, can_filters: Optional[can.typechecking.CanFilters] = None, From c62a2866b109c89d2cce6ecd2adc9251d89540e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 25 Aug 2022 22:19:45 +0800 Subject: [PATCH 15/30] added clear_rx_buffer for tosun --- can/interfaces/tosun.py | 9 +++++++++ setup.cfg | 2 ++ 2 files changed, 11 insertions(+) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 20c7d8c93..4a078a790 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -209,6 +209,15 @@ def poll_received_messages(self, timeout): except TSMasterException as e: raise can.CanOperationError(str(e)) + def clear_rx_buffer(self, channel=None): + if channel: + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) + else: + for channel in self.available: + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) + self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) + def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message], bool]: if self.rx_queue: diff --git a/setup.cfg b/setup.cfg index b402ee645..1810ab12b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,4 +31,6 @@ exclude = |^can/interfaces/udp_multicast |^can/interfaces/usb2can |^can/interfaces/virtual + |^can/interfaces/tosun + |^can/interfaces/zlgcan ) From 063ead5111492bfea0e8d9137655c505757a7933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 25 Aug 2022 22:29:55 +0800 Subject: [PATCH 16/30] tosun: replace clear_rx_buffer call --- can/interfaces/tosun.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 4a078a790..164daefec 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -204,8 +204,7 @@ def poll_received_messages(self, timeout): self.rx_queue.extend( can_msg[i] for i in range(can_num) ) - self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN) - self.device.fifo_clear_receive_buffers(channel, TSMasterMessageType.CAN_FD) + self.clear_rx_buffer(channel) except TSMasterException as e: raise can.CanOperationError(str(e)) From 57433e3fece12d310be45439229eefb0c8a5ad66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Tue, 6 Sep 2022 18:11:32 +0800 Subject: [PATCH 17/30] fix some errors about zlgcan --- can/interfaces/zlgcan.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 74286abc8..a6df21172 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -226,31 +226,31 @@ def __init__(self, init_config = {} if platform.system().lower() == 'windows': mode = config.get('mode', None) - if mode: + if mode is not None: init_config['mode'] = mode del config['mode'] filter = config.get('filter', None) - if filter: + if filter is not None: init_config['filter'] = filter del config['filter'] acc_code = config.get('acc_code', None) - if acc_code: + if acc_code is not None: init_config['acc_code'] = acc_code del config['acc_code'] acc_mask = config.get('acc_mask', None) - if acc_mask: + if acc_mask is not None: init_config['acc_mask'] = acc_mask del config['acc_mask'] brp = config.get('brp', None) - if brp: + if brp is not None: init_config['brp'] = brp del config['brp'] - abit_timing = config.get('dbit_timing', None) - if abit_timing: + abit_timing = config.get('abit_timing', None) + if abit_timing is not None: init_config['abit_timing'] = abit_timing del config['abit_timing'] dbit_timing = config.get('dbit_timing', None) - if dbit_timing: + if dbit_timing is not None: init_config['dbit_timing'] = dbit_timing del config['dbit_timing'] @@ -266,8 +266,12 @@ def __init__(self, else: del config['data_bitrate'] config['canfd_dbit_baud_rate'] = data_bitrate - - self.device.SetValue(channel, **config) + if hasattr(self.device, 'SetValue'): + # try: + # self.device.SetValue(channel, **config) + # except ZCANException: + # pass + self.device.SetValue(channel, **config) self.device.InitCAN(channel, **init_config) self.device.StartCAN(channel) self.available.append(channel) From b3663efd66808a02800b209b0edb5f699a334b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Fri, 23 Sep 2022 21:20:51 +0800 Subject: [PATCH 18/30] tosun and zlgcan timestamp us -> ms --- can/interfaces/tosun.py | 6 +++--- can/interfaces/zlgcan.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 164daefec..e97ac8ae9 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -15,7 +15,7 @@ def tosun_convert_msg(msg): if isinstance(msg, TSCanMessage): return can.Message( - timestamp=msg.FTimeUs, + timestamp=msg.FTimeUs / 1000, arbitration_id=msg.FIdentifier, is_extended_id=msg.FProperties & 0x04, is_remote_frame=msg.FProperties & 0x02, @@ -27,7 +27,7 @@ def tosun_convert_msg(msg): ) elif isinstance(msg, TSCanFdMessage): return can.Message( - timestamp=msg.FTimeUs, + timestamp=msg.FTimeUs / 1000, arbitration_id=msg.FIdentifier, is_extended_id=msg.FProperties & 0x04, is_remote_frame=msg.FProperties & 0x02, @@ -53,7 +53,7 @@ def tosun_convert_msg(msg): (0x04 if msg.is_extended_id else 0x00) result.FDLC = msg.dlc result.FIdentifier = msg.arbitration_id - result.FTimeUs = int(msg.timestamp) + result.FTimeUs = int(msg.timestamp * 1000) for index, item in enumerate(msg.data): result.FData[index] = item return result diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index a6df21172..69645a7ec 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -108,7 +108,7 @@ def zlg_convert_msg(msg, **kwargs): # channel=None, trans channel = kwargs.get('channel', None) assert channel is not None, 'channel required when convert ZLG CAN msg to std msg.' return Message( - timestamp=msg.timestamp, + timestamp=msg.timestamp / 1000, arbitration_id=msg.frame.can_id, is_extended_id=msg.frame.eff, is_remote_frame=msg.frame.rtr, @@ -121,7 +121,7 @@ def zlg_convert_msg(msg, **kwargs): # channel=None, trans channel = kwargs.get('channel', None) assert channel is not None, 'channel required when convert ZLG CANFD msg to std msg.' return Message( - timestamp=msg.timestamp, + timestamp=msg.timestamp / 1000, arbitration_id=msg.frame.can_id, is_extended_id=msg.frame.eff, is_remote_frame=msg.frame.rtr, @@ -137,7 +137,7 @@ def zlg_convert_msg(msg, **kwargs): # channel=None, trans elif isinstance(msg, ZCANDataObj): # 合并接收CAN|CANFD报文转换 data = msg.data.zcanCANFDData return Message( - timestamp=data.timeStamp, + timestamp=data.timeStamp / 1000, arbitration_id=data.frame.can_id, is_extended_id=data.frame.eff, is_remote_frame=data.frame.rtr, From c64aaab4bbaddc677425aa2f5894bc30bee233e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 12 Oct 2022 11:58:10 +0800 Subject: [PATCH 19/30] adapt length and dlc for tosun device --- can/interfaces/tosun.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index e97ac8ae9..d50db225d 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -32,8 +32,8 @@ def tosun_convert_msg(msg): is_extended_id=msg.FProperties & 0x04, is_remote_frame=msg.FProperties & 0x02, channel=msg.FIdxChn, - dlc=msg.FDLC, - data=bytes(msg.FData), + dlc=can.util.dlc2len(msg.FDLC), + data=bytes(msg.FData)[:can.util.dlc2len(msg.FDLC)], is_fd=msg.FFDProperties & 0x01, is_rx=False if msg.FProperties & 0x01 else True, bitrate_switch=msg.FFDProperties & 0x02, @@ -51,7 +51,7 @@ def tosun_convert_msg(msg): result.FProperties = 0x00 | (0x00 if msg.is_rx else 0x01) | \ (0x02 if msg.is_remote_frame else 0x00) | \ (0x04 if msg.is_extended_id else 0x00) - result.FDLC = msg.dlc + result.FDLC = can.util.len2dlc(msg.dlc) result.FIdentifier = msg.arbitration_id result.FTimeUs = int(msg.timestamp * 1000) for index, item in enumerate(msg.data): From 938c80c73fe27ea29d5458deac2e22cc880da768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 12 Oct 2022 15:39:50 +0800 Subject: [PATCH 20/30] convert bit flag to bool value --- can/interfaces/tosun.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index d50db225d..c360a0a4a 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -17,8 +17,8 @@ def tosun_convert_msg(msg): return can.Message( timestamp=msg.FTimeUs / 1000, arbitration_id=msg.FIdentifier, - is_extended_id=msg.FProperties & 0x04, - is_remote_frame=msg.FProperties & 0x02, + is_extended_id=bool(msg.FProperties & 0x04), + is_remote_frame=bool(msg.FProperties & 0x02), channel=msg.FIdxChn, dlc=msg.FDLC, data=bytes(msg.FData), @@ -29,16 +29,16 @@ def tosun_convert_msg(msg): return can.Message( timestamp=msg.FTimeUs / 1000, arbitration_id=msg.FIdentifier, - is_extended_id=msg.FProperties & 0x04, - is_remote_frame=msg.FProperties & 0x02, + is_extended_id=bool(msg.FProperties & 0x04), + is_remote_frame=bool(msg.FProperties & 0x02), channel=msg.FIdxChn, dlc=can.util.dlc2len(msg.FDLC), data=bytes(msg.FData)[:can.util.dlc2len(msg.FDLC)], - is_fd=msg.FFDProperties & 0x01, + is_fd=bool(msg.FFDProperties & 0x01), is_rx=False if msg.FProperties & 0x01 else True, - bitrate_switch=msg.FFDProperties & 0x02, - error_state_indicator=msg.FFDProperties & 0x04, - is_error_frame=msg.FProperties & 0x80 + bitrate_switch=bool(msg.FFDProperties & 0x02), + error_state_indicator=bool(msg.FFDProperties & 0x04), + is_error_frame=bool(msg.FProperties & 0x80) ) elif isinstance(msg, can.Message): if msg.is_fd: From 97846e939adb79b65322f4cd4b8fb5ad1d40a507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Fri, 21 Oct 2022 17:54:44 +0800 Subject: [PATCH 21/30] fix tosun clear msg buffer --- can/interfaces/tosun.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index c360a0a4a..4782513e5 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -23,7 +23,7 @@ def tosun_convert_msg(msg): dlc=msg.FDLC, data=bytes(msg.FData), is_fd=False, - is_rx=False if msg.FProperties & 0x01 else True, + is_rx=not bool(msg.FProperties & 0x01), # False if msg.FProperties & 0x01 else True, ) elif isinstance(msg, TSCanFdMessage): return can.Message( @@ -35,7 +35,7 @@ def tosun_convert_msg(msg): dlc=can.util.dlc2len(msg.FDLC), data=bytes(msg.FData)[:can.util.dlc2len(msg.FDLC)], is_fd=bool(msg.FFDProperties & 0x01), - is_rx=False if msg.FProperties & 0x01 else True, + is_rx=not bool(msg.FProperties & 0x01), # False if msg.FProperties & 0x01 else True, bitrate_switch=bool(msg.FFDProperties & 0x02), error_state_indicator=bool(msg.FFDProperties & 0x04), is_error_frame=bool(msg.FProperties & 0x80) @@ -193,6 +193,7 @@ def poll_received_messages(self, timeout): can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, self.receive_own_messages, TSMasterMessageType.CAN_FD) + self.clear_rx_buffer(channel) LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') self.rx_queue.extend( can_msgfd[i] for i in range(canfd_num) @@ -200,11 +201,12 @@ def poll_received_messages(self, timeout): else: can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, TSMasterMessageType.CAN) + self.clear_rx_buffer(channel) LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') self.rx_queue.extend( can_msg[i] for i in range(can_num) ) - self.clear_rx_buffer(channel) + # self.clear_rx_buffer(channel) except TSMasterException as e: raise can.CanOperationError(str(e)) From b2fae2f11ee2d26f5ed9810a25eef7092ce84d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 10 Nov 2022 09:46:32 +0800 Subject: [PATCH 22/30] tosun device: delete can receive code snippet --- can/interfaces/tosun.py | 48 +++++++---------------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 4782513e5..3a15757ff 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -144,29 +144,8 @@ def _recv_from_queue(self) -> Tuple[can.Message, bool]: def poll_received_messages(self, timeout): try: for channel in self.available: - can_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN) canfd_num = self.device.fifo_read_buffer_count(channel, TSMasterMessageType.CAN_FD) if self.device.com_enabled: - # if can_num: - LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') - while can_num > 0: - can_num -= 1 - success, chl_index, is_remote, is_extend, dlc, can_id, timestamp, data = \ - self.device.fifo_receive_msg(channel, self.receive_own_messages, TSMasterMessageType.CAN) - if success: - self.rx_queue.append( - can.Message( - timestamp=timestamp, - arbitration_id=can_id, - is_extended_id=is_extend, - is_remote_frame=is_remote, - channel=chl_index, - dlc=dlc, - data=[int(i) for i in data.split(',')], - is_fd=False, - ) - ) - # if canfd_num: LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') while canfd_num > 0: canfd_num -= 1 @@ -188,25 +167,14 @@ def poll_received_messages(self, timeout): ) ) else: - if can_num or canfd_num: - if can_num < canfd_num: - can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, - self.receive_own_messages, - TSMasterMessageType.CAN_FD) - self.clear_rx_buffer(channel) - LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') - self.rx_queue.extend( - can_msgfd[i] for i in range(canfd_num) - ) - else: - can_msg, can_num = self.device.tsfifo_receive_msgs(channel, can_num, self.receive_own_messages, - TSMasterMessageType.CAN) - self.clear_rx_buffer(channel) - LOG.debug(f'TOSUN-CAN - can message received: {can_num}.') - self.rx_queue.extend( - can_msg[i] for i in range(can_num) - ) - # self.clear_rx_buffer(channel) + if canfd_num: + can_msgfd, canfd_num = self.device.tsfifo_receive_msgs(channel, canfd_num, + self.receive_own_messages, + TSMasterMessageType.CAN_FD) + LOG.debug(f'TOSUN-CAN - canfd message received: {canfd_num}.') + self.rx_queue.extend( + can_msgfd[i] for i in range(canfd_num) + ) except TSMasterException as e: raise can.CanOperationError(str(e)) From 42af86c29c1edb54073d6d5654112a18cd8f1e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 10 Nov 2022 11:20:54 +0800 Subject: [PATCH 23/30] tosun: fix hotplug can't receive message when tsmaster running --- can/interfaces/tosun.py | 1 + 1 file changed, 1 insertion(+) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 3a15757ff..b99ed66bd 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -230,6 +230,7 @@ def fileno(self) -> int: # self.device.tsapp_configure_can_register() def __enter__(self): + self.device.disconnect() return self def shutdown(self) -> None: From 42ce4a010ad4fe72d6c114494847c162f24803e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 17 Nov 2022 14:16:19 +0800 Subject: [PATCH 24/30] fix connect and disconnect logic error for tosun device --- can/interfaces/tosun.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index b99ed66bd..f534adce3 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -83,6 +83,7 @@ def __init__(self, channel: Any = None, *, kwargs['with_com'] = False try: self.device = TosunDevice(self.channels, **kwargs) + self.device.disconnect() count = self.device.channel_count('can', len(mappings)) assert count == len(mappings) self.available = [] @@ -230,7 +231,6 @@ def fileno(self) -> int: # self.device.tsapp_configure_can_register() def __enter__(self): - self.device.disconnect() return self def shutdown(self) -> None: From 6ecb50a9172e91442f452017fc5fe10cb18f8cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sat, 26 Nov 2022 11:22:01 +0800 Subject: [PATCH 25/30] fix unable to stopn when device.connect exception --- can/interfaces/tosun.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index f534adce3..ddf8b8108 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -123,7 +123,11 @@ def __init__(self, channel: Any = None, *, self.device.configure_baudrate(chl, **config) self.device.turbo_mode(turbo_enable) - self.device.connect() + try: + self.device.connect() + except TSMasterException as e: + self.device.finalize() + raise can.CanOperationError(str(e)) try: self.device.set_receive_fifo_status(fifo_status) except TSMasterException: From cbda76cca51e9767bcff422b70f5a1db1bb40d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Sat, 26 Nov 2022 11:37:59 +0800 Subject: [PATCH 26/30] fix unable to stopn when device.connect exception --- can/interfaces/tosun.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index ddf8b8108..adb53ed1f 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -123,11 +123,7 @@ def __init__(self, channel: Any = None, *, self.device.configure_baudrate(chl, **config) self.device.turbo_mode(turbo_enable) - try: - self.device.connect() - except TSMasterException as e: - self.device.finalize() - raise can.CanOperationError(str(e)) + self.device.connect() try: self.device.set_receive_fifo_status(fifo_status) except TSMasterException: @@ -137,6 +133,7 @@ def __init__(self, channel: Any = None, *, maxlen=rx_queue_size ) # type: Deque[Any] # channel, raw_msg except TSMasterException as e: + self.device.finalize() raise can.CanOperationError(str(e)) def _recv_from_queue(self) -> Tuple[can.Message, bool]: From 8e41eb1a84ad4ea87249db3f8fa928192cbd31e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Thu, 22 Dec 2022 11:47:30 +0800 Subject: [PATCH 27/30] fix invalid channel in message --- can/interfaces/tosun.py | 11 +++++++++-- can/interfaces/zlgcan.py | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index adb53ed1f..0778dedd5 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -6,8 +6,13 @@ import can import can.typechecking import ctypes -from can import CanInitializationError from can.bus import LOG +from can.exceptions import ( + CanError, + CanInterfaceNotImplementedError, + CanOperationError, + CanInitializationError, +) from tosun import TSCanMessage, TSCanFdMessage, TSMasterException, TosunDevice, TSMasterMessageType @@ -208,8 +213,10 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[can.Message def send(self, msg: can.Message, timeout: Optional[float] = 50, sync: bool = True) -> None: try: - if msg.channel is None: + if len(self.available) > 0 and msg.channel is None: msg.channel = self.available[0] + if msg.channel not in self.available: + raise CanOperationError(f'Channel: {msg.channel} not in {self.available}') msg = tosun_convert_msg(msg) self.device.transmit(msg, sync, timeout=timeout) except TSMasterException as e: diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 69645a7ec..11cc35dd1 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -325,11 +325,13 @@ def _recv_internal(self, timeout: Optional[float]) -> Tuple[Optional[Message], b def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: try: channel = msg.channel + # if channel not in self.available: + # if len(self.available) == 0: + # raise CanOperationError(f'Channel: {channel} not in {self.available}') + if len(self.available) > 0 and channel is None: + channel = self.available[0] if channel not in self.available: - if len(self.available) == 0: - raise CanOperationError(f'Channel: {channel} not in {self.available}') - if channel is None: - channel = self.available[0] + raise CanOperationError(f'Channel: {channel} not in {self.available}') is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False if is_merge: return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) From 670e2636a70350d1234ba899c38ee001e6c8fa31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Fri, 30 Dec 2022 14:16:01 +0800 Subject: [PATCH 28/30] fix zlgcan linux api --- can/interfaces/zlgcan.py | 116 ++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 44 deletions(-) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 11cc35dd1..254d42015 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -16,51 +16,76 @@ ) from typing import Optional, Tuple, Sequence, Union, Deque, Any from can import BusABC, Message -from zlgcan import ZCAN, ZCANDeviceType, ZCAN_Transmit_Data, ZCAN_TransmitFD_Data, ZCAN_Receive_Data, \ - ZCAN_ReceiveFD_Data, ZCANDataObj, ZCANException, ZCANMessageType, ZCANCanTransType +from zlgcan import ZCAN, ZCANDeviceType, ZCANException, ZCANMessageType, ZCANCanTransType logger = logging.getLogger(__name__) +_os = platform.system() -# AFTER_OPEN_DEVICE = [ -# 'tx_timeout', -# ] -# -# BEFORE_INIT_CAN = [ -# 'canfd_standard', -# 'protocol', -# 'canfd_abit_baud_rate', -# 'canfd_dbit_baud_rate', -# 'baud_rate_custom', -# ] -# -# AFTER_INIT_CAN = [ -# 'initenal_resistance', -# 'filter_mode', -# 'filter_start', -# 'filter_end', -# 'filter_ack', -# 'filter_clear', -# ] -# -# BEFOR_START_CAN = [ -# 'set_bus_usage_enable', -# 'set_bus_usage_period', -# ] -# -# AFTER_START_CAN = [ -# 'auto_send', -# 'auto_send_canfd', -# 'auto_send_param', -# 'clear_auto_send', -# 'apply_auto_send', -# 'set_send_mode', -# ] -ZCAN_Transmit_Data_1 = (ZCAN_Transmit_Data * 1) -ZCAN_TransmitFD_Data_1 = (ZCAN_TransmitFD_Data * 1) -ZCANDataObj_1 = (ZCANDataObj * 1) - - -def zlg_convert_msg(msg, **kwargs): # channel=None, trans_type=0, is_merge=False, **kwargs): + +def zlg_convert_msg(msg, **kwargs): + if _os.lower() == 'windows': + return _zlg_convert_msg_win(msg, **kwargs) + elif _os.lower() == 'linux': + return _zlg_convert_msg_linux(msg, **kwargs) + else: + raise ZCANException(f'Unsupported platform: {_os}') + + +def _zlg_convert_msg_linux(msg, **kwargs): + from zlgcan.linux import ZCAN_CAN_FRAME, ZCAN_CANFD_FRAME, ZCAN_MSG_HEADER, ZCAN_MSG_INFO + if isinstance(msg, Message): + trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL) + if msg.is_fd: + result = (ZCAN_CANFD_FRAME * 1)() + result[0].data = (ctypes.c_ubyte * 64)(*msg.data) + else: + result = (ZCAN_CAN_FRAME * 1)() + result[0].data = (ctypes.c_ubyte * msg.dlc)(*msg.data) + info = ZCAN_MSG_INFO() + info.mode = trans_type + info.is_fd = int(msg.is_fd) + info.is_remote = int(msg.is_remote_frame) + info.is_extend = int(msg.is_extended_id) + info.is_error = int(msg.is_error_frame) + info.bitrate_switch = int(msg.bitrate_switch) + info.error_status = int(msg.error_state_indicator) + + header = ZCAN_MSG_HEADER() + header.id = msg.arbitration_id + header.info = info + header.channel = msg.channel + header.dlc = msg.dlc + + result[0].header = header + + return result + elif isinstance(msg, (ZCAN_CAN_FRAME, ZCAN_CANFD_FRAME)): + header = msg.header + info = header.info + return Message( + timestamp=header.timestamp / 1000, + arbitration_id=header.id, + is_extended_id=bool(info.is_extend), + is_remote_frame=bool(info.is_remote), + is_error_frame=bool(info.is_error), + channel=header.channel, + dlc=header.dlc, + data=bytes(msg.data), + is_fd=bool(info.is_fd), + is_rx=True, + bitrate_switch=bool(info.bitrate_switch), + error_state_indicator=bool(info.error_status), + ) + else: + raise ZCANException(f'Unknown message type: {type(msg)}') + + +def _zlg_convert_msg_win(msg, **kwargs): # channel=None, trans_type=0, is_merge=False, **kwargs): + + from zlgcan.windows import ZCAN_Transmit_Data, ZCAN_TransmitFD_Data, ZCANDataObj, ZCAN_Receive_Data, ZCAN_ReceiveFD_Data + ZCAN_Transmit_Data_1 = (ZCAN_Transmit_Data * 1) + ZCAN_TransmitFD_Data_1 = (ZCAN_TransmitFD_Data * 1) + ZCANDataObj_1 = (ZCANDataObj * 1) if isinstance(msg, Message): # 发送报文转换 is_merge = kwargs.get('is_merge', None) @@ -175,7 +200,7 @@ def __init__(self, clock: [Optional] The clock of channel. bitrate: [Must] The arbitration phase baudrate. data_bitrate: [Optional] The data phase baudrate, default is baudrate. - initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable} + initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable}, default: 1 mode: [Optional] The can mode, defined in ZCANCanMode, default is NORMAL filter: [Optional] The filter mode, defined in ZCANCanFilter, default is DOUBLE acc_code: [Optional] The frame filter acceptance code of SJA1000. @@ -186,6 +211,7 @@ def __init__(self, Other property value: please see: https://manual.zlg.cn/web/#/152/6364->设备属性, with out head "n/". When the system is Linux, the config key is: clock: [Must] The clock of channel. + initenal_resistance: [Optional] the terminal resistance enable status, optional value{1:enable|0:disable}, default: 1 arb_tseg1: [Must] The phase buffer time segment1 of arbitration phase. arb_tseg2: [Must] The phase buffer time segment2 of arbitration phase. arb_sjw: [Must] The synchronization jump width of arbitration phase. @@ -224,7 +250,7 @@ def __init__(self, LOG.warn(f'ZLG-CAN - channel:{channel} not initialized.') return init_config = {} - if platform.system().lower() == 'windows': + if _os.lower() == 'windows': mode = config.get('mode', None) if mode is not None: init_config['mode'] = mode @@ -272,6 +298,8 @@ def __init__(self, # except ZCANException: # pass self.device.SetValue(channel, **config) + elif _os.lower() == 'linux': + init_config = config self.device.InitCAN(channel, **init_config) self.device.StartCAN(channel) self.available.append(channel) From 2422f952adeaf31cece36598f4225c2fb09dbc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Mon, 6 Feb 2023 08:58:52 +0800 Subject: [PATCH 29/30] fix __init__ bug --- can/interfaces/tosun.py | 4 ++-- can/interfaces/zlgcan.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/can/interfaces/tosun.py b/can/interfaces/tosun.py index 0778dedd5..f1727f583 100644 --- a/can/interfaces/tosun.py +++ b/can/interfaces/tosun.py @@ -106,8 +106,8 @@ def __init__(self, channel: Any = None, *, try: config: dict = configs[index] except IndexError: - LOG.warn(f'TOSUN-CAN - channel:{chl} not initialized.') - return + LOG.warning(f'TOSUN-CAN - channel:{chl} not initialized.') + continue bitrate = config.get('bitrate', None) if bitrate is None: diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 254d42015..87d9c5123 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -247,8 +247,8 @@ def __init__(self, try: config: dict = configs[index] except IndexError: - LOG.warn(f'ZLG-CAN - channel:{channel} not initialized.') - return + LOG.warning(f'ZLG-CAN - channel:{channel} not initialized.') + continue init_config = {} if _os.lower() == 'windows': mode = config.get('mode', None) From 6c029490201a15c46b515ba4de12e50335fb4252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E7=91=9C=20Yu=20Z?= Date: Wed, 15 Feb 2023 17:23:42 +0800 Subject: [PATCH 30/30] added resend flag for ZLG CAN device --- can/interfaces/zlgcan.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/can/interfaces/zlgcan.py b/can/interfaces/zlgcan.py index 87d9c5123..7d9d6321e 100644 --- a/can/interfaces/zlgcan.py +++ b/can/interfaces/zlgcan.py @@ -34,7 +34,7 @@ def zlg_convert_msg(msg, **kwargs): def _zlg_convert_msg_linux(msg, **kwargs): from zlgcan.linux import ZCAN_CAN_FRAME, ZCAN_CANFD_FRAME, ZCAN_MSG_HEADER, ZCAN_MSG_INFO if isinstance(msg, Message): - trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL) + trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL if kwargs.get('resend', False) else ZCANCanTransType.SINGLE) if msg.is_fd: result = (ZCAN_CANFD_FRAME * 1)() result[0].data = (ctypes.c_ubyte * 64)(*msg.data) @@ -89,7 +89,7 @@ def _zlg_convert_msg_win(msg, **kwargs): # channel=None, if isinstance(msg, Message): # 发送报文转换 is_merge = kwargs.get('is_merge', None) - trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL) + trans_type = kwargs.get('trans_type', ZCANCanTransType.NORMAL if kwargs.get('resend', False) else ZCANCanTransType.SINGLE) assert is_merge is not None, 'is_merge required when convert to ZLG.' # assert trans_type is not None, 'trans_type required when convert to ZLG.' if not is_merge: @@ -182,6 +182,7 @@ class ZCanBus(BusABC): def __init__(self, channel: Union[int, Sequence[int], str] = None, *, + resend: bool = False, device_type: ZCANDeviceType, device_index: int = 0, rx_queue_size: Optional[int] = None, @@ -191,6 +192,7 @@ def __init__(self, """ Init ZLG CAN Bus device. :param device_type: The device type in ZCANDeviceType. + :param resend: Auto resend when transmit fail until success if True :param channel: A channel list(such as [0, 1]) or str split by ","(such as "0, 1") index cont from 0. :param device_index: The ZLG device index, default 0. :param rx_queue_size: The size of received queue. @@ -235,7 +237,7 @@ def __init__(self, maxlen=rx_queue_size ) # type: Deque[Tuple[int, Any]] # channel, raw_msg try: - self.device = ZCAN() + self.device = ZCAN(resend) self.device.OpenDevice(device_type, device_index) self.channels = self.device.channels self.available = [] @@ -362,11 +364,11 @@ def send(self, msg: Message, timeout: Optional[float] = None, **kwargs) -> None: raise CanOperationError(f'Channel: {channel} not in {self.available}') is_merge = self.device.MergeEnabled() if hasattr(self.device, 'MergeEnabled') else False if is_merge: - return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + return self.device.TransmitData(zlg_convert_msg(msg, channel=channel, resend=self.device.resend, is_merge=is_merge, **kwargs), 1) else: if msg.is_fd: - return self.device.TransmitFD(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) - return self.device.Transmit(channel, zlg_convert_msg(msg, channel=channel, is_merge=is_merge, **kwargs), 1) + return self.device.TransmitFD(channel, zlg_convert_msg(msg, resend=self.device.resend, channel=channel, is_merge=is_merge, **kwargs), 1) + return self.device.Transmit(channel, zlg_convert_msg(msg, resend=self.device.resend, channel=channel, is_merge=is_merge, **kwargs), 1) except ZCANException as e: raise CanOperationError(str(e))