moved a bunch of garbage (things that have nothing to do in root) to _trash

This commit is contained in:
mia 2025-06-15 22:42:02 +02:00
parent d094982b2c
commit 3226ed29ec
2610 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,69 @@
.. include:: ../defs.rst
:mod:`eeprom` - EEPROM API
--------------------------
.. module :: pyftdi.eeprom
Quickstart
~~~~~~~~~~
Example: dump the EEPROM content
.. code-block:: python
# Instantiate an EEPROM manager
eeprom = FtdiEeprom()
# Select the FTDI device to access (the interface is mandatory but any
# valid interface for the device fits)
eeprom.open('ftdi://ftdi:2232h/1')
# Show the EEPROM content
eeprom.dump_config()
# Show the raw EEPROM content
from pyftdi.misc import hexdump
print(hexdump(eeprom.data))
Example: update the serial number
.. code-block:: python
# Instantiate an EEPROM manager
eeprom = FtdiEeprom()
# Select the FTDI device to access
eeprom.open('ftdi://ftdi:2232h/1')
# Change the serial number
eeprom.set_serial_number('123456')
# Commit the change to the EEPROM
eeprom.commit(dry_run=False)
Classes
~~~~~~~
.. autoclass :: FtdiEeprom
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: FtdiEepromError
Tests
~~~~~
.. code-block:: shell
# optional: specify an alternative FTDI device
export FTDI_DEVICE=ftdi://ftdi:2232h/1
PYTHONPATH=. python3 pyftdi/tests/eeprom.py

View file

@ -0,0 +1,26 @@
.. -*- coding: utf-8 -*-
.. include:: ../defs.rst
:mod:`ftdi` - FTDI low-level driver
-----------------------------------
.. module :: pyftdi.ftdi
This module implements access to the low level FTDI hardware. There are very
few reasons to use this module directly. Most of PyFtdi_ features are available
through the dedicated :doc:`APIs <index>`.
Classes
~~~~~~~
.. autoclass :: Ftdi
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: FtdiError
.. autoexception :: FtdiMpsseError
.. autoexception :: FtdiFeatureError

View file

@ -0,0 +1,56 @@
.. -*- coding: utf-8 -*-
.. include:: ../defs.rst
:mod:`gpio` - GPIO API
----------------------
.. module :: pyftdi.gpio
Direct drive GPIO pins of FTDI device.
.. note::
This mode is mutually exclusive with advanced serial MPSSE features, such as
|I2C|, SPI, JTAG, ...
If you need to use GPIO pins and MPSSE interface on the same port, you need
to use the dedicated API. This shared mode is supported with the
:doc:`SPI API <spi>` and the :doc:`I2C API <i2c>`.
.. warning::
This API does not provide access to the special CBUS port of FT232R, FT232H,
FT230X and FT231X devices. See :ref:`cbus_gpio` for details.
Quickstart
~~~~~~~~~~
See ``tests/gpio.py`` example
Classes
~~~~~~~
.. autoclass :: GpioPort
.. autoclass :: GpioAsyncController
:members:
.. autoclass :: GpioSyncController
:members:
.. autoclass :: GpioMpsseController
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: GpioException
Info about GPIO API
~~~~~~~~~~~~~~~~~~~
See :doc:`../gpio` for details

View file

