Skip to content

Commit 35c3fbb

Browse files
Shaoyuhardbyte
authored andcommitted
Added new interface: CANalystII interface
1 parent 69db2ec commit 35c3fbb

2 files changed

Lines changed: 112 additions & 1 deletion

File tree

can/interfaces/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
'virtual': ('can.interfaces.virtual', 'VirtualBus'),
2222
'neovi': ('can.interfaces.ics_neovi', 'NeoViBus'),
2323
'vector': ('can.interfaces.vector', 'VectorBus'),
24-
'slcan': ('can.interfaces.slcan', 'slcanBus')
24+
'slcan': ('can.interfaces.slcan', 'slcanBus'),
25+
'canalystii': ('can.interfaces.canalystii', 'CANalystIIBus')
2526
}
2627

2728
BACKENDS.update({

can/interfaces/canalystii.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from ctypes import *
2+
import logging
3+
import platform
4+
from can import BusABC, Message
5+
6+
logger = logging.getLogger(__name__)
7+
8+
9+
class VCI_INIT_CONFIG(Structure):
10+
_fields_ = [("AccCode", c_int32),
11+
("AccMask", c_int32),
12+
("Reserved", c_int32),
13+
("Filter", c_ubyte),
14+
("Timing0", c_ubyte),
15+
("Timing1", c_ubyte),
16+
("Mode", c_ubyte)]
17+
18+
19+
class VCI_CAN_OBJ(Structure):
20+
_fields_ = [("ID", c_uint),
21+
("TimeStamp", c_int),
22+
("TimeFlag", c_byte),
23+
("SendType", c_byte),
24+
("RemoteFlag", c_byte),
25+
("ExternFlag", c_byte),
26+
("DataLen", c_byte),
27+
("Data", c_ubyte * 8),
28+
("Reserved", c_byte * 3)]
29+
30+
31+
VCI_USBCAN2 = 4
32+
33+
STATUS_OK = 0x01
34+
STATUS_ERR = 0x00
35+
36+
try:
37+
if platform.system() == "Windows":
38+
CANalystII = WinDLL("./ControlCAN.dll")
39+
else:
40+
CANalystII = CDLL("./libcontrolcan.so")
41+
logger.info("Loaded CANalystII library")
42+
except OSError as e:
43+
CANalystII = None
44+
logger.info("Cannot load CANalystII library")
45+
46+
47+
class CANalystIIBus(BusABC):
48+
def __init__(self, channel, can_filters=None):
49+
super(CANalystIIBus, self).__init__(channel, can_filters)
50+
51+
if isinstance(channel, (list, tuple)):
52+
self.channels = channel
53+
elif isinstance(channel, int):
54+
self.channels = [channel]
55+
else:
56+
# Assume comma separated string of channels
57+
self.channels = [int(ch.strip()) for ch in channel.split(',')]
58+
59+
self.init_config = VCI_INIT_CONFIG(0, 0xFFFFFFFF, 0, 1, 0x00, 0x1C, 0)
60+
61+
if CANalystII.VCI_OpenDevice(VCI_USBCAN2, 0, 0) == STATUS_ERR:
62+
logger.error("VCI_OpenDevice Error")
63+
64+
for channel in self.channels:
65+
if CANalystII.VCI_InitCAN(VCI_USBCAN2, 0, channel, byref(self.init_config)) == STATUS_ERR:
66+
logger.error("VCI_InitCAN Error")
67+
self.shutdown()
68+
return
69+
70+
if CANalystII.VCI_StartCAN(VCI_USBCAN2, 0, channel) == STATUS_ERR:
71+
logger.error("VCI_StartCAN Error")
72+
self.shutdown()
73+
return
74+
75+
def send(self, msg, timeout=None):
76+
"""
77+
78+
:param msg: message to send
79+
:param timeout: timeout is not used here
80+
:return:
81+
"""
82+
raw_message = VCI_CAN_OBJ(msg.arbitration_id, 0, 0, 0, 0, 0, msg.dlc, (c_ubyte * 8)(*msg.data), (c_byte * 3)(*[0, 0, 0]))
83+
84+
if msg.channel is not None:
85+
channel = msg.channel
86+
elif len(self.channels) == 1:
87+
channel = self.channels[0]
88+
else:
89+
raise ValueError(
90+
"msg.channel must be set when using multiple channels.")
91+
92+
CANalystII.VCI_Transmit(VCI_USBCAN2, 0, channel, byref(raw_message), 1)
93+
94+
def _recv_internal(self, timeout=None):
95+
"""
96+
97+
:param timeout: float in seconds
98+
:return:
99+
"""
100+
raw_message = VCI_CAN_OBJ()
101+
102+
timeout = -1 if timeout is None else int(timeout * 1000)
103+
104+
if CANalystII.VCI_Receive(VCI_USBCAN2, 0, self.channels[0], byref(raw_message), 1, timeout) <= STATUS_ERR:
105+
return None, False
106+
else:
107+
return Message(arbitration_id=raw_message.ID, channel=0, data=raw_message.Data), False
108+
109+
def shutdown(self):
110+
CANalystII.VCI_CloseDevice(VCI_USBCAN2, 0)

0 commit comments

Comments
 (0)