├── .github └── workflows │ ├── ci.yaml │ └── deploy-nuget.yaml ├── .gitignore ├── LICENSE ├── README.md ├── dev ├── AN_411_Source │ ├── FTD2XX_NET.XML │ ├── FTD2XX_NET.dll │ ├── FTD2XX_NET_v1.1.0 │ │ ├── FTD2XX_NET.XML │ │ ├── FTD2XX_NET.dll │ │ └── License.txt │ ├── License.txt │ ├── MPSSE Sensor Demo.Designer.cs │ ├── MPSSE Sensor Demo.cs │ ├── MPSSE Sensor Demo.cs.bak │ ├── MPSSE Sensor Demo.csproj │ ├── MPSSE Sensor Demo.resx │ ├── MPSSE Sensor Demo.sln │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── readme.md │ └── readme.pdf ├── FTD2XX_NET │ ├── FTD2XX_NET.cs │ ├── License.txt │ └── readme.md ├── SPITEST │ └── spitest.cpp ├── i-SPI Source Code │ ├── AssemblyInfo.vb │ ├── FT232H SPI Current Meter.cs │ ├── FT232H SPI Current Meter.sln │ ├── FT232H SPI Current Meter.vb │ ├── FT232H SPI Current Meter.vbproj │ ├── Form1.resx │ ├── Form1.vb │ ├── My Project │ │ ├── Resources.Designer.vb │ │ └── Resources.resx │ ├── Resources │ │ ├── FTDI.bmp │ │ ├── Thumbs.db │ │ └── i-SPI.ico │ └── readme.md ├── icon │ ├── icon-128.png │ └── icon.svg └── screenshots │ ├── adc-graph.gif │ ├── connections.pptx │ ├── demo.png │ ├── i2c-connections.png │ └── lm75a.png └── src ├── FtdiSharp.sln ├── FtdiSharp ├── Display.cs ├── FTD2XX │ ├── EEPROM_STRUCTURES │ │ ├── FT2232H_EEPROM_STRUCTURE.cs │ │ ├── FT2232_EEPROM_STRUCTURE.cs │ │ ├── FT232B_EEPROM_STRUCTURE.cs │ │ ├── FT232H_EEPROM_STRUCTURE.cs │ │ ├── FT232R_EEPROM_STRUCTURE.cs │ │ ├── FT4232H_EEPROM_STRUCTURE.cs │ │ └── FTX_EEPROM_STRUCTURE.cs │ ├── FTDI.cs │ ├── FT_232H_CBUS_OPTIONS.cs │ ├── FT_BIT_MODES.cs │ ├── FT_CBUS_OPTIONS.cs │ ├── FT_DATA_BITS.cs │ ├── FT_DEFAULT_VALUES.cs │ ├── FT_DEVICE.cs │ ├── FT_DEVICE_INFO_NODE.cs │ ├── FT_DRIVE_CURRENT.cs │ ├── FT_EEPROM_DATA.cs │ ├── FT_EEPROM_HEADER.cs │ ├── FT_ERROR.cs │ ├── FT_EVENTS.cs │ ├── FT_EXCEPTION.cs │ ├── FT_FLAGS.cs │ ├── FT_FLOW_CONTROL.cs │ ├── FT_LINE_STATUS.cs │ ├── FT_MODEM_STATUS.cs │ ├── FT_OPEN.cs │ ├── FT_PARITY.cs │ ├── FT_PROGRAM_DATA.cs │ ├── FT_PURGE.cs │ ├── FT_STATUS.cs │ ├── FT_STOP_BITS.cs │ ├── FT_XSERIES_CBUS_OPTIONS.cs │ └── FT_XSERIES_DATA.cs ├── FtdiDevice.cs ├── FtdiDevices.cs ├── FtdiManager.cs ├── FtdiSharp.csproj ├── Protocols │ ├── GPIO.cs │ ├── I2C.cs │ ├── ProtocolBase.cs │ └── SPI.cs └── Usings.cs ├── FtdiSharpDemo ├── Controls │ ├── BarGraph.Designer.cs │ ├── BarGraph.cs │ ├── BarGraph.resx │ ├── DeviceSelector.Designer.cs │ ├── DeviceSelector.cs │ ├── DeviceSelector.resx │ ├── I2cAddressSelector.Designer.cs │ ├── I2cAddressSelector.cs │ └── I2cAddressSelector.resx ├── DeviceInfoForm.Designer.cs ├── DeviceInfoForm.cs ├── DeviceInfoForm.resx ├── FtdiSharpDemo.csproj ├── GPIO_LED.Designer.cs ├── GPIO_LED.cs ├── GPIO_LED.resx ├── I2C_ADS1115.Designer.cs ├── I2C_ADS1115.cs ├── I2C_ADS1115.resx ├── I2C_ADS1115DataLogger.Designer.cs ├── I2C_ADS1115DataLogger.cs ├── I2C_ADS1115DataLogger.resx ├── I2C_BH1750.Designer.cs ├── I2C_BH1750.cs ├── I2C_BH1750.resx ├── I2C_BMP280.Designer.cs ├── I2C_BMP280.cs ├── I2C_BMP280.resx ├── I2C_LIS3DH.Designer.cs ├── I2C_LIS3DH.cs ├── I2C_LIS3DH.resx ├── I2C_LM75A.Designer.cs ├── I2C_LM75A.cs ├── I2C_LM75A.resx ├── I2C_Scan.Designer.cs ├── I2C_Scan.cs ├── I2C_Scan.resx ├── MenuForm.Designer.cs ├── MenuForm.cs ├── MenuForm.resx ├── Program.cs ├── SPI_AD7705.Designer.cs ├── SPI_AD7705.cs ├── SPI_AD7705.resx ├── SPI_ADS1220.Designer.cs ├── SPI_ADS1220.cs ├── SPI_ADS1220.resx ├── SPI_HX710.Designer.cs ├── SPI_HX710.cs ├── SPI_HX710.resx ├── SPI_MCP3008.Designer.cs ├── SPI_MCP3008.cs ├── SPI_MCP3008.resx ├── SPI_MCP3201.Designer.cs ├── SPI_MCP3201.cs └── SPI_MCP3201.resx ├── FtdiSharpTests ├── FtdiSharpTests.csproj ├── HardwareTests.cs ├── UnitTests.cs └── Usings.cs └── autoformat.bat /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | types: [opened, synchronize, reopened] 10 | 11 | jobs: 12 | build: 13 | runs-on: windows-latest 14 | name: Build 15 | steps: 16 | - name: 🛒 Checkout 17 | uses: actions/checkout@v2 18 | - name: 🐢 Set up MSBuild 19 | uses: microsoft/setup-msbuild@v1.1 20 | - name: ✨ Set up .NET 6.0 21 | uses: actions/setup-dotnet@v1 22 | with: 23 | dotnet-version: "8.0.x" 24 | - name: 🚚 Restore 25 | working-directory: src 26 | run: dotnet restore 27 | - name: 🛠️ Build 28 | working-directory: src 29 | run: msbuild -property:Configuration=Release -verbosity:minimal 30 | - name: 🧪 Test 31 | working-directory: src 32 | run: dotnet test --no-restore --verbosity minimal 33 | - name: 📦 Pack 34 | working-directory: src/FtdiSharp 35 | run: dotnet pack --configuration Release 36 | -------------------------------------------------------------------------------- /.github/workflows/deploy-nuget.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy to NuGet 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | windows: 8 | runs-on: windows-latest 9 | name: Build and Push 10 | steps: 11 | - name: 🛒 Checkout 12 | uses: actions/checkout@v3 13 | - name: 🐢 Setup MSBuild 14 | uses: microsoft/setup-msbuild@v1.1 15 | - name: ✨ Setup .NET 6.0 16 | uses: actions/setup-dotnet@v3 17 | with: 18 | dotnet-version: "8.0.x" 19 | - name: 🚚 Restore 20 | run: dotnet restore "src/FtdiSharp" 21 | - name: 🛠️ Build 22 | run: dotnet build "src/FtdiSharp" --configuration Release --no-restore 23 | - name: 🧪 Test 24 | run: dotnet test "src/FtdiSharp" --no-restore --verbosity minimal 25 | - name: 📦 Pack 26 | run: dotnet pack "src/FtdiSharp" --configuration Release 27 | - name: 💾 Store Packages 28 | uses: actions/upload-artifact@v3 29 | with: 30 | name: Packages 31 | retention-days: 1 32 | path: src/FtdiSharp/bin/Release/*.nupkg 33 | - name: 🛠️ Setup NuGet 34 | uses: nuget/setup-nuget@v1 35 | with: 36 | nuget-api-key: ${{ secrets.NUGET_API_KEY }} 37 | - name: 🚀 Publish Packages 38 | run: nuget push "src\FtdiSharp\bin\Release\*.nupkg" -SkipDuplicate -Source https://api.nuget.org/v3/index.json 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Scott W Harden 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. 22 | -------------------------------------------------------------------------------- /dev/AN_411_Source/FTD2XX_NET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/AN_411_Source/FTD2XX_NET.dll -------------------------------------------------------------------------------- /dev/AN_411_Source/FTD2XX_NET_v1.1.0/FTD2XX_NET.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/AN_411_Source/FTD2XX_NET_v1.1.0/FTD2XX_NET.dll -------------------------------------------------------------------------------- /dev/AN_411_Source/FTD2XX_NET_v1.1.0/License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/AN_411_Source/FTD2XX_NET_v1.1.0/License.txt -------------------------------------------------------------------------------- /dev/AN_411_Source/License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/AN_411_Source/License.txt -------------------------------------------------------------------------------- /dev/AN_411_Source/MPSSE Sensor Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MPSSE Sensor Demo", "MPSSE Sensor Demo.csproj", "{BE131338-3526-44FC-ACD8-88AF2726779B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BE131338-3526-44FC-ACD8-88AF2726779B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BE131338-3526-44FC-ACD8-88AF2726779B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BE131338-3526-44FC-ACD8-88AF2726779B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BE131338-3526-44FC-ACD8-88AF2726779B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /dev/AN_411_Source/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace SensorDemo 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Form1()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /dev/AN_411_Source/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SensorDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SensorDemo")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("728dbc1d-8b45-4c70-b504-fabea54d7018")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dev/AN_411_Source/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SensorDemo.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SensorDemo.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /dev/AN_411_Source/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SensorDemo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dev/AN_411_Source/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /dev/AN_411_Source/readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Official D2xx MPSSE Demo 3 | 4 | > A sample demonstrating the use of the C# wrapper with the D2xx driver, for the FT232H, FT2232H and FT4232H devices to create an I2C master through the MPSSE mode as described in AN_411 is provided for users to experiment with, and extend into their own applications. 5 | 6 | This file is unmodified since downloading from https://ftdichip.com/software-examples/code-examples/csharp-examples/ on 2023-01-25 7 | 8 | See [readme.pdf](readme.pdf) for the official description of this project 9 | 10 | Unfortunately all the useful information is in one massive [MPSSE Sensor Demo.cs](MPSSE%20Sensor%20Demo.cs) file over 1,700 lines long 🤦 11 | -------------------------------------------------------------------------------- /dev/AN_411_Source/readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/AN_411_Source/readme.pdf -------------------------------------------------------------------------------- /dev/FTD2XX_NET/FTD2XX_NET.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/FTD2XX_NET/FTD2XX_NET.cs -------------------------------------------------------------------------------- /dev/FTD2XX_NET/License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/FTD2XX_NET/License.txt -------------------------------------------------------------------------------- /dev/FTD2XX_NET/readme.md: -------------------------------------------------------------------------------- 1 | # FTD2XX_NET version 1.2.0 2 | 3 | FTDI have provided a managed .NET wrapper class for the FTD2XX DLL on the Windows platform. 4 | 5 | Files here are presented in their original form as obtained obtained from https://ftdichip.com/software-examples/code-examples/csharp-examples/ in January 2023. -------------------------------------------------------------------------------- /dev/i-SPI Source Code/AssemblyInfo.vb: -------------------------------------------------------------------------------- 1 | Imports System 2 | Imports System.Reflection 3 | Imports System.Runtime.InteropServices 4 | 5 | ' General Information about an assembly is controlled through the following 6 | ' set of attributes. Change these attribute values to modify the information 7 | ' associated with an assembly. 8 | 9 | ' Review the values of the assembly attributes 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 'The following GUID is for the ID of the typelib if this project is exposed to COM 20 | 21 | 22 | ' Version information for an assembly consists of the following four values: 23 | ' 24 | ' Major Version 25 | ' Minor Version 26 | ' Build Number 27 | ' Revision 28 | ' 29 | ' You can specify all the values or you can default the Build and Revision Numbers 30 | ' by using the '*' as shown below: 31 | 32 | 33 | -------------------------------------------------------------------------------- /dev/i-SPI Source Code/FT232H SPI Current Meter.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 10.00 2 | # Visual Studio 2008 3 | Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "FT232H SPI Current Meter", "FT232H SPI Current Meter.vbproj", "{2FC6ED1F-A2E6-45A0-9E97-25A746AED6BF}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Any CPU = Debug|Any CPU 8 | Release|Any CPU = Release|Any CPU 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {2FC6ED1F-A2E6-45A0-9E97-25A746AED6BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 12 | {2FC6ED1F-A2E6-45A0-9E97-25A746AED6BF}.Debug|Any CPU.Build.0 = Debug|Any CPU 13 | {2FC6ED1F-A2E6-45A0-9E97-25A746AED6BF}.Release|Any CPU.ActiveCfg = Release|Any CPU 14 | {2FC6ED1F-A2E6-45A0-9E97-25A746AED6BF}.Release|Any CPU.Build.0 = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /dev/i-SPI Source Code/My Project/Resources.Designer.vb: -------------------------------------------------------------------------------- 1 | '------------------------------------------------------------------------------ 2 | ' 3 | ' This code was generated by a tool. 4 | ' Runtime Version:2.0.50727.3623 5 | ' 6 | ' Changes to this file may cause incorrect behavior and will be lost if 7 | ' the code is regenerated. 8 | ' 9 | '------------------------------------------------------------------------------ 10 | 11 | Option Strict On 12 | Option Explicit On 13 | 14 | Imports System 15 | 16 | Namespace My.Resources 17 | 18 | 'This class was auto-generated by the StronglyTypedResourceBuilder 19 | 'class via a tool like ResGen or Visual Studio. 20 | 'To add or remove a member, edit your .ResX file then rerun ResGen 21 | 'with the /str option, or rebuild your VS project. 22 | ''' 23 | ''' A strongly-typed resource class, for looking up localized strings, etc. 24 | ''' 25 | _ 29 | Friend Module Resources 30 | 31 | Private resourceMan As Global.System.Resources.ResourceManager 32 | 33 | Private resourceCulture As Global.System.Globalization.CultureInfo 34 | 35 | ''' 36 | ''' Returns the cached ResourceManager instance used by this class. 37 | ''' 38 | _ 39 | Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager 40 | Get 41 | If Object.ReferenceEquals(resourceMan, Nothing) Then 42 | Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("D2XXUnit_NET.Resources", GetType(Resources).Assembly) 43 | resourceMan = temp 44 | End If 45 | Return resourceMan 46 | End Get 47 | End Property 48 | 49 | ''' 50 | ''' Overrides the current thread's CurrentUICulture property for all 51 | ''' resource lookups using this strongly typed resource class. 52 | ''' 53 | _ 54 | Friend Property Culture() As Global.System.Globalization.CultureInfo 55 | Get 56 | Return resourceCulture 57 | End Get 58 | Set 59 | resourceCulture = value 60 | End Set 61 | End Property 62 | 63 | Friend ReadOnly Property FTDI() As System.Drawing.Bitmap 64 | Get 65 | Dim obj As Object = ResourceManager.GetObject("FTDI", resourceCulture) 66 | Return CType(obj,System.Drawing.Bitmap) 67 | End Get 68 | End Property 69 | 70 | Friend ReadOnly Property i_SPI() As System.Drawing.Icon 71 | Get 72 | Dim obj As Object = ResourceManager.GetObject("i-SPI", resourceCulture) 73 | Return CType(obj,System.Drawing.Icon) 74 | End Get 75 | End Property 76 | End Module 77 | End Namespace 78 | -------------------------------------------------------------------------------- /dev/i-SPI Source Code/Resources/FTDI.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/i-SPI Source Code/Resources/FTDI.bmp -------------------------------------------------------------------------------- /dev/i-SPI Source Code/Resources/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/i-SPI Source Code/Resources/Thumbs.db -------------------------------------------------------------------------------- /dev/i-SPI Source Code/Resources/i-SPI.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/i-SPI Source Code/Resources/i-SPI.ico -------------------------------------------------------------------------------- /dev/i-SPI Source Code/readme.md: -------------------------------------------------------------------------------- 1 | https://ftdichip.com/wp-content/uploads/2020/08/AN_180_FT232H-MPSSE-Example-USB-Current-Meter-using-the-SPI-interface.pdf 2 | 3 | Downloaded from https://ftdichip.com/document/application-notes/ -------------------------------------------------------------------------------- /dev/icon/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/icon/icon-128.png -------------------------------------------------------------------------------- /dev/screenshots/adc-graph.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/screenshots/adc-graph.gif -------------------------------------------------------------------------------- /dev/screenshots/connections.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/screenshots/connections.pptx -------------------------------------------------------------------------------- /dev/screenshots/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/screenshots/demo.png -------------------------------------------------------------------------------- /dev/screenshots/i2c-connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/screenshots/i2c-connections.png -------------------------------------------------------------------------------- /dev/screenshots/lm75a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swharden/FtdiSharp/3130a05a07489b2d4ab0dd4d19f235a151f72de1/dev/screenshots/lm75a.png -------------------------------------------------------------------------------- /src/FtdiSharp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FtdiSharp", "FtdiSharp\FtdiSharp.csproj", "{DED9E0DC-21F7-4E3F-9C75-B180D15B7937}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FtdiSharpDemo", "FtdiSharpDemo\FtdiSharpDemo.csproj", "{A57017FA-2675-4001-BE9D-24D90A5C46D1}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FtdiSharpTests", "FtdiSharpTests\FtdiSharpTests.csproj", "{B909C067-6C9F-445F-8819-D5B32B67155D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {DED9E0DC-21F7-4E3F-9C75-B180D15B7937}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {DED9E0DC-21F7-4E3F-9C75-B180D15B7937}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {DED9E0DC-21F7-4E3F-9C75-B180D15B7937}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {DED9E0DC-21F7-4E3F-9C75-B180D15B7937}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {A57017FA-2675-4001-BE9D-24D90A5C46D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {A57017FA-2675-4001-BE9D-24D90A5C46D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {A57017FA-2675-4001-BE9D-24D90A5C46D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {A57017FA-2675-4001-BE9D-24D90A5C46D1}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {B909C067-6C9F-445F-8819-D5B32B67155D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {B909C067-6C9F-445F-8819-D5B32B67155D}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {B909C067-6C9F-445F-8819-D5B32B67155D}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {B909C067-6C9F-445F-8819-D5B32B67155D}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {8445ACEF-5376-41CB-9AFA-D52F91DC7D3E} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /src/FtdiSharp/Display.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace FtdiSharp; 4 | 5 | public static class Display 6 | { 7 | public static string Binary(this byte[] bytes) 8 | { 9 | return string.Join(", ", bytes.Select(x => Convert.ToString(x, 2).PadLeft(8, '0'))); 10 | } 11 | 12 | public static string Binary(this byte value) 13 | { 14 | return Binary(new byte[] { value }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/EEPROM_STRUCTURES/FT2232H_EEPROM_STRUCTURE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX.EEPROM_STRUCTURES; 2 | 3 | /// 4 | /// EEPROM structure specific to FT2232H devices. 5 | /// Inherits from FT_EEPROM_DATA. 6 | /// 7 | public class FT2232H_EEPROM_STRUCTURE : FT_EEPROM_DATA 8 | { 9 | /// 10 | /// Determines if IOs are pulled down when the device is in suspend 11 | /// 12 | public bool PullDownEnable = false; 13 | 14 | /// 15 | /// Determines if the serial number is enabled 16 | /// 17 | public bool SerNumEnable = true; 18 | 19 | /// 20 | /// Determines if AL pins have a slow slew rate 21 | /// 22 | public bool ALSlowSlew = false; 23 | 24 | /// 25 | /// Determines if the AL pins have a Schmitt input 26 | /// 27 | public bool ALSchmittInput = false; 28 | 29 | /// 30 | /// Determines the AL pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 31 | /// 32 | public byte ALDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 33 | 34 | /// 35 | /// Determines if AH pins have a slow slew rate 36 | /// 37 | public bool AHSlowSlew = false; 38 | 39 | /// 40 | /// Determines if the AH pins have a Schmitt input 41 | /// 42 | public bool AHSchmittInput = false; 43 | 44 | /// 45 | /// Determines the AH pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 46 | /// 47 | public byte AHDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 48 | 49 | /// 50 | /// Determines if BL pins have a slow slew rate 51 | /// 52 | public bool BLSlowSlew = false; 53 | 54 | /// 55 | /// Determines if the BL pins have a Schmitt input 56 | /// 57 | public bool BLSchmittInput = false; 58 | 59 | /// 60 | /// Determines the BL pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 61 | /// 62 | public byte BLDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 63 | 64 | /// 65 | /// Determines if BH pins have a slow slew rate 66 | /// 67 | public bool BHSlowSlew = false; 68 | 69 | /// 70 | /// Determines if the BH pins have a Schmitt input 71 | /// 72 | public bool BHSchmittInput = false; 73 | 74 | /// 75 | /// Determines the BH pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 76 | /// 77 | public byte BHDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 78 | 79 | /// 80 | /// Determines if channel A is in FIFO mode 81 | /// 82 | public bool IFAIsFifo = false; 83 | 84 | /// 85 | /// Determines if channel A is in FIFO target mode 86 | /// 87 | public bool IFAIsFifoTar = false; 88 | 89 | /// 90 | /// Determines if channel A is in fast serial mode 91 | /// 92 | public bool IFAIsFastSer = false; 93 | 94 | /// 95 | /// Determines if channel A loads the VCP driver 96 | /// 97 | public bool AIsVCP = true; 98 | 99 | /// 100 | /// Determines if channel B is in FIFO mode 101 | /// 102 | public bool IFBIsFifo = false; 103 | 104 | /// 105 | /// Determines if channel B is in FIFO target mode 106 | /// 107 | public bool IFBIsFifoTar = false; 108 | 109 | /// 110 | /// Determines if channel B is in fast serial mode 111 | /// 112 | public bool IFBIsFastSer = false; 113 | 114 | /// 115 | /// Determines if channel B loads the VCP driver 116 | /// 117 | public bool BIsVCP = true; 118 | 119 | /// 120 | /// For self-powered designs, keeps the FT2232H in low power state until BCBUS7 is high 121 | /// 122 | public bool PowerSaveEnable = false; 123 | } 124 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/EEPROM_STRUCTURES/FT2232_EEPROM_STRUCTURE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX.EEPROM_STRUCTURES; 2 | 3 | /// 4 | /// EEPROM structure specific to FT2232 devices. 5 | /// Inherits from FT_EEPROM_DATA. 6 | /// 7 | public class FT2232_EEPROM_STRUCTURE : FT_EEPROM_DATA 8 | { 9 | /// 10 | /// Determines if IOs are pulled down when the device is in suspend 11 | /// 12 | public bool PullDownEnable = false; 13 | 14 | /// 15 | /// Determines if the serial number is enabled 16 | /// 17 | public bool SerNumEnable = true; 18 | 19 | /// 20 | /// Determines if the USB version number is enabled 21 | /// 22 | public bool USBVersionEnable = true; 23 | 24 | /// 25 | /// The USB version number. Should be either 0x0110 (USB 1.1) or 0x0200 (USB 2.0) 26 | /// 27 | public ushort USBVersion = 0x0200; 28 | 29 | /// 30 | /// Enables high current IOs on channel A 31 | /// 32 | public bool AIsHighCurrent = false; 33 | 34 | /// 35 | /// Enables high current IOs on channel B 36 | /// 37 | public bool BIsHighCurrent = false; 38 | 39 | /// 40 | /// Determines if channel A is in FIFO mode 41 | /// 42 | public bool IFAIsFifo = false; 43 | 44 | /// 45 | /// Determines if channel A is in FIFO target mode 46 | /// 47 | public bool IFAIsFifoTar = false; 48 | 49 | /// 50 | /// Determines if channel A is in fast serial mode 51 | /// 52 | public bool IFAIsFastSer = false; 53 | 54 | /// 55 | /// Determines if channel A loads the VCP driver 56 | /// 57 | public bool AIsVCP = true; 58 | 59 | /// 60 | /// Determines if channel B is in FIFO mode 61 | /// 62 | public bool IFBIsFifo = false; 63 | 64 | /// 65 | /// Determines if channel B is in FIFO target mode 66 | /// 67 | public bool IFBIsFifoTar = false; 68 | 69 | /// 70 | /// Determines if channel B is in fast serial mode 71 | /// 72 | public bool IFBIsFastSer = false; 73 | 74 | /// 75 | /// Determines if channel B loads the VCP driver 76 | /// 77 | public bool BIsVCP = true; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/EEPROM_STRUCTURES/FT232B_EEPROM_STRUCTURE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX.EEPROM_STRUCTURES; 2 | 3 | /// 4 | /// EEPROM structure specific to FT232B and FT245B devices. 5 | /// Inherits from FT_EEPROM_DATA. 6 | /// 7 | public class FT232B_EEPROM_STRUCTURE : FT_EEPROM_DATA 8 | { 9 | /// 10 | /// Determines if IOs are pulled down when the device is in suspend 11 | /// 12 | public bool PullDownEnable = false; 13 | 14 | /// 15 | /// Determines if the serial number is enabled 16 | /// 17 | public bool SerNumEnable = true; 18 | 19 | /// 20 | /// Determines if the USB version number is enabled 21 | /// 22 | public bool USBVersionEnable = true; 23 | 24 | /// 25 | /// The USB version number. Should be either 0x0110 (USB 1.1) or 0x0200 (USB 2.0) 26 | /// 27 | public ushort USBVersion = 0x0200; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/EEPROM_STRUCTURES/FT232R_EEPROM_STRUCTURE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX.EEPROM_STRUCTURES; 2 | 3 | /// 4 | /// EEPROM structure specific to FT232R and FT245R devices. 5 | /// Inherits from FT_EEPROM_DATA. 6 | /// 7 | public class FT232R_EEPROM_STRUCTURE : FT_EEPROM_DATA 8 | { 9 | /// 10 | /// Disables the FT232R internal clock source. 11 | /// If the device has external oscillator enabled it must have an external oscillator fitted to function 12 | /// 13 | public bool UseExtOsc = false; 14 | 15 | /// 16 | /// Enables high current IOs 17 | /// 18 | public bool HighDriveIOs = false; 19 | 20 | /// 21 | /// Sets the endpoint size. This should always be set to 64 22 | /// 23 | public byte EndpointSize = 64; 24 | 25 | /// 26 | /// Determines if IOs are pulled down when the device is in suspend 27 | /// 28 | public bool PullDownEnable = false; 29 | 30 | /// 31 | /// Determines if the serial number is enabled 32 | /// 33 | public bool SerNumEnable = true; 34 | 35 | /// 36 | /// Inverts the sense of the TXD line 37 | /// 38 | public bool InvertTXD = false; 39 | 40 | /// 41 | /// Inverts the sense of the RXD line 42 | /// 43 | public bool InvertRXD = false; 44 | 45 | /// 46 | /// Inverts the sense of the RTS line 47 | /// 48 | public bool InvertRTS = false; 49 | 50 | /// 51 | /// Inverts the sense of the CTS line 52 | /// 53 | public bool InvertCTS = false; 54 | 55 | /// 56 | /// Inverts the sense of the DTR line 57 | /// 58 | public bool InvertDTR = false; 59 | 60 | /// 61 | /// Inverts the sense of the DSR line 62 | /// 63 | public bool InvertDSR = false; 64 | 65 | /// 66 | /// Inverts the sense of the DCD line 67 | /// 68 | public bool InvertDCD = false; 69 | 70 | /// 71 | /// Inverts the sense of the RI line 72 | /// 73 | public bool InvertRI = false; 74 | 75 | /// 76 | /// Sets the function of the CBUS0 pin for FT232R devices. 77 | /// Valid values are FT_CBUS_TXDEN, FT_CBUS_PWRON , FT_CBUS_RXLED, FT_CBUS_TXLED, 78 | /// FT_CBUS_TXRXLED, FT_CBUS_SLEEP, FT_CBUS_CLK48, FT_CBUS_CLK24, FT_CBUS_CLK12, 79 | /// FT_CBUS_CLK6, FT_CBUS_IOMODE, FT_CBUS_BITBANG_WR, FT_CBUS_BITBANG_RD 80 | /// 81 | public byte Cbus0 = FT_CBUS_OPTIONS.FT_CBUS_SLEEP; 82 | 83 | /// 84 | /// Sets the function of the CBUS1 pin for FT232R devices. 85 | /// Valid values are FT_CBUS_TXDEN, FT_CBUS_PWRON , FT_CBUS_RXLED, FT_CBUS_TXLED, 86 | /// FT_CBUS_TXRXLED, FT_CBUS_SLEEP, FT_CBUS_CLK48, FT_CBUS_CLK24, FT_CBUS_CLK12, 87 | /// FT_CBUS_CLK6, FT_CBUS_IOMODE, FT_CBUS_BITBANG_WR, FT_CBUS_BITBANG_RD 88 | /// 89 | public byte Cbus1 = FT_CBUS_OPTIONS.FT_CBUS_SLEEP; 90 | 91 | /// 92 | /// Sets the function of the CBUS2 pin for FT232R devices. 93 | /// Valid values are FT_CBUS_TXDEN, FT_CBUS_PWRON , FT_CBUS_RXLED, FT_CBUS_TXLED, 94 | /// FT_CBUS_TXRXLED, FT_CBUS_SLEEP, FT_CBUS_CLK48, FT_CBUS_CLK24, FT_CBUS_CLK12, 95 | /// FT_CBUS_CLK6, FT_CBUS_IOMODE, FT_CBUS_BITBANG_WR, FT_CBUS_BITBANG_RD 96 | /// 97 | public byte Cbus2 = FT_CBUS_OPTIONS.FT_CBUS_SLEEP; 98 | 99 | /// 100 | /// Sets the function of the CBUS3 pin for FT232R devices. 101 | /// Valid values are FT_CBUS_TXDEN, FT_CBUS_PWRON , FT_CBUS_RXLED, FT_CBUS_TXLED, 102 | /// FT_CBUS_TXRXLED, FT_CBUS_SLEEP, FT_CBUS_CLK48, FT_CBUS_CLK24, FT_CBUS_CLK12, 103 | /// FT_CBUS_CLK6, FT_CBUS_IOMODE, FT_CBUS_BITBANG_WR, FT_CBUS_BITBANG_RD 104 | /// 105 | public byte Cbus3 = FT_CBUS_OPTIONS.FT_CBUS_SLEEP; 106 | 107 | /// 108 | /// Sets the function of the CBUS4 pin for FT232R devices. 109 | /// Valid values are FT_CBUS_TXDEN, FT_CBUS_PWRON , FT_CBUS_RXLED, FT_CBUS_TXLED, 110 | /// FT_CBUS_TXRXLED, FT_CBUS_SLEEP, FT_CBUS_CLK48, FT_CBUS_CLK24, FT_CBUS_CLK12, 111 | /// FT_CBUS_CLK6 112 | /// 113 | public byte Cbus4 = FT_CBUS_OPTIONS.FT_CBUS_SLEEP; 114 | 115 | /// 116 | /// Determines if the VCP driver is loaded 117 | /// 118 | public bool RIsD2XX = false; 119 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/EEPROM_STRUCTURES/FT4232H_EEPROM_STRUCTURE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX.EEPROM_STRUCTURES; 2 | 3 | /// 4 | /// EEPROM structure specific to FT4232H devices. 5 | /// Inherits from FT_EEPROM_DATA. 6 | /// 7 | public class FT4232H_EEPROM_STRUCTURE : FT_EEPROM_DATA 8 | { 9 | /// 10 | /// Determines if IOs are pulled down when the device is in suspend 11 | /// 12 | public bool PullDownEnable = false; 13 | 14 | /// 15 | /// Determines if the serial number is enabled 16 | /// 17 | public bool SerNumEnable = true; 18 | 19 | /// 20 | /// Determines if A pins have a slow slew rate 21 | /// 22 | public bool ASlowSlew = false; 23 | 24 | /// 25 | /// Determines if the A pins have a Schmitt input 26 | /// 27 | public bool ASchmittInput = false; 28 | 29 | /// 30 | /// Determines the A pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 31 | /// 32 | public byte ADriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 33 | 34 | /// 35 | /// Determines if B pins have a slow slew rate 36 | /// 37 | public bool BSlowSlew = false; 38 | 39 | /// 40 | /// Determines if the B pins have a Schmitt input 41 | /// 42 | public bool BSchmittInput = false; 43 | 44 | /// 45 | /// Determines the B pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 46 | /// 47 | public byte BDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 48 | 49 | /// 50 | /// Determines if C pins have a slow slew rate 51 | /// 52 | public bool CSlowSlew = false; 53 | 54 | /// 55 | /// Determines if the C pins have a Schmitt input 56 | /// 57 | public bool CSchmittInput = false; 58 | 59 | /// 60 | /// Determines the C pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 61 | /// 62 | public byte CDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 63 | 64 | /// 65 | /// Determines if D pins have a slow slew rate 66 | /// 67 | public bool DSlowSlew = false; 68 | 69 | /// 70 | /// Determines if the D pins have a Schmitt input 71 | /// 72 | public bool DSchmittInput = false; 73 | 74 | /// 75 | /// Determines the D pins drive current in mA. Valid values are FT_DRIVE_CURRENT_4MA, FT_DRIVE_CURRENT_8MA, FT_DRIVE_CURRENT_12MA or FT_DRIVE_CURRENT_16MA 76 | /// 77 | public byte DDriveCurrent = FT_DRIVE_CURRENT.FT_DRIVE_CURRENT_4MA; 78 | 79 | /// 80 | /// RI of port A acts as RS485 transmit enable (TXDEN) 81 | /// 82 | public bool ARIIsTXDEN = false; 83 | 84 | /// 85 | /// RI of port B acts as RS485 transmit enable (TXDEN) 86 | /// 87 | public bool BRIIsTXDEN = false; 88 | 89 | /// 90 | /// RI of port C acts as RS485 transmit enable (TXDEN) 91 | /// 92 | public bool CRIIsTXDEN = false; 93 | 94 | /// 95 | /// RI of port D acts as RS485 transmit enable (TXDEN) 96 | /// 97 | public bool DRIIsTXDEN = false; 98 | 99 | /// 100 | /// Determines if channel A loads the VCP driver 101 | /// 102 | public bool AIsVCP = true; 103 | 104 | /// 105 | /// Determines if channel B loads the VCP driver 106 | /// 107 | public bool BIsVCP = true; 108 | 109 | /// 110 | /// Determines if channel C loads the VCP driver 111 | /// 112 | public bool CIsVCP = true; 113 | 114 | /// 115 | /// Determines if channel D loads the VCP driver 116 | /// 117 | public bool DIsVCP = true; 118 | } 119 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_232H_CBUS_OPTIONS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Available functions for the FT232H CBUS pins. Controlled by FT232H EEPROM settings 5 | /// 6 | public static class FT_232H_CBUS_OPTIONS 7 | { 8 | /// 9 | /// FT232H CBUS EEPROM options - Tristate 10 | /// 11 | public const byte FT_CBUS_TRISTATE = 0x00; 12 | 13 | /// 14 | /// FT232H CBUS EEPROM options - Rx LED 15 | /// 16 | public const byte FT_CBUS_RXLED = 0x01; 17 | 18 | /// 19 | /// FT232H CBUS EEPROM options - Tx LED 20 | /// 21 | public const byte FT_CBUS_TXLED = 0x02; 22 | 23 | /// 24 | /// FT232H CBUS EEPROM options - Tx and Rx LED 25 | /// 26 | public const byte FT_CBUS_TXRXLED = 0x03; 27 | 28 | /// 29 | /// FT232H CBUS EEPROM options - Power Enable# 30 | /// 31 | public const byte FT_CBUS_PWREN = 0x04; 32 | 33 | /// 34 | /// FT232H CBUS EEPROM options - Sleep 35 | /// 36 | public const byte FT_CBUS_SLEEP = 0x05; 37 | 38 | /// 39 | /// FT232H CBUS EEPROM options - Drive pin to logic 0 40 | /// 41 | public const byte FT_CBUS_DRIVE_0 = 0x06; 42 | 43 | /// 44 | /// FT232H CBUS EEPROM options - Drive pin to logic 1 45 | /// 46 | public const byte FT_CBUS_DRIVE_1 = 0x07; 47 | 48 | /// 49 | /// FT232H CBUS EEPROM options - IO Mode 50 | /// 51 | public const byte FT_CBUS_IOMODE = 0x08; 52 | 53 | /// 54 | /// FT232H CBUS EEPROM options - Tx Data Enable 55 | /// 56 | public const byte FT_CBUS_TXDEN = 0x09; 57 | 58 | /// 59 | /// FT232H CBUS EEPROM options - 30MHz clock 60 | /// 61 | public const byte FT_CBUS_CLK30 = 0x0A; 62 | 63 | /// 64 | /// FT232H CBUS EEPROM options - 15MHz clock 65 | /// 66 | public const byte FT_CBUS_CLK15 = 0x0B; 67 | 68 | /// 69 | /// FT232H CBUS EEPROM options - 7.5MHz clock 70 | /// 71 | public const byte FT_CBUS_CLK7_5 = 0x0C; 72 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_BIT_MODES.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Permitted bit mode values for FTDI devices. For use with SetBitMode 5 | /// 6 | public static class FT_BIT_MODES 7 | { 8 | /// 9 | /// Reset bit mode 10 | /// 11 | public const byte FT_BIT_MODE_RESET = 0x00; 12 | 13 | /// 14 | /// Asynchronous bit-bang mode 15 | /// 16 | public const byte FT_BIT_MODE_ASYNC_BITBANG = 0x01; 17 | 18 | /// 19 | /// MPSSE bit mode - only available on FT2232, FT2232H, FT4232H and FT232H 20 | /// 21 | public const byte FT_BIT_MODE_MPSSE = 0x02; 22 | 23 | /// 24 | /// Synchronous bit-bang mode 25 | /// 26 | public const byte FT_BIT_MODE_SYNC_BITBANG = 0x04; 27 | 28 | /// 29 | /// MCU host bus emulation mode - only available on FT2232, FT2232H, FT4232H and FT232H 30 | /// 31 | public const byte FT_BIT_MODE_MCU_HOST = 0x08; 32 | 33 | /// 34 | /// Fast opto-isolated serial mode - only available on FT2232, FT2232H, FT4232H and FT232H 35 | /// 36 | public const byte FT_BIT_MODE_FAST_SERIAL = 0x10; 37 | 38 | /// 39 | /// CBUS bit-bang mode - only available on FT232R and FT232H 40 | /// 41 | public const byte FT_BIT_MODE_CBUS_BITBANG = 0x20; 42 | 43 | /// 44 | /// Single channel synchronous 245 FIFO mode - only available on FT2232H channel A and FT232H 45 | /// 46 | public const byte FT_BIT_MODE_SYNC_FIFO = 0x40; 47 | } 48 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_CBUS_OPTIONS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Available functions for the FT232R CBUS pins. Controlled by FT232R EEPROM settings 5 | /// 6 | public class FT_CBUS_OPTIONS 7 | { 8 | /// 9 | /// FT232R CBUS EEPROM options - Tx Data Enable 10 | /// 11 | public const byte FT_CBUS_TXDEN = 0x00; 12 | 13 | /// 14 | /// FT232R CBUS EEPROM options - Power On 15 | /// 16 | public const byte FT_CBUS_PWRON = 0x01; 17 | 18 | /// 19 | /// FT232R CBUS EEPROM options - Rx LED 20 | /// 21 | public const byte FT_CBUS_RXLED = 0x02; 22 | 23 | /// 24 | /// FT232R CBUS EEPROM options - Tx LED 25 | /// 26 | public const byte FT_CBUS_TXLED = 0x03; 27 | 28 | /// 29 | /// FT232R CBUS EEPROM options - Tx and Rx LED 30 | /// 31 | public const byte FT_CBUS_TXRXLED = 0x04; 32 | 33 | /// 34 | /// FT232R CBUS EEPROM options - Sleep 35 | /// 36 | public const byte FT_CBUS_SLEEP = 0x05; 37 | 38 | /// 39 | /// FT232R CBUS EEPROM options - 48MHz clock 40 | /// 41 | public const byte FT_CBUS_CLK48 = 0x06; 42 | 43 | /// 44 | /// FT232R CBUS EEPROM options - 24MHz clock 45 | /// 46 | public const byte FT_CBUS_CLK24 = 0x07; 47 | 48 | /// 49 | /// FT232R CBUS EEPROM options - 12MHz clock 50 | /// 51 | public const byte FT_CBUS_CLK12 = 0x08; 52 | 53 | /// 54 | /// FT232R CBUS EEPROM options - 6MHz clock 55 | /// 56 | public const byte FT_CBUS_CLK6 = 0x09; 57 | 58 | /// 59 | /// FT232R CBUS EEPROM options - IO mode 60 | /// 61 | public const byte FT_CBUS_IOMODE = 0x0A; 62 | 63 | /// 64 | /// FT232R CBUS EEPROM options - Bit-bang write strobe 65 | /// 66 | public const byte FT_CBUS_BITBANG_WR = 0x0B; 67 | 68 | /// 69 | /// FT232R CBUS EEPROM options - Bit-bang read strobe 70 | /// 71 | public const byte FT_CBUS_BITBANG_RD = 0x0C; 72 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_DATA_BITS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Permitted data bits for FTDI devices 5 | /// 6 | public static class FT_DATA_BITS 7 | { 8 | /// 9 | /// 8 data bits 10 | /// 11 | public const byte FT_BITS_8 = 0x08; 12 | 13 | /// 14 | /// 7 data bits 15 | /// 16 | public const byte FT_BITS_7 = 0x07; 17 | } 18 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_DEFAULT_VALUES.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | public static class FT_DEFAULT_VALUES 4 | { 5 | public const UInt32 FT_DEFAULT_BAUD_RATE = 9600; 6 | public const UInt32 FT_DEFAULT_DEADMAN_TIMEOUT = 5000; 7 | public const Int32 FT_COM_PORT_NOT_ASSIGNED = -1; 8 | public const UInt32 FT_DEFAULT_IN_TRANSFER_SIZE = 0x1000; 9 | public const UInt32 FT_DEFAULT_OUT_TRANSFER_SIZE = 0x1000; 10 | public const byte FT_DEFAULT_LATENCY = 16; 11 | public const UInt32 FT_DEFAULT_DEVICE_ID = 0x04036001; 12 | } 13 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_DEVICE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// List of FTDI device types 5 | /// 6 | public enum FT_DEVICE 7 | { 8 | /// 9 | /// FT232B or FT245B device 10 | /// 11 | FT_DEVICE_BM = 0, 12 | 13 | /// 14 | /// FT8U232AM or FT8U245AM device 15 | /// 16 | FT_DEVICE_AM, 17 | 18 | /// 19 | /// FT8U100AX device 20 | /// 21 | FT_DEVICE_100AX, 22 | 23 | /// 24 | /// Unknown device 25 | /// 26 | FT_DEVICE_UNKNOWN, 27 | 28 | /// 29 | /// FT2232 device 30 | /// 31 | FT_DEVICE_2232, 32 | 33 | /// 34 | /// FT232R or FT245R device 35 | /// 36 | FT_DEVICE_232R, 37 | 38 | /// 39 | /// FT2232H device 40 | /// 41 | FT_DEVICE_2232H, 42 | 43 | /// 44 | /// FT4232H device 45 | /// 46 | FT_DEVICE_4232H, 47 | 48 | /// 49 | /// FT232H device 50 | /// 51 | FT_DEVICE_232H, 52 | 53 | /// 54 | /// FT X-Series device 55 | /// 56 | FT_DEVICE_X_SERIES, 57 | 58 | /// 59 | /// FT4222 hi-speed device Mode 0 - 2 interfaces 60 | /// 61 | FT_DEVICE_4222H_0, 62 | 63 | /// 64 | /// FT4222 hi-speed device Mode 1 or 2 - 4 interfaces 65 | /// 66 | FT_DEVICE_4222H_1_2, 67 | 68 | /// 69 | /// FT4222 hi-speed device Mode 3 - 1 interface 70 | /// 71 | FT_DEVICE_4222H_3, 72 | 73 | /// 74 | /// OTP programmer board for the FT4222. 75 | /// 76 | FT_DEVICE_4222_PROG, 77 | 78 | /// 79 | /// OTP programmer board for the FT900. 80 | /// 81 | FT_DEVICE_FT900, 82 | 83 | /// 84 | /// OTP programmer board for the FT930. 85 | /// 86 | FT_DEVICE_FT930, 87 | 88 | /// 89 | /// Flash programmer board for the UMFTPD3A. 90 | /// 91 | FT_DEVICE_UMFTPD3A, 92 | 93 | /// 94 | /// FT2233HP hi-speed device. 95 | /// 96 | FT_DEVICE_2233HP, 97 | 98 | /// 99 | /// FT4233HP hi-speed device. 100 | /// 101 | FT_DEVICE_4233HP, 102 | 103 | /// 104 | /// FT2233HP hi-speed device. 105 | /// 106 | FT_DEVICE_2232HP, 107 | 108 | /// 109 | /// FT4233HP hi-speed device. 110 | /// 111 | FT_DEVICE_4232HP, 112 | 113 | /// 114 | /// FT233HP hi-speed device. 115 | /// 116 | FT_DEVICE_233HP, 117 | 118 | /// 119 | /// FT232HP hi-speed device. 120 | /// 121 | FT_DEVICE_232HP, 122 | 123 | /// 124 | /// FT2233HA hi-speed device. 125 | /// 126 | FT_DEVICE_2232HA, 127 | 128 | /// 129 | /// FT4233HA hi-speed device. 130 | /// 131 | FT_DEVICE_4232HA, 132 | }; 133 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_DEVICE_INFO_NODE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Type that holds device information for GetDeviceInformation method. 5 | /// Used with FT_GetDeviceInfo and FT_GetDeviceInfoDetail in FTD2XX.DLL 6 | /// 7 | public class FT_DEVICE_INFO_NODE 8 | { 9 | /// 10 | /// Indicates device state. 11 | /// Can be any combination of the following: FT_FLAGS_OPENED, FT_FLAGS_HISPEED 12 | /// Bit 0 (least significant bit) indicates if the port is open (1) or closed (0). 13 | /// Bit 1 indicates if the device is enumerated as a high-speed USB device (2) or a full-speed USB device (0). 14 | /// 15 | public UInt32 Flags; 16 | 17 | /// 18 | /// Indicates the device type. Can be one of the following: FT_DEVICE_232R, FT_DEVICE_2232C, FT_DEVICE_BM, FT_DEVICE_AM, FT_DEVICE_100AX or FT_DEVICE_UNKNOWN 19 | /// 20 | public FT_DEVICE Type; 21 | 22 | /// 23 | /// The Vendor ID and Product ID of the device 24 | /// 25 | public UInt32 ID; 26 | 27 | /// 28 | /// The physical location identifier of the device 29 | /// 30 | public UInt32 LocId; 31 | 32 | /// 33 | /// The device serial number 34 | /// 35 | public string SerialNumber = string.Empty; 36 | 37 | /// 38 | /// The device description 39 | /// 40 | public string Description = string.Empty; 41 | 42 | /// 43 | /// The device handle. This value is not used externally and is provided for information only. 44 | /// If the device is not open, this value is 0. 45 | /// 46 | public IntPtr ftHandle; 47 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_DRIVE_CURRENT.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Valid values for drive current options on FT2232H, FT4232H and FT232H devices. 5 | /// 6 | public static class FT_DRIVE_CURRENT 7 | { 8 | /// 9 | /// 4mA drive current 10 | /// 11 | public const byte FT_DRIVE_CURRENT_4MA = 4; 12 | 13 | /// 14 | /// 8mA drive current 15 | /// 16 | public const byte FT_DRIVE_CURRENT_8MA = 8; 17 | 18 | /// 19 | /// 12mA drive current 20 | /// 21 | public const byte FT_DRIVE_CURRENT_12MA = 12; 22 | 23 | /// 24 | /// 16mA drive current 25 | /// 26 | public const byte FT_DRIVE_CURRENT_16MA = 16; 27 | } 28 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_EEPROM_DATA.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Common EEPROM elements for all devices. Inherited to specific device type EEPROMs. 5 | /// 6 | public abstract class FT_EEPROM_DATA 7 | { 8 | /// 9 | /// Vendor ID as supplied by the USB Implementers Forum 10 | /// 11 | public UInt16 VendorID = 0x0403; 12 | 13 | /// 14 | /// Product ID 15 | /// 16 | public UInt16 ProductID = 0x6001; 17 | 18 | /// 19 | /// Manufacturer name string 20 | /// 21 | public string Manufacturer = "FTDI"; 22 | 23 | /// 24 | /// Manufacturer name abbreviation to be used as a prefix for automatically generated serial numbers 25 | /// 26 | public string ManufacturerID = "FT"; 27 | 28 | /// 29 | /// Device description string 30 | /// 31 | public string Description = "USB-Serial Converter"; 32 | 33 | /// 34 | /// Device serial number string 35 | /// 36 | public string SerialNumber = ""; 37 | 38 | /// 39 | /// Maximum power the device needs 40 | /// 41 | public UInt16 MaxPower = 0x0090; 42 | 43 | //private bool PnP = true; 44 | /// 45 | /// Indicates if the device has its own power supply (self-powered) or gets power from the USB port (bus-powered) 46 | /// 47 | public bool SelfPowered = false; 48 | 49 | /// 50 | /// Determines if the device can wake the host PC from suspend by toggling the RI line 51 | /// 52 | public bool RemoteWakeup = false; 53 | } 54 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_EEPROM_HEADER.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 4 | struct FT_EEPROM_HEADER 5 | { 6 | public UInt32 deviceType; // FTxxxx device type to be programmed 7 | // Device descriptor options 8 | public UInt16 VendorId; // 0x0403 9 | public UInt16 ProductId; // 0x6001 10 | public byte SerNumEnable; // non-zero if serial number to be used 11 | // Config descriptor options 12 | public UInt16 MaxPower; // 0 < MaxPower <= 500 13 | public byte SelfPowered; // 0 = bus powered, 1 = self powered 14 | public byte RemoteWakeup; // 0 = not capable, 1 = capable 15 | // Hardware options 16 | public byte PullDownEnable; // non-zero if pull down in suspend enabled 17 | } 18 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_ERROR.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Error states not supported by FTD2XX DLL. 5 | /// 6 | public enum FT_ERROR 7 | { 8 | FT_NO_ERROR = 0, 9 | FT_INCORRECT_DEVICE, 10 | FT_INVALID_BITMODE, 11 | FT_BUFFER_SIZE 12 | }; 13 | 14 | public static class FT_ERROR_EXTENSIONS 15 | { 16 | public static bool IsOK(this FT_ERROR error) 17 | { 18 | return error == FT_ERROR.FT_NO_ERROR; 19 | } 20 | 21 | public static void ThrowIfNotOK(this FT_ERROR error) 22 | { 23 | switch (error) 24 | { 25 | case FT_ERROR.FT_NO_ERROR: 26 | return; 27 | case FT_ERROR.FT_INCORRECT_DEVICE: 28 | throw new FT_EXCEPTION("The current device type does not match the EEPROM structure."); 29 | case FT_ERROR.FT_INVALID_BITMODE: 30 | throw new FT_EXCEPTION("The requested bit mode is not valid for the current device."); 31 | case FT_ERROR.FT_BUFFER_SIZE: 32 | throw new FT_EXCEPTION("The supplied buffer is not big enough."); 33 | default: 34 | throw new FT_EXCEPTION($"Unknown Error: {error}"); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_EVENTS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// FTDI device event types that can be monitored 5 | /// 6 | public static class FT_EVENTS 7 | { 8 | /// 9 | /// Event on receive character 10 | /// 11 | public const UInt32 FT_EVENT_RXCHAR = 0x00000001; 12 | 13 | /// 14 | /// Event on modem status change 15 | /// 16 | public const UInt32 FT_EVENT_MODEM_STATUS = 0x00000002; 17 | 18 | /// 19 | /// Event on line status change 20 | /// 21 | public const UInt32 FT_EVENT_LINE_STATUS = 0x00000004; 22 | } 23 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_EXCEPTION.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Exceptions thrown by errors within the FTDI class. 5 | /// 6 | [Serializable] 7 | public class FT_EXCEPTION : Exception 8 | { 9 | /// 10 | /// 11 | /// 12 | public FT_EXCEPTION() { } 13 | /// 14 | /// 15 | /// 16 | /// 17 | public FT_EXCEPTION(string message) : base(message) { } 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | public FT_EXCEPTION(string message, Exception inner) : base(message, inner) { } 24 | /// 25 | /// 26 | /// 27 | /// 28 | /// 29 | protected FT_EXCEPTION( 30 | System.Runtime.Serialization.SerializationInfo info, 31 | System.Runtime.Serialization.StreamingContext context) 32 | : base(info, context) { } 33 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_FLAGS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Flags that provide information on the FTDI device state 5 | /// 6 | public static class FT_FLAGS 7 | { 8 | /// 9 | /// Indicates that the device is open 10 | /// 11 | public const UInt32 FT_FLAGS_OPENED = 0x00000001; 12 | 13 | /// 14 | /// Indicates that the device is enumerated as a hi-speed USB device 15 | /// 16 | public const UInt32 FT_FLAGS_HISPEED = 0x00000002; 17 | } 18 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_FLOW_CONTROL.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Permitted flow control values for FTDI devices 5 | /// 6 | public static class FT_FLOW_CONTROL 7 | { 8 | /// 9 | /// No flow control 10 | /// 11 | public const UInt16 FT_FLOW_NONE = 0x0000; 12 | 13 | /// 14 | /// RTS/CTS flow control 15 | /// 16 | public const UInt16 FT_FLOW_RTS_CTS = 0x0100; 17 | 18 | /// 19 | /// DTR/DSR flow control 20 | /// 21 | public const UInt16 FT_FLOW_DTR_DSR = 0x0200; 22 | 23 | /// 24 | /// Xon/Xoff flow control 25 | /// 26 | public const UInt16 FT_FLOW_XON_XOFF = 0x0400; 27 | } 28 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_LINE_STATUS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Line status bit definitions 5 | /// 6 | public static class FT_LINE_STATUS 7 | { 8 | /// 9 | /// Overrun Error (OE) line status 10 | /// 11 | public const byte FT_OE = 0x02; 12 | 13 | /// 14 | /// Parity Error (PE) line status 15 | /// 16 | public const byte FT_PE = 0x04; 17 | 18 | /// 19 | /// Framing Error (FE) line status 20 | /// 21 | public const byte FT_FE = 0x08; 22 | 23 | /// 24 | /// Break Interrupt (BI) line status 25 | /// 26 | public const byte FT_BI = 0x10; 27 | } 28 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_MODEM_STATUS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Modem status bit definitions 5 | /// 6 | public static class FT_MODEM_STATUS 7 | { 8 | /// 9 | /// Clear To Send (CTS) modem status 10 | /// 11 | public const byte FT_CTS = 0x10; 12 | 13 | /// 14 | /// Data Set Ready (DSR) modem status 15 | /// 16 | public const byte FT_DSR = 0x20; 17 | 18 | /// 19 | /// Ring Indicator (RI) modem status 20 | /// 21 | public const byte FT_RI = 0x40; 22 | 23 | /// 24 | /// Data Carrier Detect (DCD) modem status 25 | /// 26 | public const byte FT_DCD = 0x80; 27 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_OPEN.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | public static class FT_OPEN 4 | { 5 | public const UInt32 BY_SERIAL_NUMBER = 0x00000001; 6 | public const UInt32 BY_DESCRIPTION = 0x00000002; 7 | public const UInt32 BY_LOCATION = 0x00000004; 8 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_PARITY.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Permitted parity values for FTDI devices 5 | /// 6 | public static class FT_PARITY 7 | { 8 | /// 9 | /// No parity 10 | /// 11 | public const byte FT_PARITY_NONE = 0x00; 12 | 13 | /// 14 | /// Odd parity 15 | /// 16 | public const byte FT_PARITY_ODD = 0x01; 17 | 18 | /// 19 | /// Even parity 20 | /// 21 | public const byte FT_PARITY_EVEN = 0x02; 22 | 23 | /// 24 | /// Mark parity 25 | /// 26 | public const byte FT_PARITY_MARK = 0x03; 27 | 28 | /// 29 | /// Space parity 30 | /// 31 | public const byte FT_PARITY_SPACE = 0x04; 32 | } 33 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_PURGE.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Purge buffer constant definitions 5 | /// 6 | public static class FT_PURGE 7 | { 8 | /// 9 | /// Purge Rx buffer 10 | /// 11 | public const byte FT_PURGE_RX = 0x01; 12 | 13 | /// 14 | /// Purge Tx buffer 15 | /// 16 | public const byte FT_PURGE_TX = 0x02; 17 | } -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_STOP_BITS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Permitted stop bits for FTDI devices 5 | /// 6 | public static class FT_STOP_BITS 7 | { 8 | /// 9 | /// 1 stop bit 10 | /// 11 | public const byte FT_STOP_BITS_1 = 0x00; 12 | 13 | /// 14 | /// 2 stop bits 15 | /// 16 | public const byte FT_STOP_BITS_2 = 0x02; 17 | } 18 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_XSERIES_CBUS_OPTIONS.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | /// 4 | /// Available functions for the X-Series CBUS pins. Controlled by X-Series EEPROM settings 5 | /// 6 | public static class FT_XSERIES_CBUS_OPTIONS 7 | { 8 | /// 9 | /// FT X-Series CBUS EEPROM options - Tristate 10 | /// 11 | public const byte FT_CBUS_TRISTATE = 0x00; 12 | 13 | /// 14 | /// FT X-Series CBUS EEPROM options - RxLED# 15 | /// 16 | public const byte FT_CBUS_RXLED = 0x01; 17 | 18 | /// 19 | /// FT X-Series CBUS EEPROM options - TxLED# 20 | /// 21 | public const byte FT_CBUS_TXLED = 0x02; 22 | 23 | /// 24 | /// FT X-Series CBUS EEPROM options - TxRxLED# 25 | /// 26 | public const byte FT_CBUS_TXRXLED = 0x03; 27 | 28 | /// 29 | /// FT X-Series CBUS EEPROM options - PwrEn# 30 | /// 31 | public const byte FT_CBUS_PWREN = 0x04; 32 | 33 | /// 34 | /// FT X-Series CBUS EEPROM options - Sleep# 35 | /// 36 | public const byte FT_CBUS_SLEEP = 0x05; 37 | 38 | /// 39 | /// FT X-Series CBUS EEPROM options - Drive_0 40 | /// 41 | public const byte FT_CBUS_Drive_0 = 0x06; 42 | 43 | /// 44 | /// FT X-Series CBUS EEPROM options - Drive_1 45 | /// 46 | public const byte FT_CBUS_Drive_1 = 0x07; 47 | 48 | /// 49 | /// FT X-Series CBUS EEPROM options - GPIO 50 | /// 51 | public const byte FT_CBUS_GPIO = 0x08; 52 | 53 | /// 54 | /// FT X-Series CBUS EEPROM options - TxdEn 55 | /// 56 | public const byte FT_CBUS_TXDEN = 0x09; 57 | 58 | /// 59 | /// FT X-Series CBUS EEPROM options - Clk24MHz 60 | /// 61 | public const byte FT_CBUS_CLK24MHz = 0x0A; 62 | 63 | /// 64 | /// FT X-Series CBUS EEPROM options - Clk12MHz 65 | /// 66 | public const byte FT_CBUS_CLK12MHz = 0x0B; 67 | 68 | /// 69 | /// FT X-Series CBUS EEPROM options - Clk6MHz 70 | /// 71 | public const byte FT_CBUS_CLK6MHz = 0x0C; 72 | 73 | /// 74 | /// FT X-Series CBUS EEPROM options - BCD_Charger 75 | /// 76 | public const byte FT_CBUS_BCD_Charger = 0x0D; 77 | 78 | /// 79 | /// FT X-Series CBUS EEPROM options - BCD_Charger# 80 | /// 81 | public const byte FT_CBUS_BCD_Charger_N = 0x0E; 82 | 83 | /// 84 | /// FT X-Series CBUS EEPROM options - I2C_TXE# 85 | /// 86 | public const byte FT_CBUS_I2C_TXE = 0x0F; 87 | 88 | /// 89 | /// FT X-Series CBUS EEPROM options - I2C_RXF# 90 | /// 91 | public const byte FT_CBUS_I2C_RXF = 0x10; 92 | 93 | /// 94 | /// FT X-Series CBUS EEPROM options - VBUS_Sense 95 | /// 96 | public const byte FT_CBUS_VBUS_Sense = 0x11; 97 | 98 | /// 99 | /// FT X-Series CBUS EEPROM options - BitBang_WR# 100 | /// 101 | public const byte FT_CBUS_BitBang_WR = 0x12; 102 | 103 | /// 104 | /// FT X-Series CBUS EEPROM options - BitBang_RD# 105 | /// 106 | public const byte FT_CBUS_BitBang_RD = 0x13; 107 | 108 | /// 109 | /// FT X-Series CBUS EEPROM options - Time_Stampe 110 | /// 111 | public const byte FT_CBUS_Time_Stamp = 0x14; 112 | 113 | /// 114 | /// FT X-Series CBUS EEPROM options - Keep_Awake# 115 | /// 116 | public const byte FT_CBUS_Keep_Awake = 0x15; 117 | } 118 | -------------------------------------------------------------------------------- /src/FtdiSharp/FTD2XX/FT_XSERIES_DATA.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharp.FTD2XX; 2 | 3 | [StructLayout(LayoutKind.Sequential, Pack = 4)] 4 | struct FT_XSERIES_DATA 5 | { 6 | public FT_EEPROM_HEADER common; 7 | 8 | public byte ACSlowSlew; // non-zero if AC bus pins have slow slew 9 | public byte ACSchmittInput; // non-zero if AC bus pins are Schmitt input 10 | public byte ACDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA 11 | public byte ADSlowSlew; // non-zero if AD bus pins have slow slew 12 | public byte ADSchmittInput; // non-zero if AD bus pins are Schmitt input 13 | public byte ADDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA 14 | // CBUS options 15 | public byte Cbus0; // Cbus Mux control 16 | public byte Cbus1; // Cbus Mux control 17 | public byte Cbus2; // Cbus Mux control 18 | public byte Cbus3; // Cbus Mux control 19 | public byte Cbus4; // Cbus Mux control 20 | public byte Cbus5; // Cbus Mux control 21 | public byte Cbus6; // Cbus Mux control 22 | // UART signal options 23 | public byte InvertTXD; // non-zero if invert TXD 24 | public byte InvertRXD; // non-zero if invert RXD 25 | public byte InvertRTS; // non-zero if invert RTS 26 | public byte InvertCTS; // non-zero if invert CTS 27 | public byte InvertDTR; // non-zero if invert DTR 28 | public byte InvertDSR; // non-zero if invert DSR 29 | public byte InvertDCD; // non-zero if invert DCD 30 | public byte InvertRI; // non-zero if invert RI 31 | // Battery Charge Detect options 32 | public byte BCDEnable; // Enable Battery Charger Detection 33 | public byte BCDForceCbusPWREN; // asserts the power enable signal on CBUS when charging port detected 34 | public byte BCDDisableSleep; // forces the device never to go into sleep mode 35 | // I2C options 36 | public UInt16 I2CSlaveAddress; // I2C slave device address 37 | public UInt32 I2CDeviceId; // I2C device ID 38 | public byte I2CDisableSchmitt; // Disable I2C Schmitt trigger 39 | // FT1248 options 40 | public byte FT1248Cpol; // FT1248 clock polarity - clock idle high (1) or clock idle low (0) 41 | public byte FT1248Lsb; // FT1248 data is LSB (1) or MSB (0) 42 | public byte FT1248FlowControl; // FT1248 flow control enable 43 | // Hardware options 44 | public byte RS485EchoSuppress; // 45 | public byte PowerSaveEnable; // 46 | // Driver option 47 | public byte DriverType; // 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/FtdiSharp/FtdiDevice.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp.FTD2XX; 2 | 3 | namespace FtdiSharp; 4 | 5 | public struct FtdiDevice 6 | { 7 | public int Index; 8 | public bool IsOpen; 9 | public bool IsHighSpeed; 10 | public string Type; 11 | public UInt32 ID; 12 | public UInt32 LocationID; 13 | public string SerialNumber; 14 | public string Description; 15 | 16 | public override string ToString() 17 | { 18 | return $"{Type} ({ID})"; 19 | } 20 | } 21 | 22 | public static class DeviceInfoExtensions 23 | { 24 | public static FtdiDevice ToDevice(this FT_DEVICE_INFO_NODE device, int index) 25 | { 26 | return new FtdiDevice() 27 | { 28 | Index = index, 29 | IsOpen = (device.Flags & 0b01) > 0, 30 | IsHighSpeed = (device.Flags & 0b10) > 0, 31 | Type = device.Type.ToReadableName(), 32 | ID = device.ID, 33 | LocationID = device.LocId, 34 | SerialNumber = device.SerialNumber, 35 | Description = device.Description, 36 | }; 37 | } 38 | 39 | public static string ToReadableName(this FT_DEVICE device) 40 | { 41 | return device.ToString()!.Split('_')[2]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/FtdiSharp/FtdiDevices.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace FtdiSharp; 4 | 5 | public static class FtdiDevices 6 | { 7 | /// 8 | /// Returns all FTDI devices connected to the computer 9 | /// 10 | public static FtdiDevice[] Scan() 11 | { 12 | FTD2XX.FTDI ftdi = new(); 13 | 14 | UInt32 numDevices = 0; 15 | ftdi.GetNumberOfDevices(ref numDevices); 16 | 17 | FTD2XX.FT_DEVICE_INFO_NODE[] nodes = new FTD2XX.FT_DEVICE_INFO_NODE[numDevices]; 18 | ftdi.GetDeviceList(nodes); 19 | 20 | FtdiDevice[] devices = new FtdiDevice[numDevices]; 21 | for (int i = 0; i < numDevices; i++) 22 | { 23 | devices[i] = nodes[i].ToDevice(i); 24 | } 25 | 26 | return devices; 27 | } 28 | 29 | /// 30 | /// Returns the first FTDI device found connected to the computer 31 | /// 32 | public static FtdiDevice First() 33 | { 34 | FtdiDevice[] devices = Scan(); 35 | 36 | if (!devices.Any()) 37 | throw new InvalidOperationException("No connected FTDI devices found"); 38 | 39 | return devices.First(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/FtdiSharp/FtdiManager.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp.FTD2XX; 2 | 3 | namespace FtdiSharp; 4 | 5 | [Obsolete("Use a communicator.")] 6 | public class FtdiManager 7 | { 8 | public readonly FTDI FTD2XX = new(); 9 | 10 | public FtdiManager() 11 | { 12 | } 13 | 14 | public FtdiManager(FtdiDevice device) 15 | { 16 | Open(device); 17 | } 18 | 19 | public void Open(FtdiDevice device) 20 | { 21 | if (FTD2XX.IsOpen) 22 | throw new InvalidOperationException("a device is already open"); 23 | 24 | FTD2XX.OpenByIndex((uint)device.Index).ThrowIfNotOK(); 25 | 26 | FTD2XX.ResetDevice().ThrowIfNotOK(); 27 | } 28 | 29 | public void Close() 30 | { 31 | if (!FTD2XX.IsOpen) 32 | throw new InvalidOperationException("no device is open"); 33 | 34 | FTD2XX.Close().ThrowIfNotOK(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/FtdiSharp/FtdiSharp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 0.1.2 5 | 6 | net462;net6.0-windows 7 | false 8 | enable 9 | latest 10 | 11 | Scott Harden 12 | Harden Technologies, LLC 13 | MIT 14 | FTDI serial USB controller USART UART I2C SPI FIFO FT232 15 | A simple .NET interface for FTDI USB controllers 16 | icon.png 17 | readme.md 18 | https://github.com/swharden/FtdiSharp 19 | https://github.com/swharden/FtdiSharp.git 20 | true 21 | snupkg 22 | true 23 | true 24 | true 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | runtime; build; native; contentfiles; analyzers; buildtransitive 36 | all 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/FtdiSharp/Protocols/GPIO.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp.FTD2XX; 2 | using System.Linq; 3 | 4 | namespace FtdiSharp.Protocols; 5 | 6 | public class GPIO : ProtocolBase 7 | { 8 | public GPIO(FtdiDevice device) : base(device) 9 | { 10 | FTDI_ConfigureMpsse(); 11 | Write(0b00000000, 0b00000000); 12 | } 13 | 14 | private void FTDI_ConfigureMpsse() 15 | { 16 | FtdiDevice.SetTimeouts(1000, 1000).ThrowIfNotOK(); 17 | FtdiDevice.SetLatency(16).ThrowIfNotOK(); 18 | FtdiDevice.SetFlowControl(FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x00, 0x00).ThrowIfNotOK(); 19 | FtdiDevice.SetBitMode(0x00, 0x00).ThrowIfNotOK(); // RESET 20 | FtdiDevice.SetBitMode(0x00, 0x02).ThrowIfNotOK(); // MPSSE 21 | 22 | FtdiDevice.FlushBuffer(); 23 | 24 | /***** Synchronize the MPSSE interface by sending bad command 0xAA *****/ 25 | FtdiDevice.Write(new byte[] { 0xAA }).ThrowIfNotOK(); 26 | byte[] rx1 = FtdiDevice.ReadBytes(2, out FT_STATUS status1); 27 | status1.ThrowIfNotOK(); 28 | if ((rx1[0] != 0xFA) || (rx1[1] != 0xAA)) 29 | throw new InvalidOperationException($"bad echo bytes: {rx1[0]} {rx1[1]}"); 30 | 31 | /***** Synchronize the MPSSE interface by sending bad command 0xAB *****/ 32 | FtdiDevice.Write(new byte[] { 0xAB }).ThrowIfNotOK(); 33 | byte[] rx2 = FtdiDevice.ReadBytes(2, out FT_STATUS status2); 34 | status2.ThrowIfNotOK(); 35 | if ((rx2[0] != 0xFA) || (rx2[1] != 0xAB)) 36 | throw new InvalidOperationException($"bad echo bytes: {rx2[0]} {rx2[1]}"); 37 | 38 | const uint ClockDivisor = 199; //49 for 200 KHz, 199 for 100 KHz 39 | 40 | int numBytesToSend = 0; 41 | byte[] buffer = new byte[100]; 42 | buffer[numBytesToSend++] = 0x8A; // Disable clock divide by 5 for 60Mhz master clock 43 | buffer[numBytesToSend++] = 0x97; // Turn off adaptive clocking 44 | buffer[numBytesToSend++] = 0x8C; // Enable 3 phase data clock, used by I2C to allow data on both clock edges 45 | // The SK clock frequency can be worked out by below algorithm with divide by 5 set as off 46 | // SK frequency = 60MHz /((1 + [(1 +0xValueH*256) OR 0xValueL])*2) 47 | buffer[numBytesToSend++] = 0x86; //Command to set clock divisor 48 | buffer[numBytesToSend++] = (byte)(ClockDivisor & 0x00FF); //Set 0xValueL of clock divisor 49 | buffer[numBytesToSend++] = (byte)((ClockDivisor >> 8) & 0x00FF); //Set 0xValueH of clock divisor 50 | buffer[numBytesToSend++] = 0x85; // loopback off 51 | 52 | byte[] msg = buffer.Take(numBytesToSend).ToArray(); 53 | FtdiDevice.Write(msg).ThrowIfNotOK(); 54 | } 55 | 56 | /// 57 | /// Bits in each byte represent pins D0-D7. 58 | /// Setting a direction bit to 1 means output. 59 | /// Setting a value bit to 1 means high. 60 | /// 61 | public void Write(byte direction, byte value) 62 | { 63 | byte[] bytes = new byte[] { 0x80, value, direction }; 64 | for (int i = 0; i < 5; i++) 65 | FtdiDevice.Write(bytes); 66 | } 67 | 68 | public byte Read() 69 | { 70 | Flush(); 71 | const byte READ_GPIO_LOW = 0x81; // Application Note AN_108 (section 3.6.3) 72 | const byte SEND_IMMEDIATE = 0x87; // This will make the chip flush its buffer back to the PC. 73 | 74 | FtdiDevice.Write(new byte[] { READ_GPIO_LOW, SEND_IMMEDIATE }); 75 | 76 | byte[] result = { 0 }; 77 | uint numBytesRead = 0; 78 | FtdiDevice.Read(result, 1, ref numBytesRead).ThrowIfNotOK(); 79 | 80 | return result[0]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/FtdiSharp/Protocols/ProtocolBase.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp.FTD2XX; 2 | 3 | namespace FtdiSharp.Protocols; 4 | 5 | public abstract class ProtocolBase : IDisposable 6 | { 7 | public bool IsOpen => FtdiDevice.IsOpen; 8 | 9 | public readonly FTDI FtdiDevice = new(); 10 | 11 | public ProtocolBase(FtdiDevice device) 12 | { 13 | if (!FtdiDevice.IsOpen) 14 | FtdiDevice.OpenByIndex((uint)device.Index).ThrowIfNotOK(); 15 | 16 | FtdiDevice.ResetDevice(); 17 | } 18 | 19 | public void Flush() 20 | { 21 | FtdiDevice.FlushBuffer(); 22 | } 23 | 24 | public void Close() 25 | { 26 | if (FtdiDevice.IsOpen) 27 | FtdiDevice.Close(); 28 | } 29 | 30 | public void Dispose() 31 | { 32 | Close(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/FtdiSharp/Usings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Generic; 3 | global using System.Text; 4 | global using System.Runtime.InteropServices; 5 | global using System.Threading; 6 | global using System.IO; -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/BarGraph.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class BarGraph 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.panel1 = new System.Windows.Forms.Panel(); 32 | this.panel2 = new System.Windows.Forms.Panel(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.panel1.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // panel1 39 | // 40 | this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 41 | | System.Windows.Forms.AnchorStyles.Right))); 42 | this.panel1.BackColor = System.Drawing.SystemColors.ControlDark; 43 | this.panel1.Controls.Add(this.panel2); 44 | this.panel1.Location = new System.Drawing.Point(3, 26); 45 | this.panel1.Name = "panel1"; 46 | this.panel1.Size = new System.Drawing.Size(423, 40); 47 | this.panel1.TabIndex = 0; 48 | // 49 | // panel2 50 | // 51 | this.panel2.BackColor = System.Drawing.Color.Green; 52 | this.panel2.Location = new System.Drawing.Point(0, 0); 53 | this.panel2.Name = "panel2"; 54 | this.panel2.Size = new System.Drawing.Size(200, 40); 55 | this.panel2.TabIndex = 1; 56 | // 57 | // label1 58 | // 59 | this.label1.AutoSize = true; 60 | this.label1.Location = new System.Drawing.Point(3, 9); 61 | this.label1.Name = "label1"; 62 | this.label1.Size = new System.Drawing.Size(38, 15); 63 | this.label1.TabIndex = 1; 64 | this.label1.Text = "label1"; 65 | // 66 | // label2 67 | // 68 | this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 69 | this.label2.Location = new System.Drawing.Point(342, 9); 70 | this.label2.Name = "label2"; 71 | this.label2.Size = new System.Drawing.Size(84, 14); 72 | this.label2.TabIndex = 2; 73 | this.label2.Text = "label2"; 74 | this.label2.TextAlign = System.Drawing.ContentAlignment.TopRight; 75 | // 76 | // BarGraph 77 | // 78 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 79 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 80 | this.Controls.Add(this.label2); 81 | this.Controls.Add(this.label1); 82 | this.Controls.Add(this.panel1); 83 | this.Name = "BarGraph"; 84 | this.Size = new System.Drawing.Size(429, 70); 85 | this.panel1.ResumeLayout(false); 86 | this.ResumeLayout(false); 87 | this.PerformLayout(); 88 | 89 | } 90 | 91 | #endregion 92 | 93 | private Panel panel1; 94 | private Panel panel2; 95 | private Label label1; 96 | private Label label2; 97 | } 98 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/BarGraph.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class BarGraph : UserControl 6 | { 7 | public BarGraph() 8 | { 9 | InitializeComponent(); 10 | 11 | bool isDesignMode = Process.GetCurrentProcess().ProcessName == "devenv"; 12 | panel2.Width = isDesignMode ? panel1.Width / 2 : 0; 13 | panel2.Height = panel1.Height; 14 | label1.Text = isDesignMode ? "label1" : string.Empty; 15 | label2.Text = isDesignMode ? "label2" : string.Empty; 16 | //panel1.Visible = isDesignMode ? true : false; 17 | } 18 | 19 | public void SetValue(double value, double max, string label, bool centerAtZero = true) 20 | { 21 | panel1.Visible = true; 22 | label1.Text = label; 23 | label2.Text = max.ToString(); 24 | double span = centerAtZero ? max * 2 : max; 25 | int panelWidth = (int)(Math.Abs(value) / span * panel1.Width); 26 | int panelCenterX = panel1.Width / 2; 27 | 28 | if (centerAtZero) 29 | { 30 | panelWidth /= 2; 31 | panel2.Width = Math.Max(panelWidth, 1); 32 | 33 | if (value < 0) 34 | { 35 | panel2.Left = panelCenterX - panelWidth; 36 | } 37 | else 38 | { 39 | panel2.Left = panelCenterX; 40 | } 41 | } 42 | else 43 | { 44 | panel2.Width = panelWidth; 45 | panel2.Left = 0; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/BarGraph.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/DeviceSelector.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class DeviceSelector 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 32 | this.btnClose = new System.Windows.Forms.Button(); 33 | this.btnOpen = new System.Windows.Forms.Button(); 34 | this.cbDevices = new System.Windows.Forms.ComboBox(); 35 | this.groupBox1.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // groupBox1 39 | // 40 | this.groupBox1.Controls.Add(this.btnClose); 41 | this.groupBox1.Controls.Add(this.btnOpen); 42 | this.groupBox1.Controls.Add(this.cbDevices); 43 | this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; 44 | this.groupBox1.Location = new System.Drawing.Point(0, 0); 45 | this.groupBox1.Name = "groupBox1"; 46 | this.groupBox1.Size = new System.Drawing.Size(395, 53); 47 | this.groupBox1.TabIndex = 0; 48 | this.groupBox1.TabStop = false; 49 | this.groupBox1.Text = "FTDI Device"; 50 | // 51 | // btnClose 52 | // 53 | this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 54 | this.btnClose.Location = new System.Drawing.Point(314, 22); 55 | this.btnClose.Name = "btnClose"; 56 | this.btnClose.Size = new System.Drawing.Size(75, 23); 57 | this.btnClose.TabIndex = 2; 58 | this.btnClose.Text = "Close"; 59 | this.btnClose.UseVisualStyleBackColor = true; 60 | this.btnClose.Click += new System.EventHandler(this.btnClose_Click); 61 | // 62 | // btnOpen 63 | // 64 | this.btnOpen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 65 | this.btnOpen.Location = new System.Drawing.Point(233, 22); 66 | this.btnOpen.Name = "btnOpen"; 67 | this.btnOpen.Size = new System.Drawing.Size(75, 23); 68 | this.btnOpen.TabIndex = 1; 69 | this.btnOpen.Text = "Open"; 70 | this.btnOpen.UseVisualStyleBackColor = true; 71 | this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click); 72 | // 73 | // cbDevices 74 | // 75 | this.cbDevices.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 76 | | System.Windows.Forms.AnchorStyles.Right))); 77 | this.cbDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 78 | this.cbDevices.FormattingEnabled = true; 79 | this.cbDevices.Location = new System.Drawing.Point(6, 22); 80 | this.cbDevices.Name = "cbDevices"; 81 | this.cbDevices.Size = new System.Drawing.Size(221, 23); 82 | this.cbDevices.TabIndex = 0; 83 | // 84 | // DeviceSelector 85 | // 86 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 87 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 88 | this.Controls.Add(this.groupBox1); 89 | this.Name = "DeviceSelector"; 90 | this.Size = new System.Drawing.Size(395, 53); 91 | this.groupBox1.ResumeLayout(false); 92 | this.ResumeLayout(false); 93 | 94 | } 95 | 96 | #endregion 97 | 98 | private GroupBox groupBox1; 99 | private Button btnClose; 100 | private Button btnOpen; 101 | private ComboBox cbDevices; 102 | } 103 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/DeviceSelector.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class DeviceSelector : UserControl 6 | { 7 | readonly List Devices = new(); 8 | 9 | public event EventHandler DeviceOpened = delegate { }; // TODO: pass the ftman 10 | 11 | public event EventHandler DeviceClosed = delegate { }; 12 | 13 | public DeviceSelector() 14 | { 15 | InitializeComponent(); 16 | btnClose.Enabled = false; 17 | Scan(); 18 | } 19 | 20 | public void Scan() 21 | { 22 | cbDevices.Items.Clear(); 23 | Devices.Clear(); 24 | 25 | foreach (var device in FtdiDevices.Scan()) 26 | { 27 | Devices.Add(device); 28 | cbDevices.Items.Add(device.ToString()); 29 | } 30 | 31 | if (cbDevices.Items.Count > 0 && cbDevices.SelectedIndex == -1) 32 | { 33 | cbDevices.SelectedIndex = 0; 34 | } 35 | } 36 | 37 | private void btnOpen_Click(object sender, EventArgs e) 38 | { 39 | btnOpen.Enabled = false; 40 | btnClose.Enabled = true; 41 | cbDevices.Enabled = false; 42 | FtdiDevice device = Devices[cbDevices.SelectedIndex]; 43 | DeviceOpened.Invoke(this, device); 44 | } 45 | 46 | private void btnClose_Click(object sender, EventArgs e) 47 | { 48 | btnOpen.Enabled = true; 49 | btnClose.Enabled = false; 50 | cbDevices.Enabled = true; 51 | FtdiDevice device = Devices[cbDevices.SelectedIndex]; 52 | DeviceClosed.Invoke(this, device); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/DeviceSelector.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/I2cAddressSelector.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class I2cAddressSelector 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 32 | this.lblAddress = new System.Windows.Forms.Label(); 33 | this.nudAddress = new System.Windows.Forms.NumericUpDown(); 34 | this.groupBox1.SuspendLayout(); 35 | ((System.ComponentModel.ISupportInitialize)(this.nudAddress)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // groupBox1 39 | // 40 | this.groupBox1.Controls.Add(this.lblAddress); 41 | this.groupBox1.Controls.Add(this.nudAddress); 42 | this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; 43 | this.groupBox1.Location = new System.Drawing.Point(0, 0); 44 | this.groupBox1.Name = "groupBox1"; 45 | this.groupBox1.Size = new System.Drawing.Size(125, 53); 46 | this.groupBox1.TabIndex = 0; 47 | this.groupBox1.TabStop = false; 48 | this.groupBox1.Text = "I2C Address"; 49 | // 50 | // lblAddress 51 | // 52 | this.lblAddress.AutoSize = true; 53 | this.lblAddress.Location = new System.Drawing.Point(81, 24); 54 | this.lblAddress.Name = "lblAddress"; 55 | this.lblAddress.Size = new System.Drawing.Size(31, 15); 56 | this.lblAddress.TabIndex = 10; 57 | this.lblAddress.Text = "0x00"; 58 | // 59 | // nudAddress 60 | // 61 | this.nudAddress.Location = new System.Drawing.Point(6, 22); 62 | this.nudAddress.Maximum = new decimal(new int[] { 63 | 127, 64 | 0, 65 | 0, 66 | 0}); 67 | this.nudAddress.Name = "nudAddress"; 68 | this.nudAddress.Size = new System.Drawing.Size(69, 23); 69 | this.nudAddress.TabIndex = 8; 70 | this.nudAddress.Value = new decimal(new int[] { 71 | 72, 72 | 0, 73 | 0, 74 | 0}); 75 | this.nudAddress.ValueChanged += new System.EventHandler(this.nudAddress_ValueChanged); 76 | // 77 | // I2cAddressSelector 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.Controls.Add(this.groupBox1); 82 | this.Name = "I2cAddressSelector"; 83 | this.Size = new System.Drawing.Size(125, 53); 84 | this.groupBox1.ResumeLayout(false); 85 | this.groupBox1.PerformLayout(); 86 | ((System.ComponentModel.ISupportInitialize)(this.nudAddress)).EndInit(); 87 | this.ResumeLayout(false); 88 | 89 | } 90 | 91 | #endregion 92 | 93 | private GroupBox groupBox1; 94 | private Label lblAddress; 95 | private NumericUpDown nudAddress; 96 | } 97 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/I2cAddressSelector.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | public partial class I2cAddressSelector : UserControl 4 | { 5 | public byte Address 6 | { 7 | get => (byte)nudAddress.Value; 8 | set 9 | { 10 | nudAddress.Value = value; 11 | nudAddress_ValueChanged(null!, null!); 12 | } 13 | } 14 | 15 | public I2cAddressSelector() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void nudAddress_ValueChanged(object sender, EventArgs e) 21 | { 22 | lblAddress.Text = lblAddress.Text = "0x" + ((int)nudAddress.Value).ToString("X2"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Controls/I2cAddressSelector.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/DeviceInfoForm.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class DeviceInfoForm : Form 6 | { 7 | readonly List Devices = new(); 8 | 9 | public DeviceInfoForm() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | private void button1_Click(object sender, EventArgs e) 15 | { 16 | listBox1.Items.Clear(); 17 | Devices.Clear(); 18 | 19 | foreach (var device in FtdiDevices.Scan()) 20 | { 21 | Devices.Add(device); 22 | listBox1.Items.Add(device.ToString()); 23 | } 24 | } 25 | 26 | private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 27 | { 28 | if (listBox1.SelectedIndex < 0) 29 | return; 30 | 31 | FtdiDevice device = Devices[listBox1.SelectedIndex]; 32 | cbIsOpen.Checked = device.IsOpen; 33 | cbIsHighspeed.Checked = device.IsHighSpeed; 34 | lblType.Text = device.Type; 35 | lblID.Text = device.ID.ToString(); 36 | lblLoc.Text = device.LocationID.ToString(); 37 | lblSerial.Text = device.SerialNumber.ToString(); 38 | lblDescription.Text = device.Description; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/DeviceInfoForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/FtdiSharpDemo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net8.0-windows 6 | enable 7 | true 8 | enable 9 | latest 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/GPIO_LED.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | public partial class GPIO_LED : Form 4 | { 5 | FtdiSharp.Protocols.GPIO? GPIO; 6 | int Reads = 0; 7 | 8 | public GPIO_LED() 9 | { 10 | InitializeComponent(); 11 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 12 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 13 | toolStripStatusLabel1.Text = $"Reads: {Reads}"; 14 | groupBox1.Enabled = false; 15 | groupBox2.Enabled = false; 16 | } 17 | 18 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 19 | { 20 | GPIO = new(e); 21 | groupBox1.Enabled = true; 22 | groupBox2.Enabled = true; 23 | } 24 | 25 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 26 | { 27 | GPIO?.Dispose(); 28 | GPIO = null; 29 | groupBox1.Enabled = false; 30 | groupBox2.Enabled = false; 31 | } 32 | 33 | private void timer1_Tick(object sender, EventArgs e) 34 | { 35 | if (GPIO is null) 36 | return; 37 | 38 | byte direction = 0b11110000; 39 | int value = 40 | (cbD4.Checked ? (1 << 4) : 0) + 41 | (cbD5.Checked ? (1 << 5) : 0) + 42 | (cbD6.Checked ? (1 << 6) : 0) + 43 | (cbD7.Checked ? (1 << 7) : 0); 44 | GPIO.Write(direction, (byte)value); 45 | 46 | byte read = GPIO.Read(); 47 | cbD0.Checked = (read & 0b00000001) > 0; 48 | cbD1.Checked = (read & 0b00000010) > 0; 49 | cbD2.Checked = (read & 0b00000100) > 0; 50 | cbD3.Checked = (read & 0b00001000) > 0; 51 | 52 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/GPIO_LED.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_ADS1115.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class I2C_ADS1115 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 33 | this.i2cAddressSelector1 = new FtdiSharpDemo.I2cAddressSelector(); 34 | this.timer1 = new System.Windows.Forms.Timer(this.components); 35 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 36 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 37 | this.barGraph1 = new FtdiSharpDemo.BarGraph(); 38 | this.statusStrip1.SuspendLayout(); 39 | this.SuspendLayout(); 40 | // 41 | // deviceSelector1 42 | // 43 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 44 | this.deviceSelector1.Name = "deviceSelector1"; 45 | this.deviceSelector1.Size = new System.Drawing.Size(395, 53); 46 | this.deviceSelector1.TabIndex = 0; 47 | // 48 | // i2cAddressSelector1 49 | // 50 | this.i2cAddressSelector1.Address = ((byte)(72)); 51 | this.i2cAddressSelector1.Location = new System.Drawing.Point(413, 12); 52 | this.i2cAddressSelector1.Name = "i2cAddressSelector1"; 53 | this.i2cAddressSelector1.Size = new System.Drawing.Size(125, 53); 54 | this.i2cAddressSelector1.TabIndex = 1; 55 | // 56 | // timer1 57 | // 58 | this.timer1.Enabled = true; 59 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 60 | // 61 | // statusStrip1 62 | // 63 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 64 | this.toolStripStatusLabel1}); 65 | this.statusStrip1.Location = new System.Drawing.Point(0, 275); 66 | this.statusStrip1.Name = "statusStrip1"; 67 | this.statusStrip1.Size = new System.Drawing.Size(606, 22); 68 | this.statusStrip1.TabIndex = 8; 69 | this.statusStrip1.Text = "statusStrip1"; 70 | // 71 | // toolStripStatusLabel1 72 | // 73 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 74 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 75 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 76 | // 77 | // barGraph1 78 | // 79 | this.barGraph1.Location = new System.Drawing.Point(59, 135); 80 | this.barGraph1.Name = "barGraph1"; 81 | this.barGraph1.Size = new System.Drawing.Size(429, 70); 82 | this.barGraph1.TabIndex = 9; 83 | // 84 | // I2C_ADS1115 85 | // 86 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 87 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 88 | this.ClientSize = new System.Drawing.Size(606, 297); 89 | this.Controls.Add(this.barGraph1); 90 | this.Controls.Add(this.statusStrip1); 91 | this.Controls.Add(this.i2cAddressSelector1); 92 | this.Controls.Add(this.deviceSelector1); 93 | this.Name = "I2C_ADS1115"; 94 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 95 | this.Text = "FrdiSharp ADS1115 ADC"; 96 | this.statusStrip1.ResumeLayout(false); 97 | this.statusStrip1.PerformLayout(); 98 | this.ResumeLayout(false); 99 | this.PerformLayout(); 100 | 101 | } 102 | 103 | #endregion 104 | 105 | private DeviceSelector deviceSelector1; 106 | private I2cAddressSelector i2cAddressSelector1; 107 | private System.Windows.Forms.Timer timer1; 108 | private StatusStrip statusStrip1; 109 | private ToolStripStatusLabel toolStripStatusLabel1; 110 | private BarGraph barGraph1; 111 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_ADS1115.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class I2C_ADS1115 : Form 6 | { 7 | FtdiSharp.Protocols.I2C? I2C = null; 8 | int Reads = 0; 9 | 10 | public I2C_ADS1115() 11 | { 12 | InitializeComponent(); 13 | i2cAddressSelector1.Address = 0x48; 14 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 15 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 16 | toolStripStatusLabel1.Text = "Reads: 0"; 17 | } 18 | 19 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiDevice device) 20 | { 21 | I2C = new(device); 22 | ConfigureADC(); 23 | } 24 | 25 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiDevice e) 26 | { 27 | I2C?.Dispose(); 28 | I2C = null; 29 | } 30 | 31 | private void ConfigureADC() 32 | { 33 | if (I2C is null || !I2C.IsOpen) 34 | throw new InvalidOperationException(); 35 | 36 | byte deviceAddress = i2cAddressSelector1.Address; 37 | const byte CONFIG_REGISTER = 0x01; 38 | byte configH = 0b01000000; // AIN0 vs GND, ±6.144V, continuous conversion mode 39 | byte configL = 0b00100000; // 16 SPS 40 | 41 | I2C.Write(deviceAddress, new byte[] { CONFIG_REGISTER, configH, configL }); 42 | } 43 | 44 | private void timer1_Tick(object sender, EventArgs e) 45 | { 46 | if (I2C is null || !I2C.IsOpen) 47 | return; 48 | 49 | byte deviceAddress = i2cAddressSelector1.Address; 50 | const byte RESULT_REGISTER = 0x00; 51 | const byte CONFIG_REGISTER = 0x01; 52 | 53 | // wait for conversion 54 | bool isConverting = true; 55 | while (isConverting) 56 | { 57 | byte[] configBytes = I2C.WriteThenRead(deviceAddress, CONFIG_REGISTER, 2); 58 | isConverting = (configBytes[0] & 0b10000000) > 0; 59 | } 60 | 61 | // read the result 62 | byte[] bytes = I2C.WriteThenRead(deviceAddress, RESULT_REGISTER, 2); 63 | Array.Reverse(bytes); 64 | double value = BitConverter.ToInt16(bytes); 65 | value = Math.Max(value, 0); 66 | value *= 6.144 / (2 << 14); 67 | 68 | barGraph1.SetValue(value, 5.0, $"{value:N4} V", centerAtZero: false); 69 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_ADS1115.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_ADS1115DataLogger.cs: -------------------------------------------------------------------------------- 1 | using ScottPlot.Plottable; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class I2C_ADS1115DataLogger : Form 6 | { 7 | FtdiSharp.Protocols.I2C? I2C; 8 | int Reads = 0; 9 | double[] Ys = new double[1000]; 10 | int NextIndex = 0; 11 | readonly ScottPlot.Plottable.SignalPlot Sig; 12 | readonly ScottPlot.Plottable.VLine VLine; 13 | 14 | public I2C_ADS1115DataLogger() 15 | { 16 | InitializeComponent(); 17 | i2cAddressSelector1.Address = 0x48; 18 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 19 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 20 | toolStripStatusLabel1.Text = $"Reads: {Reads}"; 21 | 22 | Sig = formsPlot1.Plot.AddSignal(Ys); 23 | VLine = formsPlot1.Plot.AddVerticalLine(0, Color.Red, width: 2); 24 | formsPlot1.Plot.SetAxisLimits(0, 1000, -.1, 5.1); 25 | formsPlot1.Refresh(); 26 | } 27 | 28 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 29 | { 30 | I2C?.Dispose(); 31 | I2C = null; 32 | } 33 | 34 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 35 | { 36 | formsPlot1.Refresh(); 37 | I2C = new(e); 38 | ConfigureADC(); 39 | } 40 | 41 | private void ConfigureADC() 42 | { 43 | if (I2C is null || !I2C.IsOpen) 44 | throw new InvalidOperationException(); 45 | 46 | byte deviceAddress = i2cAddressSelector1.Address; 47 | const byte CONFIG_REGISTER = 0x01; 48 | byte configH = 0b01000000; // AIN0 vs GND, ±6.144V, continuous conversion mode 49 | byte configL = 0b00100000; // 16 SPS 50 | 51 | I2C.Write(deviceAddress, new byte[] { CONFIG_REGISTER, configH, configL }); 52 | } 53 | 54 | private double ReadVoltage() 55 | { 56 | if (I2C is null) 57 | return double.NaN; 58 | 59 | byte deviceAddress = i2cAddressSelector1.Address; 60 | const byte RESULT_REGISTER = 0x00; 61 | const byte CONFIG_REGISTER = 0x01; 62 | 63 | // wait for conversion 64 | bool isConverting = true; 65 | while (isConverting) 66 | { 67 | byte[] configBytes = I2C.WriteThenRead(deviceAddress, CONFIG_REGISTER, 2); 68 | isConverting = (configBytes[0] & 0b10000000) > 0; 69 | } 70 | 71 | // read the result 72 | byte[] bytes = I2C.WriteThenRead(deviceAddress, RESULT_REGISTER, 2); 73 | Array.Reverse(bytes); 74 | double value = BitConverter.ToInt16(bytes); 75 | value = Math.Max(value, 0); 76 | value *= 6.144 / (2 << 14); 77 | 78 | return value; 79 | } 80 | 81 | private void timer1_Tick(object sender, EventArgs e) 82 | { 83 | if (I2C is null) 84 | return; 85 | 86 | double value = ReadVoltage(); 87 | 88 | AddPointToGraph(value); 89 | 90 | barGraph1.SetValue(value, 5.0, $"{value:N4} V", centerAtZero: false); 91 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 92 | } 93 | 94 | private void AddPointToGraph(double value) 95 | { 96 | Ys[NextIndex] = value; 97 | 98 | NextIndex += 1; 99 | if (NextIndex >= Ys.Length) 100 | NextIndex = 0; 101 | 102 | VLine.X = NextIndex; 103 | } 104 | 105 | private void plotTimer_Tick(object sender, EventArgs e) 106 | { 107 | if (I2C is null) 108 | return; 109 | 110 | formsPlot1.Refresh(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_ADS1115DataLogger.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | 67 | 220, 17 68 | 69 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_BH1750.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class I2C_BH1750 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.i2cAddressSelector1 = new FtdiSharpDemo.I2cAddressSelector(); 33 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 34 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 35 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 36 | this.timer1 = new System.Windows.Forms.Timer(this.components); 37 | this.barGraph1 = new FtdiSharpDemo.BarGraph(); 38 | this.statusStrip1.SuspendLayout(); 39 | this.SuspendLayout(); 40 | // 41 | // i2cAddressSelector1 42 | // 43 | this.i2cAddressSelector1.Address = ((byte)(72)); 44 | this.i2cAddressSelector1.Location = new System.Drawing.Point(413, 12); 45 | this.i2cAddressSelector1.Name = "i2cAddressSelector1"; 46 | this.i2cAddressSelector1.Size = new System.Drawing.Size(125, 53); 47 | this.i2cAddressSelector1.TabIndex = 0; 48 | // 49 | // deviceSelector1 50 | // 51 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 52 | this.deviceSelector1.Name = "deviceSelector1"; 53 | this.deviceSelector1.Size = new System.Drawing.Size(395, 53); 54 | this.deviceSelector1.TabIndex = 1; 55 | // 56 | // statusStrip1 57 | // 58 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 59 | this.toolStripStatusLabel1}); 60 | this.statusStrip1.Location = new System.Drawing.Point(0, 237); 61 | this.statusStrip1.Name = "statusStrip1"; 62 | this.statusStrip1.Size = new System.Drawing.Size(598, 22); 63 | this.statusStrip1.TabIndex = 2; 64 | this.statusStrip1.Text = "statusStrip1"; 65 | // 66 | // toolStripStatusLabel1 67 | // 68 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 69 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 70 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 71 | // 72 | // timer1 73 | // 74 | this.timer1.Enabled = true; 75 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 76 | // 77 | // barGraph1 78 | // 79 | this.barGraph1.Location = new System.Drawing.Point(41, 96); 80 | this.barGraph1.Name = "barGraph1"; 81 | this.barGraph1.Size = new System.Drawing.Size(429, 70); 82 | this.barGraph1.TabIndex = 9; 83 | // 84 | // I2C_BH1750 85 | // 86 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 87 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 88 | this.ClientSize = new System.Drawing.Size(598, 259); 89 | this.Controls.Add(this.barGraph1); 90 | this.Controls.Add(this.statusStrip1); 91 | this.Controls.Add(this.deviceSelector1); 92 | this.Controls.Add(this.i2cAddressSelector1); 93 | this.Name = "I2C_BH1750"; 94 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 95 | this.Text = "FtdiSharp BH1750 Light Sensor"; 96 | this.statusStrip1.ResumeLayout(false); 97 | this.statusStrip1.PerformLayout(); 98 | this.ResumeLayout(false); 99 | this.PerformLayout(); 100 | 101 | } 102 | 103 | #endregion 104 | 105 | private I2cAddressSelector i2cAddressSelector1; 106 | private DeviceSelector deviceSelector1; 107 | private StatusStrip statusStrip1; 108 | private ToolStripStatusLabel toolStripStatusLabel1; 109 | private System.Windows.Forms.Timer timer1; 110 | private BarGraph barGraph1; 111 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_BH1750.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class I2C_BH1750 : Form 6 | { 7 | FtdiSharp.Protocols.I2C? I2C; 8 | int Reads = 0; 9 | double MaxSeenValue = 0; 10 | 11 | public I2C_BH1750() 12 | { 13 | InitializeComponent(); 14 | i2cAddressSelector1.Address = 0x23; 15 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 16 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 17 | toolStripStatusLabel1.Text = "Reads: 0"; 18 | } 19 | 20 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiDevice device) 21 | { 22 | I2C = new FtdiSharp.Protocols.I2C(device); 23 | SetupDevice(); 24 | } 25 | 26 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiDevice e) 27 | { 28 | I2C?.Dispose(); 29 | I2C = null; 30 | } 31 | 32 | private void SetupDevice() 33 | { 34 | if (I2C is null || !I2C.IsOpen) 35 | return; 36 | 37 | byte deviceAddress = i2cAddressSelector1.Address; 38 | 39 | const byte CONTINUOUS_H_RESOLUTION_MODE = 0b00010000; // page 5 of datasheet 40 | 41 | I2C.Write(deviceAddress, CONTINUOUS_H_RESOLUTION_MODE); 42 | } 43 | 44 | private void timer1_Tick(object sender, EventArgs e) 45 | { 46 | if (I2C is null || !I2C.IsOpen) 47 | return; 48 | 49 | // https://www.mouser.com/datasheet/2/348/Rohm_11162017_ROHMS34826-1-1279292.pdf 50 | byte deviceAddress = i2cAddressSelector1.Address; 51 | byte[] bytes = I2C.Read(deviceAddress, 2); 52 | double value = bytes[0] * 256 + bytes[1]; 53 | MaxSeenValue = Math.Max(value, MaxSeenValue); 54 | 55 | barGraph1.SetValue(value, MaxSeenValue, value.ToString(), centerAtZero: false); 56 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_BH1750.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 133, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_BMP280.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_LIS3DH.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | using FtdiSharp.Protocols; 3 | using System.Diagnostics; 4 | 5 | namespace FtdiSharpDemo; 6 | 7 | public partial class I2C_LIS3DH : Form 8 | { 9 | I2C? I2C = null; 10 | int Reads = 0; 11 | byte DeviceAddress => i2cAddressSelector1.Address; 12 | 13 | public I2C_LIS3DH() 14 | { 15 | InitializeComponent(); 16 | i2cAddressSelector1.Address = 0x18; 17 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 18 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 19 | } 20 | 21 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiDevice device) 22 | { 23 | I2C = new(device); 24 | } 25 | 26 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiDevice device) 27 | { 28 | I2C?.Dispose(); 29 | I2C = null; 30 | } 31 | 32 | private void timer1_Tick(object sender, EventArgs e) 33 | { 34 | if (I2C is null || !I2C.IsOpen) 35 | return; 36 | 37 | AssertWhoAmI(); 38 | SetupDevice(); 39 | ReadAxes(); 40 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 41 | } 42 | 43 | private void AssertWhoAmI() 44 | { 45 | // Register 0x0F contains the number 51 for this device 46 | // https://www.st.com/resource/en/datasheet/cd00274221.pdf (page 34) 47 | 48 | if (I2C is null) 49 | return; 50 | 51 | const byte WHO_AM_I_ADDRESS = 0x0F; 52 | byte result = I2C.WriteThenRead(DeviceAddress, WHO_AM_I_ADDRESS); 53 | 54 | const byte expectedResult = 0b00110011; 55 | 56 | if (result != expectedResult) 57 | { 58 | throw new InvalidOperationException($"Expected a WHO_AM_I byte of {expectedResult} but got {result}"); 59 | } 60 | } 61 | 62 | private void SetupDevice() 63 | { 64 | // https://www.st.com/resource/en/datasheet/cd00274221.pdf (section 8.8) 65 | 66 | byte CTRL_REG1 = 0x20; 67 | byte CONFIG = 0b00110111; // 25 Hz, enable all 3 axes 68 | I2C?.Write(DeviceAddress, new byte[] { CTRL_REG1, CONFIG }); 69 | } 70 | 71 | private void ReadAxis(byte addressL, byte addressH, BarGraph bar, string title) 72 | { 73 | if (I2C is null) 74 | return; 75 | 76 | byte[] bytes = I2C.WriteThenRead(DeviceAddress, addressH, 2); 77 | 78 | Int16 value = BitConverter.ToInt16(bytes); 79 | value >>= 6; 80 | 81 | bar.SetValue(value, 200, $"{title}: {value}"); 82 | } 83 | 84 | private void ReadAxes() 85 | { 86 | ReadAxis(0x28, 0x29, barGraph1, "X"); 87 | ReadAxis(0x2A, 0x2B, barGraph2, "Y"); 88 | ReadAxis(0x2C, 0x2D, barGraph3, "Z"); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_LIS3DH.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_LM75A.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class I2C_LM75A : Form 6 | { 7 | FtdiSharp.Protocols.I2C? I2CCOM; 8 | 9 | int Reads = 0; 10 | 11 | public I2C_LM75A() 12 | { 13 | InitializeComponent(); 14 | lblSensor.Text = ""; 15 | lblTemperature.Text = ""; 16 | nudAddress_ValueChanged(null!, EventArgs.Empty); 17 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 18 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 19 | FormClosing += I2C_LM75A_FormClosing; 20 | toolStripStatusLabel1.Text = "Reads: 0"; 21 | } 22 | 23 | private void I2C_LM75A_FormClosing(object? sender, FormClosingEventArgs e) 24 | { 25 | timer1.Enabled = false; 26 | I2CCOM?.Dispose(); 27 | } 28 | 29 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiDevice device) 30 | { 31 | I2CCOM = new(device); 32 | } 33 | 34 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 35 | { 36 | I2CCOM?.Dispose(); 37 | I2CCOM = null; 38 | } 39 | 40 | private void timer1_Tick(object sender, EventArgs e) 41 | { 42 | if (I2CCOM is null || !I2CCOM.IsOpen) 43 | return; 44 | 45 | // https://www.mouser.com/datasheet/2/302/LM75A-1126516.pdf 46 | 47 | byte deviceAddress = (byte)nudAddress.Value; 48 | byte[] bytes = I2CCOM.Read(deviceAddress, 2); 49 | 50 | lblSensor.Text = Convert.ToString(bytes[0], 2).PadLeft(8, '0') + 51 | Environment.NewLine + 52 | Convert.ToString(bytes[1], 2).PadLeft(8, '0'); 53 | 54 | Array.Reverse(bytes); 55 | int value = BitConverter.ToInt16(bytes); 56 | double temperatureC = value / 256.0; 57 | double temperatureF = temperatureC * 9 / 5 + 32; 58 | 59 | lblTemperature.Text = $"{temperatureF:N3} F\n{temperatureC:N3} C"; 60 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 61 | } 62 | 63 | private void nudAddress_ValueChanged(object sender, EventArgs e) 64 | { 65 | lblAddress.Text = "0x" + ((int)nudAddress.Value).ToString("X2"); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_LM75A.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_Scan.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class I2C_Scan 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 32 | this.listBox1 = new System.Windows.Forms.ListBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.SuspendLayout(); 35 | // 36 | // deviceSelector1 37 | // 38 | this.deviceSelector1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 39 | | System.Windows.Forms.AnchorStyles.Right))); 40 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 41 | this.deviceSelector1.Name = "deviceSelector1"; 42 | this.deviceSelector1.Size = new System.Drawing.Size(399, 53); 43 | this.deviceSelector1.TabIndex = 0; 44 | // 45 | // listBox1 46 | // 47 | this.listBox1.FormattingEnabled = true; 48 | this.listBox1.ItemHeight = 15; 49 | this.listBox1.Location = new System.Drawing.Point(126, 118); 50 | this.listBox1.Name = "listBox1"; 51 | this.listBox1.Size = new System.Drawing.Size(120, 94); 52 | this.listBox1.TabIndex = 1; 53 | // 54 | // label1 55 | // 56 | this.label1.AutoSize = true; 57 | this.label1.Location = new System.Drawing.Point(126, 100); 58 | this.label1.Name = "label1"; 59 | this.label1.Size = new System.Drawing.Size(83, 15); 60 | this.label1.TabIndex = 2; 61 | this.label1.Text = "I2C Addresses:"; 62 | // 63 | // I2C_Scan 64 | // 65 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 66 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 67 | this.ClientSize = new System.Drawing.Size(423, 258); 68 | this.Controls.Add(this.label1); 69 | this.Controls.Add(this.listBox1); 70 | this.Controls.Add(this.deviceSelector1); 71 | this.Name = "I2C_Scan"; 72 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 73 | this.Text = "I2CScan"; 74 | this.ResumeLayout(false); 75 | this.PerformLayout(); 76 | 77 | } 78 | 79 | #endregion 80 | 81 | private DeviceSelector deviceSelector1; 82 | private ListBox listBox1; 83 | private Label label1; 84 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_Scan.cs: -------------------------------------------------------------------------------- 1 | using FtdiSharp; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class I2C_Scan : Form 6 | { 7 | public I2C_Scan() 8 | { 9 | InitializeComponent(); 10 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 11 | } 12 | 13 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiDevice device) 14 | { 15 | using FtdiSharp.Protocols.I2C i2c = new(device); 16 | string[] addressStrings = i2c.Scan().Select(x => $"0x{x:X2}").ToArray(); 17 | listBox1.Items.Clear(); 18 | listBox1.Items.AddRange(addressStrings); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/I2C_Scan.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/MenuForm.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | public partial class MenuForm : Form 4 | { 5 | public MenuForm() 6 | { 7 | InitializeComponent(); 8 | } 9 | 10 | private void btnConnectedDevices_Click(object sender, EventArgs e) => new DeviceInfoForm().ShowDialog(); 11 | private void btnAddressScanner_Click(object sender, EventArgs e) => new I2C_Scan().ShowDialog(); 12 | private void btnLM75A_Click(object sender, EventArgs e) => new I2C_LM75A().ShowDialog(); 13 | private void btnBMP280_Click(object sender, EventArgs e) => new I2C_BMP280().ShowDialog(); 14 | private void btnLIS3DH_Click(object sender, EventArgs e) => new I2C_LIS3DH().ShowDialog(); 15 | private void btnADS1115_Click(object sender, EventArgs e) => new I2C_ADS1115().ShowDialog(); 16 | private void btnADS1115DataLogger_Click(object sender, EventArgs e) => new I2C_ADS1115DataLogger().ShowDialog(); 17 | private void lblBH1750_Click(object sender, EventArgs e) => new I2C_BH1750().ShowDialog(); 18 | private void btnMCP3201_Click(object sender, EventArgs e) => new SPI_MCP3201().ShowDialog(); 19 | private void btnHX710_Click(object sender, EventArgs e) => new SPI_HX710().ShowDialog(); 20 | private void btnMCP3008_Click(object sender, EventArgs e) => new SPI_MCP3008().ShowDialog(); 21 | private void btnAD7705_Click(object sender, EventArgs e) => new SPI_AD7705().ShowDialog(); 22 | private void btnADS1220_Click(object sender, EventArgs e) => new SPI_ADS1220().ShowDialog(); 23 | private void btnLED_Click(object sender, EventArgs e) => new GPIO_LED().ShowDialog(); 24 | } 25 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/MenuForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/Program.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | static class Program 4 | { 5 | /// 6 | /// The main entry point for the application. 7 | /// 8 | [STAThread] 9 | static void Main() 10 | { 11 | // To customize application configuration such as set high DPI settings or default font, 12 | // see https://aka.ms/applicationconfiguration. 13 | ApplicationConfiguration.Initialize(); 14 | Application.Run(new MenuForm()); 15 | } 16 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_AD7705.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class SPI_AD7705 : Form 6 | { 7 | /* WARNING WARNING WARNING WARNING WARNING 8 | * WARNING WARNING WARNING WARNING WARNING 9 | * WARNING WARNING WARNING WARNING WARNING 10 | * WARNING WARNING WARNING WARNING WARNING 11 | * WARNING WARNING WARNING WARNING WARNING 12 | * WARNING WARNING WARNING WARNING WARNING 13 | * WARNING WARNING WARNING WARNING WARNING 14 | * 15 | * THIS CODE DOES NOT WORK AS EXPECTED!!!! 16 | * I think it's because I have a counterfeit chip. 17 | * 18 | */ 19 | 20 | FtdiSharp.Protocols.SPI? SPI; 21 | 22 | int Reads = 0; 23 | 24 | public SPI_AD7705() 25 | { 26 | InitializeComponent(); 27 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 28 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 29 | toolStripStatusLabel1.Text = "Reads: 0"; 30 | } 31 | 32 | private void button1_Click(object sender, EventArgs e) => SetupADC(); 33 | 34 | private void button2_Click(object sender, EventArgs e) => ReadADC(); 35 | 36 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 37 | { 38 | SPI?.Dispose(); 39 | SPI = null; 40 | } 41 | 42 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 43 | { 44 | SPI = new(e, spiMode: 3, slowDownFactor: 8); 45 | } 46 | 47 | private void WaitForReadyToBeLow(int maxTries = 100) 48 | { 49 | if (SPI is null) 50 | throw new InvalidOperationException(); 51 | 52 | int tries = 0; 53 | while (true) 54 | { 55 | byte state = SPI.ReadGpioL(); 56 | bool pinIsHigh = (state & 0b00010000) > 0; 57 | if (!pinIsHigh) 58 | return; 59 | if (tries++ >= maxTries) 60 | { 61 | Debug.WriteLine("WaitForLow Timeout"); 62 | return; 63 | } 64 | Thread.Sleep(1); 65 | } 66 | } 67 | 68 | private void SetupADC() 69 | { 70 | if (SPI is null) 71 | return; 72 | 73 | // see datasheet https://www.analog.com/media/en/technical-documentation/data-sheets/ad7705_7706.pdf 74 | 75 | // WRITE TO CLOCK REGISTER 76 | //const byte REGISTER_SELECT_CLOCK = 0b00100000; // RS2=0, RS1=1, RS0=0 (datasheet table 11) 77 | //const byte CLOCK_CONFIG = 0b00001100; // CLK=1 (4.9512 MHz clock), CLKDIV=1 to divide by 2, no filtering; 78 | //const byte REGISTER_SELECT_SETUP = 0b00010000; // RS2=0, RS1=0, RS0=1 (datasheet table 11) 79 | //const byte SETUP_CONFIG = 0b01000000; // self calibration, gain 1, bipolar mode (datasheet table 14) 80 | 81 | SPI.CsLow(); 82 | Thread.Sleep(10); 83 | SPI.Write(0x20); 84 | Thread.Sleep(10); 85 | SPI.CsHigh(); 86 | 87 | SPI.CsLow(); 88 | Thread.Sleep(10); 89 | SPI.Write(0x0C); 90 | Thread.Sleep(10); 91 | SPI.CsHigh(); 92 | 93 | SPI.CsLow(); 94 | Thread.Sleep(10); 95 | SPI.Write(0x10); 96 | Thread.Sleep(10); 97 | SPI.CsHigh(); 98 | 99 | SPI.CsLow(); 100 | Thread.Sleep(10); 101 | SPI.Write(0x40); 102 | Thread.Sleep(10); 103 | SPI.CsHigh(); 104 | } 105 | 106 | private void timer1_Tick(object sender, EventArgs e) { } 107 | 108 | private void ReadADC() 109 | { 110 | if (SPI is null) 111 | return; 112 | 113 | SPI.Flush(); 114 | WaitForReadyToBeLow(); 115 | 116 | SPI.CsLow(); 117 | SPI.Write(0x38); 118 | SPI.CsHigh(); 119 | 120 | WaitForReadyToBeLow(); 121 | 122 | SPI.CsLow(); 123 | byte[] bytes = SPI.ReadBytes(2); 124 | SPI.CsHigh(); 125 | 126 | SPI.Flush(); 127 | 128 | Text = FtdiSharp.Display.Binary(bytes); 129 | 130 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_AD7705.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_ADS1220.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class SPI_ADS1220 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 33 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 34 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 35 | this.timer1 = new System.Windows.Forms.Timer(this.components); 36 | this.barGraph1 = new FtdiSharpDemo.BarGraph(); 37 | this.statusStrip1.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // deviceSelector1 41 | // 42 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 43 | this.deviceSelector1.Name = "deviceSelector1"; 44 | this.deviceSelector1.Size = new System.Drawing.Size(395, 53); 45 | this.deviceSelector1.TabIndex = 0; 46 | // 47 | // statusStrip1 48 | // 49 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 50 | this.toolStripStatusLabel1}); 51 | this.statusStrip1.Location = new System.Drawing.Point(0, 285); 52 | this.statusStrip1.Name = "statusStrip1"; 53 | this.statusStrip1.Size = new System.Drawing.Size(657, 22); 54 | this.statusStrip1.TabIndex = 1; 55 | this.statusStrip1.Text = "statusStrip1"; 56 | // 57 | // toolStripStatusLabel1 58 | // 59 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 60 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 61 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 62 | // 63 | // timer1 64 | // 65 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 66 | // 67 | // barGraph1 68 | // 69 | this.barGraph1.Location = new System.Drawing.Point(103, 165); 70 | this.barGraph1.Name = "barGraph1"; 71 | this.barGraph1.Size = new System.Drawing.Size(429, 70); 72 | this.barGraph1.TabIndex = 2; 73 | // 74 | // SPI_ADS1220 75 | // 76 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 77 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 78 | this.ClientSize = new System.Drawing.Size(657, 307); 79 | this.Controls.Add(this.barGraph1); 80 | this.Controls.Add(this.statusStrip1); 81 | this.Controls.Add(this.deviceSelector1); 82 | this.Name = "SPI_ADS1220"; 83 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 84 | this.Text = "FtdiSharp ADS1220 Demo"; 85 | this.statusStrip1.ResumeLayout(false); 86 | this.statusStrip1.PerformLayout(); 87 | this.ResumeLayout(false); 88 | this.PerformLayout(); 89 | 90 | } 91 | 92 | #endregion 93 | 94 | private DeviceSelector deviceSelector1; 95 | private StatusStrip statusStrip1; 96 | private ToolStripStatusLabel toolStripStatusLabel1; 97 | private System.Windows.Forms.Timer timer1; 98 | private BarGraph barGraph1; 99 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_ADS1220.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | public partial class SPI_ADS1220 : Form 4 | { 5 | FtdiSharp.Protocols.SPI? SPI; 6 | int Reads = 0; 7 | 8 | public SPI_ADS1220() 9 | { 10 | InitializeComponent(); 11 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 12 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 13 | toolStripStatusLabel1.Text = "Reads: 0"; 14 | timer1.Enabled = false; 15 | } 16 | 17 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 18 | { 19 | SPI = new(e); 20 | SetupADC(); 21 | timer1.Enabled = true; 22 | } 23 | 24 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 25 | { 26 | timer1.Enabled = false; 27 | SPI?.Dispose(); 28 | SPI = null; 29 | } 30 | 31 | private void SetupADC() 32 | { 33 | if (SPI is null) 34 | throw new InvalidOperationException(); 35 | 36 | SPI.CsLow(); 37 | SPI.Write(0x06); // RESET 38 | SPI.CsHigh(); 39 | } 40 | 41 | private void timer1_Tick(object sender, EventArgs e) 42 | { 43 | if (SPI is null) 44 | return; 45 | 46 | // start a single conversion 47 | SPI.CsLow(); 48 | SPI.Write(0b00001000); 49 | SPI.CsHigh(); 50 | 51 | // wait for conversion to be ready 52 | SPI.WaitForReadyToBeLow(); 53 | 54 | // get the result 55 | SPI.CsLow(); 56 | SPI.Flush(); 57 | byte[] bytes = SPI.ReadBytes(3); 58 | SPI.CsHigh(); 59 | 60 | // show the result 61 | double value = (bytes[0] << 16) + (bytes[1] << 8) + bytes[2]; 62 | double v = value / (1 << 23) * 2.048; 63 | barGraph1.SetValue(value, 1 << 23, $"{v:N5} V", centerAtZero: false); 64 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_ADS1220.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 133, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_HX710.cs: -------------------------------------------------------------------------------- 1 | using System.Buffers.Binary; 2 | 3 | namespace FtdiSharpDemo; 4 | 5 | public partial class SPI_HX710 : Form 6 | { 7 | FtdiSharp.Protocols.SPI? SPI; 8 | 9 | int Reads = 0; 10 | 11 | public SPI_HX710() 12 | { 13 | InitializeComponent(); 14 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 15 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 16 | 17 | toolStripStatusLabel1.Text = $"Reads: 0"; 18 | lblSensor.Text = ""; 19 | } 20 | 21 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 22 | { 23 | SPI = new(e); 24 | } 25 | 26 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 27 | { 28 | SPI?.Dispose(); 29 | SPI = null; 30 | } 31 | 32 | private void WaitForConversionToStart() 33 | { 34 | if (SPI is null || !SPI.IsOpen) 35 | return; 36 | 37 | bool isConverting = true; 38 | while (isConverting) 39 | { 40 | byte gpio = SPI.ReadGpioL(); 41 | isConverting = (gpio & 0b00000100) > 0; 42 | } 43 | } 44 | 45 | private void WaitForConversionComplete() 46 | { 47 | if (SPI is null || !SPI.IsOpen) 48 | return; 49 | 50 | bool isConverting = true; 51 | while (isConverting) 52 | { 53 | byte gpio = SPI.ReadGpioL(); 54 | isConverting = (gpio & 0b00000100) > 0; 55 | } 56 | } 57 | 58 | private void timer1_Tick(object sender, EventArgs e) 59 | { 60 | if (SPI is null || !SPI.IsOpen) 61 | return; 62 | 63 | WaitForConversionComplete(); 64 | SPI.FtdiDevice.FlushBuffer(); 65 | SPI.CsLow(); 66 | byte[] data = SPI.ReadBytes(3); 67 | SPI.PulseClock(3); // set mode for next conversion (see datasheet) 68 | SPI.CsHigh(); 69 | 70 | data[0] ^= 0b10000000; // flip the most significant bit 71 | long result = (data[0] << 16) + (data[1] << 8) + data[2]; 72 | 73 | lblSensor.Text = FtdiSharp.Display.Binary(data) + Environment.NewLine + result.ToString(); 74 | 75 | toolStripStatusLabel1.Text = $"Reads: {Reads++}"; 76 | barGraph1.SetValue(result, 1 << 24, "sensor", centerAtZero: false); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_HX710.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 133, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3008.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class SPI_MCP3008 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 33 | this.barGraph1 = new FtdiSharpDemo.BarGraph(); 34 | this.timer1 = new System.Windows.Forms.Timer(this.components); 35 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 36 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 37 | this.statusStrip1.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // deviceSelector1 41 | // 42 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 43 | this.deviceSelector1.Name = "deviceSelector1"; 44 | this.deviceSelector1.Size = new System.Drawing.Size(395, 53); 45 | this.deviceSelector1.TabIndex = 0; 46 | // 47 | // barGraph1 48 | // 49 | this.barGraph1.Location = new System.Drawing.Point(47, 98); 50 | this.barGraph1.Name = "barGraph1"; 51 | this.barGraph1.Size = new System.Drawing.Size(429, 70); 52 | this.barGraph1.TabIndex = 1; 53 | // 54 | // timer1 55 | // 56 | this.timer1.Enabled = true; 57 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 58 | // 59 | // statusStrip1 60 | // 61 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 62 | this.toolStripStatusLabel1}); 63 | this.statusStrip1.Location = new System.Drawing.Point(0, 194); 64 | this.statusStrip1.Name = "statusStrip1"; 65 | this.statusStrip1.Size = new System.Drawing.Size(535, 22); 66 | this.statusStrip1.TabIndex = 2; 67 | this.statusStrip1.Text = "statusStrip1"; 68 | // 69 | // toolStripStatusLabel1 70 | // 71 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 72 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 73 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 74 | // 75 | // SPI_MCP3008 76 | // 77 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 78 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 79 | this.ClientSize = new System.Drawing.Size(535, 216); 80 | this.Controls.Add(this.statusStrip1); 81 | this.Controls.Add(this.barGraph1); 82 | this.Controls.Add(this.deviceSelector1); 83 | this.Name = "SPI_MCP3008"; 84 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 85 | this.Text = "SPI_MCP3008"; 86 | this.statusStrip1.ResumeLayout(false); 87 | this.statusStrip1.PerformLayout(); 88 | this.ResumeLayout(false); 89 | this.PerformLayout(); 90 | 91 | } 92 | 93 | #endregion 94 | 95 | private DeviceSelector deviceSelector1; 96 | private BarGraph barGraph1; 97 | private System.Windows.Forms.Timer timer1; 98 | private StatusStrip statusStrip1; 99 | private ToolStripStatusLabel toolStripStatusLabel1; 100 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3008.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | public partial class SPI_MCP3008 : Form 4 | { 5 | FtdiSharp.Protocols.SPI? SPI; 6 | 7 | int Reads = 0; 8 | 9 | public SPI_MCP3008() 10 | { 11 | InitializeComponent(); 12 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 13 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 14 | toolStripStatusLabel1.Text = $"Reads: 0"; 15 | } 16 | 17 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 18 | { 19 | SPI = new(e); 20 | } 21 | 22 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 23 | { 24 | SPI?.Dispose(); 25 | SPI = null; 26 | } 27 | 28 | private void timer1_Tick(object sender, EventArgs e) 29 | { 30 | if (SPI is null || !SPI.IsOpen) 31 | return; 32 | 33 | // See datasheet figure 6-1 34 | // https://cdn-shop.adafruit.com/datasheets/MCP3008.pdf 35 | 36 | byte[] tx = { 37 | 0b00000001, // start 38 | 0b10000000, // CH0 single-ended 39 | 0b00000000, // clock for rx 40 | }; 41 | 42 | SPI.CsLow(); 43 | byte[] rx = SPI.ReadWrite(tx); 44 | SPI.CsHigh(); 45 | 46 | byte msb = (byte)(rx[1] & 0b00000011); 47 | byte lsb = rx[2]; 48 | double value = (msb << 8) + lsb; 49 | 50 | barGraph1.SetValue(value, 1 << 10, value.ToString(), centerAtZero: false); 51 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3008.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3201.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpDemo; 2 | 3 | partial class SPI_MCP3201 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.deviceSelector1 = new FtdiSharpDemo.DeviceSelector(); 33 | this.timer1 = new System.Windows.Forms.Timer(this.components); 34 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 35 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 36 | this.barGraph1 = new FtdiSharpDemo.BarGraph(); 37 | this.statusStrip1.SuspendLayout(); 38 | this.SuspendLayout(); 39 | // 40 | // deviceSelector1 41 | // 42 | this.deviceSelector1.Location = new System.Drawing.Point(12, 12); 43 | this.deviceSelector1.Name = "deviceSelector1"; 44 | this.deviceSelector1.Size = new System.Drawing.Size(395, 53); 45 | this.deviceSelector1.TabIndex = 0; 46 | // 47 | // timer1 48 | // 49 | this.timer1.Enabled = true; 50 | this.timer1.Tick += new System.EventHandler(this.timer1_Tick); 51 | // 52 | // statusStrip1 53 | // 54 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 55 | this.toolStripStatusLabel1}); 56 | this.statusStrip1.Location = new System.Drawing.Point(0, 169); 57 | this.statusStrip1.Name = "statusStrip1"; 58 | this.statusStrip1.Size = new System.Drawing.Size(474, 22); 59 | this.statusStrip1.TabIndex = 1; 60 | this.statusStrip1.Text = "statusStrip1"; 61 | // 62 | // toolStripStatusLabel1 63 | // 64 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 65 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(118, 17); 66 | this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; 67 | // 68 | // barGraph1 69 | // 70 | this.barGraph1.Location = new System.Drawing.Point(12, 86); 71 | this.barGraph1.Name = "barGraph1"; 72 | this.barGraph1.Size = new System.Drawing.Size(429, 70); 73 | this.barGraph1.TabIndex = 7; 74 | // 75 | // SPI_MCP3201 76 | // 77 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 78 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 79 | this.ClientSize = new System.Drawing.Size(474, 191); 80 | this.Controls.Add(this.barGraph1); 81 | this.Controls.Add(this.statusStrip1); 82 | this.Controls.Add(this.deviceSelector1); 83 | this.Name = "SPI_MCP3201"; 84 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 85 | this.Text = "SPI_MCP3008"; 86 | this.statusStrip1.ResumeLayout(false); 87 | this.statusStrip1.PerformLayout(); 88 | this.ResumeLayout(false); 89 | this.PerformLayout(); 90 | 91 | } 92 | 93 | #endregion 94 | 95 | private DeviceSelector deviceSelector1; 96 | private System.Windows.Forms.Timer timer1; 97 | private StatusStrip statusStrip1; 98 | private ToolStripStatusLabel toolStripStatusLabel1; 99 | private BarGraph barGraph1; 100 | } -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3201.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace FtdiSharpDemo; 13 | public partial class SPI_MCP3201 : Form 14 | { 15 | FtdiSharp.Protocols.SPI? SPI; 16 | int MaxSeenValue = 0; 17 | 18 | int Reads = 0; 19 | 20 | public SPI_MCP3201() 21 | { 22 | InitializeComponent(); 23 | deviceSelector1.DeviceOpened += DeviceSelector1_DeviceOpened; 24 | deviceSelector1.DeviceClosed += DeviceSelector1_DeviceClosed; 25 | toolStripStatusLabel1.Text = "Reads: 0"; 26 | } 27 | 28 | private void DeviceSelector1_DeviceClosed(object? sender, FtdiSharp.FtdiDevice e) 29 | { 30 | SPI?.Dispose(); 31 | SPI = null; 32 | } 33 | 34 | private void DeviceSelector1_DeviceOpened(object? sender, FtdiSharp.FtdiDevice e) 35 | { 36 | SPI = new(e); 37 | } 38 | 39 | private void timer1_Tick(object sender, EventArgs e) 40 | { 41 | if (SPI is null || !SPI.IsOpen) 42 | return; 43 | 44 | // https://www.mouser.com/pdfDocs/21290c-28774.pdf 45 | 46 | SPI.FtdiDevice.FlushBuffer(); 47 | SPI.CsLow(); 48 | byte[] bytes = SPI.ReadBytes(2); 49 | SPI.CsHigh(); 50 | 51 | // see MCP3201 datasheet figure 6-1 52 | byte b1 = (byte)(bytes[0] & 0b00011111); // first 3 clock cycles are null bits 53 | byte b2 = (byte)(bytes[1] & 0b11111110); 54 | int value = (b1 << 8) + b2; 55 | value >>= 1; 56 | MaxSeenValue = Math.Max(MaxSeenValue, value); 57 | 58 | toolStripStatusLabel1.Text = $"Reads: {++Reads}"; 59 | barGraph1.SetValue(value, MaxSeenValue, value.ToString(), false); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/FtdiSharpDemo/SPI_MCP3201.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | 61 | 17, 17 62 | 63 | 64 | 104, 17 65 | 66 | -------------------------------------------------------------------------------- /src/FtdiSharpTests/FtdiSharpTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/FtdiSharpTests/HardwareTests.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpTests; 2 | 3 | public class HardwareTests 4 | { 5 | readonly bool FtdiDeviceFound = FtdiDevices.Scan().Any(); 6 | 7 | [Test] 8 | public void Test_Scan_Devices() 9 | { 10 | foreach (FtdiDevice device in FtdiDevices.Scan()) 11 | Console.WriteLine(device); 12 | } 13 | 14 | [Test] 15 | public void Test_Scan_I2C_Addresses() 16 | { 17 | if (!FtdiDeviceFound) 18 | return; 19 | 20 | FtdiDevice device = FtdiDevices.Scan().First(); 21 | 22 | using FtdiSharp.Protocols.I2C i2c = new(device); 23 | 24 | foreach (byte address in i2c.Scan()) 25 | Console.WriteLine(address); 26 | } 27 | 28 | [Test] 29 | public void Test_Read_Light_Sensor() 30 | { 31 | if (!FtdiDeviceFound) 32 | return; 33 | 34 | // Connect to the first USB FTDI device 35 | FtdiDevice device = FtdiDevices.Scan().First(); 36 | using FtdiSharp.Protocols.I2C i2c = new(device); 37 | 38 | // Enter continuous sensor mode 39 | byte address = 0x23; 40 | byte config = 0b00010000; 41 | i2c.Write(address, config); 42 | 43 | // Read light intensity as two bytes 44 | byte[] bytes = i2c.Read(address, 2); 45 | 46 | // Convert the two bytes to lumens according to the datasheet 47 | double value = (bytes[0] * 256 + bytes[1]) / 1.2; 48 | Console.WriteLine(value); 49 | } 50 | 51 | [Test] 52 | public void Test_SPI_Write() 53 | { 54 | if (!FtdiDeviceFound) 55 | return; 56 | 57 | FtdiDevice device = FtdiDevices.Scan().First(); 58 | using FtdiSharp.Protocols.SPI spi = new(device); 59 | 60 | spi.CsLow(); 61 | byte[] bytes = spi.ReadBytes(2); 62 | spi.CsHigh(); 63 | 64 | Console.WriteLine(Display.Binary(bytes)); 65 | } 66 | } -------------------------------------------------------------------------------- /src/FtdiSharpTests/UnitTests.cs: -------------------------------------------------------------------------------- 1 | namespace FtdiSharpTests; 2 | 3 | public class UnitTests 4 | { 5 | [Test] 6 | public void Test_DeviceNames_CanBeParsed() 7 | { 8 | foreach (FtdiSharp.FTD2XX.FT_DEVICE dev in Enum.GetValues(typeof(FtdiSharp.FTD2XX.FT_DEVICE))) 9 | { 10 | Console.WriteLine(dev.ToReadableName()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/FtdiSharpTests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using NUnit.Framework; 2 | global using FtdiSharp; -------------------------------------------------------------------------------- /src/autoformat.bat: -------------------------------------------------------------------------------- 1 | :: Install and update the dotnet autoformatter 2 | :: dotnet tool update -g dotnet-format 3 | 4 | dotnet-format 5 | pause --------------------------------------------------------------------------------