@ -0,0 +1,191 @@
.. include:: ../defs.rst
:mod:`i2c` - |I2C| API
----------------------
.. module :: pyftdi.i2c
Quickstart
~~~~~~~~~~
Example: communication with an |I2C| GPIO expander
.. code-block:: python
# Instantiate an I2C controller
i2c = I2cController()
# Configure the first interface (IF/1) of the FTDI device as an I2C master
i2c.configure('ftdi://ftdi:2232h/1')
# Get a port to an I2C slave device
slave = i2c.get_port(0x21)
# Send one byte, then receive one byte
slave.exchange([0x04], 1)
# Write a register to the I2C slave
slave.write_to(0x06, b'\x00')
# Read a register from the I2C slave
slave.read_from(0x00, 1)
Example: mastering the |I2C| bus with a complex transaction
.. code-block:: python
from time import sleep
port = I2cController().get_port(0x56)
# emit a START sequence is read address, but read no data and keep the bus
# busy
port.read(0, relax=False)
# wait for ~1ms
sleep(0.001)
# write 4 bytes, without neither emitting the start or stop sequence
port.write(b'\x00\x01', relax=False, start=False)
# read 4 bytes, without emitting the start sequence, and release the bus
port.read(4, start=False)
See also pyi2cflash_ module and ``tests/i2c.py``, which provide more detailed
examples on how to use the |I2C| API.
Classes
~~~~~~~
.. autoclass :: I2cPort
:members:
.. autoclass :: I2cGpioPort
:members:
.. autoclass :: I2cController
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: I2cIOError
.. autoexception :: I2cNackError
.. autoexception:: I2cTimeoutError
GPIOs
~~~~~
See :doc:`../gpio` for details
Tests
~~~~~
|I2C| sample tests expect:
* TCA9555 device on slave address 0x21
* ADXL345 device on slave address 0x53
Checkout a fresh copy from PyFtdi_ github repository.
See :doc:`../pinout` for FTDI wiring.
.. code-block:: shell
# optional: specify an alternative FTDI device
export FTDI_DEVICE=ftdi://ftdi:2232h/1
# optional: increase log level
export FTDI_LOGLEVEL=DEBUG
# be sure to connect the appropriate I2C slaves to the FTDI I2C bus and run
PYTHONPATH=. python3 pyftdi/tests/i2c.py
.. _i2c_limitations:
Caveats
~~~~~~~
Open-collector bus
``````````````````
|I2C| uses only two bidirectional open collector (or open drain) lines, pulled
up with resistors. These resistors are also required on an |I2C| bus when an
FTDI master is used.
However, most FTDI devices do not use open collector outputs. Some software
tricks are used to fake open collector mode when possible, for example to
sample for slave ACK/NACK, but most communication (R/W, addressing, data)
cannot use open collector mode. This means that most FTDI devices source
current to the SCL and SDA lines. FTDI HW is able to cope with conflicting
signalling, where FTDI HW forces a line the high logical level while a slave
forces it to the low logical level, and limits the sourced current. You may
want to check your schematics if the slave is not able to handle 4 .. 16 mA
input current in SCL and SDA, for example. The maximal source current depends
on the FTDI device and the attached EEPROM configuration which may be used to
limit further down the sourced current.
Fortunately, FT232H device is fitted with real open collector outputs, and
PyFtdi always enable this mode on SCL and SDA lines when a FT232H device is
used.
Other FTDI devices such as FT2232H, FT4232H and FT4232HA do not support open
collector mode, and source current to SCL and SDA lines.
Clock streching
```````````````
Clock stretching is supported through a hack that re-uses the JTAG adaptative
clock mode designed for ARM devices. FTDI HW drives SCL on ``AD0`` (`BD0`), and
samples the SCL line on : the 8\ :sup:`th` pin of a port ``AD7`` (``BD7``).
When a FTDI device without an open collector capability is used
(FT2232H, FT4232H, FT4232HA) the current sourced from AD0 may prevent proper
sampling ofthe SCL line when the slave attempts to strech the clock. It is
therefore recommended to add a low forward voltage drop diode to `AD0` to
prevent AD0 to source current to the SCL bus. See the wiring section.
Speed
`````
Due to the FTDI MPSSE engine limitations, the actual bitrate for write
operations over I2C is very slow. As the I2C protocol enforces that each I2C
exchanged byte needs to be acknowledged by the peer, a I2C byte cannot be
written to the slave before the previous byte has been acknowledged by the
slave and read back by the I2C master, that is the host. This requires several
USB transfer for each byte, on top of each latency of the USB stack may add up.
With the introduction of PyFtdi_ v0.51, read operations have been optimized so
that long read operations are now much faster thanwith previous PyFtdi_
versions, and exhibits far shorter latencies.
Use of PyFtdi_ should nevetherless carefully studied and is not recommended if
you need to achieve medium to high speed write operations with a slave
(relative to the I2C clock...). Dedicated I2C master such as FT4222H device is
likely a better option, but is not currently supported with PyFtdi_ as it uses
a different communication protocol.
.. _i2c_wiring:
Wiring
~~~~~~
.. figure:: ../images/i2c_wiring.png
:scale: 50 %
:alt: I2C wiring
:align: right
Fig.1: FT2232H with clock stretching
* ``AD0`` should be connected to the SCL bus
* ``AD1`` and ``AD2`` should be both connected to the SDA bus
* ``AD7`` should be connected to the SCL bus, if clock streching is required
* remaining pins can be freely used as regular GPIOs.
*Fig.1*:
* ``D1`` is only required when clock streching is used along with
FT2232H, FT4232H or FT4232HA devices. It should not be fit with an FT232H.
* ``AD7`` may be used as a regular GPIO with clock stretching is not required.

