diff --git a/Drivers/CH341PAR/CH341DLL.DLL b/Drivers/CH341PAR/CH341DLL.DLL
new file mode 100644
index 0000000..d2215a1
Binary files /dev/null and b/Drivers/CH341PAR/CH341DLL.DLL differ
diff --git a/Drivers/CH341PAR/CH341DLLA64.DLL b/Drivers/CH341PAR/CH341DLLA64.DLL
new file mode 100644
index 0000000..d1875b4
Binary files /dev/null and b/Drivers/CH341PAR/CH341DLLA64.DLL differ
diff --git a/Drivers/CH341PAR/CH341M64.SYS b/Drivers/CH341PAR/CH341M64.SYS
new file mode 100644
index 0000000..f8bc625
Binary files /dev/null and b/Drivers/CH341PAR/CH341M64.SYS differ
diff --git a/Drivers/CH341PAR/CH341W64.SYS b/Drivers/CH341PAR/CH341W64.SYS
new file mode 100644
index 0000000..5b322e3
Binary files /dev/null and b/Drivers/CH341PAR/CH341W64.SYS differ
diff --git a/Drivers/CH341PAR/CH341WDM.CAT b/Drivers/CH341PAR/CH341WDM.CAT
new file mode 100644
index 0000000..57dffdb
Binary files /dev/null and b/Drivers/CH341PAR/CH341WDM.CAT differ
diff --git a/Drivers/CH341PAR/CH341WDM.INF b/Drivers/CH341PAR/CH341WDM.INF
new file mode 100644
index 0000000..e33d2be
--- /dev/null
+++ b/Drivers/CH341PAR/CH341WDM.INF
@@ -0,0 +1,288 @@
+; CH341WDM.INF
+; Driver for CH341/7 (USB2.0=>EPP/I2C/SPI/JTAG/UART... chip) V2.3
+; DRIVER for Windows 2000/XP/Vista/7/8/8.1/10/11/SERVER 2003/2008/2012/2016/2019/2022
+; Copyright (C) WCH 2001-2022
+;
+
+[Version]
+Signature = "$Chicago$"
+Class = WCH
+ClassGuid = {77989ADF-06DB-4025-92E8-40D902C03B0A}
+Provider = %WinChipHead%
+DriverVer = 05/06/2022, 2.3.2022.05
+CatalogFile.NT = CH341WDM.CAT
+
+[ControlFlags]
+ExcludeFromSelect = USB\VID_1A86&PID_5512
+ExcludeFromSelect = USB\VID_4348&PID_5512
+ExcludeFromSelect = USB\VID_1A86&PID_55DB&MI_02
+ExcludeFromSelect = USB\VID_1A86&PID_55DD&MI_02
+
+;ExcludeFromSelect = USB\VID_1A86&PID_7523
+;ExcludeFromSelect = USB\VID_1A86&PID_5523
+;ExcludeFromSelect = USB\VID_4348&PID_5523
+;ExcludeFromSelect = USB\VID_4348&PID_5523&REV_0250
+
+[ClassInstall32]
+Addreg = WCHReg
+
+[ClassInstall]
+Addreg = WCHReg
+
+[WCHReg]
+HKR, , , 0, %ClassName%
+HKR, , Icon, , -5
+HKR, , NoInstallClass, , 1
+
+[Manufacturer]
+%WinChipHead% = WinChipHead,NT,NTamd64,NTia64,NTARM64
+
+[WinChipHead]
+%CH341A.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NT]
+%CH341A.DeviceDesc% = CH341.Install.NT, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NT, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NT, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NT.NTamd64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NT, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTamd64]
+%CH341A.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTamd64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTamd64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTia64]
+%CH341A.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTia64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTia64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTARM64]
+%CH341A.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTARM64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTARM64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5523&REV_0250
+
+[CH341.Install]
+CopyFiles = CH341.CopyFiles.SYS, CH341.CopyFiles.DLL
+AddReg = CH341.9X.AddReg, CH341.AddReg
+
+[CH341.Install.NT]
+CopyFiles = CH341.CopyFiles.SYS, CH341.CopyFiles.DLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTamd64]
+CopyFiles = CH341.CopyFiles.SYSA64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTarm64]
+CopyFiles = CH341.CopyFiles.SYSM64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTia64]
+CopyFiles = CH341.CopyFiles.SYSI64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH347.Install]
+CopyFiles = CH341.CopyFiles.SYS, CH347.CopyFiles.DLL, CH341.CopyFiles.DLL
+AddReg = CH341.9X.AddReg, CH347.AddReg
+
+[CH347.Install.NT]
+CopyFiles = CH341.CopyFiles.SYS, CH347.CopyFiles.DLL, CH341.CopyFiles.DLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTamd64]
+CopyFiles = CH341.CopyFiles.SYSA64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTia64]
+CopyFiles = CH341.CopyFiles.SYSI64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTarm64]
+CopyFiles = CH341.CopyFiles.SYSM64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH341.CopyFiles.SYS]
+CH341WDM.SYS, , , 2
+
+[CH341.CopyFiles.SYSA64]
+CH341W64.SYS, , , 2
+
+[CH341.CopyFiles.SYSM64]
+CH341M64.SYS, , , 2
+
+[CH341.CopyFiles.SYSI64]
+;CH341I64.SYS, , , 2
+
+[CH341.CopyFiles.DLL]
+CH341DLL.DLL, , , 2
+
+[CH341.CopyFiles.DLLA64]
+CH341DLLA64.DLL, , , 2
+
+[CH341.CopyFiles.WOWDLL]
+CH341DLL.DLL, , , 2
+
+[CH347.CopyFiles.DLL]
+CH347DLL.DLL, , , 2
+
+[CH347.CopyFiles.DLLA64]
+CH347DLLA64.DLL, , , 2
+
+[CH347.CopyFiles.WOWDLL]
+CH347DLL.DLL, , , 2
+
+[CH341.9X.AddReg]
+HKR, , DevLoader, , *NTKERN
+HKR, , NTMPDriver, , CH341WDM.SYS
+
+[CH341.NT.AddReg]
+
+[CH341.AddReg]
+HKLM, SOFTWARE\WinChipHead\IC\CH341, WDM, 0x00010001, 0x00000022
+HKLM, SOFTWARE\WinChipHead\IC\CH341, DLL, 0x00010001, 0x00000021
+HKLM, SOFTWARE\WinChipHead\IC\CH341, Function, , "USB=>Parallel"
+
+[CH347.AddReg]
+HKLM, SOFTWARE\WinChipHead\IC\CH347, WDM, 0x00010001, 0x00000022
+HKLM, SOFTWARE\WinChipHead\IC\CH347, DLL, 0x00010001, 0x00000021
+HKLM, SOFTWARE\WinChipHead\IC\CH347, Function, , "USB20=>SPI&I2C&JTAG&UART"
+
+[CH341.Install.NT.Services]
+AddService = CH341, 2, CH341.Service
+
+[CH341.Install.NTamd64.Services]
+AddService = CH341_A64, 2, CH341.ServiceA64
+
+[CH341.Install.NTia64.Services]
+AddService = CH341_I64, 2, CH341.ServiceI64
+
+[CH341.Install.NTarm64.Services]
+AddService = CH341_M64, 2, CH341.ServiceM64
+
+[CH347.Install.NT.Services]
+AddService = CH341, 2, CH341.Service
+
+[CH347.Install.NTamd64.Services]
+AddService = CH341_A64, 2, CH341.ServiceA64
+
+[CH347.Install.NTia64.Services]
+AddService = CH341_I64, 2, CH341.ServiceI64
+
+[CH347.Install.NTarm64.Services]
+AddService = CH341_M64, 2, CH341.ServiceM64
+
+[CH341.Service]
+DisplayName = "CH341WDM"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341WDM.SYS
+
+[CH341.ServiceA64]
+DisplayName = "CH341WDM_A64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341W64.SYS
+
+[CH341.ServiceI64]
+DisplayName = "CH341WDM_I64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341I64.SYS
+
+[CH341.ServiceM64]
+DisplayName = "CH341WDM_M64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341M64.SYS
+
+[DestinationDirs]
+DefaultDestDir = 10, System32\Drivers
+CH347.CopyFiles.DLL = 11
+CH347.CopyFiles.DLLA64 = 11
+CH347.CopyFiles.WOWDLL = 10,SysWOW64
+CH341.CopyFiles.DLL = 11
+CH341.CopyFiles.DLLA64 = 11
+CH341.CopyFiles.WOWDLL = 10,SysWOW64
+CH341.CopyFiles.SYS = 10, System32\Drivers
+CH341.CopyFiles.SYSA64 = 10, System32\Drivers
+CH341.CopyFiles.SYSM64 = 10, System32\Drivers
+;CH347.CopyFiles.SYSI64 = 10, System32\Drivers
+;CH341.CopyFiles.SYSI64 = 10, System32\Drivers
+
+[SourceDisksFiles]
+CH341WDM.SYS = 1
+CH341W64.SYS = 1
+CH341M64.SYS = 1
+CH341DLL.DLL = 1
+CH341DLLA64.DLL = 1
+CH347DLL.DLL = 1
+CH347DLLA64.DLL = 1
+;CH341I64.SYS = 1
+;CH347I64.SYS = 1
+
+
+[SourceDisksNames]
+1 = %DISK_NAME%, CH341WDM.SYS, ,
+
+[SourceDisksNames.amd64]
+1 = %DISK_NAME%, CH341W64.SYS, ,
+
+[SourceDisksNames.ia64]
+1 = %DISK_NAME%, CH341I64.SYS, ,
+
+[SourceDisksNames.arm64]
+1 = %DISK_NAME%, CH341M64.SYS, ,
+
+[Strings]
+ClassName = "Interface"
+WinChipHead = "wch.cn"
+CH341.DeviceDesc = "USB-EPP/I2C... CH341"
+CH341A.DeviceDesc = "USB-EPP/I2C... CH341A"
+CH347M1A.DeviceDesc = "USB HighSpeed-SPI/I2C... CH347"
+CH347M1B.DeviceDesc = "USB HighSpeed-JTAG/I2C... CH347"
+CH341SER.DeviceDesc = "USB-SERIAL CH341"
+CH340SER.DeviceDesc = "USB-SERIAL CH340"
+CH341ASER.DeviceDesc = "USB-SERIAL CH341A"
+DISK_NAME = "CH341 Parallel Installation Disk"
+
+[Strings.0804]
+ClassName = "外部接口"
+WinChipHead = "wch.cn"
+CH341.DeviceDesc = "USB-EPP/I2C... CH341"
+CH341A.DeviceDesc = "USB-EPP/I2C... CH341A"
+CH347M1A.DeviceDesc = "USB HighSpeed-SPI/I2C... CH347"
+CH347M1B.DeviceDesc = "USB HighSpeed-JTAG/I2C... CH347"
+CH341SER.DeviceDesc = "USB-SERIAL CH341"
+CH340SER.DeviceDesc = "USB-SERIAL CH340"
+CH341ASER.DeviceDesc = "USB-SERIAL CH341A"
+DISK_NAME = "CH341 Parallel Installation Disk"
diff --git a/Drivers/CH341PAR/CH341WDM.SYS b/Drivers/CH341PAR/CH341WDM.SYS
new file mode 100644
index 0000000..c6a7655
Binary files /dev/null and b/Drivers/CH341PAR/CH341WDM.SYS differ
diff --git a/Drivers/CH341PAR/CH347DLL.DLL b/Drivers/CH341PAR/CH347DLL.DLL
new file mode 100644
index 0000000..bd02e43
Binary files /dev/null and b/Drivers/CH341PAR/CH347DLL.DLL differ
diff --git a/Drivers/CH341PAR/CH347DLLA64.DLL b/Drivers/CH341PAR/CH347DLLA64.DLL
new file mode 100644
index 0000000..94ebae1
Binary files /dev/null and b/Drivers/CH341PAR/CH347DLLA64.DLL differ
diff --git a/Drivers/CH341PAR/DRVSETUP64/DRVSETUP64.exe b/Drivers/CH341PAR/DRVSETUP64/DRVSETUP64.exe
new file mode 100644
index 0000000..8df2844
Binary files /dev/null and b/Drivers/CH341PAR/DRVSETUP64/DRVSETUP64.exe differ
diff --git a/Drivers/CH341PAR/SETUP.EXE b/Drivers/CH341PAR/SETUP.EXE
new file mode 100644
index 0000000..097cae8
Binary files /dev/null and b/Drivers/CH341PAR/SETUP.EXE differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341DLL.DLL b/Drivers/CH341PAR/WIN 1X/CH341DLL.DLL
new file mode 100644
index 0000000..0465fea
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341DLL.DLL differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341DLLA64.DLL b/Drivers/CH341PAR/WIN 1X/CH341DLLA64.DLL
new file mode 100644
index 0000000..1cbb726
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341DLLA64.DLL differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341M64.SYS b/Drivers/CH341PAR/WIN 1X/CH341M64.SYS
new file mode 100644
index 0000000..005d81f
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341M64.SYS differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341W64.SYS b/Drivers/CH341PAR/WIN 1X/CH341W64.SYS
new file mode 100644
index 0000000..1b6a809
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341W64.SYS differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341WDM.CAT b/Drivers/CH341PAR/WIN 1X/CH341WDM.CAT
new file mode 100644
index 0000000..19f1587
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341WDM.CAT differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH341WDM.INF b/Drivers/CH341PAR/WIN 1X/CH341WDM.INF
new file mode 100644
index 0000000..e33d2be
--- /dev/null
+++ b/Drivers/CH341PAR/WIN 1X/CH341WDM.INF
@@ -0,0 +1,288 @@
+; CH341WDM.INF
+; Driver for CH341/7 (USB2.0=>EPP/I2C/SPI/JTAG/UART... chip) V2.3
+; DRIVER for Windows 2000/XP/Vista/7/8/8.1/10/11/SERVER 2003/2008/2012/2016/2019/2022
+; Copyright (C) WCH 2001-2022
+;
+
+[Version]
+Signature = "$Chicago$"
+Class = WCH
+ClassGuid = {77989ADF-06DB-4025-92E8-40D902C03B0A}
+Provider = %WinChipHead%
+DriverVer = 05/06/2022, 2.3.2022.05
+CatalogFile.NT = CH341WDM.CAT
+
+[ControlFlags]
+ExcludeFromSelect = USB\VID_1A86&PID_5512
+ExcludeFromSelect = USB\VID_4348&PID_5512
+ExcludeFromSelect = USB\VID_1A86&PID_55DB&MI_02
+ExcludeFromSelect = USB\VID_1A86&PID_55DD&MI_02
+
+;ExcludeFromSelect = USB\VID_1A86&PID_7523
+;ExcludeFromSelect = USB\VID_1A86&PID_5523
+;ExcludeFromSelect = USB\VID_4348&PID_5523
+;ExcludeFromSelect = USB\VID_4348&PID_5523&REV_0250
+
+[ClassInstall32]
+Addreg = WCHReg
+
+[ClassInstall]
+Addreg = WCHReg
+
+[WCHReg]
+HKR, , , 0, %ClassName%
+HKR, , Icon, , -5
+HKR, , NoInstallClass, , 1
+
+[Manufacturer]
+%WinChipHead% = WinChipHead,NT,NTamd64,NTia64,NTARM64
+
+[WinChipHead]
+%CH341A.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NT]
+%CH341A.DeviceDesc% = CH341.Install.NT, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NT, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NT, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NT.NTamd64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NT, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NT, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTamd64]
+%CH341A.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTamd64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTamd64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTamd64, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTia64]
+%CH341A.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTia64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTia64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTia64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTia64, USB\VID_4348&PID_5523&REV_0250
+
+[WinChipHead.NTARM64]
+%CH341A.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_5512
+%CH341.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5512
+%CH347M1A.DeviceDesc% = CH347.Install.NTARM64, USB\VID_1A86&PID_55DB&MI_02
+%CH347M1B.DeviceDesc% = CH347.Install.NTARM64, USB\VID_1A86&PID_55DD&MI_02
+;%CH340SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_7523
+;%CH341ASER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_1A86&PID_5523
+;%CH341SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5523
+;%CH340SER.DeviceDesc% = CH341.Install.NTARM64, USB\VID_4348&PID_5523&REV_0250
+
+[CH341.Install]
+CopyFiles = CH341.CopyFiles.SYS, CH341.CopyFiles.DLL
+AddReg = CH341.9X.AddReg, CH341.AddReg
+
+[CH341.Install.NT]
+CopyFiles = CH341.CopyFiles.SYS, CH341.CopyFiles.DLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTamd64]
+CopyFiles = CH341.CopyFiles.SYSA64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTarm64]
+CopyFiles = CH341.CopyFiles.SYSM64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH341.Install.NTia64]
+CopyFiles = CH341.CopyFiles.SYSI64, CH341.CopyFiles.DLLA64,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH341.AddReg
+
+[CH347.Install]
+CopyFiles = CH341.CopyFiles.SYS, CH347.CopyFiles.DLL, CH341.CopyFiles.DLL
+AddReg = CH341.9X.AddReg, CH347.AddReg
+
+[CH347.Install.NT]
+CopyFiles = CH341.CopyFiles.SYS, CH347.CopyFiles.DLL, CH341.CopyFiles.DLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTamd64]
+CopyFiles = CH341.CopyFiles.SYSA64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTia64]
+CopyFiles = CH341.CopyFiles.SYSI64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH347.Install.NTarm64]
+CopyFiles = CH341.CopyFiles.SYSM64, CH347.CopyFiles.DLLA64, CH347.CopyFiles.WOWDLL,CH341.CopyFiles.WOWDLL
+AddReg = CH341.NT.AddReg, CH347.AddReg
+
+[CH341.CopyFiles.SYS]
+CH341WDM.SYS, , , 2
+
+[CH341.CopyFiles.SYSA64]
+CH341W64.SYS, , , 2
+
+[CH341.CopyFiles.SYSM64]
+CH341M64.SYS, , , 2
+
+[CH341.CopyFiles.SYSI64]
+;CH341I64.SYS, , , 2
+
+[CH341.CopyFiles.DLL]
+CH341DLL.DLL, , , 2
+
+[CH341.CopyFiles.DLLA64]
+CH341DLLA64.DLL, , , 2
+
+[CH341.CopyFiles.WOWDLL]
+CH341DLL.DLL, , , 2
+
+[CH347.CopyFiles.DLL]
+CH347DLL.DLL, , , 2
+
+[CH347.CopyFiles.DLLA64]
+CH347DLLA64.DLL, , , 2
+
+[CH347.CopyFiles.WOWDLL]
+CH347DLL.DLL, , , 2
+
+[CH341.9X.AddReg]
+HKR, , DevLoader, , *NTKERN
+HKR, , NTMPDriver, , CH341WDM.SYS
+
+[CH341.NT.AddReg]
+
+[CH341.AddReg]
+HKLM, SOFTWARE\WinChipHead\IC\CH341, WDM, 0x00010001, 0x00000022
+HKLM, SOFTWARE\WinChipHead\IC\CH341, DLL, 0x00010001, 0x00000021
+HKLM, SOFTWARE\WinChipHead\IC\CH341, Function, , "USB=>Parallel"
+
+[CH347.AddReg]
+HKLM, SOFTWARE\WinChipHead\IC\CH347, WDM, 0x00010001, 0x00000022
+HKLM, SOFTWARE\WinChipHead\IC\CH347, DLL, 0x00010001, 0x00000021
+HKLM, SOFTWARE\WinChipHead\IC\CH347, Function, , "USB20=>SPI&I2C&JTAG&UART"
+
+[CH341.Install.NT.Services]
+AddService = CH341, 2, CH341.Service
+
+[CH341.Install.NTamd64.Services]
+AddService = CH341_A64, 2, CH341.ServiceA64
+
+[CH341.Install.NTia64.Services]
+AddService = CH341_I64, 2, CH341.ServiceI64
+
+[CH341.Install.NTarm64.Services]
+AddService = CH341_M64, 2, CH341.ServiceM64
+
+[CH347.Install.NT.Services]
+AddService = CH341, 2, CH341.Service
+
+[CH347.Install.NTamd64.Services]
+AddService = CH341_A64, 2, CH341.ServiceA64
+
+[CH347.Install.NTia64.Services]
+AddService = CH341_I64, 2, CH341.ServiceI64
+
+[CH347.Install.NTarm64.Services]
+AddService = CH341_M64, 2, CH341.ServiceM64
+
+[CH341.Service]
+DisplayName = "CH341WDM"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341WDM.SYS
+
+[CH341.ServiceA64]
+DisplayName = "CH341WDM_A64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341W64.SYS
+
+[CH341.ServiceI64]
+DisplayName = "CH341WDM_I64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341I64.SYS
+
+[CH341.ServiceM64]
+DisplayName = "CH341WDM_M64"
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %10%\System32\Drivers\CH341M64.SYS
+
+[DestinationDirs]
+DefaultDestDir = 10, System32\Drivers
+CH347.CopyFiles.DLL = 11
+CH347.CopyFiles.DLLA64 = 11
+CH347.CopyFiles.WOWDLL = 10,SysWOW64
+CH341.CopyFiles.DLL = 11
+CH341.CopyFiles.DLLA64 = 11
+CH341.CopyFiles.WOWDLL = 10,SysWOW64
+CH341.CopyFiles.SYS = 10, System32\Drivers
+CH341.CopyFiles.SYSA64 = 10, System32\Drivers
+CH341.CopyFiles.SYSM64 = 10, System32\Drivers
+;CH347.CopyFiles.SYSI64 = 10, System32\Drivers
+;CH341.CopyFiles.SYSI64 = 10, System32\Drivers
+
+[SourceDisksFiles]
+CH341WDM.SYS = 1
+CH341W64.SYS = 1
+CH341M64.SYS = 1
+CH341DLL.DLL = 1
+CH341DLLA64.DLL = 1
+CH347DLL.DLL = 1
+CH347DLLA64.DLL = 1
+;CH341I64.SYS = 1
+;CH347I64.SYS = 1
+
+
+[SourceDisksNames]
+1 = %DISK_NAME%, CH341WDM.SYS, ,
+
+[SourceDisksNames.amd64]
+1 = %DISK_NAME%, CH341W64.SYS, ,
+
+[SourceDisksNames.ia64]
+1 = %DISK_NAME%, CH341I64.SYS, ,
+
+[SourceDisksNames.arm64]
+1 = %DISK_NAME%, CH341M64.SYS, ,
+
+[Strings]
+ClassName = "Interface"
+WinChipHead = "wch.cn"
+CH341.DeviceDesc = "USB-EPP/I2C... CH341"
+CH341A.DeviceDesc = "USB-EPP/I2C... CH341A"
+CH347M1A.DeviceDesc = "USB HighSpeed-SPI/I2C... CH347"
+CH347M1B.DeviceDesc = "USB HighSpeed-JTAG/I2C... CH347"
+CH341SER.DeviceDesc = "USB-SERIAL CH341"
+CH340SER.DeviceDesc = "USB-SERIAL CH340"
+CH341ASER.DeviceDesc = "USB-SERIAL CH341A"
+DISK_NAME = "CH341 Parallel Installation Disk"
+
+[Strings.0804]
+ClassName = "外部接口"
+WinChipHead = "wch.cn"
+CH341.DeviceDesc = "USB-EPP/I2C... CH341"
+CH341A.DeviceDesc = "USB-EPP/I2C... CH341A"
+CH347M1A.DeviceDesc = "USB HighSpeed-SPI/I2C... CH347"
+CH347M1B.DeviceDesc = "USB HighSpeed-JTAG/I2C... CH347"
+CH341SER.DeviceDesc = "USB-SERIAL CH341"
+CH340SER.DeviceDesc = "USB-SERIAL CH340"
+CH341ASER.DeviceDesc = "USB-SERIAL CH341A"
+DISK_NAME = "CH341 Parallel Installation Disk"
diff --git a/Drivers/CH341PAR/WIN 1X/CH341WDM.SYS b/Drivers/CH341PAR/WIN 1X/CH341WDM.SYS
new file mode 100644
index 0000000..b9d6f2b
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH341WDM.SYS differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH347DLL.DLL b/Drivers/CH341PAR/WIN 1X/CH347DLL.DLL
new file mode 100644
index 0000000..c2df248
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH347DLL.DLL differ
diff --git a/Drivers/CH341PAR/WIN 1X/CH347DLLA64.DLL b/Drivers/CH341PAR/WIN 1X/CH347DLLA64.DLL
new file mode 100644
index 0000000..557cfb2
Binary files /dev/null and b/Drivers/CH341PAR/WIN 1X/CH347DLLA64.DLL differ
diff --git a/Drivers/CH341SER.EXE b/Drivers/CH341SER.EXE
new file mode 100644
index 0000000..d2d649f
Binary files /dev/null and b/Drivers/CH341SER.EXE differ
diff --git a/Drivers/LIB/CH341/CH341DLL.H b/Drivers/LIB/CH341/CH341DLL.H
new file mode 100644
index 0000000..8e506d6
--- /dev/null
+++ b/Drivers/LIB/CH341/CH341DLL.H
@@ -0,0 +1,688 @@
+// 2004.05.28, 2004.10.20, 2005.01.08, 2005.03.25, 2005.04.28, 2005.07.18, 2005.07.28, 2005.09.19, 2007.12.19, 2008.10.15,2022.5
+//****************************************
+//** Copyright (C) WCH 1999-2022 **
+//** Web: http://www.winchiphead.com **
+//****************************************
+//** DLL for USB interface chip CH341 **
+//** C, VC5.0 **
+//****************************************
+//
+// USB总线接口芯片CH341并口应用层接口库 V2.2
+// 南京沁恒电子有限公司 作者: W.ch 2008.10
+// CH341-DLL V2.2
+// 运行环境: Windows 98/ME, Windows 2000/XP/7/10/11
+// support USB chip: CH341, CH341A, CH347 SPI/I2C
+// USB => Parallel, I2C, SPI, ...
+//
+
+#ifndef _CH341_DLL_H
+#define _CH341_DLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN64
+#define mOFFSET( s, m ) ( (ULONG_PTR) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
+#else
+#define mOFFSET( s, m ) ( (ULONG) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
+#endif
+
+#ifndef max
+#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) // 较大值
+#endif
+
+#ifndef min
+#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) // 较小值
+#endif
+
+#ifdef ExAllocatePool
+#undef ExAllocatePool // 删除带TAG的内存分配
+#endif
+
+#ifndef NTSTATUS
+typedef LONG NTSTATUS; // 返回状态
+#endif
+
+
+typedef struct _USB_SETUP_PKT { // USB控制传输的建立阶段的数据请求包结构
+ UCHAR mUspReqType; // 00H 请求类型
+ UCHAR mUspRequest; // 01H 请求代码
+ union {
+ struct {
+ UCHAR mUspValueLow; // 02H 值参数低字节
+ UCHAR mUspValueHigh; // 03H 值参数高字节
+ };
+ USHORT mUspValue; // 02H-03H 值参数
+ };
+ union {
+ struct {
+ UCHAR mUspIndexLow; // 04H 索引参数低字节
+ UCHAR mUspIndexHigh; // 05H 索引参数高字节
+ };
+ USHORT mUspIndex; // 04H-05H 索引参数
+ };
+ USHORT mLength; // 06H-07H 数据阶段的数据长度
+} mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;
+
+
+#define mCH341_PACKET_LENGTH 32 // CH341支持的数据包的长度
+#define mCH341_PKT_LEN_SHORT 8 // CH341支持的短数据包的长度
+
+
+typedef struct _WIN32_COMMAND { // 定义WIN32命令接口结构
+ union {
+ ULONG mFunction; // 输入时指定功能代码或者管道号
+ NTSTATUS mStatus; // 输出时返回操作状态
+ };
+ ULONG mLength; // 存取长度,返回后续数据的长度
+ union {
+ mUSB_SETUP_PKT mSetupPkt; // USB控制传输的建立阶段的数据请求
+ UCHAR mBuffer[ 512]; // 数据缓冲区,长度为0至255B
+ };
+} mWIN32_COMMAND, *mPWIN32_COMMAND;
+
+
+// WIN32应用层接口命令
+#define IOCTL_CH341_COMMAND ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // 专用接口
+
+#define mWIN32_COMMAND_HEAD mOFFSET( mWIN32_COMMAND, mBuffer ) // WIN32命令接口的头长度
+
+#define mCH341_MAX_NUMBER 16 // 最多同时连接的CH341数
+
+#define mMAX_BUFFER_LENGTH 0x1000 // 数据缓冲区最大长度4096
+
+#define mMAX_COMMAND_LENGTH ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ) // 最大数据长度加上命令结构头的长度
+
+#define mDEFAULT_BUFFER_LEN 0x0400 // 数据缓冲区默认长度1024
+
+#define mDEFAULT_COMMAND_LEN ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ) // 默认数据长度加上命令结构头的长度
+
+
+// CH341端点地址
+#define mCH341_ENDP_INTER_UP 0x81 // CH341的中断数据上传端点的地址
+#define mCH341_ENDP_INTER_DOWN 0x01 // CH341的中断数据下传端点的地址
+#define mCH341_ENDP_DATA_UP 0x82 // CH341的数据块上传端点的地址
+#define mCH341_ENDP_DATA_DOWN 0x02 // CH341的数据块下传端点的地址
+
+
+// 设备层接口提供的管道操作命令
+#define mPipeDeviceCtrl 0x00000004 // CH341的综合控制管道
+#define mPipeInterUp 0x00000005 // CH341的中断数据上传管道
+#define mPipeDataUp 0x00000006 // CH341的数据块上传管道
+#define mPipeDataDown 0x00000007 // CH341的数据块下传管道
+
+// 应用层接口的功能代码
+#define mFuncNoOperation 0x00000000 // 无操作
+#define mFuncGetVersion 0x00000001 // 获取驱动程序版本号
+#define mFuncGetConfig 0x00000002 // 获取USB设备配置描述符
+#define mFuncSetTimeout 0x00000009 // 设置USB通讯超时
+#define mFuncSetExclusive 0x0000000b // 设置独占使用
+#define mFuncResetDevice 0x0000000c // 复位USB设备
+#define mFuncResetPipe 0x0000000d // 复位USB管道
+#define mFuncAbortPipe 0x0000000e // 取消USB管道的数据请求
+
+// CH341并口专用的功能代码
+#define mFuncSetParaMode 0x0000000f // 设置并口模式
+#define mFuncReadData0 0x00000010 // 从并口读取数据块0
+#define mFuncReadData1 0x00000011 // 从并口读取数据块1
+#define mFuncWriteData0 0x00000012 // 向并口写入数据块0
+#define mFuncWriteData1 0x00000013 // 向并口写入数据块1
+#define mFuncWriteRead 0x00000014 // 先输出再输入
+#define mFuncBufferMode 0x00000020 // 设定缓冲上传模式及查询缓冲区中的数据长度
+#define mFuncBufferModeDn 0x00000021 // 设定缓冲下传模式及查询缓冲区中的数据长度
+#define mFuncGetVersionEx 0x00000022 // 获取驱动程序版本号及芯片型号
+
+
+// USB设备标准请求代码
+#define mUSB_CLR_FEATURE 0x01
+#define mUSB_SET_FEATURE 0x03
+#define mUSB_GET_STATUS 0x00
+#define mUSB_SET_ADDRESS 0x05
+#define mUSB_GET_DESCR 0x06
+#define mUSB_SET_DESCR 0x07
+#define mUSB_GET_CONFIG 0x08
+#define mUSB_SET_CONFIG 0x09
+#define mUSB_GET_INTERF 0x0a
+#define mUSB_SET_INTERF 0x0b
+#define mUSB_SYNC_FRAME 0x0c
+
+// CH341控制传输的厂商专用请求类型
+#define mCH341_VENDOR_READ 0xC0 // 通过控制传输实现的CH341厂商专用读操作
+#define mCH341_VENDOR_WRITE 0x40 // 通过控制传输实现的CH341厂商专用写操作
+
+// CH341控制传输的厂商专用请求代码
+#define mCH341_PARA_INIT 0xB1 // 初始化并口
+#define mCH341_I2C_STATUS 0x52 // 获取I2C接口的状态
+#define mCH341_I2C_COMMAND 0x53 // 发出I2C接口的命令
+
+// CH341并口操作命令代码
+#define mCH341_PARA_CMD_R0 0xAC // 从并口读数据0,次字节为长度
+#define mCH341_PARA_CMD_R1 0xAD // 从并口读数据1,次字节为长度
+#define mCH341_PARA_CMD_W0 0xA6 // 向并口写数据0,从次字节开始为数据流
+#define mCH341_PARA_CMD_W1 0xA7 // 向并口写数据1,从次字节开始为数据流
+#define mCH341_PARA_CMD_STS 0xA0 // 获取并口状态
+
+// CH341A并口操作命令代码
+#define mCH341A_CMD_SET_OUTPUT 0xA1 // 设置并口输出
+#define mCH341A_CMD_IO_ADDR 0xA2 // MEM带地址读写/输入输出,从次字节开始为命令流
+#define mCH341A_CMD_PRINT_OUT 0xA3 // PRINT兼容打印方式输出,从次字节开始为数据流
+#define mCH341A_CMD_PWM_OUT 0xA4 // PWM数据输出的命令包,从次字节开始为数据流
+#define mCH341A_CMD_SHORT_PKT 0xA5 // 短包,次字节是该命令包的真正长度,再次字节及之后的字节是原命令包
+#define mCH341A_CMD_SPI_STREAM 0xA8 // SPI接口的命令包,从次字节开始为数据流
+//#define mCH341A_CMD_SIO_STREAM 0xA9 // SIO接口的命令包,从次字节开始为数据流
+#define mCH341A_CMD_I2C_STREAM 0xAA // I2C接口的命令包,从次字节开始为I2C命令流
+#define mCH341A_CMD_UIO_STREAM 0xAB // UIO接口的命令包,从次字节开始为命令流
+#define mCH341A_CMD_PIO_STREAM 0xAE // PIO接口的命令包,从次字节开始为数据流
+
+// CH341A控制传输的厂商专用请求代码
+#define mCH341A_BUF_CLEAR 0xB2 // 清除未完成的数据
+#define mCH341A_I2C_CMD_X 0x54 // 发出I2C接口的命令,立即执行
+#define mCH341A_DELAY_MS 0x5E // 以亳秒为单位延时指定时间
+#define mCH341A_GET_VER 0x5F // 获取芯片版本
+
+#define mCH341_EPP_IO_MAX ( mCH341_PACKET_LENGTH - 1 ) // CH341在EPP/MEM方式下单次读写数据块的最大长度
+#define mCH341A_EPP_IO_MAX 0xFF // CH341A在EPP/MEM方式下单次读写数据块的最大长度
+
+#define mCH341A_CMD_IO_ADDR_W 0x00 // MEM带地址读写/输入输出的命令流:写数据,位6-位0为地址,下一个字节为待写数据
+#define mCH341A_CMD_IO_ADDR_R 0x80 // MEM带地址读写/输入输出的命令流:读数据,位6-位0为地址,读出数据一起返回
+
+#define mCH341A_CMD_I2C_STM_STA 0x74 // I2C接口的命令流:产生起始位
+#define mCH341A_CMD_I2C_STM_STO 0x75 // I2C接口的命令流:产生停止位
+#define mCH341A_CMD_I2C_STM_OUT 0x80 // I2C接口的命令流:输出数据,位5-位0为长度,后续字节为数据,0长度则只发送一个字节并返回应答
+#define mCH341A_CMD_I2C_STM_IN 0xC0 // I2C接口的命令流:输入数据,位5-位0为长度,0长度则只接收一个字节并发送无应答
+#define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) // I2C接口的命令流单个命令输入输出数据的最大长度
+#define mCH341A_CMD_I2C_STM_SET 0x60 // I2C接口的命令流:设置参数,位2=SPI的I/O数(0=单入单出,1=双入双出),位1位0=I2C速度(00=低速,01=标准,10=快速,11=高速)
+#define mCH341A_CMD_I2C_STM_US 0x40 // I2C接口的命令流:以微秒为单位延时,位3-位0为延时值
+#define mCH341A_CMD_I2C_STM_MS 0x50 // I2C接口的命令流:以亳秒为单位延时,位3-位0为延时值
+#define mCH341A_CMD_I2C_STM_DLY 0x0F // I2C接口的命令流单个命令延时的最大值
+#define mCH341A_CMD_I2C_STM_END 0x00 // I2C接口的命令流:命令包提前结束
+
+#define mCH341A_CMD_UIO_STM_IN 0x00 // UIO接口的命令流:输入数据D7-D0
+#define mCH341A_CMD_UIO_STM_DIR 0x40 // UIO接口的命令流:设定I/O方向D5-D0,位5-位0为方向数据
+#define mCH341A_CMD_UIO_STM_OUT 0x80 // UIO接口的命令流:输出数据D5-D0,位5-位0为数据
+#define mCH341A_CMD_UIO_STM_US 0xC0 // UIO接口的命令流:以微秒为单位延时,位5-位0为延时值
+#define mCH341A_CMD_UIO_STM_END 0x20 // UIO接口的命令流:命令包提前结束
+
+
+// CH341并口工作模式
+#define mCH341_PARA_MODE_EPP 0x00 // CH341并口工作模式为EPP方式
+#define mCH341_PARA_MODE_EPP17 0x00 // CH341A并口工作模式为EPP方式V1.7
+#define mCH341_PARA_MODE_EPP19 0x01 // CH341A并口工作模式为EPP方式V1.9
+#define mCH341_PARA_MODE_MEM 0x02 // CH341并口工作模式为MEM方式
+#define mCH341_PARA_MODE_ECP 0x03 // CH341A并口工作模式为ECP方式
+
+
+// I/O方向设置位定义,直接输入的状态信号的位定义,直接输出的位数据定义
+#define mStateBitERR 0x00000100 // 只读可写,ERR#引脚输入状态,1:高电平,0:低电平
+#define mStateBitPEMP 0x00000200 // 只读可写,PEMP引脚输入状态,1:高电平,0:低电平
+#define mStateBitINT 0x00000400 // 只读可写,INT#引脚输入状态,1:高电平,0:低电平
+#define mStateBitSLCT 0x00000800 // 只读可写,SLCT引脚输入状态,1:高电平,0:低电平
+#define mStateBitWAIT 0x00002000 // 只读可写,WAIT#引脚输入状态,1:高电平,0:低电平
+#define mStateBitDATAS 0x00004000 // 只写可读,DATAS#/READ#引脚输入状态,1:高电平,0:低电平
+#define mStateBitADDRS 0x00008000 // 只写可读,ADDRS#/ADDR/ALE引脚输入状态,1:高电平,0:低电平
+#define mStateBitRESET 0x00010000 // 只写,RESET#引脚输入状态,1:高电平,0:低电平
+#define mStateBitWRITE 0x00020000 // 只写,WRITE#引脚输入状态,1:高电平,0:低电平
+#define mStateBitSCL 0x00400000 // 只读,SCL引脚输入状态,1:高电平,0:低电平
+#define mStateBitSDA 0x00800000 // 只读,SDA引脚输入状态,1:高电平,0:低电平
+
+
+#define MAX_DEVICE_PATH_SIZE 128 // 设备名称的最大字符数
+#define MAX_DEVICE_ID_SIZE 64 // 设备ID的最大字符数
+
+
+typedef VOID ( CALLBACK * mPCH341_INT_ROUTINE ) ( // 中断服务程序
+ ULONG iStatus ); // 中断状态数据,参考下面的位说明
+// 位7-位0对应CH341的D7-D0引脚
+// 位8对应CH341的ERR#引脚, 位9对应CH341的PEMP引脚, 位10对应CH341的INT#引脚, 位11对应CH341的SLCT引脚
+
+
+HANDLE WINAPI CH341OpenDevice( // 打开CH341设备,返回句柄,出错则无效
+ ULONG iIndex ); // 指定CH341设备序号,0对应第一个设备
+
+
+VOID WINAPI CH341CloseDevice( // 关闭CH341设备
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+ULONG WINAPI CH341GetVersion( ); // 获得DLL版本号,返回版本号
+
+
+ULONG WINAPI CH341DriverCommand( // 直接传递命令给驱动程序,出错则返回0,否则返回数据长度
+ ULONG iIndex, // 指定CH341设备序号,V1.6以上DLL也可以是设备打开后的句柄
+ mPWIN32_COMMAND ioCommand ); // 命令结构的指针
+// 该程序在调用后返回数据长度,并且仍然返回命令结构,如果是读操作,则数据返回在命令结构中,
+// 返回的数据长度在操作失败时为0,操作成功时为整个命令结构的长度,例如读一个字节,则返回mWIN32_COMMAND_HEAD+1,
+// 命令结构在调用前,分别提供:管道号或者命令功能代码,存取数据的长度(可选),数据(可选)
+// 命令结构在调用后,分别返回:操作状态代码,后续数据的长度(可选),
+// 操作状态代码是由WINDOWS定义的代码,可以参考NTSTATUS.H,
+// 后续数据的长度是指读操作返回的数据长度,数据存放在随后的缓冲区中,对于写操作一般为0
+
+
+ULONG WINAPI CH341GetDrvVersion( ); // 获得驱动程序版本号,返回版本号,出错则返回0
+
+
+BOOL WINAPI CH341ResetDevice( // 复位USB设备
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341GetDeviceDescr( // 读取设备描述符
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存描述符
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341GetConfigDescr( // 读取配置描述符
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存描述符
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341SetIntRoutine( // 设定中断服务程序
+ ULONG iIndex, // 指定CH341设备序号
+ mPCH341_INT_ROUTINE iIntRoutine ); // 指定中断服务程序,为NULL则取消中断服务,否则在中断时调用该程序
+
+
+BOOL WINAPI CH341ReadInter( // 读取中断数据
+ ULONG iIndex, // 指定CH341设备序号
+ PULONG iStatus ); // 指向一个双字单元,用于保存读取的中断状态数据,见下行
+// 位7-位0对应CH341的D7-D0引脚
+// 位8对应CH341的ERR#引脚, 位9对应CH341的PEMP引脚, 位10对应CH341的INT#引脚, 位11对应CH341的SLCT引脚
+
+
+BOOL WINAPI CH341AbortInter( // 放弃中断数据读操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341SetParaMode( // 设置并口模式
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iMode ); // 指定并口模式: 0为EPP模式/EPP模式V1.7, 1为EPP模式V1.9, 2为MEM模式
+
+
+BOOL WINAPI CH341InitParallel( // 复位并初始化并口,RST#输出低电平脉冲
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iMode ); // 指定并口模式: 0为EPP模式/EPP模式V1.7, 1为EPP模式V1.9, 2为MEM模式, >= 0x00000100 保持当前模式
+
+
+BOOL WINAPI CH341ReadData0( // 从0#端口读取数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341ReadData1( // 从1#端口读取数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341AbortRead( // 放弃数据块读操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341WriteData0( // 向0#端口写出数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341WriteData1( // 向1#端口写出数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341AbortWrite( // 放弃数据块写操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341GetStatus( // 通过CH341直接输入数据和状态
+ ULONG iIndex, // 指定CH341设备序号
+ PULONG iStatus ); // 指向一个双字单元,用于保存状态数据,参考下面的位说明
+// 位7-位0对应CH341的D7-D0引脚
+// 位8对应CH341的ERR#引脚, 位9对应CH341的PEMP引脚, 位10对应CH341的INT#引脚, 位11对应CH341的SLCT引脚, 位23对应CH341的SDA引脚
+// 位13对应CH341的BUSY/WAIT#引脚, 位14对应CH341的AUTOFD#/DATAS#引脚,位15对应CH341的SLCTIN#/ADDRS#引脚
+
+
+BOOL WINAPI CH341ReadI2C( // 从I2C接口读取一个字节数据
+ ULONG iIndex, // 指定CH341设备序号
+ UCHAR iDevice, // 低7位指定I2C设备地址
+ UCHAR iAddr, // 指定数据单元的地址
+ PUCHAR oByte ); // 指向一个字节单元,用于保存读取的字节数据
+
+
+BOOL WINAPI CH341WriteI2C( // 向I2C接口写入一个字节数据
+ ULONG iIndex, // 指定CH341设备序号
+ UCHAR iDevice, // 低7位指定I2C设备地址
+ UCHAR iAddr, // 指定数据单元的地址
+ UCHAR iByte ); // 待写入的字节数据
+
+
+BOOL WINAPI CH341EppReadData( // EPP方式读数据: WR#=1, DS#=0, AS#=1, D0-D7=input
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341EppReadAddr( // EPP方式读地址: WR#=1, DS#=1, AS#=0, D0-D7=input
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的地址数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341EppWriteData( // EPP方式写数据: WR#=0, DS#=0, AS#=1, D0-D7=output
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341EppWriteAddr( // EPP方式写地址: WR#=0, DS#=1, AS#=0, D0-D7=output
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的地址数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341EppSetAddr( // EPP方式设置地址: WR#=0, DS#=1, AS#=0, D0-D7=output
+ ULONG iIndex, // 指定CH341设备序号
+ UCHAR iAddr ); // 指定EPP地址
+
+
+BOOL WINAPI CH341MemReadAddr0( // MEM方式读地址0: WR#=1, DS#/RD#=0, AS#/ADDR=0, D0-D7=input
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存从地址0读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341MemReadAddr1( // MEM方式读地址1: WR#=1, DS#/RD#=0, AS#/ADDR=1, D0-D7=input
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存从地址1读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341MemWriteAddr0( // MEM方式写地址0: WR#=0, DS#/RD#=1, AS#/ADDR=0, D0-D7=output
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备向地址0写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341MemWriteAddr1( // MEM方式写地址1: WR#=0, DS#/RD#=1, AS#/ADDR=1, D0-D7=output
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备向地址1写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+BOOL WINAPI CH341SetExclusive( // 设置独占使用当前CH341设备
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iExclusive ); // 为0则设备可以共享使用,非0则独占使用
+
+
+BOOL WINAPI CH341SetTimeout( // 设置USB数据读写的超时
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iWriteTimeout, // 指定USB写出数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+ ULONG iReadTimeout ); // 指定USB读取数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+
+
+BOOL WINAPI CH341ReadData( // 读取数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+
+BOOL WINAPI CH341WriteData( // 写出数据块
+ ULONG iIndex, // 指定CH341设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+
+PVOID WINAPI CH341GetDeviceName( // 返回指向CH341设备名称的缓冲区,出错则返回NULL
+ ULONG iIndex ); // 指定CH341设备序号,0对应第一个设备
+
+
+ULONG WINAPI CH341GetVerIC( // 获取CH341芯片的版本,返回:0=设备无效,0x10=CH341,0x20=CH341A
+ ULONG iIndex ); // 指定CH341设备序号
+#define IC_VER_CH341A 0x20
+#define IC_VER_CH341A3 0x30
+
+
+BOOL WINAPI CH341FlushBuffer( // 清空CH341的缓冲区
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341WriteRead( // 执行数据流命令,先输出再输入
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iWriteLength, // 写长度,准备写出的长度
+ PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据
+ ULONG iReadStep, // 准备读取的单个块的长度, 准备读取的总长度为(iReadStep*iReadTimes)
+ ULONG iReadTimes, // 准备读取的次数
+ PULONG oReadLength, // 指向长度单元,返回后为实际读取的长度
+ PVOID oReadBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+
+BOOL WINAPI CH341SetStream( // 设置串口流模式
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iMode ); // 指定模式,见下行
+// 位1-位0: I2C接口速度/SCL频率, 00=低速/20KHz,01=标准/100KHz(默认值),10=快速/400KHz,11=高速/750KHz
+// 位2: SPI的I/O数/IO引脚, 0=单入单出(D3时钟/D5出/D7入)(默认值),1=双入双出(D3时钟/D5出D4出/D7入D6入)
+// 位7: SPI字节中的位顺序, 0=低位在前, 1=高位在前
+// 其它保留,必须为0
+
+
+BOOL WINAPI CH341SetDelaymS( // 设置硬件异步延时,调用后很快返回,而在下一个流操作之前延时指定毫秒数
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iDelay ); // 指定延时的毫秒数
+
+
+BOOL WINAPI CH341StreamI2C( // 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚(准双向I/O),速度约56K字节
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iWriteLength, // 准备写出的数据字节数
+ PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位
+ ULONG iReadLength, // 准备读取的数据字节数
+ PVOID oReadBuffer ); // 指向一个缓冲区,返回后是读入的数据
+
+
+typedef enum _EEPROM_TYPE { // EEPROM型号
+ ID_24C01,
+ ID_24C02,
+ ID_24C04,
+ ID_24C08,
+ ID_24C16,
+ ID_24C32,
+ ID_24C64,
+ ID_24C128,
+ ID_24C256,
+ ID_24C512,
+ ID_24C1024,
+ ID_24C2048,
+ ID_24C4096
+} EEPROM_TYPE;
+
+
+BOOL WINAPI CH341ReadEEPROM( // 从EEPROM中读取数据块,速度约56K字节
+ ULONG iIndex, // 指定CH341设备序号
+ EEPROM_TYPE iEepromID, // 指定EEPROM型号
+ ULONG iAddr, // 指定数据单元的地址
+ ULONG iLength, // 准备读取的数据字节数
+ PUCHAR oBuffer ); // 指向一个缓冲区,返回后是读入的数据
+
+
+BOOL WINAPI CH341WriteEEPROM( // 向EEPROM中写入数据块
+ ULONG iIndex, // 指定CH341设备序号
+ EEPROM_TYPE iEepromID, // 指定EEPROM型号
+ ULONG iAddr, // 指定数据单元的地址
+ ULONG iLength, // 准备写出的数据字节数
+ PUCHAR iBuffer ); // 指向一个缓冲区,放置准备写出的数据
+
+
+BOOL WINAPI CH341GetInput( // 通过CH341直接输入数据和状态,效率比CH341GetStatus更高
+ ULONG iIndex, // 指定CH341设备序号
+ PULONG iStatus ); // 指向一个双字单元,用于保存状态数据,参考下面的位说明
+// 位7-位0对应CH341的D7-D0引脚
+// 位8对应CH341的ERR#引脚, 位9对应CH341的PEMP引脚, 位10对应CH341的INT#引脚, 位11对应CH341的SLCT引脚, 位23对应CH341的SDA引脚
+// 位13对应CH341的BUSY/WAIT#引脚, 位14对应CH341的AUTOFD#/DATAS#引脚,位15对应CH341的SLCTIN#/ADDRS#引脚
+
+
+BOOL WINAPI CH341SetOutput( // 设置CH341的I/O方向,并通过CH341直接输出数据
+/* ***** 谨慎使用该API, 防止修改I/O方向使输入引脚变为输出引脚导致与其它输出引脚之间短路而损坏芯片 ***** */
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iEnable, // 数据有效标志,参考下面的位说明
+// 位0为1说明iSetDataOut的位15-位8有效,否则忽略
+// 位1为1说明iSetDirOut的位15-位8有效,否则忽略
+// 位2为1说明iSetDataOut的7-位0有效,否则忽略
+// 位3为1说明iSetDirOut的位7-位0有效,否则忽略
+// 位4为1说明iSetDataOut的位23-位16有效,否则忽略
+ ULONG iSetDirOut, // 设置I/O方向,某位清0则对应引脚为输入,某位置1则对应引脚为输出,并口方式下默认值为0x000FC000,参考下面的位说明
+ ULONG iSetDataOut ); // 输出数据,如果I/O方向为输出,那么某位清0时对应引脚输出低电平,某位置1时对应引脚输出高电平,参考下面的位说明
+// 位7-位0对应CH341的D7-D0引脚
+// 位8对应CH341的ERR#引脚, 位9对应CH341的PEMP引脚, 位10对应CH341的INT#引脚, 位11对应CH341的SLCT引脚
+// 位13对应CH341的WAIT#引脚, 位14对应CH341的DATAS#/READ#引脚,位15对应CH341的ADDRS#/ADDR/ALE引脚
+// 以下引脚只能输出,不考虑I/O方向: 位16对应CH341的RESET#引脚, 位17对应CH341的WRITE#引脚, 位18对应CH341的SCL引脚, 位29对应CH341的SDA引脚
+
+
+BOOL WINAPI CH341Set_D5_D0( // 设置CH341的D5-D0引脚的I/O方向,并通过CH341的D5-D0引脚直接输出数据,效率比CH341SetOutput更高
+/* ***** 谨慎使用该API, 防止修改I/O方向使输入引脚变为输出引脚导致与其它输出引脚之间短路而损坏芯片 ***** */
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iSetDirOut, // 设置D5-D0各引脚的I/O方向,某位清0则对应引脚为输入,某位置1则对应引脚为输出,并口方式下默认值为0x00全部输入
+ ULONG iSetDataOut ); // 设置D5-D0各引脚的输出数据,如果I/O方向为输出,那么某位清0时对应引脚输出低电平,某位置1时对应引脚输出高电平
+// 以上数据的位5-位0分别对应CH341的D5-D0引脚
+
+
+BOOL WINAPI CH341StreamSPI3( // 该API已失效,请勿使用
+ ULONG iIndex,
+ ULONG iChipSelect,
+ ULONG iLength,
+ PVOID ioBuffer );
+
+
+BOOL WINAPI CH341StreamSPI4( // 处理SPI数据流,4线接口,时钟线为DCK/D3引脚,输出数据线为DOUT/D5引脚,输入数据线为DIN/D7引脚,片选线为D0/D1/D2,速度约68K字节
+/* SPI时序: DCK/D3引脚为时钟输出, 默认为低电平, DOUT/D5引脚在时钟上升沿之前的低电平期间输出, DIN/D7引脚在时钟下降沿之前的高电平期间输入 */
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效: 位1位0为00/01/10分别选择D0/D1/D2引脚作为低电平有效片选
+ ULONG iLength, // 准备传输的数据字节数
+ PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
+
+
+BOOL WINAPI CH341StreamSPI5( // 处理SPI数据流,5线接口,时钟线为DCK/D3引脚,输出数据线为DOUT/D5和DOUT2/D4引脚,输入数据线为DIN/D7和DIN2/D6引脚,片选线为D0/D1/D2,速度约30K字节*2
+/* SPI时序: DCK/D3引脚为时钟输出, 默认为低电平, DOUT/D5和DOUT2/D4引脚在时钟上升沿之前的低电平期间输出, DIN/D7和DIN2/D6引脚在时钟下降沿之前的高电平期间输入 */
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效: 位1位0为00/01/10分别选择D0/D1/D2引脚作为低电平有效片选
+ ULONG iLength, // 准备传输的数据字节数
+ PVOID ioBuffer, // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
+ PVOID ioBuffer2 ); // 指向第二个缓冲区,放置准备从DOUT2写出的数据,返回后是从DIN2读入的数据
+
+
+BOOL WINAPI CH341BitStreamSPI( // 处理SPI位数据流,4线/5线接口,时钟线为DCK/D3引脚,输出数据线为DOUT/DOUT2引脚,输入数据线为DIN/DIN2引脚,片选线为D0/D1/D2,速度约8K位*2
+ ULONG iIndex, // 指定CH341设备序号
+ ULONG iLength, // 准备传输的数据位数,一次最多896,建议不超过256
+ PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT/DOUT2/D2-D0写出的数据,返回后是从DIN/DIN2读入的数据
+/* SPI时序: DCK/D3引脚为时钟输出, 默认为低电平, DOUT/D5和DOUT2/D4引脚在时钟上升沿之前的低电平期间输出, DIN/D7和DIN2/D6引脚在时钟下降沿之前的高电平期间输入 */
+/* ioBuffer中的一个字节共8位分别对应D7-D0引脚, 位5输出到DOUT, 位4输出到DOUT2, 位2-位0输出到D2-D0, 位7从DIN输入, 位6从DIN2输入, 位3数据忽略 */
+/* 在调用该API之前,应该先调用CH341Set_D5_D0设置CH341的D5-D0引脚的I/O方向,并设置引脚的默认电平 */
+
+
+BOOL WINAPI CH341SetBufUpload( // 设定内部缓冲上传模式
+ ULONG iIndex, // 指定CH341设备序号,0对应第一个设备
+ ULONG iEnableOrClear ); // 为0则禁止内部缓冲上传模式,使用直接上传,非0则启用内部缓冲上传模式并清除缓冲区中的已有数据
+// 如果启用内部缓冲上传模式,那么CH341驱动程序创建线程自动接收USB上传数据到内部缓冲区,同时清除缓冲区中的已有数据,当应用程序调用CH341ReadData后将立即返回缓冲区中的已有数据
+
+
+LONG WINAPI CH341QueryBufUpload( // 查询内部上传缓冲区中的已有数据包个数,成功返回数据包个数,出错返回-1
+ ULONG iIndex ); // 指定CH341设备序号,0对应第一个设备
+
+
+BOOL WINAPI CH341SetBufDownload( // 设定内部缓冲下传模式
+ ULONG iIndex, // 指定CH341设备序号,0对应第一个设备
+ ULONG iEnableOrClear ); // 为0则禁止内部缓冲下传模式,使用直接下传,非0则启用内部缓冲下传模式并清除缓冲区中的已有数据
+// 如果启用内部缓冲下传模式,那么当应用程序调用CH341WriteData后将仅仅是将USB下传数据放到内部缓冲区并立即返回,而由CH341驱动程序创建的线程自动发送直到完毕
+
+
+LONG WINAPI CH341QueryBufDownload( // 查询内部下传缓冲区中的剩余数据包个数(尚未发送),成功返回数据包个数,出错返回-1
+ ULONG iIndex ); // 指定CH341设备序号,0对应第一个设备
+
+
+BOOL WINAPI CH341ResetInter( // 复位中断数据读操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341ResetRead( // 复位数据块读操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+BOOL WINAPI CH341ResetWrite( // 复位数据块写操作
+ ULONG iIndex ); // 指定CH341设备序号
+
+
+typedef VOID ( CALLBACK * mPCH341_NOTIFY_ROUTINE ) ( // 设备事件通知回调程序
+ ULONG iEventStatus ); // 设备事件和当前状态(在下行定义): 0=设备拔出事件, 3=设备插入事件
+
+#define CH341_DEVICE_ARRIVAL 3 // 设备插入事件,已经插入
+#define CH341_DEVICE_REMOVE_PEND 1 // 设备将要拔出
+#define CH341_DEVICE_REMOVE 0 // 设备拔出事件,已经拔出
+
+
+BOOL WINAPI CH341SetDeviceNotify( // 设定设备事件通知程序
+ ULONG iIndex, // 指定CH341设备序号,0对应第一个设备
+ PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
+ mPCH341_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
+
+
+BOOL WINAPI CH341SetupSerial( // 设定CH341的串口特性,该API只能用于工作于串口方式的CH341芯片
+ ULONG iIndex, // 指定CH341设备序号,0对应第一个设备
+ ULONG iParityMode, // 指定CH341串口的数据校验模式: NOPARITY/ODDPARITY/EVENPARITY/MARKPARITY/SPACEPARITY
+ ULONG iBaudRate ); // 指定CH341串口的通讯波特率值,可以是50至3000000之间的任意值
+
+/* 以下API可以用于工作于串口方式的CH341芯片,除此之外的API一般只能用于并口方式的CH341芯片
+ CH341OpenDevice
+ CH341CloseDevice
+ CH341SetupSerial
+ CH341ReadData
+ CH341WriteData
+ CH341SetBufUpload
+ CH341QueryBufUpload
+ CH341SetBufDownload
+ CH341QueryBufDownload
+ CH341SetDeviceNotify
+ CH341GetStatus
+// 以上是主要API,以下是次要API
+ CH341GetVersion
+ CH341DriverCommand
+ CH341GetDrvVersion
+ CH341ResetDevice
+ CH341GetDeviceDescr
+ CH341GetConfigDescr
+ CH341SetIntRoutine
+ CH341ReadInter
+ CH341AbortInter
+ CH341AbortRead
+ CH341AbortWrite
+ CH341ReadI2C
+ CH341WriteI2C
+ CH341SetExclusive
+ CH341SetTimeout
+ CH341GetDeviceName
+ CH341GetVerIC
+ CH341FlushBuffer
+ CH341WriteRead
+ CH341ResetInter
+ CH341ResetRead
+ CH341ResetWrite
+*/
+HANDLE WINAPI CH341OpenDeviceEx( // 打开CH341设备,返回句柄,出错则无效
+ ULONG iIndex ); // 指定CH341设备序号,0对应插入的第一个设备,1对应插入的第二个设备,为节约设备设备序号资源,用完后要关闭设备
+
+VOID WINAPI CH341CloseDeviceEx( // 关闭CH341设备
+ ULONG iIndex ); // 指定CH341设备序号
+
+PCHAR WINAPI CH341GetDeviceNameEx( // 返回指向CH341设备名称的缓冲区,出错则返回NULL
+ ULONG iIndex ); // 指定CH341设备序号,0对应第一个设备
+
+BOOL WINAPI CH341SetDeviceNotifyEx( // 设定设备事件通知程序
+ ULONG iIndex, // 指定CH341设备序号,0对应第一个设备
+ PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
+ mPCH341_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CH341_DLL_H
diff --git a/Drivers/LIB/CH341/CH341DLL_EN.H b/Drivers/LIB/CH341/CH341DLL_EN.H
new file mode 100644
index 0000000..d3afa08
--- /dev/null
+++ b/Drivers/LIB/CH341/CH341DLL_EN.H
@@ -0,0 +1,680 @@
+// 2004.05.28, 2004.10.20, 2005.01.08, 2005.03.25, 2005.04.28, 2005.07.18, 2005.07.28, 2005.09.19, 2007.12.19, 2008.10.15, 2022.5
+//****************************************
+//** Copyright (C) WCH 1999-2022 **
+//** Web: http://www.winchiphead.com **
+//****************************************
+//** DLL for USB interface chip CH341 **
+//** C, VC5.0 **
+//****************************************
+//
+// USB interface chip CH341 parallel application interface lib V2.2
+// Nanjing Qinheng Microelectronics Co., Ltd. Author: W.ch 2008.10
+// CH341-DLL V2.2
+// Runtime environment: Windows 98/ME, Windows 2000/XP/7/10/11
+// support USB chip: CH341, CH341A, CH347 SPI/I2C
+// USB => Parallel, I2C, SPI, ...
+//
+
+#ifndef _CH341_DLL_H
+#define _CH341_DLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN64
+#define mOFFSET( s, m ) ( (ULONG_PTR) & ( ( ( s * ) 0 ) -> m ) ) // Defines a macro that gets the relative offset address of a structure member
+#else
+#define mOFFSET( s, m ) ( (ULONG) & ( ( ( s * ) 0 ) -> m ) ) // Defines a macro that gets the relative offset address of a structure member
+#endif
+
+#ifndef max
+#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) // Larger value
+#endif
+
+#ifndef min
+#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) // Smaller values
+#endif
+
+#ifdef ExAllocatePool
+#undef ExAllocatePool // Delete a memory allocation with TAG
+#endif
+
+#ifndef NTSTATUS
+typedef LONG NTSTATUS; // Return status
+#endif
+
+
+typedef struct _USB_SETUP_PKT { // USB control transmission of the establishment phase of the data request packet structure
+ UCHAR mUspReqType; // 00H Request type
+ UCHAR mUspRequest; // 01H Request code
+ union {
+ struct {
+ UCHAR mUspValueLow; // 02H Value parameter low bytes
+ UCHAR mUspValueHigh; // 03H Value parameter high bytes
+ };
+ USHORT mUspValue; // 02H-03H Value parameter
+ };
+ union {
+ struct {
+ UCHAR mUspIndexLow; // 04H Index parameter low bytes
+ UCHAR mUspIndexHigh; // 05H Index parameter high bytes
+ };
+ USHORT mUspIndex; // 04H-05H Index parameter
+ };
+ USHORT mLength; // 06H-07H Data length of the data phase
+} mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;
+
+
+#define mCH341_PACKET_LENGTH 32 // Length of data packets supported by CH341
+#define mCH341_PKT_LEN_SHORT 8 // Length of short packets supported by CH341
+
+
+typedef struct _WIN32_COMMAND { // Define WIN32 command interface structure
+ union {
+ ULONG mFunction; // Specify the function code or pipe number when entering
+ NTSTATUS mStatus; // Returns operation status on output
+ };
+ ULONG mLength; // Access length, returns the length of subsequent data
+ union {
+ mUSB_SETUP_PKT mSetupPkt; // USB controls the transmission of data requests during the setup phase
+ UCHAR mBuffer[ 512]; // Data buffer, 0 to 255B in length
+ };
+} mWIN32_COMMAND, *mPWIN32_COMMAND;
+
+// WIN32 application layer interface command
+#define IOCTL_CH341_COMMAND ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // Special interface
+
+#define mWIN32_COMMAND_HEAD mOFFSET( mWIN32_COMMAND, mBuffer ) // WIN32 command interface header length
+
+#define mCH341_MAX_NUMBER 16 // Maximum number of CH341 connected at the same time
+
+#define mMAX_BUFFER_LENGTH 0x1000 // Maximum length of the data buffer is 4096
+
+#define mMAX_COMMAND_LENGTH ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ) // Maximum data length plus the length of the command structure header
+
+#define mDEFAULT_BUFFER_LEN 0x0400 // Default length of the data buffer is 1024
+
+#define mDEFAULT_COMMAND_LEN ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ) // Default data length plus the length of the command structure header
+
+// CH341 endpoint address
+#define mCH341_ENDP_INTER_UP 0x81 // Address of the interrupt data upload endpoint of CH341
+#define mCH341_ENDP_INTER_DOWN 0x01 // Address of the interrupt data download endpoint of CH341
+#define mCH341_ENDP_DATA_UP 0x82 // Address of the data block upload endpoint of CH341
+#define mCH341_ENDP_DATA_DOWN 0x02 // IP address of the data block download endpoint of the CH341
+
+// Operation command of pipes provided by device layer interfaces
+#define mPipeDeviceCtrl 0x00000004 // Integrated control piping for CH341
+#define mPipeInterUp 0x00000005 // Interrupt data upload pipeline for CH341
+#define mPipeDataUp 0x00000006 // CH341 data block upload pipeline
+#define mPipeDataDown 0x00000007 // CH341 data block dowload pipeline
+
+// Function code of the application interface
+#define mFuncNoOperation 0x00000000 // No operation
+#define mFuncGetVersion 0x00000001 // Gets the driver version number
+#define mFuncGetConfig 0x00000002 // Gets the USB device configuration descriptor
+#define mFuncSetTimeout 0x00000009 // Set USB communication timeout
+#define mFuncSetExclusive 0x0000000b // Set exclusive use
+#define mFuncResetDevice 0x0000000c // Reset USB device
+#define mFuncResetPipe 0x0000000d // Reset USB pipe
+#define mFuncAbortPipe 0x0000000e // Cancels data requests for USB pipes
+
+//Function code of CH341 parallel port dedicated
+#define mFuncSetParaMode 0x0000000f // Set parallel port mode
+#define mFuncReadData0 0x00000010 // Read block 0 from parallel port
+#define mFuncReadData1 0x00000011 // Read block 1 from parallel port
+#define mFuncWriteData0 0x00000012 // Write data block 0 to parallel port
+#define mFuncWriteData1 0x00000013 // Write data block 1 to parallel port
+#define mFuncWriteRead 0x00000014 // Output before input
+#define mFuncBufferMode 0x00000020 // Set buffered upload mode and query the length of data in the buffer
+#define mFuncBufferModeDn 0x00000021 // Set buffered download mode and query the length of data in the buffer
+#define mFuncGetVersionEx 0x00000022 // Get driver version number and chip model
+
+// USB device standard request code
+#define mUSB_CLR_FEATURE 0x01
+#define mUSB_SET_FEATURE 0x03
+#define mUSB_GET_STATUS 0x00
+#define mUSB_SET_ADDRESS 0x05
+#define mUSB_GET_DESCR 0x06
+#define mUSB_SET_DESCR 0x07
+#define mUSB_GET_CONFIG 0x08
+#define mUSB_SET_CONFIG 0x09
+#define mUSB_GET_INTERF 0x0a
+#define mUSB_SET_INTERF 0x0b
+#define mUSB_SYNC_FRAME 0x0c
+
+// Vendor-specific request type of CH341 control transmission
+#define mCH341_VENDOR_READ 0xC0 // CH341 Vendor-specific read operations which achieved by control transmission
+#define mCH341_VENDOR_WRITE 0x40 // CH341 Vendor-specific write operations which achieved by control transmission
+
+// Vendor-specific request code of CH341 control transmission
+#define mCH341_PARA_INIT 0xB1 // Initialize parallel port
+#define mCH341_I2C_STATUS 0x52 // Get status of the I2C interface
+#define mCH341_I2C_COMMAND 0x53 // Sends I2C interface command
+
+// CH341 Parallel port operation command code
+#define mCH341_PARA_CMD_R0 0xAC // Read data 0 from parallel port, subbyte length
+#define mCH341_PARA_CMD_R1 0xAD // Read data from parallel port 1, subbyte length
+#define mCH341_PARA_CMD_W0 0xA6 // Writes data 0 to parallel port, starting with the next byte as a data stream
+#define mCH341_PARA_CMD_W1 0xA7 // Writes data 1 to parallel port, starting with the next byte as a data stream
+#define mCH341_PARA_CMD_STS 0xA0 // Gets parallel port status
+
+// CH341A Parallel port operation command code
+#define mCH341A_CMD_SET_OUTPUT 0xA1 // Set parallel output
+#define mCH341A_CMD_IO_ADDR 0xA2 // MEM address read&write/ input&output, starting with the next byte as a command stream
+#define mCH341A_CMD_PRINT_OUT 0xA3 // Compatible PRINT print output, starting with the next byte as a code stream
+#define mCH341A_CMD_PWM_OUT 0xA4 // PWM command package for data output, starting with the next byte as a code stream
+#define mCH341A_CMD_SHORT_PKT 0xA5 // Short packet, the next byte is the actual length of the command packet, the next after next byte and the bytes after that are the original command packet
+#define mCH341A_CMD_SPI_STREAM 0xA8 // SPI interface command package, starting with the next byte as data stream
+//#define mCH341A_CMD_SIO_STREAM 0xA9 // SIO interface command package, starting with the next byte as data stream
+#define mCH341A_CMD_I2C_STREAM 0xAA // I2C interface command package ,I2C command stream starting from subbyte
+#define mCH341A_CMD_UIO_STREAM 0xAB // The command packet of the UIO interface, starting from the next byte is the command stream
+#define mCH341A_CMD_PIO_STREAM 0xAE // The command packet of the PIO interface, starting from the second byte is the data stream
+
+// Vendor-specific request code of CH341 control transmission
+#define mCH341A_BUF_CLEAR 0xB2 // Clear unfinished data
+#define mCH341A_I2C_CMD_X 0x54 // Issue the command of the I2C interface and execute it immediately
+#define mCH341A_DELAY_MS 0x5E // Delay the specified time in milliseconds
+#define mCH341A_GET_VER 0x5F // Get the chip version
+
+#define mCH341_EPP_IO_MAX ( mCH341_PACKET_LENGTH - 1 ) // The maximum length of a single read and write data block of CH341 in EPP/MEM mode
+#define mCH341A_EPP_IO_MAX 0xFF // The maximum length of a single read and write data block for CH341A in EPP/MEM mode
+
+#define mCH341A_CMD_IO_ADDR_W 0x00 // MEM command stream with address read/write/input and output: write data, bit 6-bit 0 is the address, and the next byte is the data to be written
+#define mCH341A_CMD_IO_ADDR_R 0x80 // MEM command stream with address read/write/input and output: read data, bit 6-bit 0 is the address, read data and return together
+
+#define mCH341A_CMD_I2C_STM_STA 0x74 // Command flow of I2C interface: generate start bit
+#define mCH341A_CMD_I2C_STM_STO 0x75 // Command flow of I2C interface: generate stop bit
+#define mCH341A_CMD_I2C_STM_OUT 0x80 // Command flow of I2C interface: output data, bit 5-bit 0 is the length, the subsequent bytes are data, and only one byte is sent with a length of 0 and a response is returned
+#define mCH341A_CMD_I2C_STM_IN 0xC0 // Command flow of I2C interface: input data, bit 5-bit 0 is the length, 0 length means only one byte is received and no response is sent
+#define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) // The maximum length of the input and output data of a single command in the command stream of the I2C interface
+#define mCH341A_CMD_I2C_STM_SET 0x60 // Command flow of I2C interface: set parameters, bit 2=SPI I/O number (0=single input and single output, 1=double input and double output), bit 1 bit 0=I2C speed (00=low speed, 01=standard, 10=fast, 11=high speed)
+#define mCH341A_CMD_I2C_STM_US 0x40 // Command flow of I2C interface: delay in microseconds, bit 3-bit 0 is the delay value
+#define mCH341A_CMD_I2C_STM_MS 0x50 // Command flow of I2C interface: delay in milliseconds, bit 3-bit 0 is the delay value
+#define mCH341A_CMD_I2C_STM_DLY 0x0F // The maximum value of the single command delay of the command stream of the I2C interface
+#define mCH341A_CMD_I2C_STM_END 0x00 // Command flow of I2C interface: command packet ends prematurely
+
+#define mCH341A_CMD_UIO_STM_IN 0x00 // Command flow of UIO interface: input data D7-D0
+#define mCH341A_CMD_UIO_STM_DIR 0x40 // Command flow of UIO interface: set I/O direction D5-D0, bit 5-bit 0 is the direction data
+#define mCH341A_CMD_UIO_STM_OUT 0x80 // Command flow of UIO interface: output data D5-D0, bit 5-bit 0 is data
+#define mCH341A_CMD_UIO_STM_US 0xC0 // Command flow of UIO interface: delay in microseconds, bit 5-bit 0 is the delay value
+#define mCH341A_CMD_UIO_STM_END 0x20 // Command flow of UIO interface: command packet ends prematurely
+
+// CH341 parallen port work model
+#define mCH341_PARA_MODE_EPP 0x00 // CH341 parallel port working mode is EPP mode
+#define mCH341_PARA_MODE_EPP17 0x00 // CH341A parallel port working mode is EPP mode V1.7
+#define mCH341_PARA_MODE_EPP19 0x01 // CH341A parallel port working mode is EPP mode V1.9
+#define mCH341_PARA_MODE_MEM 0x02 // CH341 parallel port working mode is MEM mode
+#define mCH341_PARA_MODE_ECP 0x03 // CH341A parallel port working mode is ECP mode
+
+// I/O direction setting bit definition, direct input status signal bit definition, direct output bit data definition
+#define mStateBitERR 0x00000100 // Read-only and writable, ERR# pin input status, 1: high level, 0: low level
+#define mStateBitPEMP 0x00000200 // Read-only and writable, PEMP pin input state, 1: high level, 0: low level
+#define mStateBitINT 0x00000400 // Read-only and writable, INT# pin input status, 1: high level, 0: low level
+#define mStateBitSLCT 0x00000800 // Read-only and writable, SLCT pin input status, 1: high level, 0: low level
+#define mStateBitWAIT 0x00002000 // Read-only and writable, WAIT# pin input status, 1: high level, 0: low level
+#define mStateBitDATAS 0x00004000 // Only write and read, DATAS#/READ# pin input status, 1: high level, 0: low level
+#define mStateBitADDRS 0x00008000 // Write only read, ADDRS#/ADDR/ALE pin input status, 1: high level, 0: low level
+#define mStateBitRESET 0x00010000 // Write only, RESET# pin input status, 1: high level, 0: low level
+#define mStateBitWRITE 0x00020000 // Write only, WRITE# pin input status, 1: high level, 0: low level
+#define mStateBitSCL 0x00400000 // Read only, SCL pin input status, 1: high level, 0: low level
+#define mStateBitSDA 0x00800000 // Read only, SDA pin input status, 1: high level, 0: low level
+
+#define MAX_DEVICE_PATH_SIZE 128 // Maximum number of characters for device name
+#define MAX_DEVICE_ID_SIZE 64 // Maximum number of characters for device ID
+
+typedef VOID ( CALLBACK * mPCH341_INT_ROUTINE ) ( // interrupt service routine
+ ULONG iStatus ); // Interrupt status data, refer to the following bit description
+// Bit 7-bit 0 correspond to D7-D0 pins of CH341
+// Bit 8 corresponds to ERR# pin of CH341, Bit 9 corresponds to PEMP pin of CH341, Bit 10 corresponds to INT# pin of CH341, Bit 11 corresponds to SLCT pin of CH341
+
+
+HANDLE WINAPI CH341OpenDevice( // Open the CH341 device, return the handle, if an error occurs, it will be invalid
+ ULONG iIndex ); // Specify the device serial number of CH341, 0 corresponds to the first device
+
+
+VOID WINAPI CH341CloseDevice( // Close the CH341 device
+ ULONG iIndex ); // Specify the serial number of the CH341 device
+
+
+ULONG WINAPI CH341GetVersion( ); // Get the DLL version number, return the version number
+
+
+ULONG WINAPI CH341DriverCommand( // Directly pass the command to the driver, return 0 if there is an error, otherwise return the data length
+ ULONG iIndex, // Specify the serial number of the CH341 device, the DLL above V1.6 can also be the handle after the device is opened
+ mPWIN32_COMMAND ioCommand ); // pointer to command structure
+// The program returns the data length after the call, and still returns the command structure, if it is a read operation, the data is returned in the command structure,
+// The returned data length is 0 when the operation fails, and the length of the entire command structure when the operation is successful. For example, if one byte is read, mWIN32_COMMAND_HEAD+1 is returned.
+// Before the command structure is called, provide: pipe number or command function code, length of access data (optional), data (optional)
+// After the command structure is called, it returns: the operation status code, the length of the subsequent data (optional),
+// The operation status code is the code defined by WINDOWS, you can refer to NTSTATUS.H,
+// The length of the subsequent data refers to the length of the data returned by the read operation. The data is stored in the subsequent buffer, and is generally 0 for the write operation.
+
+ULONG WINAPI CH341GetDrvVersion( ); // Get the driver version number, return the version number, or return 0 if there is an error
+
+
+BOOL WINAPI CH341ResetDevice( // Reset USB device
+ ULONG iIndex ); // Specify the serial number of the CH341 device
+
+
+BOOL WINAPI CH341GetDeviceDescr( // Read device descriptor
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Points to a buffer large enough to hold the descriptor
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+
+BOOL WINAPI CH341GetConfigDescr( // Read configuration descriptor
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Points to a buffer large enough to hold the descriptor
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+
+BOOL WINAPI CH341SetIntRoutine( // Set interrupt service routine
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ mPCH341_INT_ROUTINE iIntRoutine ); // Specify the interrupt service routine, if it is NULL, the interrupt service will be cancelled, otherwise the routine will be called when interrupted
+
+
+BOOL WINAPI CH341ReadInter( // Read interrupt data
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PULONG iStatus ); // Points to a double word location used to store the read interrupt status data, see below
+// Bit 7-bit 0 correspond to D7-D0 pins of CH341
+// Bit 8 corresponds to err# pin of CH341, bit 9 corresponds to PEMP pin of CH341, bit 10 corresponds to int# pin of CH341, and bit 11 corresponds to SLCT pin of CH341
+
+BOOL WINAPI CH341AbortInter( // Abort interrupt data read operation
+ ULONG iIndex ); // Specify the serial number of the CH341 device
+
+
+BOOL WINAPI CH341SetParaMode( // Set parallel port mode
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ ULONG iMode ); // Specify parallel port mode: 0 is EPP mode/EPP mode V1.7, 1 is EPP mode V1.9, 2 is MEM mode
+
+
+BOOL WINAPI CH341InitParallel( // Reset and initialize the parallel port, RST# outputs a low-level pulse
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ ULONG iMode ); // Specify parallel port mode: 0 is EPP mode/EPP mode V1.7, 1 is EPP mode V1.9, 2 is MEM mode, >= 0x00000100 keep current mode
+
+
+BOOL WINAPI CH341ReadData0( // Read data block from 0# port
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Points to a buffer large enough to hold the read data
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+
+BOOL WINAPI CH341ReadData1( // Read data block from port 1#
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Points to a buffer large enough to hold the read data
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+
+BOOL WINAPI CH341AbortRead( // Abort data block read operation
+ ULONG iIndex ); // Specify the serial number of the CH341 device
+
+
+BOOL WINAPI CH341WriteData0( // Write data block to port 0#
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID iBuffer, // Pointer to a buffer where the data to be written is placed
+ PULONG ioLength ); // Points to the length unit, the length to be written out when input is the length to be written out, and the length actually written out after return
+
+
+BOOL WINAPI CH341WriteData1( // Write data block to port 1#
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID iBuffer, // Pointer to a buffer where the data to be written is placed
+ PULONG ioLength ); // Points to the length unit, the length to be written out when input is the length to be written out, and the length actually written out after return
+
+
+BOOL WINAPI CH341AbortWrite( // Abort block write operation
+ ULONG iIndex ); // Specify the serial number of the CH341 device
+
+
+BOOL WINAPI CH341GetStatus( // Input data and status directly through CH341
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PULONG iStatus ); // Points to a double word unit, used to save status data, refer to the following bit description
+// Bit 7-bit 0 correspond to D7-D0 pins of CH341
+// Bit 8 corresponds to ERR# pin of CH341, Bit 9 corresponds to PEMP pin of CH341, Bit 10 corresponds to INT# pin of CH341, Bit 11 corresponds to SLCT pin of CH341, Bit 23 corresponds to SDA pin of CH341
+// Bit 13 corresponds to BUSY/WAIT# pin of CH341, Bit 14 corresponds to AUTOFD#/DATAS# pin of CH341, Bit 15 corresponds to SLCTIN#/ADDRS# pin of CH341
+
+
+BOOL WINAPI CH341ReadI2C( // Read one byte of data from the I2C interface
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ UCHAR iDevice, // The lower 7 bits specify the I2C device address
+ UCHAR iAddr, // Address of specified data unit
+ PUCHAR oByte ); // Address of specified data unit
+
+
+BOOL WINAPI CH341WriteI2C( // Write a byte of data to the I2C interface
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ UCHAR iDevice, // The lower 7 bits specify the I2C device address
+ UCHAR iAddr, // Address of specified data unit
+ UCHAR iByte ); // Byte data to be written
+
+
+BOOL WINAPI CH341EppReadData( // Byte data to be written
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Points to a buffer large enough to hold the read data
+ PULONG ioLength ); // Points to a buffer large enough to hold the read data
+
+
+BOOL WINAPI CH341EppReadAddr( // Read address in EPP mode: WR#=1, DS#=1, AS#=0, D0-D7=input
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID oBuffer, // Point to a buffer large enough to hold the read address data
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+
+BOOL WINAPI CH341EppWriteData( // Write data in EPP mode: WR#=0, DS#=0, AS#=1, D0-D7=output
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID iBuffer, // Pointer to a buffer where the data to be written is placed
+ PULONG ioLength ); // Points to the length unit, the length to be written out when input is the length to be written out, and the length actually written out after return
+
+
+BOOL WINAPI CH341EppWriteAddr( // Write address in EPP mode: WR#=0, DS#=1, AS#=0, D0-D7=output
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ PVOID iBuffer, // Point to a buffer to place the address data to be written out
+ PULONG ioLength ); // Points to the length unit, the length to be written out when input is the length to be written out, and the length actually written out after return
+
+
+BOOL WINAPI CH341EppSetAddr( // EPP mode setting address: WR#=0, DS#=1, AS#=0, D0-D7=output
+ ULONG iIndex, // Specify the serial number of the CH341 device
+ UCHAR iAddr ); // Specify the EPP address
+
+
+BOOL WINAPI CH341MemReadAddr0( // Read the address in MEM mode 0: WR#=1, DS#/RD#=0, AS#/ADDR=0, D0-D7=input
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID oBuffer, // Points to a buffer large enough to hold the data read from address 0
+ PULONG ioLength ); // Refers to the length unit, input is the length to read, return is the actual length to read
+
+
+BOOL WINAPI CH341MemReadAddr1( // Read the address in MEM mode 1: WR#=1, DS#/RD#=0, AS#/ADDR=1, D0-D7=input
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID oBuffer, // Points to a buffer large enough to hold the data read from address 1
+ PULONG ioLength ); // Refers to the length unit, input is the length to read, return is the actual length to read
+
+
+BOOL WINAPI CH341MemWriteAddr0( // Write the address in MEM mode 0: WR#=0, DS#/RD#=1, AS#/ADDR=0, D0-D7=output
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID iBuffer, // Points to a buffer to place the data to be written to address 0
+ PULONG ioLength ); // Refers to the length unit. The input is the intended length and the return is the actual length
+
+
+BOOL WINAPI CH341MemWriteAddr1( // Write the address in MEM mode 1: WR#=0, DS#/RD#=1, AS#/ADDR=1, D0-D7=output
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID iBuffer, // Points to a buffer to place the data to be written to address 1
+ PULONG ioLength ); // Refers to the length unit. The input is the intended length and the return is the actual length
+
+
+BOOL WINAPI CH341SetExclusive( // Set exclusive use of the current CH341 device
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iExclusive ); // If the value is 0, the device can be shared. If the value is not 0, the device can be exclusively used
+
+BOOL WINAPI CH341SetTimeout( // Set the timeout of USB data read and write
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iWriteTimeout, // Specifies the timeout for USB to write data blocks, in milliseconds mS, 0xFFFFFFFF specifies no timeout (default)
+ ULONG iReadTimeout ); // Specifies the timeout for USB to read data blocks, in milliseconds mS, 0xFFFFFFFF specifies no timeout (default)
+
+
+BOOL WINAPI CH341ReadData( // Read data block
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID oBuffer, // Points to a buffer large enough to hold the read data
+ PULONG ioLength ); // Refers to the length unit, input is the length to read, return is the actual length to read
+
+
+BOOL WINAPI CH341WriteData( // Write out blocks of data
+ ULONG iIndex, // Specify the CH341 device number
+ PVOID iBuffer, // Points to a buffer to place data ready to be written out
+ PULONG ioLength ); // Refers to the length unit. The input is the intended length and the return is the actual length
+
+
+PVOID WINAPI CH341GetDeviceName( // Returns a buffer pointing to the CH341 device name, or NULL on error
+ ULONG iIndex ); // Specify the CH341 device number,0 corresponds to the first device
+
+
+ULONG WINAPI CH341GetVerIC( // 0= device invalid,0x10=CH341,0x20=CH341A
+ ULONG iIndex ); // Specify the CH341 device number
+#define IC_VER_CH341A 0x20
+#define IC_VER_CH341A3 0x30
+
+
+BOOL WINAPI CH341FlushBuffer( // Clear the buffer of CH341
+ ULONG iIndex ); // Specify the CH341 device number
+
+
+BOOL WINAPI CH341WriteRead( // Execute the data flow command, output before input
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iWriteLength, // Write the length, the length you're going to write
+ PVOID iWriteBuffer, // Points to a buffer to place data ready to be written out
+ ULONG iReadStep, // The length of a single block to be read. The total length to be read is(iReadStep*iReadTimes)
+ ULONG iReadTimes, // Number of times you are ready to read
+ PULONG oReadLength, // Points to the length unit and returns the length actually read
+ PVOID oReadBuffer ); // Points to a buffer large enough to hold the read data
+
+
+BOOL WINAPI CH341SetStream( // Set the serial port flow mode
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iMode ); // To specify the mode, see Downlink
+// Bit 1-bit 0: I2C interface speed /SCL frequency, 00= low speed /20KHz,01= standard /100KHz(default),10= fast /400KHz,11= high speed /750KHz
+// Bit 2: SPI I/O number /IO pins, 0= single in/single out (D3 clock /D5 out /D7 in)(default),1= double in/double out (D3 clock /D5 out D4 out /D7 in D6 in)
+// Bit 7: Bit order in SPI bytes, 0= low first, 1= high first
+// All other reservations must be 0
+
+
+BOOL WINAPI CH341SetDelaymS( // Set the hardware asynchronous delay to a specified number of milliseconds before the next stream operation
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iDelay ); // Specifies the number of milliseconds to delay
+
+
+BOOL WINAPI CH341StreamI2C( // Process I2C data stream, 2-wire interface, clock line for SCL pin, data line for SDA pin (quasi-bidirectional I/O), speed of about 56K bytes
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iWriteLength, // Number of bytes of data to write out
+ PVOID iWriteBuffer, // Points to a buffer to place data to be written, usually with the I2C device address and read/write direction bits as the first byte
+ ULONG iReadLength, // Number of bytes of data to be read
+ PVOID oReadBuffer ); // Points to a buffer and returns the data read in
+
+
+typedef enum _EEPROM_TYPE { // EEPROM type
+ ID_24C01,
+ ID_24C02,
+ ID_24C04,
+ ID_24C08,
+ ID_24C16,
+ ID_24C32,
+ ID_24C64,
+ ID_24C128,
+ ID_24C256,
+ ID_24C512,
+ ID_24C1024,
+ ID_24C2048,
+ ID_24C4096
+} EEPROM_TYPE;
+
+
+BOOL WINAPI CH341ReadEEPROM( // Reads data blocks from EEPROM at a speed of about 56 KB
+ ULONG iIndex, // Specify the CH341 device number
+ EEPROM_TYPE iEepromID, // Specifies the EEPROM model
+ ULONG iAddr, // Specifies the address of the data unit
+ ULONG iLength, // Number of bytes of data to be read
+ PUCHAR oBuffer ); // Points to a buffer and returns the data read in
+
+
+BOOL WINAPI CH341WriteEEPROM( // Writes a data block to the EEPROM
+ ULONG iIndex, // Specify the CH341 device number
+ EEPROM_TYPE iEepromID, // Specifies the EEPROM model
+ ULONG iAddr, // Specifies the address of the data unit
+ ULONG iLength, // Number of bytes of data to write out
+ PUCHAR iBuffer ); // Points to a buffer to place data ready to be written out
+
+
+BOOL WINAPI CH341GetInput( // Using the CH341 to directly enter data and status is more efficient than using the CH341GetStatus function
+ ULONG iIndex, // Specify the CH341 device number
+ PULONG iStatus ); // Points to a two-word unit that holds state data, as described in the bit description below
+// Bits 7-0 correspond to the D7-D0 pins of CH341
+// Bit 8 corresponds to the ERR# pin of CH341, bit 9 to the PEMP pin of CH341, bit 10 to the INT# pin of CH341, bit 11 to the SLCT pin of CH341, and bit 23 to the SDA pin of CH341
+// Bit 13 corresponds to the BUSY/WAIT# pin of CH341, bit 14 corresponds to the AUTOFD#/ data # pin of CH341, and bit 15 corresponds to the SLCTIN#/ADDRS# pin of CH341
+
+
+BOOL WINAPI CH341SetOutput( // Set the I/O direction for the CH341 and output data over the CH341
+/* ***** Use this API with care to prevent damage to the chip by changing the I/O direction to change the input pin to the output pin, resulting in short circuits with other output pins ***** */
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iEnable, // Data valid flag, refer to the bit description below
+// If bit 0 is 1, bits 15 to 8 of iSetDataOut are valid. Otherwise, it is ignored
+// If bit 1 is 1, bits 15 to 8 of iSetDirOut are valid. Otherwise, the value is ignored
+// If bit 2 is 1, the 7-bit 0 of iSetDataOut is valid. Otherwise, it is ignored
+// If bit 3 is 1, the iSetDirOut bit 7 to bit 0 is valid. Otherwise, the iSetDirOut bit is ignored
+// If bit 4 is 1, bits 23 to 16 of iSetDataOut are valid. Otherwise, it is ignored
+ ULONG iSetDirOut, // To set the I/O direction, pin 0 corresponds to input and pin 1 corresponds to output. In parallel port mode, the default value is 0x000FC000. Refer to the bit description below
+ ULONG iSetDataOut ); // Output data. If the I/O direction is output, then a clear 0 corresponds to pin output low level, and a position 1 corresponds to pin output high level, refer to the bit description below
+// Bits 7-0 correspond to the D7-D0 pins of CH341
+// Bit 8 corresponds to the ERR# pin of CH341, bit 9 to the PEMP pin of CH341, bit 10 to the INT# pin of CH341, and bit 11 to the SLCT pin of CH341
+// Bit 13 corresponds to the WAIT# pin of CH341, bit 14 to the DATAS#/READ# pin of CH341, and bit 15 to the ADDRS#/ADDR/ALE pin of CH341
+// The following pins can only be output, irrespective of the I/O direction: bit 16 corresponds to set # for CH341, bit 17 corresponds to WRITE# for CH341, bit 18 corresponds to SCL for CH341, and bit 29 corresponds to SDA for CH341
+
+
+BOOL WINAPI CH341Set_D5_D0( // Set the I/O direction of D5-D0 pins of CH341, and directly output data through THE D5-D0 pins of CH341. The efficiency is higher than that of CH341SetOutput
+/* ***** Use this API with care to prevent damage to the chip by changing the I/O direction to change the input pin to the output pin, resulting in short circuits with other output pins ***** */
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iSetDirOut, // Set the I/O direction of each pin d5-D0. Pin 0 corresponds to input, pin 1 corresponds to output. In parallel port mode, the default value is 0x00 for all input
+ ULONG iSetDataOut ); // Set the output data of each pin of D5-D0. If the I/O direction is output, then a clear 0 corresponds to pin output low level, and a position 1 corresponds to pin output high level
+// Bits 5-0 of the above data correspond to the D5-D0 pins of CH341 respectively
+
+
+BOOL WINAPI CH341StreamSPI3( // This API is invalid. Do not use it
+ ULONG iIndex,
+ ULONG iChipSelect,
+ ULONG iLength,
+ PVOID ioBuffer );
+
+
+BOOL WINAPI CH341StreamSPI4( // SPI data stream processing, 4-line interface, clock line is DCK/D3 pin, output data line is DOUT/D5 pin, input data line is DIN/D7 pin, chip line is D0/D1/D2, speed is about 68K bytes
+/* SPI timing: DCK/D3 pin is clock output, default low level, DOUT/D5 pin is output during low level before clock rising edge, DIN/D7 pin is input during high level before clock falling edge */
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iChipSelect, // Chip selection control. If bit 7 is 0, chip selection control is ignored. If bit 7 is 1, the parameter is effective: if bit 1 is 00/01/10, D0/D1/D2 pins are selected as low level effective chip selection respectively
+ ULONG iLength, // Number of bytes of data to be transferred
+ PVOID ioBuffer ); // Points to a buffer, places data to be written out from DOUT, and returns data to be read in from DIN
+
+
+BOOL WINAPI CH341StreamSPI5( // SPI data stream processing, 5-line interface, clock line is DCK/D3 pin, output data line is DOUT/D5 and DOUT2/D4 pin, input data line is DIN/D7 and DIN2/D6 pin, chip line is D0/D1/D2, speed is about 30K bytes *2
+/* SPI timing: DCK/D3 pins are clock outputs and are low by default, DOUT/D5 and DOUT2/D4 pins are output during the low period before the rising edge of the clock, and DIN/D7 and DIN2/D6 pins are input during the high period before the falling edge of the clock */
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iChipSelect, // Chip selection control. If bit 7 is 0, chip selection control is ignored. If bit 7 is 1, the parameter is effective: if bit 1 is 00/01/10, D0/D1/D2 pins are selected as low level effective chip selection respectively
+ ULONG iLength, // Number of bytes of data to be transferred
+ PVOID ioBuffer, // Points to a buffer, places data to be written out from DOUT, and returns data to be read in from DIN
+ PVOID ioBuffer2 ); // Point to the second buffer, place the data to be written from DOUT2, and return the data to be read from DIN2
+
+
+BOOL WINAPI CH341BitStreamSPI( // SPI bit data flow processing,4 line /5 line interface, clock line for DCK/D3 pin, output data line for DOUT/DOUT2 pin, input data line for DIN/DIN2 pin, chip line for D0/D1/D2, speed about 8K bit *2
+ ULONG iIndex, // Specify the CH341 device number
+ ULONG iLength, // The number of bits to be transmitted at a time is a maximum of 896. It is recommended that the number not exceed 256
+ PVOID ioBuffer ); // Point to a buffer, place data to be written from DOUT/DOUT2/ d2-d0, and return data to be read from DIN/DIN2
+/* SPI timing: DCK/D3 pins are clock outputs and are low by default, DOUT/D5 and DOUT2/D4 pins are output during the low period before the rising edge of the clock, and DIN/D7 and DIN2/D6 pins are input during the high period before the falling edge of the clock*/
+/* One byte of the ioBuffer has 8 bits corresponding to d7-D0 pins. Bit 5 is output to DOUT, bit 4 to DOUT2, bit 2-0 to D2-d0, bit 7 is input from DIN, bit 6 is input from DIN2, bit 3 is ignored */
+/* Before calling this API, CH341Set_D5_D0 should be called to set the I/O direction of the D5-D0 pins of CH341 and set the default level of the pins */
+
+
+BOOL WINAPI CH341SetBufUpload( // Set internal buffered upload mode
+ ULONG iIndex, // Specify the CH341 device number,0 corresponds to the first device
+ ULONG iEnableOrClear ); // If the value is 0, the internal buffered upload mode is disabled and direct upload is used. If the value is not 0, the internal buffered upload mode is enabled and the existing data in the buffer is cleared
+// If internal buffered-upload mode is enabled, the CH341 driver creation thread automatically receives USB upload data to the internal buffer and clears the existing data in the buffer. The existing data in the buffer will be returned immediately when the application calls CH341ReadData
+
+
+LONG WINAPI CH341QueryBufUpload( // Query the number of existing data packets in the internal upload buffer. The number of data packets is returned successfully, or -1 is returned if an error occurs
+ ULONG iIndex ); // Specify the CH341 device number,0 corresponds to the first device
+
+
+BOOL WINAPI CH341SetBufDownload( // Set the internal buffer down mode
+ ULONG iIndex, // Specify the CH341 device number,0 corresponds to the first device
+ ULONG iEnableOrClear ); // If the value is 0, the internal buffered downtransmission mode is disabled and direct downtransmission is used. If the value is not 0, the internal buffered downtransmission mode is enabled and the existing data in the buffer is cleared
+// If internal buffer-down mode is enabled, when an application calls CH341WriteData, it simply puts USB downpass data into an internal buffer and returns it immediately, while threads created by the CH341 driver automatically send it to completion
+
+
+LONG WINAPI CH341QueryBufDownload( // Query the number of remaining packets in the internal downtransmission buffer (that have not been sent). The number of successful packets is returned, and -1 is returned if an error occurs
+ ULONG iIndex ); // Specify the CH341 device number,0 corresponds to the first device
+
+
+BOOL WINAPI CH341ResetInter( // Reset an interrupted data read operation
+ ULONG iIndex ); // Specify the CH341 device number
+
+
+BOOL WINAPI CH341ResetRead( // Reset the data block read operation
+ ULONG iIndex ); // Specify the CH341 device number
+
+
+BOOL WINAPI CH341ResetWrite( // Reset a block write operation
+ ULONG iIndex ); // Specify the CH341 device number
+
+
+typedef VOID ( CALLBACK * mPCH341_NOTIFY_ROUTINE ) ( // Device event notification callback program
+ ULONG iEventStatus ); // Device event and current status (defined downstream): 0= device removal event, 3= device insertion event
+
+#define CH341_DEVICE_ARRIVAL 3 // Device insertion event, already inserted
+#define CH341_DEVICE_REMOVE_PEND 1 // Device to be pulled out
+#define CH341_DEVICE_REMOVE 0 // The device is removed
+
+
+BOOL WINAPI CH341SetDeviceNotify( // Set up the device event notification procedure
+ ULONG iIndex, // Specify the CH341 device number,0 corresponds to the first device
+ PCHAR iDeviceID, // Optional argument pointing to a string specifying the ID of the device to be monitored, terminated with \0
+ mPCH341_NOTIFY_ROUTINE iNotifyRoutine ); // Specifies a device event callback that cancels event notification if NULL, or is called when an event is detected
+
+
+BOOL WINAPI CH341SetupSerial( // Set the serial port feature of the CH341. This API can only be used for CH341 chips that work in serial port mode
+ ULONG iIndex, // Specify the CH341 device number,0 corresponds to the first device
+ ULONG iParityMode, // Specifies the data verification mode of the CH341 serial port: NOPARITY/ODDPARITY/EVENPARITY/MARKPARITY/SPACEPARITY
+ ULONG iBaudRate ); // Set the baud rate of the CH341 serial port. The value ranges from 50 to 3000000
+
+/* The following apis can be used for CH341 chips that work in serial port mode. Other apis can only be used for CH341 chips that work in parallel port mode
+ CH341OpenDevice
+ CH341CloseDevice
+ CH341SetupSerial
+ CH341ReadData
+ CH341WriteData
+ CH341SetBufUpload
+ CH341QueryBufUpload
+ CH341SetBufDownload
+ CH341QueryBufDownload
+ CH341SetDeviceNotify
+ CH341GetStatus
+// The above API is the primary API and the following API is the secondary API
+ CH341GetVersion
+ CH341DriverCommand
+ CH341GetDrvVersion
+ CH341ResetDevice
+ CH341GetDeviceDescr
+ CH341GetConfigDescr
+ CH341SetIntRoutine
+ CH341ReadInter
+ CH341AbortInter
+ CH341AbortRead
+ CH341AbortWrite
+ CH341ReadI2C
+ CH341WriteI2C
+ CH341SetExclusive
+ CH341SetTimeout
+ CH341GetDeviceName
+ CH341GetVerIC
+ CH341FlushBuffer
+ CH341WriteRead
+ CH341ResetInter
+ CH341ResetRead
+ CH341ResetWrite
+*/
+HANDLE WINAPI CH341OpenDeviceEx( // Turn on the CH341 device and return the handle
+ ULONG iIndex ); // Specify the CH341 device number,0 corresponds to the first device to be inserted, and 1 corresponds to the second device to be inserted. To save device serial number resources, shut down the device after it is used up
+
+
+VOID WINAPI CH341CloseDeviceEx( // Close the CH341
+ ULONG iIndex ); // Specify the CH341 device number
+
+
+PCHAR WINAPI CH341GetDeviceNameEx( // Returns a buffer pointing to the CH341 device name, or NULL on error
+ ULONG iIndex ); // Specify the CH341 device number,0 corresponds to the first device
+
+
+BOOL WINAPI CH341SetDeviceNotifyEx( // Set up the device event notification procedure
+ ULONG iIndex, // Specify the CH341 device number,0 corresponds to the first device
+ PCHAR iDeviceID, // Optional argument pointing to a string specifying the ID of the device to be monitored, terminated with \0
+ mPCH341_NOTIFY_ROUTINE iNotifyRoutine ); // Specifies a device event callback that cancels event notification if NULL, or is called when an event is detected
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CH341_DLL_H
diff --git a/Drivers/LIB/CH341/amd64/CH341DLLA64.LIB b/Drivers/LIB/CH341/amd64/CH341DLLA64.LIB
new file mode 100644
index 0000000..c62ba77
Binary files /dev/null and b/Drivers/LIB/CH341/amd64/CH341DLLA64.LIB differ
diff --git a/Drivers/LIB/CH341/arm64/CH341DLLA64.LIB b/Drivers/LIB/CH341/arm64/CH341DLLA64.LIB
new file mode 100644
index 0000000..c62ba77
Binary files /dev/null and b/Drivers/LIB/CH341/arm64/CH341DLLA64.LIB differ
diff --git a/Drivers/LIB/CH341/i386/CH341DLL.LIB b/Drivers/LIB/CH341/i386/CH341DLL.LIB
new file mode 100644
index 0000000..682b960
Binary files /dev/null and b/Drivers/LIB/CH341/i386/CH341DLL.LIB differ
diff --git a/Drivers/LIB/CH347/CH347DLL.H b/Drivers/LIB/CH347/CH347DLL.H
new file mode 100644
index 0000000..06a7c25
--- /dev/null
+++ b/Drivers/LIB/CH347/CH347DLL.H
@@ -0,0 +1,504 @@
+/*****************************************************************************
+** Copyright (C) WCH 2001-2022 **
+** Web: http://wch.cn **
+******************************************************************************
+Abstract:
+ USB2.0转接芯片CH347,基于480Mbps高速USB总线扩展UART、SPI、I2C、JTAG
+Environment:
+user mode only,VC6.0 and later
+Notes:
+Copyright (c) 2022 Nanjing Qinheng Microelectronics Co., Ltd.
+--*/
+
+#ifndef _CH347_DLL_H
+#define _CH347_DLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN64
+#define mOFFSET( s, m ) ( (ULONG_PTR) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
+#else
+#define mOFFSET( s, m ) ( (ULONG) & ( ( ( s * ) 0 ) -> m ) ) // 定义获取结构成员相对偏移地址的宏
+#endif
+
+#ifndef max
+#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) // 较大值
+#endif
+
+#ifndef min
+#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) // 较小值
+#endif
+
+#ifdef ExAllocatePool
+#undef ExAllocatePool // 删除带TAG的内存分配
+#endif
+
+#ifndef NTSTATUS
+typedef LONG NTSTATUS; // 返回状态
+#endif
+
+//与CH31DLL合用CH341WDM驱动
+#ifndef _CH341_DLL_H
+typedef struct _USB_SETUP_PKT { // USB控制传输的建立阶段的数据请求包结构
+ UCHAR mUspReqType; // 00H 请求类型
+ UCHAR mUspRequest; // 01H 请求代码
+ union {
+ struct {
+ UCHAR mUspValueLow; // 02H 值参数低字节
+ UCHAR mUspValueHigh; // 03H 值参数高字节
+ };
+ USHORT mUspValue; // 02H-03H 值参数
+ };
+ union {
+ struct {
+ UCHAR mUspIndexLow; // 04H 索引参数低字节
+ UCHAR mUspIndexHigh; // 05H 索引参数高字节
+ };
+ USHORT mUspIndex; // 04H-05H 索引参数
+ };
+ USHORT mLength; // 06H-07H 数据阶段的数据长度
+} mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;
+
+
+typedef struct _WIN32_COMMAND { // 定义WIN32命令接口结构
+ union {
+ ULONG mFunction; // 输入时指定功能代码或者管道号
+ NTSTATUS mStatus; // 输出时返回操作状态
+ };
+ ULONG mLength; // 存取长度,返回后续数据的长度
+ union {
+ mUSB_SETUP_PKT mSetupPkt; // USB控制传输的建立阶段的数据请求
+ UCHAR mBuffer[ 512]; // 数据缓冲区,长度为0至255B
+ };
+} mWIN32_COMMAND, *mPWIN32_COMMAND;
+// WIN32应用层接口命令
+#define IOCTL_CH341_COMMAND ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // 专用接口
+
+#define mWIN32_COMMAND_HEAD mOFFSET( mWIN32_COMMAND, mBuffer ) // WIN32命令接口的头长度
+
+#define mCH341_MAX_NUMBER 16 // 最多同时连接的CH341数
+
+#define mMAX_BUFFER_LENGTH 0x1000 // 数据缓冲区最大长度4096
+
+#define mMAX_COMMAND_LENGTH ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ) // 最大数据长度加上命令结构头的长度
+
+#define mDEFAULT_BUFFER_LEN 0x0400 // 数据缓冲区默认长度1024
+
+#define mDEFAULT_COMMAND_LEN ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ) // 默认数据长度加上命令结构头的长度
+
+// CH341端点地址
+#define mCH347_ENDP_DATA_UP 0x86 // CH347的数据块上传端点的地址
+#define mCH347_ENDP_DATA_DOWN 0x06 // CH347的数据块下传端点的地址
+
+// 设备层接口提供的管道操作命令
+#define mPipeDeviceCtrl 0x00000004 // CH347的综合控制管道
+#define mPipeDataUp 0x00000006 // CH347的数据块上传管道
+#define mPipeDataDown 0x00000007 // CH347的数据块下传管道
+
+// 应用层接口的功能代码
+#define mFuncNoOperation 0x00000000 // 无操作
+#define mFuncGetVersion 0x00000001 // 获取驱动程序版本号
+#define mFuncGetConfig 0x00000002 // 获取USB设备配置描述符
+#define mFuncSetTimeout 0x00000009 // 设置USB通讯超时
+#define mFuncSetExclusive 0x0000000b // 设置独占使用
+#define mFuncResetDevice 0x0000000c // 复位USB设备
+#define mFuncResetPipe 0x0000000d // 复位USB管道
+#define mFuncAbortPipe 0x0000000e // 取消USB管道的数据请求
+#define mFuncBufferMode 0x00000020 // 设定缓冲上传模式及查询缓冲区中的数据长度
+#define mFuncBufferModeDn 0x00000021 // 设定缓冲下传模式及查询缓冲区中的数据长度
+#define mFuncGetVersionEx 0x00000022 // 获取驱动程序版本号及芯片型号
+// USB设备标准请求代码
+#define mUSB_CLR_FEATURE 0x01
+#define mUSB_SET_FEATURE 0x03
+#define mUSB_GET_STATUS 0x00
+#define mUSB_SET_ADDRESS 0x05
+#define mUSB_GET_DESCR 0x06
+#define mUSB_SET_DESCR 0x07
+#define mUSB_GET_CONFIG 0x08
+#define mUSB_SET_CONFIG 0x09
+#define mUSB_GET_INTERF 0x0a
+#define mUSB_SET_INTERF 0x0b
+#define mUSB_SYNC_FRAME 0x0c
+
+// CH341控制传输的厂商专用请求类型
+#define mCH341_VENDOR_READ 0xC0 // 通过控制传输实现的CH341厂商专用读操作
+#define mCH341_VENDOR_WRITE 0x40 // 通过控制传输实现的CH341厂商专用写操作
+
+#define mCH341A_CMD_I2C_STREAM 0xAA // I2C接口的命令包,从次字节开始为I2C命令流
+#define mCH341A_CMD_UIO_STREAM 0xAB // UIO接口的命令包,从次字节开始为命令流
+#define mCH341A_CMD_PIO_STREAM 0xAE // PIO接口的命令包,从次字节开始为数据流
+// CH341A控制传输的厂商专用请求代码
+#define mCH341A_BUF_CLEAR 0xB2 // 清除未完成的数据
+#define mCH341A_I2C_CMD_X 0x54 // 发出I2C接口的命令,立即执行
+#define mCH341A_DELAY_MS 0x5E // 以亳秒为单位延时指定时间
+#define mCH341A_GET_VER 0x5F // 获取芯片版本
+
+#define mCH341A_CMD_I2C_STM_STA 0x74 // I2C接口的命令流:产生起始位
+#define mCH341A_CMD_I2C_STM_STO 0x75 // I2C接口的命令流:产生停止位
+#define mCH341A_CMD_I2C_STM_OUT 0x80 // I2C接口的命令流:输出数据,位5-位0为长度,后续字节为数据,0长度则只发送一个字节并返回应答
+#define mCH341A_CMD_I2C_STM_IN 0xC0 // I2C接口的命令流:输入数据,位5-位0为长度,0长度则只接收一个字节并发送无应答
+#define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) // I2C接口的命令流单个命令输入输出数据的最大长度
+#define mCH341A_CMD_I2C_STM_SET 0x60 // I2C接口的命令流:设置参数,位2=SPI的I/O数(0=单入单出,1=双入双出),位1位0=I2C速度(00=低速,01=标准,10=快速,11=高速)
+#define mCH341A_CMD_I2C_STM_US 0x40 // I2C接口的命令流:以微秒为单位延时,位3-位0为延时值
+#define mCH341A_CMD_I2C_STM_MS 0x50 // I2C接口的命令流:以亳秒为单位延时,位3-位0为延时值
+#define mCH341A_CMD_I2C_STM_DLY 0x0F // I2C接口的命令流单个命令延时的最大值
+#define mCH341A_CMD_I2C_STM_END 0x00 // I2C接口的命令流:命令包提前结束
+
+#define mCH341A_CMD_UIO_STM_IN 0x00 // UIO接口的命令流:输入数据D7-D0
+#define mCH341A_CMD_UIO_STM_DIR 0x40 // UIO接口的命令流:设定I/O方向D5-D0,位5-位0为方向数据
+#define mCH341A_CMD_UIO_STM_OUT 0x80 // UIO接口的命令流:输出数据D5-D0,位5-位0为数据
+#define mCH341A_CMD_UIO_STM_US 0xC0 // UIO接口的命令流:以微秒为单位延时,位5-位0为延时值
+#define mCH341A_CMD_UIO_STM_END 0x20 // UIO接口的命令流:命令包提前结束
+
+#define MAX_DEVICE_PATH_SIZE 128 // 设备名称的最大字符数
+#define MAX_DEVICE_ID_SIZE 64 // 设备ID的最大字符数
+#endif _CH341_DLL_H
+
+//驱动接口
+#define CH347_USB_VENDOR 0
+#define CH347_USB_HID 2
+#define CH347_USB_VCP 3
+
+//CH347_USB_VENDOR支持CH341/7
+#define CHIP_TYPE_CH341 0
+#define CHIP_TYPE_CH347 1
+
+//芯片功能接口号
+#define CH347_FUNC_UART 0
+#define CH347_FUNC_SPI_IIC 1
+#define CH347_FUNC_JTAG_IIC 2
+
+#define DEFAULT_READ_TIMEOUT 500 //默认读超时毫秒数
+#define DEFAULT_WRITE_TIMEOUT 500 //默认写超时毫秒数
+
+#define mCH347_PACKET_LENGTH 512 // CH347支持的数据包的长度
+
+#pragma pack(1)
+//SPI控制器配置
+typedef struct _SPI_CONFIG{
+ UCHAR iMode; // 0-3:SPI Mode0/1/2/3
+ UCHAR iClock; // 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz, 4=3.75MHz, 5=1.875MHz, 6=937.5KHz,7=468.75KHz
+ UCHAR iByteOrder; // 0=低位在前(LSB), 1=高位在前(MSB)
+ USHORT iSpiWriteReadInterval; // SPI接口常规读取写入数据命令,单位为uS
+ UCHAR iSpiOutDefaultData; // SPI读数据时默认输出数据
+ ULONG iChipSelect; // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效: 位1位0为00/01分别选择CS1/CS2引脚作为低电平有效片选
+ UCHAR CS1Polarity; // 位0:片选CS1极性控制:0:低电平有效;1:高电平有效;
+ UCHAR CS2Polarity; // 位0:片选CS2极性控制:0:低电平有效;1:高电平有效;
+ USHORT iIsAutoDeativeCS; // 操作完成后是否自动撤消片选
+ USHORT iActiveDelay; // 设置片选后执行读写操作的延时时间,单位us
+ ULONG iDelayDeactive; // 撤消片选后执行读写操作的延时时间,单位us
+}mSpiCfgS,*mPSpiCfgS;
+
+//设备信息
+typedef struct _DEV_INFOR{
+ UCHAR iIndex; // 当前打开序号
+ UCHAR DevicePath[MAX_PATH]; // 设备链接名,用于CreateFile
+ UCHAR UsbClass; // 0:CH347_USB_CH341, 2:CH347_USB_HID,3:CH347_USB_VCP
+ UCHAR FuncType; // 0:CH347_FUNC_UART,1:CH347_FUNC_SPI_I2C,2:CH347_FUNC_JTAG_I2C
+ CHAR DeviceID[64]; // USB\VID_xxxx&PID_xxxx
+ UCHAR ChipMode; // 芯片模式,0:Mode0(UART0/1); 1:Mode1(Uart1+SPI+I2C); 2:Mode2(HID Uart1+SPI+I2C) 3:Mode3(Uart1+Jtag+IIC)
+ HANDLE DevHandle; // 设备句柄
+ USHORT BulkOutEndpMaxSize; // 上传端点大小
+ USHORT BulkInEndpMaxSize; // 下传端点大小
+ UCHAR UsbSpeedType; // USB速度类型,0:FS,1:HS,2:SS
+ UCHAR CH347IfNum; // 设备接口号: 0:UART,1:SPI/IIC/JTAG/GPIO
+ UCHAR DataUpEndp; // 端点地址
+ UCHAR DataDnEndp; // 端点地址
+ CHAR ProductString[64]; // USB产品字符串
+ CHAR ManufacturerString[64]; // USB厂商字符串
+ ULONG WriteTimeout; // USB写超时
+ ULONG ReadTimeout; // USB读超时
+ CHAR FuncDescStr[64]; // 接口功能描述符
+ UCHAR FirewareVer; // 固件版本
+}mDeviceInforS,*mPDeviceInforS;
+#pragma pack()
+
+// CH347模式公用函数,支持CH347所有模式下的打开、关闭、USB读、USB写,包含HID
+//打开USB设备
+HANDLE WINAPI CH347OpenDevice(ULONG DevI);
+
+//关闭USB设备
+BOOL WINAPI CH347CloseDevice(ULONG iIndex);
+
+//获取设备信息
+BOOL WINAPI CH347GetDeviceInfor(ULONG iIndex,mDeviceInforS *DevInformation);
+
+// 获得驱动版本、库版本、设备版本、芯片类型(CH341(FS)/CH347HS)
+BOOL WINAPI CH347GetVersion(ULONG iIndex,
+ PUCHAR iDriverVer,
+ PUCHAR iDLLVer,
+ PUCHAR ibcdDevice,
+ PUCHAR iChipType); //CHIP_TYPE_CH341/7
+
+typedef VOID ( CALLBACK * mPCH347_NOTIFY_ROUTINE ) ( // 设备事件通知回调程序
+ ULONG iEventStatus ); // 设备事件和当前状态(在下行定义): 0=设备拔出事件, 3=设备插入事件
+
+#define CH347_DEVICE_ARRIVAL 3 // 设备插入事件,已经插入
+#define CH347_DEVICE_REMOVE_PEND 1 // 设备将要拔出
+#define CH347_DEVICE_REMOVE 0 // 设备拔出事件,已经拔出
+
+BOOL WINAPI CH347SetDeviceNotify( // 设定设备事件通知程序
+ ULONG iIndex, // 指定设备序号,0对应第一个设备
+ PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
+ mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
+
+// 读取USB数据块
+BOOL WINAPI CH347ReadData( ULONG iIndex, // 指定设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+// 写取USB数据块
+BOOL WINAPI CH347WriteData(ULONG iIndex, // 指定设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength ); // 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+// 设置USB数据读写的超时
+BOOL WINAPI CH347SetTimeout(ULONG iIndex, // 指定设备序号
+ ULONG iWriteTimeout, // 指定USB写出数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+ ULONG iReadTimeout ); // 指定USB读取数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+
+/***************SPI********************/
+// SPI控制器初始化
+BOOL WINAPI CH347SPI_Init(ULONG iIndex,mSpiCfgS *SpiCfg);
+
+//获取SPI控制器配置信息
+BOOL WINAPI CH347SPI_GetCfg(ULONG iIndex,mSpiCfgS *SpiCfg);
+
+//设置片选状态,使用前需先调用CH347SPI_Init对CS进行设置
+BOOL WINAPI CH347SPI_ChangeCS(ULONG iIndex, // 指定设备序号
+ UCHAR iStatus); // 0=撤消片选,1=设置片选
+
+//设置SPI片选
+BOOL WINAPI CH347SPI_SetChipSelect(ULONG iIndex, // 指定设备序号
+ USHORT iEnableSelect, // 低八位为CS1,高八位为CS2; 字节值为1=设置CS,为0=忽略此CS设置
+ USHORT iChipSelect, // 低八位为CS1,高八位为CS2;片选输出,0=撤消片选,1=设置片选
+ ULONG iIsAutoDeativeCS, // 低16位为CS1,高16位为CS2;操作完成后是否自动撤消片选
+ ULONG iActiveDelay, // 低16位为CS1,高16位为CS2;设置片选后执行读写操作的延时时间,单位us
+ ULONG iDelayDeactive); // 低16位为CS1,高16位为CS2;撤消片选后执行读写操作的延时时间,单位us
+
+//SPI4写数据
+BOOL WINAPI CH347SPI_Write(ULONG iIndex, // 指定设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1进行片选操作
+ ULONG iLength, // 准备传输的数据字节数
+ ULONG iWriteStep, // 准备读取的单个块的长度
+ PVOID ioBuffer); // 指向一个缓冲区,放置准备从MOSI写出的数据
+
+//SPI4读数据.无需先写数据,效率较CH347SPI_WriteRead高很多
+BOOL WINAPI CH347SPI_Read(ULONG iIndex, // 指定设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1进行片选操作
+ ULONG oLength, // 准备发出的字节数
+ PULONG iLength, // 准备读入的数据字节数
+ PVOID ioBuffer); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
+
+// 处理SPI数据流,4线接口
+BOOL WINAPI CH347SPI_WriteRead(ULONG iIndex, // 指定设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则操作片选
+ ULONG iLength, // 准备传输的数据字节数
+ PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
+
+// 处理SPI数据流,4线接口
+BOOL WINAPI CH347StreamSPI4(ULONG iIndex, // 指定设备序号
+ ULONG iChipSelect, // 片选控制, 位7为0则忽略片选控制, 位7为1则参数有效
+ ULONG iLength, // 准备传输的数据字节数
+ PVOID ioBuffer ); // 指向一个缓冲区,放置准备从DOUT写出的数据,返回后是从DIN读入的数据
+
+/***************JTAG********************/
+//JTAG接口初始化,设置模式及速度
+BOOL WINAPI CH347Jtag_INIT(ULONG iIndex,
+ UCHAR iClockRate); //通信速度;有效值为0-5,值越大通信速度越快
+
+//获取Jtag速度设置
+BOOL WINAPI CH347Jtag_GetCfg(ULONG iIndex, // 指定设备序号
+ UCHAR *ClockRate); //通信速度;有效值为0-5,值越大通信速度越快
+
+//位带方式JTAG IR/DR数据读写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用CH347Jtag_WriteRead_Fast
+//命令包以4096字节为单位批量读写
+//状态机:Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
+BOOL WINAPI CH347Jtag_WriteRead(ULONG iIndex, // 指定设备序号
+ BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
+ ULONG iWriteBitLength, // 写长度,准备写出的长度
+ PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
+ PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//JTAG IR/DR数据批量读写,用于多字节连续读写。如JTAG固件下载操作。因硬件有4K缓冲区,如先写后读,长度不超过4096字节。缓冲区大小可自行调整
+//状态机:Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
+BOOL WINAPI CH347Jtag_WriteRead_Fast(ULONG iIndex, // 指定设备序号
+ BOOL IsDR, // =TRUE: DR数据读写,=FALSE:IR数据读写
+ ULONG iWriteBitLength, // 写长度,准备写出的长度
+ PVOID iWriteBitBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的长度
+ PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//切换JTAG状态机
+BOOL WINAPI CH347Jtag_SwitchTapState(UCHAR TapState);
+
+//JTAG DR写,以字节为单位,用于多字节连续读写。如JTAG固件下载操作。
+//状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteWriteDR(ULONG iIndex, // 指定设备序号
+ ULONG iWriteLength, // 写长度,准备写出的字节长度
+ PVOID iWriteBuffer); // 指向一个缓冲区,放置准备写出的数据
+
+//JTAG DR读,以字节为单位,多字节连续读。
+//状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteReadDR(ULONG iIndex, // 指定设备序号
+ PULONG oReadLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID oReadBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//JTAG IR写,以字节为单位,多字节连续写。
+//状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteWriteIR(ULONG iIndex, // 指定设备序号
+ ULONG iWriteLength, // 写长度,准备写出的字节长度
+ PVOID iWriteBuffer); // 指向一个缓冲区,放置准备写出的数据
+
+//JTAG IR读,以字节为单位,多字节连续读写。
+//状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteReadIR(ULONG iIndex, // 指定设备序号
+ PULONG oReadLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID oReadBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//位带方式JTAG DR数据写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用USB20Jtag_ByeWriteDR
+//状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_BitWriteDR(ULONG iIndex, // 指定设备序号
+ ULONG iWriteBitLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID iWriteBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//位带方式JTAG IR数据写.适用于少量数据的读写。如指令操作、状态机切换等控制类传输。如批量数据传输,建议使用USB20Jtag_ByteWriteIR
+//状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_BitWriteIR(ULONG iIndex, // 指定设备序号
+ ULONG iWriteBitLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID iWriteBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//位带方式JTAG IR数据读.适用于少量数据的读写。如指令操作、状态机切换等。如批量数据传输,建议使用USB20Jtag_ByteReadIR
+//状态机:Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_BitReadIR(ULONG iIndex, // 指定设备序号
+ PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//位带方式JTAG DR数据读.适用于少量数据的读写。如批量和高速数据传输,建议使用USB20Jtag_ByteReadDR
+//状态机:Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_BitReadDR(ULONG iIndex, // 指定设备序号
+ PULONG oReadBitLength, // 指向长度单元,返回后为实际读取的字节长度
+ PVOID oReadBitBuffer ); // 指向一个足够大的缓冲区,用于保存读取的数据
+
+//获取CH347的GPIO方向和引脚电平值
+BOOL WINAPI CH347GPIO_Get(ULONG iIndex,
+ UCHAR *iDir, //引脚方向:GPIO0-7对应位0-7.0:输入;1:输出
+ UCHAR *iData); //GPIO0电平:GPIO0-7对应位0-7,0:低电平;1:高电平)
+
+//设置CH347的GPIO方向和引脚电平值
+BOOL WINAPI CH347GPIO_Set(ULONG iIndex,
+ UCHAR iEnable, //数据有效标志:对应位0-7,对应GPIO0-7.
+ UCHAR iSetDirOut, //设置I/O方向,某位清0则对应引脚为输入,某位置1则对应引脚为输出.GPIO0-7对应位0-7.
+ UCHAR iSetDataOut); //输出数据,如果I/O方向为输出,那么某位清0时对应引脚输出低电平,某位置1时对应引脚输出高电平
+
+//进入IAP固件升级模式
+BOOL WINAPI CH347StartIapFwUpate(ULONG iIndex,
+ ULONG FwSize); // 固件长度
+
+/**************HID/VCP串口**********************/
+//打开串口
+HANDLE WINAPI CH347Uart_Open(ULONG iIndex);
+
+//关闭串口
+BOOL WINAPI CH347Uart_Close(ULONG iIndex);
+
+BOOL WINAPI CH347Uart_SetDeviceNotify( // 设定设备事件通知程序
+ ULONG iIndex, // 指定设备序号,0对应第一个设备
+ PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
+ mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
+
+//获取UART硬件配置
+BOOL WINAPI CH347Uart_GetCfg(ULONG iIndex, // 指定设备序号
+ PULONG BaudRate, // 波特率
+ PUCHAR ByteSize, // 数据位数(5,6,7,8,16)
+ PUCHAR Parity, // 校验位(0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
+ PUCHAR StopBits, // 停止位数(0:1停止位; 1:1.5停止位; 2:2停止位);
+ PUCHAR ByteTimeout); //字节超时
+
+//设置UART配置
+BOOL WINAPI CH347Uart_Init(ULONG iIndex, // 指定设备序号
+ DWORD BaudRate, // 波特率
+ UCHAR ByteSize, // 数据位数(5,6,7,8,16)
+ UCHAR Parity, // 校验位(0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
+ UCHAR StopBits, // 停止位数(0:1停止位; 1:1.5停止位; 2:2停止位);
+ UCHAR ByteTimeout);// 字节超时时间,单位100uS
+
+// 设置USB数据读写的超时
+BOOL WINAPI CH347Uart_SetTimeout(ULONG iIndex, // 指定设备序号
+ ULONG iWriteTimeout, // 指定USB写出数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+ ULONG iReadTimeout ); // 指定USB读取数据块的超时时间,以毫秒mS为单位,0xFFFFFFFF指定不超时(默认值)
+
+// 读取数据块
+BOOL WINAPI CH347Uart_Read(ULONG iIndex, // 指定设备序号
+ PVOID oBuffer, // 指向一个足够大的缓冲区,用于保存读取的数据
+ PULONG ioLength );// 指向长度单元,输入时为准备读取的长度,返回后为实际读取的长度
+
+// 写出数据块
+BOOL WINAPI CH347Uart_Write(ULONG iIndex, // 指定设备序号
+ PVOID iBuffer, // 指向一个缓冲区,放置准备写出的数据
+ PULONG ioLength );// 指向长度单元,输入时为准备写出的长度,返回后为实际写出的长度
+
+//查询读缓冲区有多少字节未取
+BOOL WINAPI CH347Uart_QueryBufUpload(ULONG iIndex, // 指定设备序号
+ LONGLONG *RemainBytes);
+
+//获取设备信息
+BOOL WINAPI CH347Uart_GetDeviceInfor(ULONG iIndex,mDeviceInforS *DevInformation);
+
+
+/********IIC***********/
+// 设置串口流模式
+BOOL WINAPI CH347I2C_Set(ULONG iIndex, // 指定设备序号
+ ULONG iMode ); // 指定模式,见下行
+// 位1-位0: I2C接口速度/SCL频率, 00=低速/20KHz,01=标准/100KHz(默认值),10=快速/400KHz,11=高速/750KHz
+// 其它保留,必须为0
+
+// 设置硬件异步延时,调用后很快返回,而在下一个流操作之前延时指定毫秒数
+BOOL WINAPI CH347I2C_SetDelaymS(ULONG iIndex, // 指定设备序号
+ ULONG iDelay ) ; // 指定延时的毫秒数
+
+ // 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚
+BOOL WINAPI CH347StreamI2C( ULONG iIndex, // 指定设备序号
+ ULONG iWriteLength, // 准备写出的数据字节数
+ PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位
+ ULONG iReadLength, // 准备读取的数据字节数
+ PVOID oReadBuffer ); // 指向一个缓冲区,返回后是读入的数据
+#ifndef _CH341_DLL_H
+typedef enum _EEPROM_TYPE {// EEPROM型号
+ ID_24C01,
+ ID_24C02,
+ ID_24C04,
+ ID_24C08,
+ ID_24C16,
+ ID_24C32,
+ ID_24C64,
+ ID_24C128,
+ ID_24C256,
+ ID_24C512,
+ ID_24C1024,
+ ID_24C2048,
+ ID_24C4096
+} EEPROM_TYPE;
+#endif
+
+// 从EEPROM中读取数据块,速度约56K字节
+BOOL WINAPI CH347ReadEEPROM(ULONG iIndex, // 指定设备序号
+ EEPROM_TYPE iEepromID, // 指定EEPROM型号
+ ULONG iAddr, // 指定数据单元的地址
+ ULONG iLength, // 准备读取的数据字节数
+ PUCHAR oBuffer ); // 指向一个缓冲区,返回后是读入的数据
+// 向EEPROM中写入数据块
+BOOL WINAPI CH347WriteEEPROM(ULONG iIndex, // 指定设备序号
+ EEPROM_TYPE iEepromID, // 指定EEPROM型号
+ ULONG iAddr, // 指定数据单元的地址
+ ULONG iLength, // 准备写出的数据字节数
+ PUCHAR iBuffer ); // 指向一个缓冲区,放置准备写出的数据
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CH347_DLL_H
diff --git a/Drivers/LIB/CH347/CH347DLL_EN.H b/Drivers/LIB/CH347/CH347DLL_EN.H
new file mode 100644
index 0000000..491bdb5
--- /dev/null
+++ b/Drivers/LIB/CH347/CH347DLL_EN.H
@@ -0,0 +1,506 @@
+/*****************************************************************************
+** Copyright (C) WCH 2001-2022 **
+** Web: http://wch.cn **
+******************************************************************************
+Abstract:
+ USB2.0 adapter chip ch347, based on 480mbps high-speed USB bus, extends UART/SPI/I2C/JTAG
+Environment:
+user mode only,VC6.0 and later
+Notes:
+Copyright (c) 2022 Nanjing Qinheng Microelectronics Co., Ltd.
+--*/
+
+#ifndef _CH347_DLL_H
+#define _CH347_DLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN64
+#define mOFFSET( s, m ) ( (ULONG_PTR) & ( ( ( s * ) 0 ) -> m ) ) // Defines a macro that gets the relative offset address of a structure member
+#else
+#define mOFFSET( s, m ) ( (ULONG) & ( ( ( s * ) 0 ) -> m ) ) // Defines a macro that gets the relative offset address of a structure member
+#endif
+
+#ifndef max
+#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) // Larger value
+#endif
+
+#ifndef min
+#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) // Smaller Value
+#endif
+
+#ifdef ExAllocatePool
+#undef ExAllocatePool // Delete memory allocation with TAG
+#endif
+
+#ifndef NTSTATUS
+typedef LONG NTSTATUS; // Return status
+#endif
+
+//Sharing CH341WDM driver with CH341DLL
+#ifndef _CH341_DLL_H
+typedef struct _USB_SETUP_PKT { // Data request packet structure in the setup phase of USB control transfer
+ UCHAR mUspReqType; // 00H request type
+ UCHAR mUspRequest; // 01H request code
+ union {
+ struct {
+ UCHAR mUspValueLow; // 02H Value parameter low byte
+ UCHAR mUspValueHigh; // 03H Value parameter high byte
+ };
+ USHORT mUspValue; // 02H-03H value parameters
+ };
+ union {
+ struct {
+ UCHAR mUspIndexLow; // 04H index parameter low byte
+ UCHAR mUspIndexHigh; // 05H index parameter high byte
+ };
+ USHORT mUspIndex; // 04H-05H index parameter
+ };
+ USHORT mLength; // 06H-07H data length of data stage
+} mUSB_SETUP_PKT, *mPUSB_SETUP_PKT;
+
+
+typedef struct _WIN32_COMMAND { // Define the WIN32 command interface structure
+ union {
+ ULONG mFunction; // Specify function code or pipe number when inputting
+ NTSTATUS mStatus; // return operation status when output
+ };
+ ULONG mLength; // access length, return the length of subsequent data
+ union {
+ mUSB_SETUP_PKT mSetupPkt; // Data request in the setup phase of USB control transfer
+ UCHAR mBuffer[ 512]; // data buffer, the length is 0 to 255B
+ };
+} mWIN32_COMMAND, *mPWIN32_COMMAND;
+// WIN32 Application layer interface command
+#define IOCTL_CH341_COMMAND ( FILE_DEVICE_UNKNOWN << 16 | FILE_ANY_ACCESS << 14 | 0x0f34 << 2 | METHOD_BUFFERED ) // private interface
+
+#define mWIN32_COMMAND_HEAD mOFFSET( mWIN32_COMMAND, mBuffer ) // Header length of WIN32 command interface
+
+#define mCH341_MAX_NUMBER 16 // Maximum number of CH375 connected at the same time
+
+#define mMAX_BUFFER_LENGTH 0x1000 // The maximum length of the data buffer is 4MB
+
+#define mMAX_COMMAND_LENGTH ( mWIN32_COMMAND_HEAD + mMAX_BUFFER_LENGTH ) // maximum data length plus the length of the command structure header
+
+#define mDEFAULT_BUFFER_LEN 0x0400 // The default length of the data buffer is 1024
+
+#define mDEFAULT_COMMAND_LEN ( mWIN32_COMMAND_HEAD + mDEFAULT_BUFFER_LEN ) // default data length plus the length of the command structure header
+
+// CH341 endpoint address
+#define mCH347_ENDP_DATA_UP 0x86 // The address of the data block upload endpoint of CH347
+#define mCH347_ENDP_DATA_DOWN 0x06 // The address of the data block download endpoint of CH347
+
+// Pipeline operation command provided by equipment layer interface
+#define mPipeDeviceCtrl 0x00000004 // CH347 integrated control pipeline
+#define mPipeDataUp 0x00000006 // CH347 data block upload pipeline
+#define mPipeDataDown 0x00000007 // CH347 data block download pipeline
+
+// Function code of application layer interface
+#define mFuncNoOperation 0x00000000 // no operation
+#define mFuncGetVersion 0x00000001 // Get the driver version number
+#define mFuncGetConfig 0x00000002 // Get the USB device configuration descriptor
+#define mFuncSetTimeout 0x00000009 // Set USB communication timeout
+#define mFuncSetExclusive 0x0000000b // Set exclusive use
+#define mFuncResetDevice 0x0000000c // Reset the USB device
+#define mFuncResetPipe 0x0000000d // Reset the USB pipe
+#define mFuncAbortPipe 0x0000000e // Cancel the data request of the USB pipe
+#define mFuncBufferMode 0x00000020 // Set the buffer upload mode and query the data length in the buffer
+#define mFuncBufferModeDn 0x00000021 // Set the buffer download mode and query the data length in the buffer
+#define mFuncGetVersionEx 0x00000022 // Get the driver version number and chip model
+// USB device standard request code
+#define mUSB_CLR_FEATURE 0x01
+#define mUSB_SET_FEATURE 0x03
+#define mUSB_GET_STATUS 0x00
+#define mUSB_SET_ADDRESS 0x05
+#define mUSB_GET_DESCR 0x06
+#define mUSB_SET_DESCR 0x07
+#define mUSB_GET_CONFIG 0x08
+#define mUSB_SET_CONFIG 0x09
+#define mUSB_GET_INTERF 0x0a
+#define mUSB_SET_INTERF 0x0b
+#define mUSB_SYNC_FRAME 0x0c
+
+// CH341 manufacturer specific request type for control transmission
+#define mCH341_VENDOR_READ 0xC0 // CH347 vendor-specific read operation through control transfer
+#define mCH341_VENDOR_WRITE 0x40 // CH347 vendor-specific write operation through control transfer
+
+#define mCH341A_CMD_I2C_STREAM 0xAA // The command package of the I2C interface, starting from the secondary byte, is the I2C command stream
+#define mCH341A_CMD_UIO_STREAM 0xAB // The command package of the UIO interface, starting from the secondary byte, is the command stream
+#define mCH341A_CMD_PIO_STREAM 0xAE // The command package of PIO interface, starting from the secondary byte, is the data stream
+// CH341A manufacturer specific request code for control transmission
+#define mCH341A_BUF_CLEAR 0xB2 // Clear incomplete data
+#define mCH341A_I2C_CMD_X 0x54 // Issue the command of I2C interface and execute it immediately
+#define mCH341A_DELAY_MS 0x5E // Delay the specified time in microseconds
+#define mCH341A_GET_VER 0x5F // Get chip version
+
+#define mCH341A_CMD_I2C_STM_STA 0x74 // Command flow of I2C interface: generate start bit
+#define mCH341A_CMD_I2C_STM_STO 0x75 // Command flow of I2C interface: generate stop bit
+#define mCH341A_CMD_I2C_STM_OUT 0x80 // Command flow of I2C interface: output data, bit 5- bit 0 is the length, subsequent bytes are data, and length 0 only sends one byte and returns an answer
+#define mCH341A_CMD_I2C_STM_IN 0xC0 // I2C interface command flow: input data, bit 5-bit 0 is the length, and 0 length only receives one byte and sends no response
+#define mCH341A_CMD_I2C_STM_MAX ( min( 0x3F, mCH341_PACKET_LENGTH ) ) // The maximum length of input and output data of a single command in the command stream of I2C interface
+#define mCH341A_CMD_I2C_STM_SET 0x60 // Command flow of I2C interface: set parameters, bit 2=i/o number of SPI (0= single input single output, 1= double input double output), bit 1 0=i2c speed (00= low speed, 01= standard, 10= fast, 11= high speed)
+#define mCH341A_CMD_I2C_STM_US 0x40 // Command flow of I2C interface: delay in microseconds, bit 3- bit 0 as delay value
+#define mCH341A_CMD_I2C_STM_MS 0x50 // Command flow of I2C interface: delay in microseconds, bit 3-bit 0 as delay value
+#define mCH341A_CMD_I2C_STM_DLY 0x0F // Maximum value of single command delay of command flow of I2C interface
+#define mCH341A_CMD_I2C_STM_END 0x00 // Command flow of I2C interface: Command package ends in advance
+
+#define mCH341A_CMD_UIO_STM_IN 0x00 // Command flow of UIO interface: input data D7-D0
+#define mCH341A_CMD_UIO_STM_DIR 0x40 // Command flow of UIO interface: set i/o direction D5-D0, bit 5- bit 0 as direction data
+#define mCH341A_CMD_UIO_STM_OUT 0x80 // Command flow of UIO interface: output data D5-D0, bit 5-bit 0 is data
+#define mCH341A_CMD_UIO_STM_US 0xC0 // Command flow of UIO interface: delay in microseconds, bit 5- bit 0 as delay value
+#define mCH341A_CMD_UIO_STM_END 0x20 // Command flow of UIO interface: Command package ends in advance
+
+#define MAX_DEVICE_PATH_SIZE 128 // Maximum number of characters for device name
+#define MAX_DEVICE_ID_SIZE 64 // Maximum number of characters for device ID
+#endif _CH341_DLL_H
+
+//Drive Interface
+#define CH347_USB_VENDOR 0
+#define CH347_USB_HID 2
+#define CH347_USB_VCP 3
+
+//CH347_USB_VENDOR support CH341/7
+#define CHIP_TYPE_CH341 0
+#define CHIP_TYPE_CH347 1
+
+//Chip Function Interface Number
+#define CH347_FUNC_UART 0
+#define CH347_FUNC_SPI_IIC 1
+#define CH347_FUNC_JTAG_IIC 2
+
+#define DEFAULT_READ_TIMEOUT 500 // Default read timeout duration (mS)
+#define DEFAULT_WRITE_TIMEOUT 500 // Default write timeout duration (mS)
+
+#define mCH347_PACKET_LENGTH 512 // Length of packets supported by ch347
+#pragma pack(1)
+//SPI Controller Configuration
+typedef struct _SPI_CONFIG{
+ UCHAR iMode; // 0-3:SPI Mode0/1/2/3
+ UCHAR iClock; // 0=60MHz, 1=30MHz, 2=15MHz, 3=7.5MHz, 4=3.75MHz, 5=1.875MHz, 6=937.5KHz,7=468.75KHz
+ UCHAR iByteOrder; // 0=LSB first(LSB), 1=MSB first(MSB)
+ USHORT iSpiWriteReadInterval; // The SPI interface routinely reads and writes data command, the unit is uS
+ UCHAR iSpiOutDefaultData; // SPI prints data by default when it reads data
+ ULONG iChipSelect; // Piece of selected control, if bit 7 is 0, slice selection control is ignored, if bit 7 is 1, the parameter is valid: bit 1 bit 0 is 00/01 and CS1/CS2 pins are selected as low level active chip options respectively
+ UCHAR CS1Polarity; // Bit 0: CS1 polarity control: 0: effective low level; 1: effective lhigh level;
+ UCHAR CS2Polarity; // Bit 0: CS2 polarity control: 0: effective low level; 1: effective lhigh level;
+ USHORT iIsAutoDeativeCS; // Whether to undo slice selection automatically after the operation is complete
+ USHORT iActiveDelay; // Set the latency for read/write operations after slice selection,the unit is us
+ ULONG iDelayDeactive; // Delay time for read and write operations after slice selection is unselected,the unit is us
+}mSpiCfgS,*mPSpiCfgS;
+
+//Device Information
+typedef struct _DEV_INFOR{
+ UCHAR iIndex; // Current open number
+ UCHAR DevicePath[MAX_PATH]; // Device link name, used for CreateFile
+ UCHAR UsbClass; // 0:CH347_USB_CH341, 2:CH347_USB_HID,3:CH347_USB_VCP
+ UCHAR FuncType; // 0:CH347_FUNC_UART,1:CH347_FUNC_SPI_IIC,2:CH347_FUNC_JTAG_IIC
+ CHAR DeviceID[64]; // USB\VID_xxxx&PID_xxxx
+ UCHAR ChipMode; // Chip Mode, 0:Mode0(UART0/1); 1:Mode1(Uart1+SPI+IIC); 2:Mode2(HID Uart1+SPI+IIC) 3:Mode3(Uart1+Jtag+IIC)
+ HANDLE DevHandle; // Device handle
+ USHORT BulkOutEndpMaxSize; // Upload endpoint size
+ USHORT BulkInEndpMaxSize; // The size of the downstream endpoint
+ UCHAR UsbSpeedType; // USB Speed type,0:FS,1:HS,2:SS
+ UCHAR CH347IfNum; // USB interface number: 0:UART,1:SPI/IIC/JTAG/GPIO
+ UCHAR DataUpEndp; // The endpoint address
+ UCHAR DataDnEndp; // The endpoint address
+ CHAR ProductString[64]; // Product string in USB descriptor
+ CHAR ManufacturerString[64]; // Manufacturer string in USB descriptor
+ ULONG WriteTimeout; // USB write timeout
+ ULONG ReadTimeout; // USB read timeout
+ CHAR FuncDescStr[64]; // Interface functions
+ UCHAR FirewareVer; // Firmware version
+
+}mDeviceInforS,*mPDeviceInforS;
+#pragma pack()
+
+//CH347 Mode Common Function,support open,close,USB read,USB written and HID of all modes.
+//Open USB device
+HANDLE WINAPI CH347OpenDevice(ULONG DevI);
+
+//Close USB device
+BOOL WINAPI CH347CloseDevice(ULONG iIndex);
+
+//Get Device Information
+BOOL WINAPI CH347GetDeviceInfor(ULONG iIndex,mDeviceInforS *DevInformation);
+
+// Obtain driver version, library version, device version and chip type(CH341(FS)/CH347HS)
+BOOL WINAPI CH347GetVersion(ULONG iIndex,
+ PUCHAR iDriverVer,
+ PUCHAR iDLLVer,
+ PUCHAR ibcdDevice,
+ PUCHAR iChipType); //CHIP_TYPE_CH341/7
+
+typedef VOID ( CALLBACK * mPCH347_NOTIFY_ROUTINE ) ( // Device event notification callback routine
+ ULONG iEventStatus ); // Device event and current status (refer to the description below): 0=Device unplug event, 3=Device insertion event
+
+#define CH347_DEVICE_ARRIVAL 3 // Device insertion event,has been inserted
+#define CH347_DEVICE_REMOVE_PEND 1 // Device wil be unplugged
+#define CH347_DEVICE_REMOVE 0 // Device unplug event,has been pulled out
+
+BOOL WINAPI CH347SetDeviceNotify( // Configure device event notifier
+ ULONG iIndex, // Specifies the device number,bit 0 corresponds to the first device
+ PCHAR iDeviceID, // Optional parameter,pointing to a string terminated by \0,specifying the ID of the monitored device
+ mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // Specifies the port device event callback program. If it is NULL, the event notification will be canceled. Otherwise, the program will be called when an event is detected.
+
+// Read USB data block
+BOOL WINAPI CH347ReadData( ULONG iIndex, // Specifies the device number
+ PVOID oBuffer, // Points to a buffer large enough to save the read data
+ PULONG ioLength ); // Points to the length unit, the length to be read when input is the length to be read, and the actual read length after return
+
+// Write USB data block
+BOOL WINAPI CH347WriteData(ULONG iIndex, // Specifies the device number
+ PVOID iBuffer, // Points to a buffer large enough to save the written data
+ PULONG ioLength ); // Points to the length unit,the input length is the intended length, and the return length is the actual length
+
+// Set the timeout of USB data read and write
+BOOL WINAPI CH347SetTimeout(ULONG iIndex, // Specifies the device number
+ ULONG iWriteTimeout, // Specifies the timeout for USB to write data blocks, in milliseconds mS,0xFFFFFFFF specifies no timeout (default)
+ ULONG iReadTimeout ); // Specifies the timeout for USB to read data blocks, in milliseconds mS,0xFFFFFFFF specifies no timeout (default)
+
+/***************SPI********************/
+// SPI Controller Initialization
+BOOL WINAPI CH347SPI_Init(ULONG iIndex,mSpiCfgS *SpiCfg);
+
+// Get SPI controller configuration information
+BOOL WINAPI CH347SPI_GetCfg(ULONG iIndex,mSpiCfgS *SpiCfg);
+
+// Before setting the chip selection status, call CH347SPI_Init to set CS
+BOOL WINAPI CH347SPI_ChangeCS(ULONG iIndex, // Specify device number
+ UCHAR iStatus); // 0=Cancel the piece to choose,1=Set piece selected
+
+// Set SPI slice selection
+BOOL WINAPI CH347SPI_SetChipSelect(ULONG iIndex, // Specify device number
+ USHORT iEnableSelect, // The lower octet is CS1 and the higher octet is CS2. A byte value of 1= sets CS, 0= ignores this CS setting
+ USHORT iChipSelect, // The lower octet is CS1 and the higher octet is CS2. A byte value of 1= sets CS, 0= ignores this CS setting
+ ULONG iIsAutoDeativeCS, // The lower 16 bits are CS1 and the higher 16 bits are CS2. Whether to undo slice selection automatically after the operation is complete
+ ULONG iActiveDelay, // The lower 16 bits are CS1 and the higher 16 bits are CS2. Set the latency of read/write operations after chip selection, the unit is us
+ ULONG iDelayDeactive); // The lower 16 bits are CS1 and the higher 16 bits are CS2. Delay time for read and write operations after slice selection the unit is us
+
+//SPI4 write data
+BOOL WINAPI CH347SPI_Write(ULONG iIndex, // Specify device number
+ ULONG iChipSelect, // Slice selection control, when bit 7 is 0, slice selection control is ignored, and when bit 7 is 1, slice selection operation is performed
+ ULONG iLength, // Number of bytes of data to be transferred
+ ULONG iWriteStep, // The length of a single block to be read
+ PVOID ioBuffer); // Point to a buffer to place the data to be written out from MOSI
+
+//SPI4 read data. No need to write data first, the efficiency is higher than that of the CH347SPI_WriteRead
+BOOL WINAPI CH347SPI_Read(ULONG iIndex, // Specify device number
+ ULONG iChipSelect, // Slice selection control, when bit 7 is 0, slice selection control is ignored, and when bit 7 is 1, slice selection operation is performed
+ ULONG oLength, // Number of bytes to send
+ PULONG iLength, // Number of bytes of data to be read in
+ PVOID ioBuffer); // Points to a buffer that place the data to be written out from DOUT, return the data read in from DIN
+
+// Handle SPI data stream 4-wire interface
+BOOL WINAPI CH347SPI_WriteRead(ULONG iIndex, // Specify the device number
+ ULONG iChipSelect, // Selection control, if the film selection control bit 7 is 0, ignore the film selection control bit 7 is 1 and operate the film selection
+ ULONG iLength, // Number of bytes of data to be transferred
+ PVOID ioBuffer ); // Points to a buffer that place the data to be written out from DOUT, return the data read in from DIN
+
+//place the data to be written from MOSI, return the data read in from MISO
+BOOL WINAPI CH347StreamSPI4(ULONG iIndex, // Specify the device number
+ ULONG iChipSelect, // Film selection control, if bit 7 is 0, slice selection control is ignored.If bit 7 is 1, the parameter is valid:Bit 1 bit 0 is 00/01/10. Select D0/D1/D2 pins as low level active chip options respectively
+ ULONG iLength, // Number of bytes of data to be transferred
+ PVOID ioBuffer ); // Points to a buffer, places data to be written out from DOUT, and returns data to be read in from DIN
+
+/***************JTAG********************/
+//JTAG interface initialization, set mode and speed
+BOOL WINAPI CH347Jtag_INIT(ULONG iIndex,
+ UCHAR iClockRate); // Communication speed; The value ranges from 0 to 5. A larger value indicates a faster communication speed
+
+//Gets Jtag speed configuration
+BOOL WINAPI CH347Jtag_GetCfg(ULONG iIndex, // Specify the device number
+ UCHAR *ClockRate); // Communication speed; The value ranges from 0 to 5. A larger value indicates a faster communication speed
+
+//Bit band mode JTAG IR/DR data read and write. Suitable for reading and writing small amounts of data. Such as command operation, state machine switching and other control transmission. For batch data transmission, you are advised to use CH347Jtag_WriteRead_Fast
+//Command packages are read and written in batches in 4096 bytes
+//The state machine: Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
+BOOL WINAPI CH347Jtag_WriteRead(ULONG iIndex, // Specify the device number
+ BOOL IsDR, // =TRUE: DR data read/write, =FALSE:IR data read/write
+ ULONG iWriteBitLength, // Write length, the length to be written
+ PVOID iWriteBitBuffer, // Points to a buffer to place data ready to be written out
+ PULONG oReadBitLength, // Points to the length unit and returns the length actually read
+ PVOID oReadBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//JTAG IR/DR data batch read and write The IR/DR data is used for multi-byte continuous read and write. For example, download firmware. The hardware has four buffers. If the buffer is written before the buffer is read, the length cannot exceed 4096 bytes. Buffer size can be adjusted
+//The state machine: Run-Test->Shift-IR/DR..->Exit IR/DR -> Run-Test
+BOOL WINAPI CH347Jtag_WriteRead_Fast(ULONG iIndex, // Specify the device number
+ BOOL IsDR, // =TRUE: DRdata read/write, =FALSE:IR data read/write
+ ULONG iWriteBitLength, // Write length. The length to be written
+ PVOID iWriteBitBuffer, // Points to a buffer to place data ready to be written out
+ PULONG oReadBitLength, // Point to the length unit and return the actual read length
+ PVOID oReadBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//Switch the JTAG state machine
+BOOL WINAPI CH347Jtag_SwitchTapState(UCHAR TapState);
+
+//JTAG DR Write, in bytes, for multi-byte sequential reads and writes. For example, download firmware.
+//The state machine: Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteWriteDR(ULONG iIndex, // Specify the device number
+ ULONG iWriteLength, // Write length, length of bytes to be written
+ PVOID iWriteBuffer); // Points to a buffer to place data ready to be written out
+
+//JTAG DR Read, read multiple bytes consecutively in bytes.
+//The state machine: Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteReadDR(ULONG iIndex, // Specify the device number
+ PULONG oReadLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID oReadBuffer ); // Points to a buffer large enough to hold the read data
+
+//JTAG IR write, written in bytes, multiple bytes are written consecutively.
+//The state machine: Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteWriteIR(ULONG iIndex, // Specify the CH347 device number
+ ULONG iWriteLength, // Write length, the length of bytes to be written
+ PVOID iWriteBuffer); // Points to a buffer to place data ready to be written out
+
+//JTAG IR read, readen in bytes, multiple bytes are readen consecutively.
+//The state machine: Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_ByteReadIR(ULONG iIndex, // Specify the device number
+ PULONG oReadLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID oReadBuffer ); // Points to a buffer large enough to hold the read data
+
+//Bit band mode JTAG DR data write. Suitable for reading and writing small amounts of data. Such as command operation, state machine switching and other control transmission. For batch data transmission, CH347Jtag_ByteWriteDR is recommended
+//The state machine: Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_BitWriteDR(ULONG iIndex, // Specify the device number
+ ULONG iWriteBitLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID iWriteBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//Bit band mode JTAG IR data write. Suitable for reading and writing small amounts of data. Such as command operation, state machine switching and other control transmission. For batch data transmission, CH347Jtag_ByteWriteIR is recommended
+//The state machine: Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_BitWriteIR(ULONG iIndex, // Specify the device number
+ ULONG iWriteBitLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID iWriteBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//Bit band mode JTAG IR data read. Suitable for reading and writing small amounts of data. Such as command operation, state machine switching, etc. For batch data transmission, CH347Jtag_ByteReadIR is recommended.
+//The state machine: Run-Test->Shift-IR..->Exit IR -> Run-Test
+BOOL WINAPI CH347Jtag_BitReadIR(ULONG iIndex, // Specify the device number
+ PULONG oReadBitLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID oReadBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//Bit band mode JTAG DR data read. Suitable for reading and writing small amounts of data. For batch and high-speed data transmission, CH347Jtag_ByteReadDR is recommended
+//The state machine: Run-Test->Shift-DR..->Exit DR -> Run-Test
+BOOL WINAPI CH347Jtag_BitReadDR(ULONG iIndex, // Specify the device number
+ PULONG oReadBitLength, // Points to the length unit and returns the length of the bytes actually read
+ PVOID oReadBitBuffer ); // Points to a buffer large enough to hold the read data
+
+//Get the GPIO direction and pin level of CH347
+BOOL WINAPI CH347GPIO_Get(ULONG iIndex,
+ UCHAR *iDir, // Pin direction: GPIo0-7 corresponding bit 0-7,0: input; 1: output
+ UCHAR *iData); // GPIO0 level: GPIO0-7 corresponding bit 0-7,0: low level; 1: high level
+
+
+//Set the GPIO direction and pin level of CH347
+BOOL WINAPI CH347GPIO_Set(ULONG iIndex,
+ UCHAR iEnable, // Data validity flag: The corresponding bits 0-7 correspond to GPIO0-7.
+ UCHAR iSetDirOut, // Sets the I/O direction, with pin 0 corresponding to input and pin 1 corresponding to output. Gpio0-7 corresponds to bits 0-7.
+ UCHAR iSetDataOut); // Outputs data. If the I/O direction is output, then a pin outputs low level at a clear 0 and high level at a position 1
+
+//Enter the IAP firmware upgrade mode
+BOOL WINAPI CH347StartIapFwUpate(ULONG iIndex,
+ ULONG FwSize); // The length of the firmware
+
+/**************HID/VCP Serial Port*********************/
+//Open serial port
+HANDLE WINAPI CH347Uart_Open(ULONG iIndex);
+
+//Close serial port
+BOOL WINAPI CH347Uart_Close(ULONG iIndex);
+
+//Set the device event notification program
+BOOL WINAPI CH347Uart_SetDeviceNotify(
+ ULONG iIndex, // Specify the device number, 0 corresponds to the first device
+ PCHAR iDeviceID, // Optional parameter,points to a string specifying the ID of the device to be monitored, terminated with \0
+ mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // Specifies the device event callback. NULL cancels event notification, otherwise it will be called when an event is detected
+
+//Obtain UART hardware configuration
+BOOL WINAPI CH347Uart_GetCfg(ULONG iIndex, // Specify the device number
+ PULONG BaudRate, // Baud rate
+ PUCHAR ByteSize, // Data bits (5,6,7,8,16)
+ PUCHAR Parity, // Parity bits(0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
+ PUCHAR StopBits, // Stop bits (0:1 stop bits; 1:1.5 stop bit; 2:2 stop bit);
+ PUCHAR ByteTimeout); // Byte timeout
+
+//Set UART configuration
+BOOL WINAPI CH347Uart_Init(ULONG iIndex, // Specify the device number
+ DWORD BaudRate, // Baud rate
+ UCHAR ByteSize, // Data bits (5,6,7,8,16)
+ UCHAR Parity, // Check bit (0:None; 1:Odd; 2:Even; 3:Mark; 4:Space)
+ UCHAR StopBits, // Stop bits 0:1 Stop bit; 1:1.5 stop bit; 2:2 stop bit);
+ UCHAR ByteTimeout);// Byte Timeout duration, in unit of 100uS
+
+//Set the timeout of USB data read and write
+BOOL WINAPI CH347Uart_SetTimeout(ULONG iIndex, // Specify the device number
+ ULONG iWriteTimeout, // Specifies the timeout for USB to write data blocks, in milliseconds mS,0xFFFFFFFF specifies no timeout (default)
+ ULONG iReadTimeout ); // Specifies the timeout for USB to read data blocks, in milliseconds mS,0xFFFFFFFF specifies no timeout (default)
+
+//Read data block
+BOOL WINAPI CH347Uart_Read(ULONG iIndex, // Specify the device number
+ PVOID oBuffer, // Points to a buffer large enough to hold the read data
+ PULONG ioLength );// Refers to the length unit. The input is the length to be read and the return is the actual length to be read
+
+//Write out blocks of data
+BOOL WINAPI CH347Uart_Write(ULONG iIndex, // Specify the device number
+ PVOID iBuffer, // Points to a buffer to place data ready to be written out
+ PULONG ioLength );// Point to the length unit. The input is the intended length and the return is the actual length
+
+//Query how many bytes are unfetched in the read buffer
+BOOL WINAPI CH347Uart_QueryBufUpload(ULONG iIndex, // Specify the device number
+ LONGLONG *RemainBytes);
+
+//Obtaining Device Information
+BOOL WINAPI CH347Uart_GetDeviceInfor(ULONG iIndex,mDeviceInforS *DevInformation);
+
+/********IIC***********/
+//Set the serial port flow mode
+BOOL WINAPI CH347I2C_Set(ULONG iIndex, // Specify the device number
+ ULONG iMode ); // See downlink for the specified mode
+//bit 1-bit 0: I2C interface speed /SCL frequency, 00= low speed /20KHz,01= standard /100KHz(default),10= fast /400KHz,11= high speed /750KHz
+//Other reservations, must be 0
+
+//Set the hardware asynchronous delay to a specified number of milliseconds before the next stream operation
+BOOL WINAPI CH347I2C_SetDelaymS(ULONG iIndex, // Specify the device number
+ ULONG iDelay ) ; // Specifies the delay duration (mS)
+
+//Process I2C data stream, 2-wire interface, clock line for SCL pin, data line for SDA pin
+BOOL WINAPI CH347StreamI2C( ULONG iIndex, // Specify the device number
+ ULONG iWriteLength, // The number of bytes of data to write
+ PVOID iWriteBuffer, // Points to a buffer to place data ready to be written out, the first byte is usually the I2C device address and read/write direction bit
+ ULONG iReadLength, // Number of bytes of data to be read
+ PVOID oReadBuffer ); // Points to a buffer to place data ready to be read in
+#ifndef _CH341_DLL_H
+typedef enum _EEPROM_TYPE {// EEPROM type
+ ID_24C01,
+ ID_24C02,
+ ID_24C04,
+ ID_24C08,
+ ID_24C16,
+ ID_24C32,
+ ID_24C64,
+ ID_24C128,
+ ID_24C256,
+ ID_24C512,
+ ID_24C1024,
+ ID_24C2048,
+ ID_24C4096
+} EEPROM_TYPE;
+#endif
+
+// Reads data blocks from EEPROM at a speed of about 56 KB
+BOOL WINAPI CH347ReadEEPROM(ULONG iIndex, // Specify the device number
+ EEPROM_TYPE iEepromID, // Specifies the EEPROM model
+ ULONG iAddr, // Specifies the address of data unit
+ ULONG iLength, // Number of bytes of data to be read
+ PUCHAR oBuffer ); // Points to a buffer to place data ready to be read in
+
+// Writes a data block to the EEPROM
+BOOL WINAPI CH347WriteEEPROM(ULONG iIndex, // Specify the device number
+ EEPROM_TYPE iEepromID, // Specifies the EEPROM model
+ ULONG iAddr, // Specifies the address of data unit
+ ULONG iLength, // Number of bytes of data to be written out
+ PUCHAR iBuffer ); // Points to a buffer to place data ready to be written out
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CH347_DLL_H
diff --git a/Drivers/LIB/CH347/amd64/CH347DLLA64.LIB b/Drivers/LIB/CH347/amd64/CH347DLLA64.LIB
new file mode 100644
index 0000000..151c1cd
Binary files /dev/null and b/Drivers/LIB/CH347/amd64/CH347DLLA64.LIB differ
diff --git a/Drivers/LIB/CH347/arm64/CH347DLLA64.LIB b/Drivers/LIB/CH347/arm64/CH347DLLA64.LIB
new file mode 100644
index 0000000..151c1cd
Binary files /dev/null and b/Drivers/LIB/CH347/arm64/CH347DLLA64.LIB differ
diff --git a/Drivers/LIB/CH347/i386/CH347DLL.LIB b/Drivers/LIB/CH347/i386/CH347DLL.LIB
new file mode 100644
index 0000000..fc96a54
Binary files /dev/null and b/Drivers/LIB/CH347/i386/CH347DLL.LIB differ
diff --git a/Tools/AsProgrammer/settings.xml b/Tools/AsProgrammer/settings.xml
index a2e8f90..db15732 100644
--- a/Tools/AsProgrammer/settings.xml
+++ b/Tools/AsProgrammer/settings.xml
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.dll b/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.dll
new file mode 100644
index 0000000..9d0d613
Binary files /dev/null and b/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.dll differ
diff --git a/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.xml b/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.xml
new file mode 100644
index 0000000..f1f7b4b
--- /dev/null
+++ b/Tools/CH341A Programmer V1.03/Be.Windows.Forms.HexBox.xml
@@ -0,0 +1,1780 @@
+
+
+
+ Be.Windows.Forms.HexBox
+
+
+
+
+ Defines a build-in ContextMenuStrip manager for HexBox control to show Copy, Cut, Paste menu in contextmenu of the control.
+
+
+
+
+ Contains the HexBox control.
+
+
+
+
+ Contains the ContextMenuStrip control.
+
+
+
+
+ Contains the "Cut"-ToolStripMenuItem object.
+
+
+
+
+ Contains the "Copy"-ToolStripMenuItem object.
+
+
+
+
+ Contains the "Paste"-ToolStripMenuItem object.
+
+
+
+
+ Contains the "Select All"-ToolStripMenuItem object.
+
+
+
+
+ Initializes a new instance of BuildInContextMenu class.
+
+ the HexBox control
+
+
+
+ If ByteProvider
+
+ the sender object
+ the event data
+
+
+
+ Assigns the ContextMenuStrip control to the HexBox control.
+
+
+
+
+ Before opening the ContextMenuStrip, we manage the availability of the items.
+
+ the sender object
+ the event data
+
+
+
+ The handler for the "Cut"-Click event
+
+ the sender object
+ the event data
+
+
+
+ The handler for the "Copy"-Click event
+
+ the sender object
+ the event data
+
+
+
+ The handler for the "Paste"-Click event
+
+ the sender object
+ the event data
+
+
+
+ The handler for the "Select All"-Click event
+
+ the sender object
+ the event data
+
+
+
+ Gets or sets the custom text of the "Copy" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the custom text of the "Cut" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the custom text of the "Paste" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the custom text of the "Select All" ContextMenuStrip item.
+
+
+
+
+ Gets the text of the "Cut" ContextMenuStrip item.
+
+
+
+
+ Gets the text of the "Copy" ContextMenuStrip item.
+
+
+
+
+ Gets the text of the "Paste" ContextMenuStrip item.
+
+
+
+
+ Gets the text of the "Select All" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the image of the "Cut" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the image of the "Copy" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the image of the "Paste" ContextMenuStrip item.
+
+
+
+
+ Gets or sets the image of the "Select All" ContextMenuStrip item.
+
+
+
+
+ Represents a collection of bytes.
+
+
+
+
+ Initializes a new instance of ByteCollection class.
+
+
+
+
+ Initializes a new instance of ByteCollection class.
+
+ an array of bytes to add to collection
+
+
+
+ Gets or sets the value of a byte
+
+
+
+
+ Adds a byte into the collection.
+
+ the byte to add
+
+
+
+ Adds a range of bytes to the collection.
+
+ the bytes to add
+
+
+
+ Removes a byte from the collection.
+
+ the byte to remove
+
+
+
+ Removes a range of bytes from the collection.
+
+ the index of the start byte
+ the count of the bytes to remove
+
+
+
+ Inserts a range of bytes to the collection.
+
+ the index of start byte
+ an array of bytes to insert
+
+
+
+ Gets all bytes in the array
+
+ an array of bytes.
+
+
+
+ Inserts a byte to the collection.
+
+ the index
+ a byte to insert
+
+
+
+ Returns the index of the given byte.
+
+
+
+
+ Returns true, if the byte exists in the collection.
+
+
+
+
+ Copies the content of the collection into the given array.
+
+
+
+
+ Copies the content of the collection into an array.
+
+ the array containing all bytes.
+
+
+
+ Represents a position in the HexBox control
+
+
+
+
+ Byte provider for a small amount of data.
+
+
+
+
+ Contains information about changes.
+
+
+
+
+ Contains a byte collection.
+
+
+
+
+ Initializes a new instance of the DynamicByteProvider class.
+
+
+
+
+
+ Initializes a new instance of the DynamicByteProvider class.
+
+
+
+
+
+ Raises the Changed event.
+
+
+
+
+ Raises the LengthChanged event.
+
+
+
+
+ Gets the byte collection.
+
+
+
+
+ True, when changes are done.
+
+
+
+
+ Applies changes.
+
+
+
+
+ Occurs, when the write buffer contains new changes.
+
+
+
+
+ Occurs, when InsertBytes or DeleteBytes method is called.
+
+
+
+
+ Reads a byte from the byte collection.
+
+ the index of the byte to read
+ the byte
+
+
+
+ Write a byte into the byte collection.
+
+ the index of the byte to write.
+ the byte
+
+
+
+ Deletes bytes from the byte collection.
+
+ the start index of the bytes to delete.
+ the length of bytes to delete.
+
+
+
+ Inserts byte into the byte collection.
+
+ the start index of the bytes in the byte collection
+ the byte array to insert
+
+
+
+ Gets the length of the bytes in the byte collection.
+
+
+
+
+ Returns true
+
+
+
+
+ Returns true
+
+
+
+
+ Returns true
+
+
+
+
+ Implements a fully editable byte provider for file data of any size.
+
+
+ Only changes to the file are stored in memory with reads from the
+ original data occurring as required.
+
+
+
+
+ Constructs a new instance.
+
+ The name of the file from which bytes should be provided.
+
+
+
+ Constructs a new instance.
+
+ The name of the file from which bytes should be provided.
+ True, opens the file in read-only mode.
+
+
+
+ Constructs a new instance.
+
+ the stream containing the data.
+
+ The stream must supported seek operations.
+
+
+
+
+
+
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ Save current memory stream to a file.
+
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ See for more information.
+
+
+
+
+ Gets a value, if the file is opened in read-only mode.
+
+
+
+
+ Byte provider for (big) files.
+
+
+
+
+ Represents the write buffer class
+
+
+
+
+ Gets or sets a byte in the collection
+
+
+
+
+ Adds a byte into the collection
+
+ the index of the byte
+ the value of the byte
+
+
+
+ Determines if a byte with the given index exists.
+
+ the index of the byte
+ true, if the is in the collection
+
+
+
+ Occurs, when the write buffer contains new changes.
+
+
+
+
+ Contains all changes
+
+
+
+
+ Contains the file name.
+
+
+
+
+ Contains the file stream.
+
+
+
+
+ Read-only access.
+
+
+
+
+ Initializes a new instance of the FileByteProvider class.
+
+
+
+
+
+ Terminates the instance of the FileByteProvider class.
+
+
+
+
+ Raises the Changed event.
+
+ Never used.
+
+
+
+ Gets the name of the file the byte provider is using.
+
+
+
+
+ Returns a value if there are some changes.
+
+ true, if there are some changes
+
+
+
+ Updates the file with all changes the write buffer contains.
+
+
+
+
+ Clears the write buffer and reject all changes made.
+
+
+
+
+ Never used.
+
+
+
+
+ Reads a byte from the file.
+
+ the index of the byte to read
+ the byte
+
+
+
+ Gets the length of the file.
+
+
+
+
+ Writes a byte into write buffer
+
+
+
+
+ Not supported
+
+
+
+
+ Not supported
+
+
+
+
+ Returns true
+
+
+
+
+ Returns false
+
+
+
+
+ Returns false
+
+
+
+
+ Releases the file handle used by the FileByteProvider.
+
+
+
+
+ Defines the type of the Find operation.
+
+
+
+
+ Used for Text Find operations
+
+
+
+
+ Used for Hex Find operations
+
+
+
+
+ Defines all state information nee
+
+
+
+
+ Gets or sets whether the Find options are valid
+
+
+
+
+ Gets the Find buffer used for case insensitive Find operations. This is the binary representation of Text.
+
+
+
+
+ Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in lower case format.
+
+
+
+
+ Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in upper case format.
+
+
+
+
+ Contains the MatchCase value
+
+
+
+
+ Gets or sets the value, whether the Find operation is case sensitive or not.
+
+
+
+
+ Contains the text that should be found.
+
+
+
+
+ Gets or sets the text that should be found. Only used, when Type is FindType.Hex.
+
+
+
+
+ Gets or sets the hex buffer that should be found. Only used, when Type is FindType.Hex.
+
+
+
+
+ Gets or sets the type what should be searched.
+
+
+
+
+ Updates the find buffer.
+
+
+
+
+ Represents a hex box control.
+
+
+
+
+ Defines a user input handler such as for mouse and keyboard input
+
+
+
+
+ Activates mouse events
+
+
+
+
+ Deactivate mouse events
+
+
+
+
+ Preprocesses WM_KEYUP window message.
+
+ the Message object to process.
+ True, if the message was processed.
+
+
+
+ Preprocesses WM_CHAR window message.
+
+ the Message object to process.
+ True, if the message was processed.
+
+
+
+ Preprocesses WM_KEYDOWN window message.
+
+ the Message object to process.
+ True, if the message was processed.
+
+
+
+ Gives some information about where to place the caret.
+
+ the index of the byte
+ the position where the caret is to place.
+
+
+
+ Represents an empty input handler without any functionality.
+ If is set ByteProvider to null, then this interpreter is used.
+
+
+
+
+ Handles user input such as mouse and keyboard input during hex view edit
+
+
+
+
+ Delegate for key-down processing.
+
+ the message object contains key data information
+ True, if the message was processed
+
+
+
+ Contains the parent HexBox control
+
+
+
+
+ Contains True, if shift key is down
+
+
+
+
+ Contains True, if mouse is down
+
+
+
+
+ Contains the selection start position info
+
+
+
+
+ Contains the current mouse selection position info
+
+
+
+
+ Contains all message handlers of key interpreter key down message
+
+
+
+
+ Handles user input such as mouse and keyboard input during string view edit
+
+
+
+
+ Contains the hole content bounds of all text
+
+
+
+
+ Contains the line info bounds
+
+
+
+
+ Contains the column info header rectangle bounds
+
+
+
+
+ Contains the hex data bounds
+
+
+
+
+ Contains the string view bounds
+
+
+
+
+ Contains string format information for text drawing
+
+
+
+
+ Contains the maximum of visible horizontal bytes
+
+
+
+
+ Contains the maximum of visible vertical bytes
+
+
+
+
+ Contains the maximum of visible bytes.
+
+
+
+
+ Contains the scroll bars minimum value
+
+
+
+
+ Contains the scroll bars maximum value
+
+
+
+
+ Contains the scroll bars current position
+
+
+
+
+ Contains a vertical scroll
+
+
+
+
+ Contains a timer for thumbtrack scrolling
+
+
+
+
+ Contains the thumbtrack scrolling position
+
+
+
+
+ Contains the thumptrack delay for scrolling in milliseconds.
+
+
+
+
+ Contains the Enviroment.TickCount of the last refresh
+
+
+
+
+ Contains the border锟絪 left shift
+
+
+
+
+ Contains the border锟絪 right shift
+
+
+
+
+ Contains the border锟絪 top shift
+
+
+
+
+ Contains the border bottom shift
+
+
+
+
+ Contains the index of the first visible byte
+
+
+
+
+ Contains the index of the last visible byte
+
+
+
+
+ Contains the current byte position
+
+
+
+
+ Contains the current char position in one byte
+
+
+ "1A"
+ "1" = char position of 0
+ "A" = char position of 1
+
+
+
+
+ Contains string format information for hex values
+
+
+
+
+ Contains the current key interpreter
+
+
+
+
+ Contains an empty key interpreter without functionality
+
+
+
+
+ Contains the default key interpreter
+
+
+
+
+ Contains the string key interpreter
+
+
+
+
+ Contains True if caret is visible
+
+
+
+
+ Contains true, if the find (Find method) should be aborted.
+
+
+
+
+ Contains a value of the current finding position.
+
+
+
+
+ Contains a state value about Insert or Write mode. When this value is true and the ByteProvider SupportsInsert is true bytes are inserted instead of overridden.
+
+
+
+
+ Occurs, when the value of InsertActive property has changed.
+
+
+
+
+ Occurs, when the value of ReadOnly property has changed.
+
+
+
+
+ Occurs, when the value of ByteProvider property has changed.
+
+
+
+
+ Occurs, when the value of SelectionStart property has changed.
+
+
+
+
+ Occurs, when the value of SelectionLength property has changed.
+
+
+
+
+ Occurs, when the value of LineInfoVisible property has changed.
+
+
+
+
+ Occurs, when the value of ColumnInfoVisibleChanged property has changed.
+
+
+
+
+ Occurs, when the value of GroupSeparatorVisibleChanged property has changed.
+
+
+
+
+ Occurs, when the value of StringViewVisible property has changed.
+
+
+
+
+ Occurs, when the value of BorderStyle property has changed.
+
+
+
+
+ Occurs, when the value of ColumnWidth property has changed.
+
+
+
+
+ Occurs, when the value of BytesPerLine property has changed.
+
+
+
+
+ Occurs, when the value of UseFixedBytesPerLine property has changed.
+
+
+
+
+ Occurs, when the value of VScrollBarVisible property has changed.
+
+
+
+
+ Occurs, when the value of HexCasing property has changed.
+
+
+
+
+ Occurs, when the value of HorizontalByteCount property has changed.
+
+
+
+
+ Occurs, when the value of VerticalByteCount property has changed.
+
+
+
+
+ Occurs, when the value of CurrentLine property has changed.
+
+
+
+
+ Occurs, when the value of CurrentPositionInLine property has changed.
+
+
+
+
+ Occurs, when Copy method was invoked and ClipBoardData changed.
+
+
+
+
+ Occurs, when CopyHex method was invoked and ClipBoardData changed.
+
+
+
+
+ Occurs, when the CharSize property has changed
+
+
+
+
+ Occurs, when the RequiredWidth property changes
+
+
+
+
+ Initializes a new instance of a HexBox class.
+
+
+
+
+ Performs the thumbtrack scrolling after an delay.
+
+
+
+
+ Scrolls the selection start byte into view
+
+
+
+
+ Scrolls the specific byte into view
+
+ the index of the byte
+
+
+
+ Returns true if Select method could be invoked.
+
+
+
+
+ Selects all bytes.
+
+
+
+
+ Selects the hex box.
+
+ the start index of the selection
+ the length of the selection
+
+
+
+ Preprocesses windows messages.
+
+ the message to process.
+ true, if the message was processed
+
+
+
+ Searches the current ByteProvider
+
+ contains all find options
+ the SelectionStart property value if find was successfull or
+ -1 if there is no match
+ -2 if Find was aborted.
+
+
+
+ Aborts a working Find method.
+
+
+
+
+ Gets a value that indicates the current position during Find method execution.
+
+
+
+
+ Copies the current selection in the hex box to the Clipboard.
+
+
+
+
+ Return true if Copy method could be invoked.
+
+
+
+
+ Moves the current selection in the hex box to the Clipboard.
+
+
+
+
+ Return true if Cut method could be invoked.
+
+
+
+
+ Replaces the current selection in the hex box with the contents of the Clipboard.
+
+
+
+
+ Return true if Paste method could be invoked.
+
+
+
+
+ Return true if PasteHex method could be invoked.
+
+
+
+
+ Replaces the current selection in the hex box with the hex string data of the Clipboard.
+
+
+
+
+ Copies the current selection in the hex box to the Clipboard in hex format.
+
+
+
+
+ Paints the background.
+
+ A PaintEventArgs that contains the event data.
+
+
+
+ Paints the hex box.
+
+ A PaintEventArgs that contains the event data.
+
+
+
+ Gets or sets the background color for the control.
+
+
+
+
+ The font used to display text in the hexbox.
+
+
+
+
+ Not used.
+
+
+
+
+ Not used.
+
+
+
+
+ Gets or sets the background color for the disabled control.
+
+
+
+
+ Gets or sets if the count of bytes in one line is fix.
+
+
+ When set to True, BytesPerLine property determine the maximum count of bytes in one line.
+
+
+
+
+ Gets or sets the maximum count of bytes in one line.
+
+
+ UseFixedBytesPerLine property no longer has to be set to true for this to work
+
+
+
+
+ Gets or sets the number of bytes in a group. Used to show the group separator line (if GroupSeparatorVisible is true)
+
+
+ GroupSeparatorVisible property must set to true
+
+
+
+
+ Gets or sets if the count of bytes in one line is fix.
+
+
+ When set to True, BytesPerLine property determine the maximum count of bytes in one line.
+
+
+
+
+ Gets or sets the visibility of a vertical scroll bar.
+
+
+
+
+ Gets or sets the ByteProvider.
+
+
+
+
+ Gets or sets the visibility of the group separator.
+
+
+
+
+ Gets or sets the visibility of the column info
+
+
+
+
+ Gets or sets the visibility of a line info.
+
+
+
+
+ Gets or sets the offset of a line info.
+
+
+
+
+ Gets or sets the hex box锟絪 border style.
+
+
+
+
+ Gets or sets the visibility of the string view.
+
+
+
+
+ Gets or sets whether the HexBox control displays the hex characters in upper or lower case.
+
+
+
+
+ Gets and sets the starting point of the bytes selected in the hex box.
+
+
+
+
+ Gets and sets the number of bytes selected in the hex box.
+
+
+
+
+ Gets or sets the info color used for column info and line info. When this property is null, then ForeColor property is used.
+
+
+
+
+ Gets or sets the background color for the selected bytes.
+
+
+
+
+ Gets or sets the foreground color for the selected bytes.
+
+
+
+
+ Gets or sets the visibility of a shadow selection.
+
+
+
+
+ Gets or sets the color of the shadow selection.
+
+
+ A alpha component must be given!
+ Default alpha = 100
+
+
+
+
+ Contains the size of a single character in pixel
+
+
+
+
+ Gets the width required for the content
+
+
+
+
+ Gets the number bytes drawn horizontally.
+
+
+
+
+ Gets the number bytes drawn vertically.
+
+
+
+
+ Gets the current line
+
+
+
+
+ Gets the current position in the current line
+
+
+
+
+ Gets the a value if insertion mode is active or not.
+
+
+
+
+ Gets or sets the built-in context menu.
+
+
+
+
+ Gets or sets the converter that will translate between byte and character values.
+
+
+
+
+ Converts a byte array to a hex string. For example: {10,11} = "0A 0B"
+
+ the byte array
+ the hex string
+
+
+
+ Converts the byte to a hex string. For example: "10" = "0A";
+
+ the byte to format
+ the hex string
+
+
+
+ Converts the hex string to an byte array. The hex string must be separated by a space char ' '. If there is any invalid hex information in the string the result will be null.
+
+ the hex string separated by ' '. For example: "0A 0B 0C"
+ the byte array. null if hex is invalid or empty
+
+
+
+ Raises the InsertActiveChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the ReadOnlyChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the ByteProviderChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the SelectionStartChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the SelectionLengthChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the LineInfoVisibleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the OnColumnInfoVisibleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the ColumnSeparatorVisibleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the StringViewVisibleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the BorderStyleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the UseFixedBytesPerLineChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the GroupSizeChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the BytesPerLineChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the VScrollBarVisibleChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the HexCasingChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the HorizontalByteCountChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the VerticalByteCountChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the CurrentLineChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the CurrentPositionInLineChanged event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the Copied event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the CopiedHex event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the MouseDown event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the MouseWhell event
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the Resize event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the GotFocus event.
+
+ An EventArgs that contains the event data.
+
+
+
+ Raises the LostFocus event.
+
+ An EventArgs that contains the event data.
+
+
+
+ For high resolution screen support
+
+ the factor
+ bounds
+
+
+
+ Specifies the case of hex characters in the HexBox control
+
+
+
+
+ Converts all characters to uppercase.
+
+
+
+
+ Converts all characters to lowercase.
+
+
+
+
+ The interface for objects that can translate between characters and bytes.
+
+
+
+
+ Returns the character to display for the byte passed across.
+
+
+
+
+
+
+ Returns the byte to use when the character passed across is entered during editing.
+
+
+
+
+
+
+ The default implementation.
+
+
+
+
+ Returns the character to display for the byte passed across.
+
+
+
+
+
+
+ Returns the byte to use for the character passed across.
+
+
+
+
+
+
+ Returns a description of the byte char provider.
+
+
+
+
+
+ A byte char provider that can translate bytes encoded in codepage 500 EBCDIC
+
+
+
+
+ The IBM EBCDIC code page 500 encoding. Note that this is not always supported by .NET,
+ the underlying platform has to provide support for it.
+
+
+
+
+ Returns the EBCDIC character corresponding to the byte passed across.
+
+
+
+
+
+
+ Returns the byte corresponding to the EBCDIC character passed across.
+
+
+
+
+
+
+ Returns a description of the byte char provider.
+
+
+
+
+
+ Defines a byte provider for HexBox control
+
+
+
+
+ Reads a byte from the provider
+
+ the index of the byte to read
+ the byte to read
+
+
+
+ Writes a byte into the provider
+
+ the index of the byte to write
+ the byte to write
+
+
+
+ Inserts bytes into the provider
+
+
+
+ This method must raise the LengthChanged event.
+
+
+
+ Deletes bytes from the provider
+
+ the start index of the bytes to delete
+ the length of the bytes to delete
+ This method must raise the LengthChanged event.
+
+
+
+ Returns the total length of bytes the byte provider is providing.
+
+
+
+
+ Occurs, when the Length property changed.
+
+
+
+
+ True, when changes are done.
+
+
+
+
+ Applies changes.
+
+
+
+
+ Occurs, when bytes are changed.
+
+
+
+
+ Returns a value if the WriteByte methods is supported by the provider.
+
+ True, when it锟絪 supported.
+
+
+
+ Returns a value if the InsertBytes methods is supported by the provider.
+
+ True, when it锟絪 supported.
+
+
+
+ Returns a value if the DeleteBytes methods is supported by the provider.
+
+ True, when it锟絪 supported.
+
+
+
+ A strongly-typed resource class, for looking up localized strings, etc.
+
+
+
+
+ Returns the cached ResourceManager instance used by this class.
+
+
+
+
+ Overrides the current thread's CurrentUICulture property for all
+ resource lookups using this strongly typed resource class.
+
+
+
+
+ Contains true, if we are in design mode of Visual Studio
+
+
+
+
+ Initializes an instance of Util class
+
+
+
+
+ Gets true, if we are in design mode of Visual Studio
+
+
+ In Visual Studio 2008 SP1 the designer is crashing sometimes on windows forms.
+ The DesignMode property of Control class is buggy and cannot be used, so use our own implementation instead.
+
+
+
+
diff --git a/Tools/CH341A Programmer V1.03/CH341A_Programmer.exe b/Tools/CH341A Programmer V1.03/CH341A_Programmer.exe
new file mode 100644
index 0000000..3ec8fce
Binary files /dev/null and b/Tools/CH341A Programmer V1.03/CH341A_Programmer.exe differ
diff --git a/Tools/CH341A Programmer V1.03/CH341A_Programmer.pdb b/Tools/CH341A Programmer V1.03/CH341A_Programmer.pdb
new file mode 100644
index 0000000..136f37a
Binary files /dev/null and b/Tools/CH341A Programmer V1.03/CH341A_Programmer.pdb differ
diff --git a/Tools/CH341A Programmer V1.03/CH341DLL.DLL b/Tools/CH341A Programmer V1.03/CH341DLL.DLL
new file mode 100644
index 0000000..c9f2eb1
Binary files /dev/null and b/Tools/CH341A Programmer V1.03/CH341DLL.DLL differ
diff --git a/Tools/CH341A Programmer V1.03/chiplist.xml b/Tools/CH341A Programmer V1.03/chiplist.xml
new file mode 100644
index 0000000..46b4359
--- /dev/null
+++ b/Tools/CH341A Programmer V1.03/chiplist.xml
@@ -0,0 +1,953 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_25AA010A page="16" size="128" spicmd="95"/>
+ <_25AA020A page="16" size="256" spicmd="95"/>
+ <_25AA040 page="16" size="512" spicmd="95"/>
+ <_25AA040A page="16" size="512" spicmd="95"/>
+ <_25AA080 page="16" size="1024" spicmd="95"/>
+ <_25AA080A page="16" size="1024" spicmd="95"/>
+ <_25AA080B page="32" size="1024" spicmd="95"/>
+ <_25AA080C page="16" size="1024" spicmd="95"/>
+ <_25AA080D page="32" size="1024" spicmd="95"/>
+ <_25AA1024 page="256" size="131072" spicmd="95"/>
+ <_25AA128 page="64" size="16384" spicmd="95"/>
+ <_25AA160 page="16" size="2048" spicmd="95"/>
+ <_25AA160A page="16" size="2048" spicmd="95"/>
+ <_25AA160B page="32" size="2048" spicmd="95"/>
+ <_25AA256 page="64" size="32768" spicmd="95"/>
+ <_25AA320 page="32" size="4096" spicmd="95"/>
+ <_25AA512 page="128" size="65536" spicmd="95"/>
+ <_25AA640 page="32" size="8192" spicmd="95"/>
+ <_25C040 page="16" size="512" spicmd="95"/>
+ <_25C080 page="16" size="1024" spicmd="95"/>
+ <_25C160 page="16" size="2048" spicmd="95"/>
+ <_25C320 page="32" size="4096" spicmd="95"/>
+ <_25C640 page="32" size="8192" spicmd="95"/>
+ <_25LC010A page="16" size="128" spicmd="95"/>
+ <_25LC020A page="16" size="256" spicmd="95"/>
+ <_25LC040 page="16" size="512" spicmd="95"/>
+ <_25LC040A page="16" size="512" spicmd="95"/>
+ <_25LC080 page="16" size="1024" spicmd="95"/>
+ <_25LC080A page="16" size="1024" spicmd="95"/>
+ <_25LC080B page="32" size="1024" spicmd="95"/>
+ <_25LC080C page="16" size="1024" spicmd="95"/>
+ <_25LC080D page="32" size="1024" spicmd="95"/>
+ <_25LC1024 page="256" size="131072" spicmd="95"/>
+ <_25LC128 page="64" size="16384" spicmd="95"/>
+ <_25LC160 page="16" size="2048" spicmd="95"/>
+ <_25LC160A page="16" size="2048" spicmd="95"/>
+ <_25LC160B page="32" size="2048" spicmd="95"/>
+ <_25LC256 page="64" size="32768" spicmd="95"/>
+ <_25LC320 page="32" size="4096" spicmd="95"/>
+ <_25LC512 page="128" size="65536" spicmd="95"/>
+ <_25LC640 page="32" size="8192" spicmd="95"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_24Cxxx>
+
+ <_24C01 page="1" size="128" addrtype="1"/>
+ <_24C02 page="1" size="256" addrtype="1"/>
+ <_24C04 page="1" size="512" addrtype="2"/>
+ <_24C08 page="16" size="1024" addrtype="3"/>
+ <_24C16 page="16" size="2048" addrtype="4"/>
+ <_24C32 page="32" size="4096" addrtype="5"/>
+ <_24C64 page="32" size="8192" addrtype="5"/>
+ <_24C128 page="64" size="16384" addrtype="5"/>
+ <_24C256 page="64" size="32768" addrtype="5"/>
+ <_24C512 page="128" size="65536" addrtype="5"/>
+ <_24C1024 page="128" size="131072" addrtype="6"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/CH341A EEPROM Reader - ConsoleMods Wiki.pdf b/docs/CH341A EEPROM Reader - ConsoleMods Wiki.pdf
new file mode 100644
index 0000000..d72ad3d
Binary files /dev/null and b/docs/CH341A EEPROM Reader - ConsoleMods Wiki.pdf differ