Skip to content

Commit 92f0d14

Browse files
authored
Merge pull request hardbyte#849 from zariiii9003/xlSetApplConfig
Add methods get_application_config(), set_application_config() and set_timer_rate() to VectorBus
2 parents 7601f22 + 0c5c259 commit 92f0d14

File tree

5 files changed

+252
-23
lines changed

5 files changed

+252
-23
lines changed

can/interfaces/vector/canlib.py

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import logging
1111
import time
1212
import os
13-
from typing import Optional, Tuple
13+
from typing import List, Optional, Tuple
1414

1515
import typing
1616

@@ -152,29 +152,19 @@ def __init__(
152152
for channel in self.channels:
153153
if app_name:
154154
# Get global channel index from application channel
155-
hw_type = ctypes.c_uint(0)
156-
hw_index = ctypes.c_uint(0)
157-
hw_channel = ctypes.c_uint(0)
158-
xldriver.xlGetApplConfig(
159-
self._app_name,
160-
channel,
161-
hw_type,
162-
hw_index,
163-
hw_channel,
164-
xldefine.XL_BusTypes.XL_BUS_TYPE_CAN.value,
155+
hw_type, hw_index, hw_channel = self.get_application_config(
156+
app_name, channel, xldefine.XL_BusTypes.XL_BUS_TYPE_CAN
165157
)
166158
LOG.debug("Channel index %d found", channel)
167-
idx = xldriver.xlGetChannelIndex(
168-
hw_type.value, hw_index.value, hw_channel.value
169-
)
159+
idx = xldriver.xlGetChannelIndex(hw_type.value, hw_index, hw_channel)
170160
if idx < 0:
171161
# Undocumented behavior! See issue #353.
172162
# If hardware is unavailable, this function returns -1.
173163
# Raise an exception as if the driver
174164
# would have signalled XL_ERR_HW_NOT_PRESENT.
175165
raise VectorError(
176166
xldefine.XL_Status.XL_ERR_HW_NOT_PRESENT.value,
177-
"XL_ERR_HW_NOT_PRESENT",
167+
xldefine.XL_Status.XL_ERR_HW_NOT_PRESENT.name,
178168
"xlGetChannelIndex",
179169
)
180170
else:
@@ -634,15 +624,99 @@ def popup_vector_hw_configuration(wait_for_finish: int = 0) -> None:
634624
"""
635625
xldriver.xlPopupHwConfig(ctypes.c_char_p(), ctypes.c_uint(wait_for_finish))
636626

627+
@staticmethod
628+
def get_application_config(
629+
app_name: str, app_channel: int, bus_type: xldefine.XL_BusTypes
630+
) -> Tuple[xldefine.XL_HardwareType, int, int]:
631+
"""Retrieve information for an application in Vector Hardware Configuration.
632+
633+
:param app_name:
634+
The name of the application.
635+
:param app_channel:
636+
The channel of the application.
637+
:param bus_type:
638+
The bus type Enum e.g. `XL_BusTypes.XL_BUS_TYPE_CAN`
639+
:return:
640+
Returns a tuple of the hardware type, the hardware index and the
641+
hardware channel.
642+
:raises VectorError:
643+
Raises a VectorError when the application name does not exist in
644+
Vector Hardware Configuration.
645+
"""
646+
hw_type = ctypes.c_uint()
647+
hw_index = ctypes.c_uint()
648+
hw_channel = ctypes.c_uint()
649+
650+
xldriver.xlGetApplConfig(
651+
app_name.encode(),
652+
app_channel,
653+
hw_type,
654+
hw_index,
655+
hw_channel,
656+
bus_type.value,
657+
)
658+
return xldefine.XL_HardwareType(hw_type.value), hw_index.value, hw_channel.value
659+
660+
@staticmethod
661+
def set_application_config(
662+
app_name: str,
663+
app_channel: int,
664+
hw_type: xldefine.XL_HardwareType,
665+
hw_index: int,
666+
hw_channel: int,
667+
bus_type: xldefine.XL_BusTypes,
668+
) -> None:
669+
"""Modify the application settings in Vector Hardware Configuration.
670+
671+
:param app_name:
672+
The name of the application. Creates a new application if it does
673+
not exist yet.
674+
:param app_channel:
675+
The channel of the application.
676+
:param hw_type:
677+
The hardware type of the interface.
678+
E.g XL_HardwareType.XL_HWTYPE_VIRTUAL
679+
:param hw_index:
680+
The index of the interface if multiple interface with the same
681+
hardware type are present.
682+
:param hw_channel:
683+
The channel index of the interface.
684+
:param bus_type:
685+
The bus type of the interfaces, which should be
686+
XL_BusTypes.XL_BUS_TYPE_CAN for most cases.
687+
"""
688+
xldriver.xlSetApplConfig(
689+
app_name.encode(),
690+
app_channel,
691+
hw_type.value,
692+
hw_index,
693+
hw_channel,
694+
bus_type.value,
695+
)
696+
697+
def set_timer_rate(self, timer_rate_ms: int) -> None:
698+
"""Set the cyclic event rate of the port.
699+
700+
Once set, the port will generate a cyclic event with the tag XL_EventTags.XL_TIMER.
701+
This timer can be used to keep an application alive. See XL Driver Library Description
702+
for more information
703+
704+
:param timer_rate_ms:
705+
The timer rate in ms. The minimal timer rate is 1ms, a value of 0 deactivates
706+
the timer events.
707+
"""
708+
timer_rate_10us = timer_rate_ms * 100
709+
xldriver.xlSetTimerRate(self.port_handle, timer_rate_10us)
710+
637711

638-
def get_channel_configs():
712+
def get_channel_configs() -> List[xlclass.XLchannelConfig]:
639713
if xldriver is None:
640714
return []
641715
driver_config = xlclass.XLdriverConfig()
642716
try:
643717
xldriver.xlOpenDriver()
644718
xldriver.xlGetDriverConfig(driver_config)
645719
xldriver.xlCloseDriver()
646-
except Exception:
720+
except VectorError:
647721
pass
648722
return [driver_config.channel[i] for i in range(driver_config.channelCount)]

can/interfaces/vector/xlclass.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
XLstatus = ctypes.c_short
1919
XLportHandle = ctypes.c_long
2020
XLeventTag = ctypes.c_ubyte
21+
XLstringType = ctypes.c_char_p
22+
2123

2224
# structure for XL_RECEIVE_MSG, XL_TRANSMIT_MSG
2325
class s_xl_can_msg(ctypes.Structure):

can/interfaces/vector/xldefine.py

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class XL_CANFD_RX_MessageFlags(Enum):
8484

8585

8686
class XL_CANFD_TX_EventTags(Enum):
87-
XL_CAN_EV_TAG_TX_MSG = 1088
87+
XL_CAN_EV_TAG_TX_MSG = 1088 # =0x0440
88+
XL_CAN_EV_TAG_TX_ERRFR = 1089 # =0x0441
8889

8990

9091
class XL_CANFD_TX_MessageFlags(Enum):
@@ -158,13 +159,111 @@ class XL_Sizes(Enum):
158159

159160

160161
class XL_Status(Enum):
161-
XL_SUCCESS = 0
162-
XL_PENDING = 1
163-
XL_ERR_QUEUE_IS_EMPTY = 10
164-
XL_ERR_HW_NOT_PRESENT = 129
162+
XL_SUCCESS = 0 # =0x0000
163+
XL_PENDING = 1 # =0x0001
164+
XL_ERR_QUEUE_IS_EMPTY = 10 # =0x000A
165+
XL_ERR_QUEUE_IS_FULL = 11 # =0x000B
166+
XL_ERR_TX_NOT_POSSIBLE = 12 # =0x000C
167+
XL_ERR_NO_LICENSE = 14 # =0x000E
168+
XL_ERR_WRONG_PARAMETER = 101 # =0x0065
169+
XL_ERR_TWICE_REGISTER = 110 # =0x006E
170+
XL_ERR_INVALID_CHAN_INDEX = 111 # =0x006F
171+
XL_ERR_INVALID_ACCESS = 112 # =0x0070
172+
XL_ERR_PORT_IS_OFFLINE = 113 # =0x0071
173+
XL_ERR_CHAN_IS_ONLINE = 116 # =0x0074
174+
XL_ERR_NOT_IMPLEMENTED = 117 # =0x0075
175+
XL_ERR_INVALID_PORT = 118 # =0x0076
176+
XL_ERR_HW_NOT_READY = 120 # =0x0078
177+
XL_ERR_CMD_TIMEOUT = 121 # =0x0079
178+
XL_ERR_HW_NOT_PRESENT = 129 # =0x0081
179+
XL_ERR_NOTIFY_ALREADY_ACTIVE = 131 # =0x0083
180+
XL_ERR_NO_RESOURCES = 152 # =0x0098
181+
XL_ERR_WRONG_CHIP_TYPE = 153 # =0x0099
182+
XL_ERR_WRONG_COMMAND = 154 # =0x009A
183+
XL_ERR_INVALID_HANDLE = 155 # =0x009B
184+
XL_ERR_RESERVED_NOT_ZERO = 157 # =0x009D
185+
XL_ERR_INIT_ACCESS_MISSING = 158 # =0x009E
186+
XL_ERR_CANNOT_OPEN_DRIVER = 201 # =0x00C9
187+
XL_ERR_WRONG_BUS_TYPE = 202 # =0x00CA
188+
XL_ERR_DLL_NOT_FOUND = 203 # =0x00CB
189+
XL_ERR_INVALID_CHANNEL_MASK = 204 # =0x00CC
190+
XL_ERR_NOT_SUPPORTED = 205 # =0x00CD
191+
XL_ERR_CONNECTION_BROKEN = 210 # =0x00D2
192+
XL_ERR_CONNECTION_CLOSED = 211 # =0x00D3
193+
XL_ERR_INVALID_STREAM_NAME = 212 # =0x00D4
194+
XL_ERR_CONNECTION_FAILED = 213 # =0x00D5
195+
XL_ERR_STREAM_NOT_FOUND = 214 # =0x00D6
196+
XL_ERR_STREAM_NOT_CONNECTED = 215 # =0x00D7
197+
XL_ERR_QUEUE_OVERRUN = 216 # =0x00D8
198+
XL_ERROR = 255 # =0x00FF
199+
200+
# CAN FD Error Codes
201+
XL_ERR_INVALID_DLC = 513 # =0x0201
202+
XL_ERR_INVALID_CANID = 514 # =0x0202
203+
XL_ERR_INVALID_FDFLAG_MODE20 = 515 # =0x203
204+
XL_ERR_EDL_RTR = 516 # =0x204
205+
XL_ERR_EDL_NOT_SET = 517 # =0x205
206+
XL_ERR_UNKNOWN_FLAG = 518 # =0x206
165207

166208

167209
class XL_TimeSyncNewValue(Enum):
168210
XL_SET_TIMESYNC_NO_CHANGE = 0
169211
XL_SET_TIMESYNC_ON = 1
170212
XL_SET_TIMESYNC_OFF = 2
213+
214+
215+
class XL_HardwareType(Enum):
216+
XL_HWTYPE_NONE = 0
217+
XL_HWTYPE_VIRTUAL = 1
218+
XL_HWTYPE_CANCARDX = 2
219+
XL_HWTYPE_CANAC2PCI = 6
220+
XL_HWTYPE_CANCARDY = 12
221+
XL_HWTYPE_CANCARDXL = 15
222+
XL_HWTYPE_CANCASEXL = 21
223+
XL_HWTYPE_CANCASEXL_LOG_OBSOLETE = 23
224+
XL_HWTYPE_CANBOARDXL = 25
225+
XL_HWTYPE_CANBOARDXL_PXI = 27
226+
XL_HWTYPE_VN2600 = 29
227+
XL_HWTYPE_VN2610 = XL_HWTYPE_VN2600
228+
XL_HWTYPE_VN3300 = 37
229+
XL_HWTYPE_VN3600 = 39
230+
XL_HWTYPE_VN7600 = 41
231+
XL_HWTYPE_CANCARDXLE = 43
232+
XL_HWTYPE_VN8900 = 45
233+
XL_HWTYPE_VN8950 = 47
234+
XL_HWTYPE_VN2640 = 53
235+
XL_HWTYPE_VN1610 = 55
236+
XL_HWTYPE_VN1630 = 57
237+
XL_HWTYPE_VN1640 = 59
238+
XL_HWTYPE_VN8970 = 61
239+
XL_HWTYPE_VN1611 = 63
240+
XL_HWTYPE_VN5610 = 65
241+
XL_HWTYPE_VN5620 = 66
242+
XL_HWTYPE_VN7570 = 67
243+
XL_HWTYPE_IPCLIENT = 69
244+
XL_HWTYPE_IPSERVER = 71
245+
XL_HWTYPE_VX1121 = 73
246+
XL_HWTYPE_VX1131 = 75
247+
XL_HWTYPE_VT6204 = 77
248+
XL_HWTYPE_VN1630_LOG = 79
249+
XL_HWTYPE_VN7610 = 81
250+
XL_HWTYPE_VN7572 = 83
251+
XL_HWTYPE_VN8972 = 85
252+
XL_HWTYPE_VN0601 = 87
253+
XL_HWTYPE_VN5640 = 89
254+
XL_HWTYPE_VX0312 = 91
255+
XL_HWTYPE_VH6501 = 94
256+
XL_HWTYPE_VN8800 = 95
257+
XL_HWTYPE_IPCL8800 = 96
258+
XL_HWTYPE_IPSRV8800 = 97
259+
XL_HWTYPE_CSMCAN = 98
260+
XL_HWTYPE_VN5610A = 101
261+
XL_HWTYPE_VN7640 = 102
262+
XL_HWTYPE_VX1135 = 104
263+
XL_HWTYPE_VN4610 = 105
264+
XL_HWTYPE_VT6306 = 107
265+
XL_HWTYPE_VT6104A = 108
266+
XL_HWTYPE_VN5430 = 109
267+
XL_HWTYPE_VN1530 = 112
268+
XL_HWTYPE_VN1531 = 113
269+
XL_MAX_HWTYPE = 113

can/interfaces/vector/xldriver.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# ctypes wrapping for API functions
2828
xlGetErrorString = _xlapi_dll.xlGetErrorString
2929
xlGetErrorString.argtypes = [xlclass.XLstatus]
30-
xlGetErrorString.restype = ctypes.c_char_p
30+
xlGetErrorString.restype = xlclass.XLstringType
3131

3232

3333
def check_status(result, function, arguments):
@@ -63,6 +63,18 @@ def check_status(result, function, arguments):
6363
xlGetApplConfig.restype = xlclass.XLstatus
6464
xlGetApplConfig.errcheck = check_status
6565

66+
xlSetApplConfig = _xlapi_dll.xlSetApplConfig
67+
xlSetApplConfig.argtypes = [
68+
ctypes.c_char_p,
69+
ctypes.c_uint,
70+
ctypes.c_uint,
71+
ctypes.c_uint,
72+
ctypes.c_uint,
73+
ctypes.c_uint,
74+
]
75+
xlSetApplConfig.restype = xlclass.XLstatus
76+
xlSetApplConfig.errcheck = check_status
77+
6678
xlGetChannelIndex = _xlapi_dll.xlGetChannelIndex
6779
xlGetChannelIndex.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int]
6880
xlGetChannelIndex.restype = ctypes.c_int
@@ -234,3 +246,16 @@ def check_status(result, function, arguments):
234246
xlPopupHwConfig.argtypes = [ctypes.c_char_p, ctypes.c_uint]
235247
xlPopupHwConfig.restype = xlclass.XLstatus
236248
xlPopupHwConfig.errcheck = check_status
249+
250+
xlSetTimerRate = _xlapi_dll.xlSetTimerRate
251+
xlSetTimerRate.argtypes = [xlclass.XLportHandle, ctypes.c_ulong]
252+
xlSetTimerRate.restype = xlclass.XLstatus
253+
xlSetTimerRate.errcheck = check_status
254+
255+
xlGetEventString = _xlapi_dll.xlGetEventString
256+
xlGetEventString.argtypes = [ctypes.POINTER(xlclass.XLevent)]
257+
xlGetEventString.restype = xlclass.XLstringType
258+
259+
xlCanGetEventString = _xlapi_dll.xlCanGetEventString
260+
xlCanGetEventString.argtypes = [ctypes.POINTER(xlclass.XLcanRxEvent)]
261+
xlCanGetEventString.restype = xlclass.XLstringType

test/test_vector.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,35 @@ def test_popup_hw_cfg(self) -> None:
249249
assert isinstance(args[0], ctypes.c_char_p)
250250
assert isinstance(args[1], ctypes.c_uint)
251251

252+
def test_get_application_config(self) -> None:
253+
canlib.xldriver.xlGetApplConfig = Mock()
254+
canlib.VectorBus.get_application_config(
255+
app_name="CANalyzer",
256+
app_channel=0,
257+
bus_type=xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
258+
)
259+
assert canlib.xldriver.xlGetApplConfig.called
260+
261+
def test_set_application_config(self) -> None:
262+
canlib.xldriver.xlSetApplConfig = Mock()
263+
canlib.VectorBus.set_application_config(
264+
app_name="CANalyzer",
265+
app_channel=0,
266+
hw_type=xldefine.XL_HardwareType.XL_HWTYPE_VN1610,
267+
hw_index=0,
268+
hw_channel=0,
269+
bus_type=xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
270+
)
271+
assert canlib.xldriver.xlSetApplConfig.called
272+
273+
def test_set_timer_rate(self) -> None:
274+
canlib.xldriver.xlSetTimerRate = Mock()
275+
bus: canlib.VectorBus = can.Bus(
276+
channel=0, bustype="vector", fd=True, _testing=True
277+
)
278+
bus.set_timer_rate(timer_rate_ms=1)
279+
assert canlib.xldriver.xlSetTimerRate.called
280+
252281
def test_called_without_testing_argument(self) -> None:
253282
"""This tests if an exception is thrown when we are not running on Windows."""
254283
if os.name != "nt":

0 commit comments

Comments
 (0)