PyD2XX 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyd2xx-0.0.1/LICENSE +19 -0
- pyd2xx-0.0.1/PKG-INFO +33 -0
- pyd2xx-0.0.1/README.md +17 -0
- pyd2xx-0.0.1/pyproject.toml +38 -0
- pyd2xx-0.0.1/src/PyD2XX/FTD2XX.dll +0 -0
- pyd2xx-0.0.1/src/PyD2XX/FTD2XX_32.dll +0 -0
- pyd2xx-0.0.1/src/PyD2XX/FTD2XX_ARM.dll +0 -0
- pyd2xx-0.0.1/src/PyD2XX/Licenses/FTDI DRIVER LICENSE.txt +150 -0
- pyd2xx-0.0.1/src/PyD2XX/Licenses/PyD2XX LICENSE.txt +21 -0
- pyd2xx-0.0.1/src/PyD2XX/PyD2XX.py +404 -0
- pyd2xx-0.0.1/src/PyD2XX/__init__.py +3 -0
- pyd2xx-0.0.1/src/PyD2XX/libftd2xx.dylib +0 -0
- pyd2xx-0.0.1/src/PyD2XX/libftd2xx.so +0 -0
- pyd2xx-0.0.1/src/PyD2XX/libftd2xx_32.so +0 -0
- pyd2xx-0.0.1/src/PyD2XX/libftd2xx_ARM.so +0 -0
- pyd2xx-0.0.1/src/PyD2XX/libftd2xx_ARM_32.so +0 -0
pyd2xx-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2024 Hector Soto
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
pyd2xx-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: PyD2XX
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Python wrapper for the FTDI D@XX library.
|
|
5
|
+
Keywords: FTDI,ftdichip,PyD2XX,D2XX,FTD2XX
|
|
6
|
+
Author-Email: Hector Soto <hector.soto@ftdichip.com>
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Project-URL: GitHub_Repo, https://github.com/S-Hector/PyD3XX
|
|
11
|
+
Project-URL: FTDI_Homepage, https://ftdichip.com/
|
|
12
|
+
Project-URL: FTDI_D3XX_Drivers, https://ftdichip.com/drivers/d2xx-drivers/
|
|
13
|
+
Project-URL: D2XX_Programming_Guide, https://ftdichip.com/wp-content/uploads/2025/06/D2XX_Programmers_Guide.pdf
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# PyD2XX
|
|
18
|
+
A Python wrapper for the FTDI D2XX library.
|
|
19
|
+
PyD2XX will eventually support Windows, Linux, and MacOS.
|
|
20
|
+
Most D2XX dynamic library variants are included in this package, so you don't need to include them directly in your project!
|
|
21
|
+
\^You don't need and should not have any D2XX .dll, .dylib, or .so file in your script's directory.
|
|
22
|
+
This was designed so the user needs zero ctypes knowledge and not need to import anything besides PyD2XX to interact with D2XX devices. The user should never have to interact with a ctypes object or method.
|
|
23
|
+
|
|
24
|
+
## Documentation
|
|
25
|
+
None yet! This is still in extremely early development mainly as a test.
|
|
26
|
+
While the MAJOR version is 0, this is considered incomplete and not a full translation of the D2XX library to Python.
|
|
27
|
+
The API and behavior can change at any time until the MAJOR version is 1.
|
|
28
|
+
You should use PyFTDI instead: https://github.com/eblot/pyftdi
|
|
29
|
+
|
|
30
|
+
## Licensing
|
|
31
|
+
The PyD2XX package is licensed under MIT.
|
|
32
|
+
The underlying D2XX libraries distributed with this package fall under FTDI's license.
|
|
33
|
+
FTDI's License: https://ftdichip.com/driver-licence-terms-details/
|
pyd2xx-0.0.1/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# PyD2XX
|
|
2
|
+
A Python wrapper for the FTDI D2XX library.
|
|
3
|
+
PyD2XX will eventually support Windows, Linux, and MacOS.
|
|
4
|
+
Most D2XX dynamic library variants are included in this package, so you don't need to include them directly in your project!
|
|
5
|
+
\^You don't need and should not have any D2XX .dll, .dylib, or .so file in your script's directory.
|
|
6
|
+
This was designed so the user needs zero ctypes knowledge and not need to import anything besides PyD2XX to interact with D2XX devices. The user should never have to interact with a ctypes object or method.
|
|
7
|
+
|
|
8
|
+
## Documentation
|
|
9
|
+
None yet! This is still in extremely early development mainly as a test.
|
|
10
|
+
While the MAJOR version is 0, this is considered incomplete and not a full translation of the D2XX library to Python.
|
|
11
|
+
The API and behavior can change at any time until the MAJOR version is 1.
|
|
12
|
+
You should use PyFTDI instead: https://github.com/eblot/pyftdi
|
|
13
|
+
|
|
14
|
+
## Licensing
|
|
15
|
+
The PyD2XX package is licensed under MIT.
|
|
16
|
+
The underlying D2XX libraries distributed with this package fall under FTDI's license.
|
|
17
|
+
FTDI's License: https://ftdichip.com/driver-licence-terms-details/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"pdm-backend",
|
|
4
|
+
]
|
|
5
|
+
build-backend = "pdm.backend"
|
|
6
|
+
|
|
7
|
+
[tool.pdm.build]
|
|
8
|
+
includes = [
|
|
9
|
+
"src/PyD2XX/",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
[project]
|
|
13
|
+
name = "PyD2XX"
|
|
14
|
+
version = "0.0.1"
|
|
15
|
+
authors = [
|
|
16
|
+
{ name = "Hector Soto", email = "hector.soto@ftdichip.com" },
|
|
17
|
+
]
|
|
18
|
+
description = "A Python wrapper for the FTDI D@XX library."
|
|
19
|
+
readme = "README.md"
|
|
20
|
+
requires-python = ">=3.10"
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
]
|
|
26
|
+
keywords = [
|
|
27
|
+
"FTDI",
|
|
28
|
+
"ftdichip",
|
|
29
|
+
"PyD2XX",
|
|
30
|
+
"D2XX",
|
|
31
|
+
"FTD2XX",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
GitHub_Repo = "https://github.com/S-Hector/PyD3XX"
|
|
36
|
+
FTDI_Homepage = "https://ftdichip.com/"
|
|
37
|
+
FTDI_D3XX_Drivers = "https://ftdichip.com/drivers/d2xx-drivers/"
|
|
38
|
+
D2XX_Programming_Guide = "https://ftdichip.com/wp-content/uploads/2025/06/D2XX_Programmers_Guide.pdf"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
The D2XX library files fall under FTDI's license: https://ftdichip.com/driver-licence-terms-details/
|
|
2
|
+
FTDI LICENSE:
|
|
3
|
+
[
|
|
4
|
+
Driver Licence Terms – Details
|
|
5
|
+
IMPORTANT NOTICE: PLEASE READ CAREFULLY BEFORE INSTALLING THE RELEVANT SOFTWARE: This licence agreement (“Licence”) is a legal agreement between you (“Licencee” or “you”) and Future Technology Devices International Limited of 2 Seaward Place, Centurion Business Park, Glasgow, Scotland, G41 1HH (UK Company Number SC136640) (“Licensor” or “we) for use of driver software provided by the Licensor (“Software”).
|
|
6
|
+
|
|
7
|
+
BY INSTALLING OR USING THIS SOFTWARE YOU AGREE TO THE TERMS OF THIS LICENCE WHICH WILL BIND YOU. IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, WE ARE UNWILLING TO LICENSE THE SOFTWARE TO YOU AND YOU MUST DISCONTINUE INSTALLATION OF THE SOFTWARE NOW.
|
|
8
|
+
|
|
9
|
+
1. Grant and scope of licence
|
|
10
|
+
|
|
11
|
+
1.1 In consideration of you agreeing to abide by the terms of this Licence, the Licensor hereby grants to you a non-exclusive, non-transferable, royalty free licence to use the Software on the terms of this Licence.
|
|
12
|
+
|
|
13
|
+
1.2 In this Licence a “Genuine FTDI Component” means an item of hardware that was manufactured for, and sold by, the Licensor or a member of the Licensor’s group of companies. It does not include any counterfeit or fake products.
|
|
14
|
+
|
|
15
|
+
1.3 If you are a manufacturer of a device that includes a Genuine FTDI Component (each a “Device“) then you may install the Software onto that device. If you are a seller or distributor of a Device then You may distribute the Software with the Device. If you are a user of a Device then you may install the Software on the Device, or onto a computer system in order to use the Device.
|
|
16
|
+
|
|
17
|
+
1.4 In each of those cases you may:
|
|
18
|
+
|
|
19
|
+
1.4.1 Install and use the Software for your purposes only; and
|
|
20
|
+
|
|
21
|
+
1.4.2 Only use the Software in conjunction with products based on and/or incorporating a Genuine FTDI Component.
|
|
22
|
+
|
|
23
|
+
1.5 The Software will not function properly on or with a component that is not a Genuine FTDI Component. Use of the Software as a driver for, or installation of the Software onto, a component that is not a Genuine FTDI Component, including without limitation counterfeit components, MAY IRRETRIEVABLY DAMAGE THAT COMPONENT. It is the Licensee’s responsibility to make sure that all chips it installs the Software on, or uses the Software as a driver for, are Genuine FTDI Components. If in doubt then contact the Licensor.
|
|
24
|
+
|
|
25
|
+
2. If a custom vendor ID and/or product ID or description string are used, it is the responsibility of the product manufacturer to maintain any changes and subsequent WHQL re-certification as a result of making these changes.
|
|
26
|
+
|
|
27
|
+
3. Licensee’s undertakings
|
|
28
|
+
|
|
29
|
+
3.1 Except as expressly set out in this Licence or as permitted by any local law, you undertake:
|
|
30
|
+
|
|
31
|
+
3.1.1 not to copy the Software, except where such copying is incidental to normal use of the Software or where it is necessary for the purpose of back-up or operational security;
|
|
32
|
+
|
|
33
|
+
3.1.2 not to rent, lease, sub-license, loan, translate, merge, adapt, vary or modify the Software or any part of it;
|
|
34
|
+
|
|
35
|
+
3.1.3 not to make alterations to, or modifications of, the whole or any part of the Software nor permit the Software or any part of it to be combined with, or become incorporated in, any other programs;
|
|
36
|
+
|
|
37
|
+
3.1.4 not to disassemble, de-compile, reverse engineer or create derivative works based on the whole or any part of the Software;
|
|
38
|
+
|
|
39
|
+
3.1.5 to keep all copies of the Software secure;
|
|
40
|
+
|
|
41
|
+
3.1.6 to include the copyright notice of the Licensor on all entire and partial copies of the Software in any form; and
|
|
42
|
+
|
|
43
|
+
3.1.7 not to provide, or otherwise make available, the Software in any form, in whole or in part (including, but not limited to, program listings, object and source program listings, object code and source code) to any person.
|
|
44
|
+
|
|
45
|
+
4. Intellectual property rights
|
|
46
|
+
|
|
47
|
+
4.1 You acknowledge that all intellectual property rights in the Software throughout the world belong to the Licensor, that rights in the Software are licensed (not sold) to you, and that you have no rights in, or to, the Software other than the right to use them in accordance with the terms of this Licence.
|
|
48
|
+
|
|
49
|
+
5. Warranty
|
|
50
|
+
|
|
51
|
+
5.1 To the maximum extent permitted by applicable law, the software is provided “as is”.
|
|
52
|
+
|
|
53
|
+
5.2 All implied warranties, implied conditions and/or implied licences are excluded from this Licence, including but not limited to implied warranties of quality and/or fitness for purpose (in all cases) to the fullest extent permitted by law.
|
|
54
|
+
|
|
55
|
+
5.3 You acknowledge that the Software has not been developed to meet your individual requirements and that the Software may not be uninterrupted or free of bugs or errors.
|
|
56
|
+
|
|
57
|
+
6. Licensor’s liability
|
|
58
|
+
|
|
59
|
+
6.1 To the maximum extent permitted by applicable law, in no event shall the Licensor be liable for any:
|
|
60
|
+
|
|
61
|
+
6.1.1 special loss or damage;
|
|
62
|
+
|
|
63
|
+
6.1.2 incidental loss or damage;
|
|
64
|
+
|
|
65
|
+
6.1.3 indirect or consequential loss or damage:
|
|
66
|
+
|
|
67
|
+
6.1.4 loss of income;
|
|
68
|
+
|
|
69
|
+
6.1.5 loss of business;
|
|
70
|
+
|
|
71
|
+
6.1.6 loss of profits;
|
|
72
|
+
|
|
73
|
+
6.1.7 loss of revenue;
|
|
74
|
+
|
|
75
|
+
6.1.8 loss of contracts;
|
|
76
|
+
|
|
77
|
+
6.1.9 business interruption;
|
|
78
|
+
|
|
79
|
+
6.1.10 loss of the use of money or anticipated savings;
|
|
80
|
+
|
|
81
|
+
6.1.11 loss of information;
|
|
82
|
+
|
|
83
|
+
6.1.12 loss of opportunity;
|
|
84
|
+
|
|
85
|
+
6.1.13 loss of goodwill or reputation; and/or
|
|
86
|
+
|
|
87
|
+
6.1.14 loss of, damage to or corruption of data;
|
|
88
|
+
|
|
89
|
+
(in each case) of any kind howsoever arising and whether caused by delict (including negligence), breach of contract or otherwise.
|
|
90
|
+
|
|
91
|
+
6.2 FTDI’s total liability to you in relation to the Software shall not exceed 500 US Dollars.
|
|
92
|
+
|
|
93
|
+
6.3 Nothing in this Licence limits or excludes liability for death or personal injury or for fraud.
|
|
94
|
+
|
|
95
|
+
7. Termination
|
|
96
|
+
|
|
97
|
+
7.1 The Licensor may terminate this Licence immediately if:
|
|
98
|
+
|
|
99
|
+
7.1.1 you fail to comply with any of the terms and conditions of the Licence; or
|
|
100
|
+
|
|
101
|
+
7.1.2 you commence or participate in any legal proceedings against the Licensor.
|
|
102
|
+
|
|
103
|
+
7.2 Upon termination:
|
|
104
|
+
|
|
105
|
+
7.2.1 all rights granted to you under this Licence shall cease;
|
|
106
|
+
|
|
107
|
+
7.2.2 you must cease all activities authorised by this Licence; and
|
|
108
|
+
|
|
109
|
+
7.2.3 you must immediately delete or remove the Software from all computer equipment in your possession and immediately destroy all copies of the Software then in your possession, custody or control.
|
|
110
|
+
|
|
111
|
+
8. Transfer of rights and obligations
|
|
112
|
+
|
|
113
|
+
8.1 You may not transfer, assign, charge or otherwise dispose of this Licence, or any of your rights or obligations arising under it.
|
|
114
|
+
|
|
115
|
+
8.2 The Licensor may transfer, assign, charge, sub-contract or otherwise dispose of this Licence, or any of his rights or obligations arising under it, at any time during the term of the Licence.
|
|
116
|
+
|
|
117
|
+
9. Waiver
|
|
118
|
+
|
|
119
|
+
9.1 If the Licensor fails, at any time during the term of this Licence, to insist on strict performance of any of your obligations under this Licence, or if the Licensor fails to exercise any of the rights or remedies to which he is entitled under this Licence, this shall not constitute a waiver of such rights or remedies and shall not relieve you from compliance with such obligations.
|
|
120
|
+
|
|
121
|
+
9.2 A waiver by the Licensor of any default shall not constitute a waiver of any subsequent default.
|
|
122
|
+
|
|
123
|
+
9.3 No waiver by the Licensor of any of these terms and conditions shall be effective unless it is expressly stated to be a waiver and is communicated to you in writing.
|
|
124
|
+
|
|
125
|
+
10. Severability
|
|
126
|
+
|
|
127
|
+
If any of the terms of this Licence are determined by any competent authority to be invalid, unlawful or unenforceable to any extent, such term, condition or provision will to that extent be severed from the remaining terms, conditions and provisions which will continue to be valid to the fullest extent permitted by law.
|
|
128
|
+
|
|
129
|
+
11. Entire agreement
|
|
130
|
+
|
|
131
|
+
11.1 This Licence constitutes the whole agreement between us and supersedes any previous arrangement, understanding or agreement between us, relating to the licensing of the Software.
|
|
132
|
+
|
|
133
|
+
11.2 Each party acknowledges that in entering into this Licence it does not rely on any statement, representation, warranty or understanding other than those expressly set out in this Licence. Each party agrees that it will have no remedy in respect of any statement, representation, warranty or understanding that is not expressly set out in this Licence. Each party agrees that its only remedy in respect of those representations, statements, assurances and warranties that are set out in this Licence will be for breach of contract in accordance with the terms of this Licence.
|
|
134
|
+
|
|
135
|
+
11.3 The parties agree that nothing in this Licence will limit or exclude any liability they may have for fraud.
|
|
136
|
+
|
|
137
|
+
12. Miscellaneous
|
|
138
|
+
|
|
139
|
+
12.1 This Licence does not create a partnership or joint venture between the parties to it, nor authorise a party to act as agent for the other.
|
|
140
|
+
|
|
141
|
+
12.2 This Licence does not create any legal rights enforceable by any third party.
|
|
142
|
+
|
|
143
|
+
12.3 This Licence may only be varied by express written legal agreement between the parties.
|
|
144
|
+
|
|
145
|
+
13. Law and jurisdiction
|
|
146
|
+
|
|
147
|
+
This Licence, its subject matter or its formation (including non-contractual disputes or claims) shall be governed by and construed in accordance with Scots law and submitted to the non-exclusive jurisdiction of the Scottish courts.
|
|
148
|
+
|
|
149
|
+
Copyright © 2026 Future Technology Devices International Limited. All Rights Reserved
|
|
150
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 S-Hector
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# Created by Hector Soto
|
|
2
|
+
# A Python conversion of the FTD2XX library.
|
|
3
|
+
# While the MAJOR version is 0, this is considered incomplete
|
|
4
|
+
# and not a full translation of the D2XX library to Python.
|
|
5
|
+
# The API and behavior can change at any time until the MAJOR version is 1.
|
|
6
|
+
|
|
7
|
+
print("PyD2XX: PyD2XX is still in EXTREMELY early development!")
|
|
8
|
+
print("PyD2XX: You should use PyFTDI instead: https://github.com/eblot/pyftdi")
|
|
9
|
+
|
|
10
|
+
import ctypes
|
|
11
|
+
import ctypes.wintypes
|
|
12
|
+
import typing
|
|
13
|
+
import platform as _Platform
|
|
14
|
+
import subprocess
|
|
15
|
+
import locale
|
|
16
|
+
|
|
17
|
+
from importlib.resources import files as _files
|
|
18
|
+
from sys import platform as Platform
|
|
19
|
+
|
|
20
|
+
# ---| Python Library Specific Definitions |---
|
|
21
|
+
|
|
22
|
+
VERSION = "0.0.1"
|
|
23
|
+
VERSION_TEST = "0.0.1_schimbarea_direcției"
|
|
24
|
+
|
|
25
|
+
PRINT_NONE = int("00000", 2) # Print no messages.
|
|
26
|
+
PRINT_ERROR_CRITICAL = int("00001", 2) # Print critical error messages.
|
|
27
|
+
PRINT_ERROR_MAJOR = int("00010", 2) # Print major error messages.
|
|
28
|
+
PRINT_ERROR_MINOR = int("00100", 2) # Print minor error messages.
|
|
29
|
+
PRINT_ERROR_ALL = int("00111", 2) # Print all error messages.
|
|
30
|
+
|
|
31
|
+
PRINT_INFO_START = int("01000", 2) # Print informational startup messages.
|
|
32
|
+
PRINT_INFO_DEVICE = int("10000", 2) # Print device information.
|
|
33
|
+
PRINT_INFO_ALL = int("11000", 2) # Print all informational messages.
|
|
34
|
+
PRINT_ALL = int("11111", 2) # Print all messages.
|
|
35
|
+
|
|
36
|
+
_PrintLevel = PRINT_NONE # What levels of printing are allowed.
|
|
37
|
+
_PrintQueue = []
|
|
38
|
+
|
|
39
|
+
def SetPrintLevel(PrintLevel: int) -> int:
|
|
40
|
+
global _PrintLevel
|
|
41
|
+
global _PrintQueue
|
|
42
|
+
_PrintLevel = PrintLevel
|
|
43
|
+
if _PrintQueue:
|
|
44
|
+
for Message in _PrintQueue:
|
|
45
|
+
_Print(Message[0], Message[1], False)
|
|
46
|
+
_PrintQueue = []
|
|
47
|
+
return FT_OK
|
|
48
|
+
|
|
49
|
+
def _Print(Message: str, Level: int, Queue: bool):
|
|
50
|
+
if Queue:
|
|
51
|
+
_PrintQueue.append([Message, Level])
|
|
52
|
+
elif(Level & PRINT_ERROR_CRITICAL & _PrintLevel):
|
|
53
|
+
print("PyD2XX - CRITICAL ERROR: " + Message)
|
|
54
|
+
elif(Level & PRINT_ERROR_MAJOR & _PrintLevel):
|
|
55
|
+
print("PyD2XX - MAJOR ERROR: " + Message)
|
|
56
|
+
elif(Level & PRINT_ERROR_MINOR & _PrintLevel):
|
|
57
|
+
print("PyD2XX - MINOR ERROR: " + Message)
|
|
58
|
+
elif(Level & PRINT_INFO_START & _PrintLevel):
|
|
59
|
+
print("PyD2XX - Startup INFO: " + Message)
|
|
60
|
+
|
|
61
|
+
# Determine OS and type sizes.
|
|
62
|
+
if (Platform.startswith("linux")):
|
|
63
|
+
Platform = "linux"
|
|
64
|
+
elif (Platform.startswith("win")):
|
|
65
|
+
Platform = "windows"
|
|
66
|
+
elif (Platform.startswith("darwin")):
|
|
67
|
+
Platform = "darwin"
|
|
68
|
+
elif (Platform.startswith("cygwin")):
|
|
69
|
+
Platform = "windows"
|
|
70
|
+
else: # Default to linux if we didn't catch the platform.
|
|
71
|
+
_Print("OS UNKNOWN: Assuming OS is linux.", PRINT_INFO_START, True)
|
|
72
|
+
Platform = "linux"
|
|
73
|
+
|
|
74
|
+
if Platform == "linux":
|
|
75
|
+
import gc
|
|
76
|
+
|
|
77
|
+
_IsARM = _Platform.machine().startswith('arm') or _Platform.machine().startswith('aarch64')
|
|
78
|
+
|
|
79
|
+
if ((Platform == "linux") or (Platform == "darwin")): #Fix type sizes for Linux and macOS
|
|
80
|
+
ctypes.c_ulong = ctypes.c_int32
|
|
81
|
+
ctypes.wintypes.DWORD = ctypes.c_int32
|
|
82
|
+
|
|
83
|
+
SIZE_UINT = ctypes.sizeof(ctypes.c_uint)
|
|
84
|
+
SIZE_ULONG = ctypes.sizeof(ctypes.c_ulong)
|
|
85
|
+
SIZE_SHORT = ctypes.sizeof(ctypes.c_short)
|
|
86
|
+
SIZE_CHAR = ctypes.sizeof(ctypes.c_char)
|
|
87
|
+
SIZE_WCHAR = ctypes.sizeof(ctypes.c_wchar)
|
|
88
|
+
SIZE_PTR = ctypes.sizeof(ctypes.c_void_p)
|
|
89
|
+
SIZE_DWORD = ctypes.sizeof(ctypes.wintypes.DWORD)
|
|
90
|
+
|
|
91
|
+
# ---| FTD2XX C/C++ HEADER EQUIVALENT STARTS HERE |---
|
|
92
|
+
# THIS IS NOT A FULL EQUIVALENT TO THE FTD2XX HEADER.
|
|
93
|
+
# I HAVE TAKEN MY OWN LIBERTIES ON HOW TO REPRESENT STRUCTS.
|
|
94
|
+
|
|
95
|
+
NULL = ctypes.c_void_p(0)
|
|
96
|
+
|
|
97
|
+
#FT_STATUS values.
|
|
98
|
+
FT_OK = 0
|
|
99
|
+
FT_INVALID_HANDLE = 1
|
|
100
|
+
FT_DEVICE_NOT_FOUND = 2
|
|
101
|
+
FT_DEVICE_NOT_OPENED = 3
|
|
102
|
+
FT_IO_ERROR = 4
|
|
103
|
+
FT_INSUFFICIENT_RESOURCES = 5
|
|
104
|
+
FT_INVALID_PARAMETER = 6
|
|
105
|
+
FT_INVALID_BAUD_RATE = 7
|
|
106
|
+
FT_DEVICE_NOT_OPENED_FOR_ERASE = 8
|
|
107
|
+
FT_DEVICE_NOT_OPENED_FOR_WRITE = 9
|
|
108
|
+
FT_FAILED_TO_WRITE_DEVICE = 10
|
|
109
|
+
FT_EEPROM_READ_FAILED = 11
|
|
110
|
+
FT_EEPROM_WRITE_FAILED = 12
|
|
111
|
+
FT_EEPROM_ERASE_FAILED = 13
|
|
112
|
+
FT_EEPROM_NOT_PRESENT = 14
|
|
113
|
+
FT_EEPROM_NOT_PROGRAMMED = 15
|
|
114
|
+
FT_INVALID_ARGS = 16
|
|
115
|
+
FT_NOT_SUPPORTED = 17
|
|
116
|
+
FT_OTHER_ERROR = 18
|
|
117
|
+
FT_DEVICE_LIST_NOT_READY = 19
|
|
118
|
+
|
|
119
|
+
# Describe dictionaries for easier error code conversion.
|
|
120
|
+
FT_STATUS_STR = {
|
|
121
|
+
FT_OK: "FT_OK",
|
|
122
|
+
FT_INVALID_HANDLE: "FT_INVALID_HANDLE",
|
|
123
|
+
FT_DEVICE_NOT_FOUND: "FT_DEVICE_NOT_FOUND",
|
|
124
|
+
FT_DEVICE_NOT_OPENED: "FT_DEVICE_NOT_OPENED",
|
|
125
|
+
FT_IO_ERROR: "FT_IO_ERROR",
|
|
126
|
+
FT_INSUFFICIENT_RESOURCES: "FT_INSUFFICIENT_RESOURCES",
|
|
127
|
+
FT_INVALID_PARAMETER: "FT_INVALID_PARAMETER",
|
|
128
|
+
FT_INVALID_BAUD_RATE: "FT_INVALID_BAUD_RATE",
|
|
129
|
+
FT_DEVICE_NOT_OPENED_FOR_ERASE: "FT_DEVICE_NOT_OPENED_FOR_ERASE",
|
|
130
|
+
FT_DEVICE_NOT_OPENED_FOR_WRITE: "FT_DEVICE_NOT_OPENED_FOR_WRITE",
|
|
131
|
+
FT_FAILED_TO_WRITE_DEVICE: "FT_FAILED_TO_WRITE_DEVICE",
|
|
132
|
+
FT_EEPROM_READ_FAILED: "FT_EEPROM_READ_FAILED",
|
|
133
|
+
FT_EEPROM_WRITE_FAILED: "FT_EEPROM_WRITE_FAILED",
|
|
134
|
+
FT_EEPROM_ERASE_FAILED: "FT_EEPROM_ERASE_FAILED",
|
|
135
|
+
FT_EEPROM_NOT_PRESENT: "FT_EEPROM_NOT_PRESENT",
|
|
136
|
+
FT_EEPROM_NOT_PROGRAMMED: "FT_EEPROM_NOT_PROGRAMMED",
|
|
137
|
+
FT_INVALID_ARGS: "FT_INVALID_ARGS",
|
|
138
|
+
FT_NOT_SUPPORTED: "FT_NOT_SUPPORTED",
|
|
139
|
+
FT_OTHER_ERROR: "FT_OTHER_ERROR"
|
|
140
|
+
}
|
|
141
|
+
FT_STATUS = {v: k for k, v in FT_STATUS_STR.items()}
|
|
142
|
+
|
|
143
|
+
FT_DEVICE_BM = 0
|
|
144
|
+
FT_DEVICE_AM = 1
|
|
145
|
+
FT_DEVICE_100AX = 2
|
|
146
|
+
FT_DEVICE_UNKNOWN = 3
|
|
147
|
+
FT_DEVICE_2232C = 4
|
|
148
|
+
FT_DEVICE_232R = 5
|
|
149
|
+
FT_DEVICE_2232H = 6
|
|
150
|
+
FT_DEVICE_4232H = 7
|
|
151
|
+
FT_DEVICE_232H = 8
|
|
152
|
+
FT_DEVICE_X_SERIES = 9
|
|
153
|
+
FT_DEVICE_4222H_0 = 10
|
|
154
|
+
FT_DEVICE_4222H_1_2 = 11
|
|
155
|
+
FT_DEVICE_4222H_3 = 12
|
|
156
|
+
FT_DEVICE_4222_PROG = 13
|
|
157
|
+
FT_DEVICE_900 = 14
|
|
158
|
+
FT_DEVICE_930 = 15
|
|
159
|
+
FT_DEVICE_UMFTPD3A = 16
|
|
160
|
+
FT_DEVICE_2233HP = 17
|
|
161
|
+
FT_DEVICE_4233HP = 18
|
|
162
|
+
FT_DEVICE_2232HP = 19
|
|
163
|
+
FT_DEVICE_4232HP = 20
|
|
164
|
+
FT_DEVICE_233HP = 21
|
|
165
|
+
FT_DEVICE_232HP = 22
|
|
166
|
+
FT_DEVICE_2232HA = 23
|
|
167
|
+
FT_DEVICE_4232HA = 24
|
|
168
|
+
FT_DEVICE_232RN = 25
|
|
169
|
+
FT_DEVICE_2233HPN = 26
|
|
170
|
+
FT_DEVICE_4233HPN = 27
|
|
171
|
+
FT_DEVICE_2232HPN = 28
|
|
172
|
+
FT_DEVICE_4232HPN = 29
|
|
173
|
+
FT_DEVICE_233HPN = 30
|
|
174
|
+
FT_DEVICE_232HPN = 31
|
|
175
|
+
FT_DEVICE_BM_A = 32
|
|
176
|
+
|
|
177
|
+
FT_DEVICE_STR = {
|
|
178
|
+
FT_DEVICE_BM: "FT_DEVICE_BM",
|
|
179
|
+
FT_DEVICE_AM: "FT_DEVICE_AM",
|
|
180
|
+
FT_DEVICE_100AX: "FT_DEVICE_100AX",
|
|
181
|
+
FT_DEVICE_UNKNOWN: "FT_DEVICE_UNKNOWN",
|
|
182
|
+
FT_DEVICE_2232C: "FT_DEVICE_2232C",
|
|
183
|
+
FT_DEVICE_232R: "FT_DEVICE_232R",
|
|
184
|
+
FT_DEVICE_2232H: "FT_DEVICE_2232H",
|
|
185
|
+
FT_DEVICE_4232H: "FT_DEVICE_4232H",
|
|
186
|
+
FT_DEVICE_232H: "FT_DEVICE_232H",
|
|
187
|
+
FT_DEVICE_X_SERIES: "FT_DEVICE_X_SERIES",
|
|
188
|
+
FT_DEVICE_4222H_0: "FT_DEVICE_4222H_0",
|
|
189
|
+
FT_DEVICE_4222H_1_2: "FT_DEVICE_4222H_1_2",
|
|
190
|
+
FT_DEVICE_4222H_3: "FT_DEVICE_4222H_3",
|
|
191
|
+
FT_DEVICE_4222_PROG: "FT_DEVICE_4222_PROG",
|
|
192
|
+
FT_DEVICE_900: "FT_DEVICE_900",
|
|
193
|
+
FT_DEVICE_930: "FT_DEVICE_930",
|
|
194
|
+
FT_DEVICE_UMFTPD3A: "FT_DEVICE_UMFTPD3A",
|
|
195
|
+
FT_DEVICE_2233HP: "FT_DEVICE_2233HP",
|
|
196
|
+
FT_DEVICE_4233HP: "FT_DEVICE_4233HP",
|
|
197
|
+
FT_DEVICE_2232HP: "FT_DEVICE_2232HP",
|
|
198
|
+
FT_DEVICE_4232HP: "FT_DEVICE_4232HP",
|
|
199
|
+
FT_DEVICE_233HP: "FT_DEVICE_233HP",
|
|
200
|
+
FT_DEVICE_232HP: "FT_DEVICE_232HP",
|
|
201
|
+
FT_DEVICE_2232HA: "FT_DEVICE_2232HA",
|
|
202
|
+
FT_DEVICE_4232HA: "FT_DEVICE_4232HA",
|
|
203
|
+
FT_DEVICE_232RN: "FT_DEVICE_232RN",
|
|
204
|
+
FT_DEVICE_2233HPN: "FT_DEVICE_2233HPN",
|
|
205
|
+
FT_DEVICE_4233HPN: "FT_DEVICE_4233HPN",
|
|
206
|
+
FT_DEVICE_2232HPN: "FT_DEVICE_2232HPN",
|
|
207
|
+
FT_DEVICE_4232HPN: "FT_DEVICE_4232HPN",
|
|
208
|
+
FT_DEVICE_233HPN: "FT_DEVICE_233HPN",
|
|
209
|
+
FT_DEVICE_232HPN: "FT_DEVICE_232HPN",
|
|
210
|
+
FT_DEVICE_BM_A: "FT_DEVICE_BM_A"
|
|
211
|
+
}
|
|
212
|
+
FT_DEVICE = {v: k for k, v in FT_DEVICE_STR.items()}
|
|
213
|
+
|
|
214
|
+
FT_BITMODE_RESET = int("0x00", 16)
|
|
215
|
+
FT_BITMODE_ASYNC_BITBANG = int("0x01", 16)
|
|
216
|
+
FT_BITMODE_MPSSE = int("0x02", 16)
|
|
217
|
+
FT_BITMODE_SYNC_BITBANG = int("0x04", 16)
|
|
218
|
+
FT_BITMODE_MCU_HOST = int("0x08", 16)
|
|
219
|
+
FT_BITMODE_FAST_SERIAL = int("0x10", 16)
|
|
220
|
+
FT_BITMODE_CBUS_BITBANG = int("0x20", 16)
|
|
221
|
+
FT_BITMODE_SYNC_FIFO = int("0x40", 16)
|
|
222
|
+
|
|
223
|
+
FT_FLAGS_OPENED = 1
|
|
224
|
+
FT_FLAGS_HISPEED = 2
|
|
225
|
+
|
|
226
|
+
class FT_Buffer:
|
|
227
|
+
def __init__(self, Size: int = None):
|
|
228
|
+
if(isinstance(Size, int)):
|
|
229
|
+
self._RawAddress = ctypes.c_buffer(init=0, size=Size)
|
|
230
|
+
self._Length = Size
|
|
231
|
+
else:
|
|
232
|
+
self._RawAddress = "FT_OTHER_ERROR"
|
|
233
|
+
self._Length = 0
|
|
234
|
+
def from_int(Integer: int):
|
|
235
|
+
NewBuffer = FT_Buffer()
|
|
236
|
+
if(isinstance(Integer, int)):
|
|
237
|
+
NewBuffer._RawAddress = ctypes.c_buffer(Integer.to_bytes(SIZE_UINT, "little"), SIZE_UINT)
|
|
238
|
+
NewBuffer._Length = SIZE_UINT
|
|
239
|
+
else:
|
|
240
|
+
_Print("FT_Buffer(int), not given an int!", PRINT_ERROR_MINOR, False)
|
|
241
|
+
return NewBuffer
|
|
242
|
+
def from_str(String: str):
|
|
243
|
+
NewBuffer = FT_Buffer()
|
|
244
|
+
if(isinstance(String, str)):
|
|
245
|
+
NewBuffer._Length = len(String) + 1
|
|
246
|
+
NewBuffer._RawAddress = ctypes.create_string_buffer(init=String.encode("ascii"))
|
|
247
|
+
else:
|
|
248
|
+
_Print("FT_Buffer(str), not given a str!", PRINT_ERROR_MINOR, False)
|
|
249
|
+
return NewBuffer
|
|
250
|
+
def from_bytearray(ByteArray: bytearray):
|
|
251
|
+
NewBuffer = FT_Buffer()
|
|
252
|
+
if(isinstance(ByteArray, bytearray)):
|
|
253
|
+
NewBuffer._Length = len(ByteArray)
|
|
254
|
+
NewBuffer._RawAddress = ctypes.c_buffer(init=bytes(ByteArray), size=NewBuffer._Length)
|
|
255
|
+
else:
|
|
256
|
+
_Print("FT_Buffer(bytearray), not given a bytearray!", PRINT_ERROR_MINOR, False)
|
|
257
|
+
return NewBuffer
|
|
258
|
+
def from_bytes(Bytes: bytes):
|
|
259
|
+
NewBuffer = FT_Buffer()
|
|
260
|
+
if(isinstance(Bytes, bytes)):
|
|
261
|
+
NewBuffer._Length = len(Bytes)
|
|
262
|
+
NewBuffer._RawAddress = ctypes.c_buffer(init=Bytes, size=NewBuffer._Length)
|
|
263
|
+
else:
|
|
264
|
+
_Print("FT_Buffer(bytes), not given bytes!", PRINT_ERROR_MINOR, False)
|
|
265
|
+
return NewBuffer
|
|
266
|
+
def Value(self) -> bytearray:
|
|
267
|
+
if isinstance(self._RawAddress, str):
|
|
268
|
+
return self._RawAddress.encode("ascii")
|
|
269
|
+
return bytearray(self._RawAddress)
|
|
270
|
+
|
|
271
|
+
class _FT_DEVICE_LIST_INFO_NODE(ctypes.Structure):
|
|
272
|
+
_fields_ = [
|
|
273
|
+
("Flags", ctypes.c_int32), #ULONG for Windows is 4 bytes. Linux library follows same byte alignment against normal convention.
|
|
274
|
+
("Type", ctypes.c_int32),
|
|
275
|
+
("ID", ctypes.c_int32),
|
|
276
|
+
("LocID", ctypes.c_int32),
|
|
277
|
+
("SerialNumber", ctypes.c_char * 16),
|
|
278
|
+
("Description", ctypes.c_char * 64)
|
|
279
|
+
]
|
|
280
|
+
class FT_Device:
|
|
281
|
+
_Handle = "FT_OTHER_ERROR"
|
|
282
|
+
Handle = "FT_OTHER_ERROR"
|
|
283
|
+
Flags = 0
|
|
284
|
+
Type = 0
|
|
285
|
+
ID = 0
|
|
286
|
+
LocID = 0
|
|
287
|
+
SerialNumber = ""
|
|
288
|
+
Description = ""
|
|
289
|
+
|
|
290
|
+
def _CreateDevice():
|
|
291
|
+
NewDevice = FT_Device()
|
|
292
|
+
NewDevice._Handle = ctypes.c_void_p(0)
|
|
293
|
+
NewDevice.Flags = 0
|
|
294
|
+
NewDevice.Type = 0
|
|
295
|
+
NewDevice.ID = 0
|
|
296
|
+
NewDevice.LocID = 0
|
|
297
|
+
NewDevice.SerialNumber = ""
|
|
298
|
+
NewDevice.Description = ""
|
|
299
|
+
return NewDevice
|
|
300
|
+
|
|
301
|
+
# ---| END OF EQUIVALENT HEADER PORTION |---
|
|
302
|
+
|
|
303
|
+
# ---| LIBRARY INCLUSION PART |---
|
|
304
|
+
_Python64 = (ctypes.sizeof(ctypes.c_void_p) == 8) # True if 64-bit version of Python is running.
|
|
305
|
+
|
|
306
|
+
# ---| Try to Load Dynamic Library |---
|
|
307
|
+
_LibraryFile = ""
|
|
308
|
+
_LibraryFile += "FTD2XX" if (Platform=="windows") else "libftd2xx"
|
|
309
|
+
_LibraryFile += ("_ARM" if (_IsARM and (Platform!="darwin")) else "")
|
|
310
|
+
_LibraryFile += ("_32" if not(_Python64) else "")
|
|
311
|
+
_LibraryFile += ".dll" if (Platform=="windows") else (".dylib" if (Platform=="darwin") else ".so")
|
|
312
|
+
_DLL_Path = str(_files("PyD2XX").joinpath(_LibraryFile))
|
|
313
|
+
try:
|
|
314
|
+
if(Platform == "windows"):
|
|
315
|
+
_DLL = ctypes.windll.LoadLibrary(_DLL_Path) # Check if dll exists in same directory as executable.
|
|
316
|
+
else:
|
|
317
|
+
_DLL = ctypes.cdll.LoadLibrary(_DLL_Path) # Check if dll exists in same directory as executable.
|
|
318
|
+
except:
|
|
319
|
+
print("PyD3XX ERROR: Did not find '" + _DLL_Path + "', EXITING.")
|
|
320
|
+
exit()
|
|
321
|
+
_Print("Successfully loaded D2XX: '" + _LibraryFile + "'", PRINT_INFO_START, True)
|
|
322
|
+
|
|
323
|
+
# ---| FTD2XX Python Function Implementations |---
|
|
324
|
+
|
|
325
|
+
def FT_CreateDeviceInfoList() -> tuple[int, int]:
|
|
326
|
+
DeviceCount = ctypes.c_ulong(0)
|
|
327
|
+
Status = _DLL.FT_CreateDeviceInfoList(ctypes.byref(DeviceCount))
|
|
328
|
+
return Status, DeviceCount.value # Device count is converted to a Python int.
|
|
329
|
+
|
|
330
|
+
def FT_GetDeviceInfoList(DeviceCount: int) -> tuple[int, list[FT_Device]] | tuple[int, str]:
|
|
331
|
+
Status = FT_OK
|
|
332
|
+
DeviceCount = ctypes.c_ulong(DeviceCount)
|
|
333
|
+
if(DeviceCount.value < 1):
|
|
334
|
+
_Print(FT_STATUS_STR[Status] + " | ERROR: DeviceCount IS LESS THAN 1.", PRINT_ERROR_MINOR, False)
|
|
335
|
+
return Status, "FT_OTHER_ERROR"
|
|
336
|
+
DeviceList = (_FT_DEVICE_LIST_INFO_NODE * DeviceCount.value)()
|
|
337
|
+
Handle = ctypes.c_void_p(0)
|
|
338
|
+
Status = _DLL.FT_GetDeviceInfoList(ctypes.byref(DeviceList), ctypes.byref(DeviceCount))
|
|
339
|
+
if(Status != FT_OK):
|
|
340
|
+
_Print(FT_STATUS_STR[Status] + " | ERROR: FAILED TO GET DEVICE INFO LIST.", PRINT_ERROR_MAJOR, False)
|
|
341
|
+
return Status, "FT_OTHER_ERROR"
|
|
342
|
+
ReturnDeviceList = []
|
|
343
|
+
for i in range(DeviceCount.value):
|
|
344
|
+
ReturnDeviceList.append(_CreateDevice())
|
|
345
|
+
ReturnDeviceList[i].Handle = "FT_OTHER_ERROR"
|
|
346
|
+
ReturnDeviceList[i].Flags = DeviceList[i].Flags
|
|
347
|
+
ReturnDeviceList[i].Type = DeviceList[i].Type
|
|
348
|
+
ReturnDeviceList[i].ID = DeviceList[i].ID
|
|
349
|
+
ReturnDeviceList[i].LocID = DeviceList[i].LocID
|
|
350
|
+
ReturnDeviceList[i].SerialNumber = DeviceList[i].SerialNumber.decode("utf-8")
|
|
351
|
+
ReturnDeviceList[i].Description = DeviceList[i].Description.decode("utf-8")
|
|
352
|
+
return Status, ReturnDeviceList
|
|
353
|
+
|
|
354
|
+
def FT_Open(Index: int, Device: FT_Device) -> int:
|
|
355
|
+
Status = FT_OTHER_ERROR
|
|
356
|
+
if(not(isinstance(Device, FT_Device))):
|
|
357
|
+
_Print("FT_Open(), did not get an FT_Device!", PRINT_ERROR_MAJOR, False)
|
|
358
|
+
elif(not(isinstance(Device._Handle, ctypes.c_void_p))):
|
|
359
|
+
_Print("FT_Open(), got an uninitialized or broken FT_Device object!", PRINT_ERROR_MAJOR, False)
|
|
360
|
+
else:
|
|
361
|
+
Status = _DLL.FT_Open(ctypes.c_int(Index), ctypes.byref(Device._Handle))
|
|
362
|
+
Device.Handle = Device._Handle.value
|
|
363
|
+
return Status
|
|
364
|
+
|
|
365
|
+
def FT_Close(Device: FT_Device) -> int:
|
|
366
|
+
Status = FT_OTHER_ERROR
|
|
367
|
+
if(not(isinstance(Device, FT_Device))):
|
|
368
|
+
_Print("FT_Close(), did not get an FT_Device!", PRINT_ERROR_MAJOR, False)
|
|
369
|
+
elif(not(isinstance(Device._Handle, ctypes.c_void_p))):
|
|
370
|
+
_Print("FT_Close(), got an uninitialized or broken FT_Device object!", PRINT_ERROR_MAJOR, False)
|
|
371
|
+
else:
|
|
372
|
+
Status = _DLL.FT_Close(Device._Handle)
|
|
373
|
+
Device.Handle = "FT_OTHER_ERROR"
|
|
374
|
+
return Status
|
|
375
|
+
|
|
376
|
+
def FT_SetBitMode(Device: FT_Device, Mask: int, Mode: int) -> int:
|
|
377
|
+
Status = FT_OTHER_ERROR
|
|
378
|
+
Status = _DLL.FT_SetBitMode(Device._Handle, ctypes.c_char(Mask), ctypes.c_char(Mode))
|
|
379
|
+
return Status
|
|
380
|
+
|
|
381
|
+
def FT_Write(Device: FT_Device, Buffer: FT_Buffer, BufferLength: int) -> tuple[int, int]:
|
|
382
|
+
Status = FT_OTHER_ERROR
|
|
383
|
+
if(isinstance(Buffer._RawAddress, FT_Buffer)):
|
|
384
|
+
_Print("FT_Write(), was not given expected FT_Buffer.", PRINT_ERROR_MAJOR, False)
|
|
385
|
+
return Status, 0
|
|
386
|
+
BytesTransferred = ctypes.wintypes.DWORD(0)
|
|
387
|
+
Status = _DLL.FT_Write(Device._Handle,
|
|
388
|
+
ctypes.byref(Buffer._RawAddress),
|
|
389
|
+
BufferLength,
|
|
390
|
+
ctypes.byref(BytesTransferred))
|
|
391
|
+
return Status, BytesTransferred.value
|
|
392
|
+
|
|
393
|
+
def FT_Read(Device: FT_Device, BufferLength: int) -> tuple[int, FT_Buffer, int]:
|
|
394
|
+
Status = FT_OTHER_ERROR
|
|
395
|
+
Buffer = FT_Buffer()
|
|
396
|
+
Buffer._RawAddress = ctypes.c_buffer(BufferLength)
|
|
397
|
+
Buffer._Length = BufferLength
|
|
398
|
+
BytesTransferred = ctypes.c_ulong(0)
|
|
399
|
+
Status = _DLL.FT_Read(Device._Handle,
|
|
400
|
+
ctypes.byref(Buffer._RawAddress),
|
|
401
|
+
BufferLength,
|
|
402
|
+
ctypes.byref(BytesTransferred))
|
|
403
|
+
return Status, Buffer, BytesTransferred.value
|
|
404
|
+
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|