Skip to content

Commit 17f05d7

Browse files
authored
Merge branch 'develop' into feature/gs-usb-support
2 parents 751dfa4 + 72c4ac9 commit 17f05d7

File tree

9 files changed

+157
-36
lines changed

9 files changed

+157
-36
lines changed

.mergify.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
pull_request_rules:
2-
- name: Automatic merge on up to date branch with dual approval
2+
- name: Automatic merge passing PR on up to date branch with approving CR
33
conditions:
4-
- "#approved-reviews-by>=2"
4+
- "#approved-reviews-by>=1"
5+
- "#review-requested=0"
6+
- "#changes-requested-reviews-by=0"
7+
- "#commented-reviews-by=0"
58
- "status-success=continuous-integration/travis-ci/pr"
69
- "label!=work-in-progress"
710
actions:
811
merge:
912
method: merge
10-
strict: true
13+
strict: smart+fasttrack
14+
- name: Request Brian to review changes on core api.
15+
conditions:
16+
- "-files~=^can/interfaces/$"
17+
- "-closed"
18+
- "author!=hardbyte"
19+
actions:
20+
request_reviews:
21+
users:
22+
- hardbyte
23+
24+
- name: delete head branch after merge
25+
conditions:
26+
- merged
27+
actions:
28+
delete_head_branch: {}

README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ python-can
3737
:target: https://codecov.io/gh/hardbyte/python-can/branch/develop
3838
:alt: Test coverage reports on Codecov.io
3939

40+
.. image:: https://img.shields.io/endpoint.svg?url=https://gh.mergify.io/badges/hardbyte/python-can&style=flat
41+
:target: https://mergify.io
42+
:alt: Mergify Status
43+
4044
The **C**\ ontroller **A**\ rea **N**\ etwork is a bus standard designed
4145
to allow microcontrollers and devices to communicate with each other. It
4246
has priority based bus arbitration and reliable deterministic

