Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f1646c0
After ACK, if reading next, make SDA an input to avoid shorts
henryay1 Feb 5, 2022
ee3f6c6
Merge branch 'eblot:master' into sda_input_after_read_ack
henryay1 Mar 11, 2022
135072a
Fake tri-state: After ACK, if reading next, make SDA an input to avoi…
henryay1 Feb 5, 2022
381546f
Simplify implementation
henryay1 Mar 15, 2022
5ad09be
Fix start address of CRC word (16 bit) when checking the remaining sp…
Kalofin May 5, 2022
051ccb2
i2c: relax the bus after epilog in fake-tristate mode
c0d3z3r0 Aug 14, 2022
73dfd82
Added -F option to force clock mode (needed to force enable I2C on FT…
tai Nov 6, 2022
5fab92a
Fix confusing typo
unixb0y Apr 25, 2023
1d6e154
Merge pull request #341 from unixb0y/patch-1
eblot Aug 5, 2023
3c0e8d1
Update setup syntax
eblot Aug 5, 2023
8654b6f
Support for FTDI FT4232HA added.
kornel-swierzy-embevity Aug 5, 2023
543fb4b
Fix line width
eblot Aug 5, 2023
d58a78b
Update GitHub actions for Python version and fix Sphinx RTD theme URL
eblot Aug 5, 2023
800fccb
Update Python requirements
eblot Aug 5, 2023
27a1e24
eeprom: fix regression introduced in #301
eblot Mar 14, 2022
6c65a72
eeprom: use f-strings
eblot Mar 14, 2022
579403f
eeprom: add more eeprom_mock tests to verify EEPROM mirroring works c…
eblot Mar 14, 2022
9e35192
version: update to 0.55.1
eblot Aug 12, 2023
e0342f5
Merge pull request #326 from tai/add-force-option-to-i2cscan
eblot Aug 12, 2023
9914488
Merge pull request #314 from c0d3z3r0/for-upstream/fake-tristate-relax
eblot Aug 12, 2023
f2f619c
Merge pull request #308 from Kalofin/fix-eeprom-strings
eblot Aug 12, 2023
0b5ed80
Merge pull request #290 from henryay1/sda_input_after_read_ack
eblot Aug 12, 2023
70f0ede
i2ctools: fix line width introduced w/ #326.
eblot Aug 12, 2023
9a46a30
doc: update contributors list
eblot Aug 12, 2023
dc970f7
.gitignore: ignore local virtual env
eblot Aug 12, 2023
9c84527
github: update checkout action version
eblot Aug 12, 2023
20d55e9
eeprom: improve tests
eblot Aug 12, 2023
35e5bb2
Revert "Merge pull request #308 from Kalofin/fix-eeprom-strings"
eblot Aug 12, 2023
0d20ccd
doc: update GitHub action badges
eblot Aug 12, 2023
ea4d2f5
Documentation fix of i2c docstrings
tapetersen Nov 29, 2023
14a901f
.github: run all CI sessions on PR
eblot Nov 29, 2023
d9233c4
Merge pull request #363 from eblot/dev/ebl/citweak
eblot Nov 29, 2023
5282c18
Merge pull request #362 from tapetersen/master
eblot Nov 29, 2023
4301823
eeprom: fix bug with setting single-bit options
romavis Feb 24, 2024
e68e4c3
eeprom: add support for some ft232h/ft2232h features
romavis Feb 24, 2024
28605c3
eeprom: update author & date
eblot Apr 5, 2024
8e1f4db
tests: use module_setup to establish virtual mock environment
markmentovai Aug 16, 2023
e2b4ac4
tests: don't present untestable base classes via pytest
markmentovai Aug 16, 2023
b06886a
eeprom: update author & date
eblot Apr 5, 2024
bee78e3
eeprom: add support for some ft4232h features
aleeraser Apr 4, 2024
9834c46
eeprom: update authors
eblot Apr 5, 2024
5ca35f4
pylint: create a global configuration file
eblot Apr 5, 2024
6b2c749
code cleanup
eblot Apr 6, 2024
aeebeea
.github: add PyLint linter to CI
eblot Apr 6, 2024
93954e2
add Python 3.12
eblot Apr 6, 2024
3d2fed8
unit tests: replace deprecated makeSuite method
eblot Apr 6, 2024
5f0f7c3
.gitlab: replace actions stuff with other actions stuff
eblot Apr 6, 2024
58d60a8
update doc date
eblot Apr 6, 2024
c0fdffd
fix a regression introduced in 6b2c74945
eblot Apr 10, 2024
327a1a7
bump version to v0.55.4
eblot Apr 10, 2024
426e1ab
tests: Fix for Python 3.13 (unittest.makeSuite was removed)
markmentovai Nov 4, 2024
acad347
pylint: address several issues that were not previously reported.
eblot Nov 19, 2024
a7a5f90
Merge pull request #391 from eblot/dev/ebl/pylint_issues
eblot Nov 19, 2024
2f9923c
Merge branch 'markmentovai-python_3.13_tests'
eblot Nov 19, 2024
3c78976
python: deprecated EOL'ed v3.8, add v3.13
eblot Nov 19, 2024
b0aefe7
Merge pull request #390 from eblot/dev/ebl/prep-py3.13
eblot Nov 19, 2024
bab0f5f
eeprom: Fall back to device version of type not set in eeprom
sjoerdsimons Nov 2, 2024
56e6afb
update contributors
eblot Nov 19, 2024
33fdb76
Merge pull request #393 from eblot/sjoerdsimons-guess-device
eblot Nov 19, 2024
0cc7909
bugfix(eeprom): make sure to close eeprom #394
Nov 20, 2024
74cff4d
Merge pull request #395 from NuQuantum/bugfix/eeprom_close
eblot Nov 23, 2024
075a734
.github: improve readability
eblot Nov 23, 2024
03c33be
.github: create PyPI workflow
eblot Nov 23, 2024
353c723
pylint: configure
eblot May 1, 2024
c228f72
Merge pull request #396 from eblot/dev/ebl/pypi
eblot Nov 23, 2024
556ce51
doc: update requirements and dependencies
eblot Nov 23, 2024
16398f3
Merge pull request #397 from eblot/dev/ebl/uprev_doc
eblot Nov 23, 2024
8d9a85c
Correct mistake in SPI API documentation example
MattHowardCT Mar 24, 2025
fa84913
i2c: fix reading >116 bytes with the non-optimized read path
dnschneid May 2, 2025
1c5176b
i2c: glitch high rather than low when tristating SCL+SDA
dnschneid May 7, 2025
88805dd
Merge pull request #412 from dnschneid/dev/david/i2c-nonoptim
eblot Aug 14, 2025
c692a47
i2c: avoid getting stuck due to adaptive clocking
dnschneid May 7, 2025
d8cf514
Merge pull request #413 from 'dev/david/adaptiveclkcfg'
eblot Aug 14, 2025
104bfe6
Merge pull request #414 from dnschneid/dev/david/i2cfaketristate
eblot Aug 14, 2025
38d0952
Merge pull request #407 from MattHowardCT/spi-api-doc-correction
eblot Aug 14, 2025
6ff4b5c
doc: update authors
eblot Aug 14, 2025
129c5cd
version: update to 0.57.0
eblot Aug 14, 2025
088c037
Merge pull request #423 from eblot/dev/ebl/v0.57
eblot Aug 14, 2025
998583b
version: update to 0.57.1
eblot Aug 14, 2025
3ff944e
Merge remote-tracking branch 'remotes/origin/upstream' into jplotzke/…
Mar 30, 2026
d1286fa
Fixing merge issues from original pyftdiwin
Mar 31, 2026
060123c
Replace fstring function from upstream library
Mar 31, 2026
a8fe6cb
Reducing function for lint test
Mar 31, 2026
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
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 80
47 changes: 47 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Publish to PyPI

on:
release:
types:
- published
workflow_dispatch:
inputs:
twine_verbose:
description: 'Enable Twine verbose mode'
required: true
type: boolean

jobs:
pypi-publish:
name: upload release to PyPI
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/pyftdi
permissions:
id-token: write
strategy:
matrix:
python-version: ['3.13']
steps:

- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel

- name: Build package
run: |
python setup.py bdist_wheel

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: ${{ inputs.twine_verbose }}
23 changes: 18 additions & 5 deletions .github/workflows/pythonchecksyntax.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
name: Python syntax tests
# check that there is no import issues with tool suite

on: [push]
on:
push:
pull_request:
types: [assigned, opened, synchronize, reopened]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install setuptools wheel ruamel.yaml
pip install -r test-requirements.txt

- name: Check style
run: |
python setup.py check_style

- name: Linter
run: |
pylint --disable=fixme --disable=duplicate-code \
$(git ls-files '*.py')

- name: Install package
run: |
python setup.py install

- name: Run tests
run: |
python pyftdi/tests/toolsimport.py
6 changes: 3 additions & 3 deletions .github/workflows/pythonmocktests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand Down
19 changes: 12 additions & 7 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
name: Python package

on: [push]
on:
push:
pull_request:
types: [assigned, opened, synchronize, reopened]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install setuptools wheel sphinx sphinx_autodoc_typehints
# Shpinx Read the Doc theme seems to never get a release w/ fixed issues
pip install -U -e git+https://github.com/readthedocs/sphinx_rtd_theme.git@2b8717a3647cc650625c566259e00305f7fb60aa#egg=sphinx_rtd_theme
pip install setuptools wheel sphinx sphinx_rtd_theme sphinx_autodoc_typehints

- name: Build package
run: |
python setup.py bdist
python setup.py sdist bdist_wheel

- name: Build documentation
run: |
mkdir doc
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build/
sphinx/
.vs/
.vscode/
.venv/
19 changes: 19 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[MASTER]

init-hook='import sys; sys.path.append(".")'

[MESSAGES CONTROL]

disable=
too-few-public-methods,
too-many-arguments,
too-many-branches,
too-many-instance-attributes,
too-many-lines,
too-many-locals,
too-many-nested-blocks,
too-many-positional-arguments,
too-many-public-methods,
too-many-return-statements,
too-many-statements,
unspecified-encoding
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2008-2021 Emmanuel Blot <emmanuel.blot@free.fr>
Copyright (c) 2008-2025 Emmanuel Blot <emmanuel.blot@free.fr>
All Rights Reserved.

SPDX-License-Identifier: BSD-3-Clause
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# PyFtdiWin


![Python package](https://github.com/mariusgreuel/pyftdiwin/workflows/Python%20package/badge.svg)
![Mock tests](https://github.com/mariusgreuel/pyftdiwin/workflows/Python%20mock%20tests/badge.svg)
![Syntax tests](https://github.com/mariusgreuel/pyftdiwin/workflows/Python%20syntax%20tests/badge.svg)

[![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine)

[![PyPI](https://img.shields.io/pypi/v/pyftdiwin.svg?maxAge=2592000)](https://pypi.org/project/pyftdiwin/)
Expand Down Expand Up @@ -44,6 +46,7 @@ Suported FTDI devices include:
* FT232H (single port, clock up to 30 MHz)
* FT2232H (dual port, clock up to 30 MHz)
* FT4232H (quad port, clock up to 30 MHz)
* FT4232HA (quad port, clock up to 30 MHz)

## Features

Expand Down Expand Up @@ -90,6 +93,6 @@ pip install pyftdiwin

### Python support

PyFtdi requires Python 3.7+.
PyFtdi requires Python 3.9+.

See `pyftdi/doc/requirements.rst` for more details.
10 changes: 5 additions & 5 deletions pyftdi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Copyright (c) 2010-2022 Emmanuel Blot <emmanuel.blot@free.fr>
# Copyright (c) 2010-2025 Emmanuel Blot <emmanuel.blot@free.fr>
# Copyright (c) 2010-2016, Neotion
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

#pylint: disable-msg=missing-docstring
# pylint: disable=missing-docstring

__version__ = '0.54.0'
__version__ = '0.57.1'
__title__ = 'PyFtdi'
__description__ = 'FTDI device driver (pure Python)'
__uri__ = 'http://github.com/eblot/pyftdi'
__doc__ = __description__ + ' <' + __uri__ + '>'
__author__ = 'Emmanuel Blot'
# For all support requests, please open a new issue on GitHub
__email__ = 'emmanuel.blot@free.fr'
__license__ = 'Modified BSD'
__copyright__ = 'Copyright (c) 2011-2021 Emmanuel Blot'
__license__ = 'BSD-3-Clause'
__copyright__ = 'Copyright (c) 2011-2025 Emmanuel Blot'


from logging import WARNING, NullHandler, getLogger
Expand Down
35 changes: 18 additions & 17 deletions pyftdi/bin/ftconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@
"""Simple FTDI EEPROM configurator.
"""

# Copyright (c) 2019-2022, Emmanuel Blot <emmanuel.blot@free.fr>
# Copyright (c) 2019-2024, Emmanuel Blot <emmanuel.blot@free.fr>
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

from argparse import ArgumentParser, FileType
from io import StringIO
from logging import Formatter, StreamHandler, DEBUG, ERROR
from sys import modules, stderr, stdout
from sys import exit as sys_exit, modules, stderr, stdout
from textwrap import fill
from traceback import format_exc
from pyftdi import FtdiLogger
from pyftdi.eeprom import FtdiEeprom
from pyftdi.ftdi import Ftdi
from pyftdi.misc import add_custom_devices, hexdump

#pylint: disable-msg=too-many-locals
#pylint: disable-msg=too-many-branches
#pylint: disable-msg=too-many-statements
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
# pylint: disable=too-many-statements


def main():
Expand Down Expand Up @@ -86,9 +86,9 @@ def main():

extra = argparser.add_argument_group(title='Extras')
extra.add_argument('-v', '--verbose', action='count', default=0,
help='increase verbosity')
help='increase verbosity')
extra.add_argument('-d', '--debug', action='store_true',
help='enable debug mode')
help='enable debug mode')
args = argparser.parse_args()
debug = args.debug

Expand All @@ -107,7 +107,7 @@ def main():
FtdiLogger.log.addHandler(StreamHandler(stderr))

if args.virtual:
#pylint: disable-msg=import-outside-toplevel
# pylint: disable=import-outside-toplevel
from pyftdi.usbtools import UsbTools
# Force PyUSB to use PyFtdi test framework for USB backends
UsbTools.BACKENDS = ('pyftdi.tests.backend.usbvirt', )
Expand Down Expand Up @@ -138,13 +138,12 @@ def main():
helpstr = ', '.join(sorted(eeprom.properties))
print(fill(helpstr, initial_indent=' ',
subsequent_indent=' '))
exit(1)
sys_exit(1)
for sep in ':=':
if sep in conf:
name, value = conf.split(sep, 1)
if not value:
argparser.error('Configuration %s without value' %
conf)
argparser.error(f'Configuration {conf} without value')
if value == 'help':
value = '?'
helpio = StringIO()
Expand All @@ -153,10 +152,10 @@ def main():
if helpstr:
print(fill(helpstr, initial_indent=' ',
subsequent_indent=' '))
exit(1)
sys_exit(1)
break
else:
argparser.error('Missing name:value separator in %s' % conf)
argparser.error(f'Missing name:value separator in {conf}')
if args.vid:
eeprom.set_property('vendor_id', args.vid)
if args.pid:
Expand All @@ -166,7 +165,7 @@ def main():
if args.hexblock is not None:
indent = ' ' * args.hexblock
for pos in range(0, len(eeprom.data), 16):
hexa = ' '.join(['%02x' % x for x in eeprom.data[pos:pos+16]])
hexa = ' '.join([f'{x:02x}' for x in eeprom.data[pos:pos+16]])
print(indent, hexa, sep='')
if args.update:
if eeprom.commit(False, no_crc=args.full_erase):
Expand All @@ -181,12 +180,14 @@ def main():
eeprom.save_config(ofp)

except (ImportError, IOError, NotImplementedError, ValueError) as exc:
print('\nError: %s' % exc, file=stderr)
print(f'\nError: {exc}', file=stderr)
if debug:
print(format_exc(chain=False), file=stderr)
exit(1)
sys_exit(1)
except KeyboardInterrupt:
exit(2)
sys_exit(2)
finally:
eeprom.close()


if __name__ == '__main__':
Expand Down
12 changes: 6 additions & 6 deletions pyftdi/bin/ftdi_urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

# Copyright (c) 2019-2022, Emmanuel Blot <emmanuel.blot@free.fr>
# Copyright (c) 2019-2024, Emmanuel Blot <emmanuel.blot@free.fr>
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
Expand All @@ -9,7 +9,7 @@

from argparse import ArgumentParser, FileType
from logging import Formatter, StreamHandler, DEBUG, ERROR
from sys import modules, stderr
from sys import exit as sys_exit, modules, stderr
from traceback import format_exc
from pyftdi import FtdiLogger
from pyftdi.ftdi import Ftdi
Expand Down Expand Up @@ -45,7 +45,7 @@ def main():
FtdiLogger.log.addHandler(StreamHandler(stderr))

if args.virtual:
#pylint: disable-msg=import-outside-toplevel
# pylint: disable=import-outside-toplevel
from pyftdi.usbtools import UsbTools
# Force PyUSB to use PyFtdi test framework for USB backends
UsbTools.BACKENDS = ('pyftdi.tests.backend.usbvirt', )
Expand All @@ -62,12 +62,12 @@ def main():
Ftdi.show_devices()

except (ImportError, IOError, NotImplementedError, ValueError) as exc:
print('\nError: %s' % exc, file=stderr)
print(f'\nError: {exc}', file=stderr)
if debug:
print(format_exc(chain=False), file=stderr)
exit(1)
sys_exit(1)
except KeyboardInterrupt:
exit(2)
sys_exit(2)


if __name__ == '__main__':
Expand Down
Loading
Loading