Skip to content

Commit

Permalink
gs_usb command-line support (and documentation updates and stability …
Browse files Browse the repository at this point in the history
…fixes) (#1790)

* gs_usb, doc: correct docs to indicate libusbK not libusb-win32

* gs_usb, interface: fix bug on second .start() by repeating in shutdown()

v2:
updates as per review #1790 (review) by @zariiii9003

* gs_usb, interface: set a default bitrate of 500k (like many other interfaces)

* gs_usb, interface: support this interface on command-line with e.g. can.logger by treating channel like index when all other arguments are missing

* gs_usb: improve docs, don't use dev reference before assignment as requested in review #1790 (review) by @zariiii9003

* gs_usb: fix bug in transmit when frame timestamp is set (causes failure to pack 64bit host timestamp into gs_usb field)
  • Loading branch information
BenGardiner authored Aug 10, 2024
1 parent d34b2d6 commit aeff58d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
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

0 comments on commit aeff58d

Please sign in to comment.