View file

@ -0,0 +1,20 @@
API documentation
=================
.. include:: ../defs.rst
|release|
---------
.. toctree::
:maxdepth: 1
:glob:
ftdi
gpio
i2c
spi
uart
usbtools
misc
eeprom

View file

@ -0,0 +1,11 @@
.. -*- coding: utf-8 -*-
:mod:`misc` - Miscellaneous helpers
-----------------------------------
Functions
~~~~~~~~~
.. automodule:: pyftdi.misc
:members:

View file

@ -0,0 +1,203 @@
.. include:: ../defs.rst
:mod:`spi` - SPI API
--------------------
.. module :: pyftdi.spi
Quickstart
~~~~~~~~~~
Example: communication with a SPI data flash (half-duplex example)
.. code-block:: python
# Instantiate a SPI controller
spi = SpiController()
# Configure the first interface (IF/1) of the FTDI device as a SPI master
spi.configure('ftdi://ftdi:2232h/1')
# Get a port to a SPI slave w/ /CS on A*BUS3 and SPI mode 0 @ 12MHz
slave = spi.get_port(cs=0, freq=12E6, mode=0)
# Request the JEDEC ID from the SPI slave
jedec_id = slave.exchange([0x9f], 3)
Example: communication with a remote SPI device using full-duplex mode
.. code-block:: python
# Instantiate a SPI controller
# We need want to use A*BUS4 for /CS, so at least 2 /CS lines should be
# reserved for SPI, the remaining IO are available as GPIOs.
spi = SpiController(cs_count=2)
# Configure the first interface (IF/1) of the FTDI device as a SPI master
spi.configure('ftdi://ftdi:2232h/1')
# Get a port to a SPI slave w/ /CS on A*BUS4 and SPI mode 2 @ 10MHz
slave = spi.get_port(cs=1, freq=10E6, mode=2)
# Synchronous exchange with the remote SPI slave
write_buf = b'\x01\x02\x03'
read_buf = slave.exchange(write_buf, duplex=True)
Example: communication with a SPI device and an extra GPIO
.. code-block:: python
# Instantiate a SPI controller
spi = SpiController()
# Configure the first interface (IF/1) of the first FTDI device as a
# SPI master
spi.configure('ftdi://::/1')
# Get a SPI port to a SPI slave w/ /CS on A*BUS3 and SPI mode 0 @ 12MHz
slave = spi.get_port(cs=0, freq=12E6, mode=0)
# Get GPIO port to manage extra pins, use A*BUS4 as GPO, A*BUS4 as GPI
gpio = spi.get_gpio()
gpio.set_direction(0x30, 0x10)
# Assert GPO pin
gpio.write(0x10)
# Write to SPI slace
slave.write(b'hello world!')
# Release GPO pin
gpio.write(0x00)
# Test GPI pin
pin = bool(gpio.read() & 0x20)
Example: managing non-byte aligned transfers
.. code-block:: python
# Instantiate a SPI controller
spi = SpiController()
# Configure the first interface (IF/1) of the first FTDI device as a
# SPI master
spi.configure('ftdi://::/1')
# Get a SPI port to a SPI slave w/ /CS on A*BUS3
slave = spi.get_port(cs=0)
# write 6 first bits of a byte buffer
slave.write(b'\xff', droptail=2)
# read only 13 bits from a slave (13 clock cycles)
# only the 5 MSBs of the last byte are valid, 3 LSBs are force to zero
slave.read(2, droptail=3)
See also pyspiflash_ module and ``tests/spi.py``, which provide more detailed
examples on how to use the SPI API.
Classes
~~~~~~~
.. autoclass :: SpiPort
:members:
.. autoclass :: SpiGpioPort
:members:
.. autoclass :: SpiController
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: SpiIOError
GPIOs
~~~~~
See :doc:`../gpio` for details
Tests
~~~~~
SPI sample tests expect:
* MX25L1606E device on /CS 0, SPI mode 0
* ADXL345 device on /CS 1, SPI mode 2
* RFDA2125 device on /CS 2, SPI mode 0
Checkout a fresh copy from PyFtdi_ github repository.
See :doc:`../pinout` for FTDI wiring.
.. code-block:: shell
# optional: specify an alternative FTDI device
export FTDI_DEVICE=ftdi://ftdi:2232h/1
# optional: increase log level
export FTDI_LOGLEVEL=DEBUG
# be sure to connect the appropriate SPI slaves to the FTDI SPI bus and run
PYTHONPATH=. python3 pyftdi/tests/spi.py
.. _spi_limitations:
Limitations
~~~~~~~~~~~
SPI Modes 1 & 3
```````````````
FTDI hardware does not support cpha=1 (mode 1 and mode 3). As stated in
Application Node 114:
"*It is recommended that designers review the SPI Slave
data sheet to determine the SPI mode implementation. FTDI device can only
support mode 0 and mode 2 due to the limitation of MPSSE engine.*".
Support for mode 1 and mode 3 is implemented with some workarounds, but
generated signals may not be reliable: YMMV. It is only available with -H
series (232H, 2232H, 4232H, 4232HA).
The 3-clock phase mode which has initially be designed to cope with |I2C|
signalling is used to delay the data lines from the clock signals. A direct
consequence of this workaround is that SCLK duty cycle is not longer 50% but
25% (mode 1) or 75% (mode 3). Again, support for mode 1 and mode 3 should be
considered as a kludge, you've been warned.
Time-sensitive usage
````````````````````
Due to the MPSSE engine limitation, it is not possible to achieve
time-controlled request sequence. In other words, if the SPI slave needs to
receive command sequences at precise instants - for example ADC or DAC
devices - PyFtdi_ use is not recommended. This limitation is likely to apply
to any library that relies on FTDI device. The USB bus latency and the lack
of timestamped commands always add jitter and delays, with no easy known
workaround.
.. _spi_wiring:
Wiring
~~~~~~
.. figure:: ../images/spi_wiring.png
:scale: 50 %
:alt: SPI wiring
:align: right
Fig.1: FT2232H with two SPI slaves
* ``AD0`` should be connected to SCLK
* ``AD1`` should be connected to MOSI
* ``AD2`` should be connected to MISO
* ``AD3`` should be connected to the first slave /CS.
* ``AD4`` should be connected to the second slave /CS, if any
* remaining pins can be freely used as regular GPIOs.
*Fig.1*:
* ``AD4`` may be used as a regular GPIO if a single SPI slave is used
* ``AD5`` may be used as another /CS signal for a third slave, in this case
the first available GPIO is ``AD6``, etc.

View file

@ -0,0 +1,228 @@
.. include:: ../defs.rst
:mod:`serialext` - UART API
---------------------------
There is no dedicated module for the UART API, as PyFtdi_ acts as a backend of
the well-known pyserial_ module.
The pyserial_ backend module is implemented as the `serialext.protocol_ftdi`
module. It is not documented here as no direct call to this module is required,
as the UART client should use the regular pyserial_ API.
Usage
~~~~~
To enable PyFtdi_ as a pyserial_ backend, use the following import:
.. code-block:: python
import pyftdi.serialext
Then use
.. code-block:: python
pyftdi.serialext.serial_for_url(url, **options)
to open a pyserial_ serial port instance.
Quickstart
~~~~~~~~~~
.. code-block:: python
# Enable pyserial extensions
import pyftdi.serialext
# Open a serial port on the second FTDI device interface (IF/2) @ 3Mbaud
port = pyftdi.serialext.serial_for_url('ftdi://ftdi:2232h/2', baudrate=3000000)
# Send bytes
port.write(b'Hello World')
# Receive bytes
data = port.read(1024)
.. _uart_gpio:
GPIO access
~~~~~~~~~~~
UART mode, the primary function of FTDI \*232\* devices, is somewhat limited
when it comes to GPIO management, as opposed to alternative mode such as |I2C|,
SPI and JTAG. It is not possible to assign the unused pins of an UART mode to
arbitrary GPIO functions.
All the 8 lower pins of an UART port are dedicated to the UART function,
although most of them are seldomely used, as dedicated to manage a modem or a
legacy DCE_ device. Upper pins (b\ :sub:`7`\ ..b\ :sub:`15`\ ), on devices that
have ones, cannot be driven while UART port is enabled.
It is nevertheless possible to have limited access to the lower pins as GPIO,
with many limitations:
- the GPIO direction of each pin is hardcoded and cannot be changed
- GPIO pins cannot be addressed atomically: it is possible to read the state
of an input GPIO, or to change the state of an output GPIO, one after
another. This means than obtaining the state of several input GPIOs or
changing the state of several output GPIO at once is not possible.
- some pins cannot be used as GPIO is hardware flow control is enabled.
Keep in mind However that HW flow control with FTDI is not reliable, see the
:ref:`hardware_flow_control` section.
Accessing those GPIO pins is done through the UART extended pins, using their
UART assigned name, as PySerial port attributes. See the table below:
+---------------+------+-----------+-------------------------------+
| Bit | UART | Direction | API |
+===============+======+===========+===============================+
| b\ :sub:`0`\ | TX | Out | ``port.write(buffer)`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`1`\ | RX | In | ``buffer = port.read(count)`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`2`\ | RTS | Out | ``port.rts = state`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`3`\ | CTS | In | ``state = port.cts`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`4`\ | DTR | Out | ``port.dtr = state`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`5`\ | DSR | In | ``state = port.dsr`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`6`\ | DCD | In | ``state = port.dcd`` |
+---------------+------+-----------+-------------------------------+
| b\ :sub:`7`\ | RI | In | ``state = port.ri`` |
+---------------+------+-----------+-------------------------------+
CBUS support
````````````
Some FTDI devices (FT232R, FT232H, FT230X, FT231X) support additional CBUS
pins, which can be used as regular GPIOs pins. See :ref:`CBUS GPIO<cbus_gpio>`
for details.
.. _pyterm:
Mini serial terminal
~~~~~~~~~~~~~~~~~~~~
``pyterm.py`` is a simple serial terminal that can be used to test the serial
port feature. See the :ref:`tools` chapter to locate this tool.
::
Usage: pyterm.py [-h] [-f] [-b BAUDRATE] [-w] [-e] [-r] [-l] [-s] [-P VIDPID]
[-V VIRTUAL] [-v] [-d]
[device]
Simple Python serial terminal
positional arguments:
device serial port device name (default: ftdi:///1)
optional arguments:
-h, --help show this help message and exit
-f, --fullmode use full terminal mode, exit with [Ctrl]+B
-b BAUDRATE, --baudrate BAUDRATE
serial port baudrate (default: 115200)
-w, --hwflow hardware flow control
-e, --localecho local echo mode (print all typed chars)
-r, --crlf prefix LF with CR char, use twice to replace all LF
with CR chars
-l, --loopback loopback mode (send back all received chars)
-s, --silent silent mode
-P VIDPID, --vidpid VIDPID
specify a custom VID:PID device ID, may be repeated
-V VIRTUAL, --virtual VIRTUAL
use a virtual device, specified as YaML
-v, --verbose increase verbosity
-d, --debug enable debug mode
If the PyFtdi module is not yet installed and ``pyterm.py`` is run from the
archive directory, ``PYTHONPATH`` should be defined to the current directory::
PYTHONPATH=$PWD pyftdi/bin/pyterm.py ftdi:///?
The above command lists all the available FTDI device ports. To avoid conflicts
with some shells such as `zsh`, escape the `?` char as ``ftdi:///\?``.
To start up a serial terminal session, specify the FTDI port to use, for
example:
.. code-block:: shell
# detect all FTDI connected devices
PYTHONPATH=. python3 pyftdi/bin/ftdi_urls.py
# use the first interface of the first FT2232H as a serial port
PYTHONPATH=$PWD pyftdi/bin/pyterm.py ftdi://ftdi:2232/1
.. _uart-limitations:
Limitations
~~~~~~~~~~~
Although the FTDI H series are in theory capable of 12 MBps baudrate, baudrates
above 6 Mbps are barely usable.
See the following table for details.
+------------+-------------+------------+-------------+------------+--------+
| Requ. bps |HW capability| 9-bit time | Real bps | Duty cycle | Stable |
+============+=============+============+=============+============+========+
| 115.2 Kbps | 115.2 Kbps | 78.08 µs | 115.26 Kbps | 49.9% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 460.8 Kbps | 461.54 Kbps | 19.49 µs | 461.77 Kbps | 49.9% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 1 Mbps | 1 Mbps | 8.98 µs | 1.002 Mbps | 49.5% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 4 Mbps | 4 Mbps | 2.24 µs | 4.018 Mbps | 48% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 5 Mbps | 5.052 Mbps | 1.78 µs | 5.056 Mbps | 50% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 6 Mbps | 6 Mbps | 1.49 µs | 6.040 Mbps | 48.5% | Yes |
+------------+-------------+------------+-------------+------------+--------+
| 7 Mbps | 6.857 Mbps | 1.11 µs | 8.108 Mbps | 44% | No |
+------------+-------------+------------+-------------+------------+--------+
| 8 Mbps | 8 Mbps | 1.11 µs | 8.108 Mbps | 44%-48% | No |
+------------+-------------+------------+-------------+------------+--------+
| 8.8 Mbps | 8.727 Mbps | 1.13 µs | 7.964 Mbps | 44% | No |
+------------+-------------+------------+-------------+------------+--------+
| 9.6 Mbps | 9.6 Mbps | 1.12 µs | 8.036 Mbps | 48% | No |
+------------+-------------+------------+-------------+------------+--------+
| 10.5 Mbps | 10.667 Mbps | 1.11 µs | 8.108 Mbps | 44% | No |
+------------+-------------+------------+-------------+------------+--------+
| 12 Mbps | 12 Mbps | 0.75 µs | 12 Mbps | 43% | Yes |
+------------+-------------+------------+-------------+------------+--------+
* 9-bit time is the measured time @ FTDI output pins for a 8-bit character
(start bit + 8 bit data)
* Duty cycle is the ratio between a low-bit duration and a high-bit duration,
a good UART should exhibit the same duration for low bits and high bits,
*i.e.* a duty cycle close to 50%.
* Stability reports whether subsequent runs, with the very same HW settings,
produce the same timings.
Achieving a reliable connection over 6 Mbps has proven difficult, if not
impossible: Any baudrate greater than 6 Mbps (except the upper 12 Mbps limit)
results into an actual baudrate of about 8 Mbps, and suffer from clock
fluterring [7.95 .. 8.1Mbps].
.. _hardware_flow_control:
Hardware flow control
`````````````````````
Moreover, as the hardware flow control of the FTDI device is not a true HW
flow control. Quoting FTDI application note:
*If CTS# is logic 1 it is indicating the external device cannot accept more
data. the FTxxx will stop transmitting within 0~3 characters, depending on
what is in the buffer.*
**This potential 3 character overrun does occasionally present problems.**
*Customers shoud be made aware the FTxxx is a USB device and not a "normal"
RS232 device as seen on a PC. As such the device operates on a packet
basis as opposed to a byte basis.*

View file

@ -0,0 +1,19 @@
.. -*- coding: utf-8 -*-
:mod:`usbtools` - USB tools
---------------------------
.. module :: pyftdi.usbtools
Classes
~~~~~~~
.. autoclass :: UsbTools
:members:
Exceptions
~~~~~~~~~~
.. autoexception :: UsbToolsError