can/interfaces/ixxat/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
Copyright (C) 2016 Giuseppe Corbelli <[email protected]>
55
"""
66

7-
from can.interfaces.ixxat.canlib import IXXATBus
7+
from can.interfaces.ixxat.canlib import IXXATBus, get_ixxat_hwids

can/interfaces/ixxat/canlib.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,22 @@ def _format_can_status(status_flags: int):
800800
return "CAN status message: {}".format(", ".join(states))
801801
else:
802802
return "Empty CAN status message"
803+
804+
805+
def get_ixxat_hwids():
806+
"""Get a list of hardware ids of all available IXXAT devices."""
807+
hwids = []
808+
device_handle = HANDLE()
809+
device_info = structures.VCIDEVICEINFO()
810+
811+
_canlib.vciEnumDeviceOpen(ctypes.byref(device_handle))
812+
while True:
813+
try:
814+
_canlib.vciEnumDeviceNext(device_handle, ctypes.byref(device_info))
815+
except StopIteration:
816+
break
817+
else:
818+
hwids.append(device_info.UniqueHardwareId.AsChar.decode("ascii"))
819+
_canlib.vciEnumDeviceClose(device_handle)
820+
821+
return hwids

can/interfaces/vector/canlib.py

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def __init__(
102102
:param int serial:
103103
Serial number of the hardware to be used.
104104
If set, the channel parameter refers to the channels ONLY on the specified hardware.
105-
If set, the app_name is unused.
105+
If set, the app_name does not have to be previously defined in Vector Hardware Config.
106106
:param bool fd:
107107
If CAN-FD frames should be supported.
108108
:param int data_bitrate:
@@ -175,7 +175,7 @@ def __init__(
175175
if app_name:
176176
# Get global channel index from application channel
177177
hw_type, hw_index, hw_channel = self.get_application_config(
178-
app_name, channel, xldefine.XL_BusTypes.XL_BUS_TYPE_CAN
178+
app_name, channel
179179
)
180180
LOG.debug("Channel index %d found", channel)
181181
idx = xldriver.xlGetChannelIndex(hw_type, hw_index, hw_channel)
@@ -609,19 +609,24 @@ def _detect_available_configs():
609609
):
610610
continue
611611
LOG.info(
612-
"Channel index %d: %s",
613-
channel_config.channelIndex,
614-
channel_config.name.decode("ascii"),
612+
"Channel index %d: %s", channel_config.channelIndex, channel_config.name
615613
)
616614
configs.append(
617615
{
616+
# data for use in VectorBus.__init__():
618617
"interface": "vector",
619-
"app_name": None,
620-
"channel": channel_config.channelIndex,
618+
"channel": channel_config.hwChannel,
619+
"serial": channel_config.serialNumber,
620+
# data for use in VectorBus.set_application_config():
621+
"hw_type": channel_config.hwType,
622+
"hw_index": channel_config.hwIndex,
623+
"hw_channel": channel_config.hwChannel,
624+
# additional information:
621625
"supports_fd": bool(
622-
channel_config.channelBusCapabilities
626+
channel_config.channelCapabilities
623627
& xldefine.XL_ChannelCapabilities.XL_CHANNEL_FLAG_CANFD_ISO_SUPPORT
624628
),
629+
"vector_channel_config": channel_config,
625630
}
626631
)
627632
return configs
@@ -637,16 +642,14 @@ def popup_vector_hw_configuration(wait_for_finish: int = 0) -> None:
637642

638643
@staticmethod
639644
def get_application_config(
640-
app_name: str, app_channel: int, bus_type: xldefine.XL_BusTypes
645+
app_name: str, app_channel: int
641646
) -> Tuple[xldefine.XL_HardwareType, int, int]:
642647
"""Retrieve information for an application in Vector Hardware Configuration.
643648
644649
:param app_name:
645650
The name of the application.
646651
:param app_channel:
647652
The channel of the application.
648-
:param bus_type:
649-
The bus type Enum e.g. `XL_BusTypes.XL_BUS_TYPE_CAN`
650653
:return:
651654
Returns a tuple of the hardware type, the hardware index and the
652655
hardware channel.
@@ -659,7 +662,12 @@ def get_application_config(
659662
hw_channel = ctypes.c_uint()
660663

661664
xldriver.xlGetApplConfig(
662-
app_name.encode(), app_channel, hw_type, hw_index, hw_channel, bus_type
665+
app_name.encode(),
666+
app_channel,
667+
hw_type,
668+
hw_index,
669+
hw_channel,
670+
xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
663671
)
664672
return xldefine.XL_HardwareType(hw_type.value), hw_index.value, hw_channel.value
665673

@@ -670,10 +678,19 @@ def set_application_config(
670678
hw_type: xldefine.XL_HardwareType,
671679
hw_index: int,
672680
hw_channel: int,
673-
bus_type: xldefine.XL_BusTypes,
681+
**kwargs,
674682
) -> None:
675683
"""Modify the application settings in Vector Hardware Configuration.
676684
685+
This method can also be used with a channel config dictionary::
686+
687+
import can
688+
from can.interfaces.vector import VectorBus
689+
690+
configs = can.detect_available_configs(interfaces=['vector'])
691+
cfg = configs[0]
692+
VectorBus.set_application_config(app_name="MyApplication", app_channel=0, **cfg)
693+
677694
:param app_name:
678695
The name of the application. Creates a new application if it does
679696
not exist yet.
@@ -687,12 +704,14 @@ def set_application_config(
687704
hardware type are present.
688705
:param hw_channel:
689706
The channel index of the interface.
690-
:param bus_type:
691-
The bus type of the interfaces, which should be
692-
XL_BusTypes.XL_BUS_TYPE_CAN for most cases.
693707
"""
694708
xldriver.xlSetApplConfig(
695-
app_name.encode(), app_channel, hw_type, hw_index, hw_channel, bus_type
709+
app_name.encode(),
710+
app_channel,
711+
hw_type,
712+
hw_index,
713+
hw_channel,
714+
xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
696715
)
697716

698717
def set_timer_rate(self, timer_rate_ms: int) -> None:
@@ -710,7 +729,23 @@ def set_timer_rate(self, timer_rate_ms: int) -> None:
710729
xldriver.xlSetTimerRate(self.port_handle, timer_rate_10us)
711730

712731

713-
def get_channel_configs() -> List[xlclass.XLchannelConfig]:
732+
class VectorChannelConfig(typing.NamedTuple):
733+
name: str
734+
hwType: xldefine.XL_HardwareType
735+
hwIndex: int
736+
hwChannel: int
737+
channelIndex: int
738+
channelMask: int
739+
channelCapabilities: xldefine.XL_ChannelCapabilities
740+
channelBusCapabilities: xldefine.XL_BusCapabilities
741+
isOnBus: bool
742+
connectedBusType: xldefine.XL_BusTypes
743+
serialNumber: int
744+
articleNumber: int
745+
transceiverName: str
746+
747+
748+
def get_channel_configs() -> List[VectorChannelConfig]:
714749
if xldriver is None:
715750
return []
716751
driver_config = xlclass.XLdriverConfig()
@@ -720,4 +755,28 @@ def get_channel_configs() -> List[xlclass.XLchannelConfig]:
720755
xldriver.xlCloseDriver()
721756
except VectorError:
722757
pass
723-
return [driver_config.channel[i] for i in range(driver_config.channelCount)]
758+
759+
channel_list: List[VectorChannelConfig] = []
760+
for i in range(driver_config.channelCount):
761+
xlcc: xlclass.XLchannelConfig = driver_config.channel[i]
762+
vcc = VectorChannelConfig(
763+
name=xlcc.name.decode(),
764+
hwType=xldefine.XL_HardwareType(xlcc.hwType),
765+
hwIndex=xlcc.hwIndex,
766+
hwChannel=xlcc.hwChannel,
767+
channelIndex=xlcc.channelIndex,
768+
channelMask=xlcc.channelMask,
769+
channelCapabilities=xldefine.XL_ChannelCapabilities(
770+
xlcc.channelCapabilities
771+
),
772+
channelBusCapabilities=xldefine.XL_BusCapabilities(
773+
xlcc.channelBusCapabilities
774+
),
775+
isOnBus=bool(xlcc.isOnBus),
776+
connectedBusType=xldefine.XL_BusTypes(xlcc.connectedBusType),
777+
serialNumber=xlcc.serialNumber,
778+
articleNumber=xlcc.articleNumber,
779+
transceiverName=xlcc.transceiverName.decode(),
780+
)
781+
channel_list.append(vcc)
782+
return channel_list

can/interfaces/vector/xldefine.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# Import Python Modules
66
# ==============================
7-
from enum import IntEnum
7+
from enum import IntEnum, IntFlag
88

99

1010
MAX_MSG_LEN = 8
@@ -22,7 +22,7 @@ class XL_AcceptanceFilter(IntEnum):
2222
XL_CAN_EXT = 2
2323

2424

25-
class XL_BusCapabilities(IntEnum):
25+
class XL_BusCapabilities(IntFlag):
2626
XL_BUS_COMPATIBLE_CAN = 1
2727
XL_BUS_ACTIVE_CAP_CAN = 65536
2828

@@ -35,8 +35,17 @@ class XL_BusStatus(IntEnum):
3535

3636

3737
class XL_BusTypes(IntEnum):
38-
XL_BUS_TYPE_NONE = 0
39-
XL_BUS_TYPE_CAN = 1
38+
XL_BUS_TYPE_NONE = 0 # =0x00000000
39+
XL_BUS_TYPE_CAN = 1 # =0x00000001
40+
XL_BUS_TYPE_LIN = 2 # =0x00000002
41+
XL_BUS_TYPE_FLEXRAY = 4 # =0x00000004
42+
XL_BUS_TYPE_AFDX = 8 # =0x00000008
43+
XL_BUS_TYPE_MOST = 16 # =0x00000010
44+
XL_BUS_TYPE_DAIO = 64 # =0x00000040
45+
XL_BUS_TYPE_J1708 = 256 # =0x00000100
46+
XL_BUS_TYPE_KLINE = 2048 # =0x00000800
47+
XL_BUS_TYPE_ETHERNET = 4096 # =0x00001000
48+
XL_BUS_TYPE_A429 = 8192 # =0x00002000
4049

4150

4251
class XL_CANFD_BusParams_CanOpMode(IntEnum):
@@ -97,7 +106,7 @@ class XL_CANFD_TX_MessageFlags(IntEnum):
97106
XL_CAN_TXMSG_FLAG_WAKEUP = 512
98107

99108

100-
class XL_ChannelCapabilities(IntEnum):
109+
class XL_ChannelCapabilities(IntFlag):
101110
XL_CHANNEL_FLAG_TIME_SYNC_RUNNING = 1
102111
XL_CHANNEL_FLAG_NO_HWSYNC_SUPPORT = 1024
103112
XL_CHANNEL_FLAG_SPDIF_CAPABLE = 16384
@@ -106,6 +115,10 @@ class XL_ChannelCapabilities(IntEnum):
106115
XL_CHANNEL_FLAG_CANFD_ISO_SUPPORT = 2147483648
107116

108117

118+
class XL_EventFlags(IntEnum):
119+
XL_EVENT_FLAG_OVERRUN = 1
120+
121+
109122
class XL_EventTags(IntEnum):
110123
XL_NO_COMMAND = 0
111124
XL_RECEIVE_MSG = 1
@@ -135,7 +148,6 @@ class XL_MessageFlags(IntEnum):
135148
XL_CAN_MSG_FLAG_TX_COMPLETED = 64
136149
XL_CAN_MSG_FLAG_TX_REQUEST = 128
137150
XL_CAN_MSG_FLAG_SRR_BIT_DOM = 512
138-
XL_EVENT_FLAG_OVERRUN = 1
139151

140152

141153
class XL_MessageFlagsExtended(IntEnum):
@@ -266,4 +278,6 @@ class XL_HardwareType(IntEnum):
266278
XL_HWTYPE_VN5430 = 109
267279
XL_HWTYPE_VN1530 = 112
268280
XL_HWTYPE_VN1531 = 113
269-
XL_MAX_HWTYPE = 113
281+
XL_HWTYPE_VX1161A = 114
282+
XL_HWTYPE_VX1161B = 115
283+
XL_MAX_HWTYPE = 119

doc/interfaces/ixxat.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ The can_id/mask must be specified according to IXXAT behaviour, that is
5353
bit 0 of can_id/mask parameters represents the RTR field in CAN frame. See IXXAT
5454
VCI documentation, section "Message filters" for more info.
5555

56+
List available devices
57+
-----------------
58+
In case you have connected multiple IXXAT devices, you have to select them by using their unique hardware id.
59+
To get a list of all connected IXXAT you can use the function ``get_ixxat_hwids()`` as demonstrated below:
60+
61+
>>> from can.interfaces.ixxat import get_ixxat_hwids
62+
>>> for hwid in get_ixxat_hwids(): print("Found IXXAT with hardware id '%s'." % hwid)
63+
Found IXXAT with hardware id 'HW441489'.
64+
Found IXXAT with hardware id 'HW107422'.
65+
5666

5767
Internals
5868
---------

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
# see https://www.python.org/dev/peps/pep-0345/#version-specifiers
8080
python_requires=">=3.6",
8181
install_requires=[
82+
# Setuptools provides pkg_resources which python-can makes use of.
83+
"setuptools",
8284
"wrapt~=1.10",
8385
'windows-curses;platform_system=="Windows"',
8486
"filelock",

test/test_vector.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,7 @@ def test_popup_hw_cfg(self) -> None:
249249

250250
def test_get_application_config(self) -> None:
251251
canlib.xldriver.xlGetApplConfig = Mock()
252-
canlib.VectorBus.get_application_config(
253-
app_name="CANalyzer",
254-
app_channel=0,
255-
bus_type=xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
256-
)
252+
canlib.VectorBus.get_application_config(app_name="CANalyzer", app_channel=0)
257253
assert canlib.xldriver.xlGetApplConfig.called
258254

259255
def test_set_application_config(self) -> None:
@@ -264,7 +260,6 @@ def test_set_application_config(self) -> None:
264260
hw_type=xldefine.XL_HardwareType.XL_HWTYPE_VN1610,
265261
hw_index=0,
266262
hw_channel=0,
267-
bus_type=xldefine.XL_BusTypes.XL_BUS_TYPE_CAN,
268263
)
269264
assert canlib.xldriver.xlSetApplConfig.called
270265

0 commit comments

Comments
 (0)