Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions can/interfaces/gs_usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GsUsbBus(can.BusABC):
def __init__(
self,
channel,
bitrate,
bitrate: int = 500_000,
index=None,
bus=None,
address=None,
Expand All @@ -33,18 +33,24 @@ def __init__(
:param can_filters: not supported
:param bitrate: CAN network bandwidth (bits/s)
"""
self._is_shutdown = False
if (index is not None) and ((bus or address) is not None):
raise CanInitializationError(
"index and bus/address cannot be used simultaneously"
)

if index is None and address is None and bus is None:
index = channel

self._index = None
if index is not None:
devs = GsUsb.scan()
if len(devs) <= index:
raise CanInitializationError(
f"Cannot find device {index}. Devices found: {len(devs)}"
)
gs_usb = devs[index]
self._index = index
else:
gs_usb = GsUsb.find(bus=bus, address=address)
if not gs_usb:
Expand All @@ -68,6 +74,7 @@ def __init__(
brp=bit_timing.brp,
)
self.gs_usb.start()
self._bitrate = bitrate

super().__init__(
channel=channel,
Expand Down Expand Up @@ -102,7 +109,7 @@ def send(self, msg: can.Message, timeout: Optional[float] = None):
frame = GsUsbFrame()
frame.can_id = can_id
frame.can_dlc = msg.dlc
frame.timestamp_us = int(msg.timestamp * 1000000)
frame.timestamp_us = 0 # timestamp frame field is only useful on receive
frame.data = list(msg.data)

try:
Expand Down Expand Up @@ -154,5 +161,21 @@ def _recv_internal(
return msg, False

def shutdown(self):
if self._is_shutdown:
return

super().shutdown()
self.gs_usb.stop()
if self._index is not None:
# Avoid errors on subsequent __init() by repeating the .scan() and .start() that would otherwise fail
# the next time the device is opened in __init__()
devs = GsUsb.scan()
if self._index < len(devs):
gs_usb = devs[self._index]
try:
gs_usb.set_bitrate(self._bitrate)
gs_usb.start()
gs_usb.stop()
except usb.core.USBError:
pass
self._is_shutdown = True
7 changes: 5 additions & 2 deletions doc/interfaces/gs_usb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ and candleLight USB CAN interfaces.

Install: ``pip install "python-can[gs_usb]"``

Usage: pass device ``index`` (starting from 0) if using automatic device detection:
Usage: pass device ``index`` or ``channel`` (starting from 0) if using automatic device detection:

::

import can
import usb
dev = usb.core.find(idVendor=0x1D50, idProduct=0x606F)

bus = can.Bus(interface="gs_usb", channel=dev.product, index=0, bitrate=250000)
bus = can.Bus(interface="gs_usb", channel=0, bitrate=250000) # same

Alternatively, pass ``bus`` and ``address`` to open a specific device. The parameters can be got by ``pyusb`` as shown below:

Expand Down Expand Up @@ -50,7 +53,7 @@ Windows, Linux and Mac.
``libusb`` must be installed.

On Windows a tool such as `Zadig <https://zadig.akeo.ie/>`_ can be used to set the USB device driver to
``libusb-win32``.
``libusbK``.


Supplementary Info
Expand Down