├── .travis.yml ├── .gitignore ├── MCP2210 ├── Libs │ ├── HidSharp.dll │ ├── HidSharp.pdb │ ├── HidSharp.tlb │ └── HidSharp.XML ├── IVolatileRam.cs ├── Properties │ └── AssemblyInfo.cs ├── IExternalInterruptPin.cs ├── IEepromMemory.cs ├── Constants.cs ├── IHidCommunicationHandler.cs ├── ExternalInterruptPin.cs ├── INonVoltatileRam.cs ├── IUsbToSpiDevice.cs ├── HidSharpCommunicationHandler.cs ├── EepromMemory.cs ├── Codes.cs ├── Exceptions.cs ├── MCP2210.csproj ├── ISpiDataTransfer.cs ├── UsbToSpiDevice.cs ├── IRamModule.cs ├── VolatileRam.cs ├── SpiDataTransfer.cs ├── NonVolatileRam.cs └── RamBaseModule.cs ├── License.txt ├── README.md ├── Application ├── Properties │ └── AssemblyInfo.cs ├── Tester.csproj └── Program.cs └── MCP2210.sln /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: MCP2210.sln 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | /Application/bin/ 3 | /Application/obj/ 4 | /MCP2210/bin/ 5 | /MCP2210/obj/ 6 | -------------------------------------------------------------------------------- /MCP2210/Libs/HidSharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobizt/MCP2210-Sharp/master/MCP2210/Libs/HidSharp.dll -------------------------------------------------------------------------------- /MCP2210/Libs/HidSharp.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobizt/MCP2210-Sharp/master/MCP2210/Libs/HidSharp.pdb -------------------------------------------------------------------------------- /MCP2210/Libs/HidSharp.tlb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobizt/MCP2210-Sharp/master/MCP2210/Libs/HidSharp.tlb -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Andrea Cervesato 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [![Build Status](https://travis-ci.org/acerv/MCP2210-Sharp.svg?branch=master)](https://travis-ci.org/acerv/MCP2210-Sharp) 4 | 5 | This is a C# (.NET 3.5) library that is built to interface with the Microchip 6 | MCP2210 USB to SPI device. 7 | 8 | ## License 9 | The library is using the MIT License and it's open for commercial usage. 10 | 11 | ## Dependences 12 | The only dependency is HidSharp, a multi-platform library that supports 13 | Windows, MacOS, and Linux (hidraw). You can find it 14 | [here](http://www.zer7.com/software/hidsharp). 15 | The reason why I used this library, is related to its simplicity, documentation 16 | and stability. And, of course, the ISC license, that is compatible with the 17 | MIT one. 18 | 19 | ## General view 20 | The library supports all the features of the MCP2210, which are explained in 21 | the datasheet. 22 | The main interface is given by the `IUsbToSpiDevice`, that contains the modules 23 | used to interface with various parts of the device. 24 | The modules are the following: 25 | 26 | * `INonVoltatileRam`: the non-volatile RAM module 27 | * `IVolatileRam`: the volatile RAM module 28 | * `IExternalInterruptPin`: the external interrupt pin module 29 | * `ISpiDataTransfer`: the SPI data transfer module 30 | * `IEepromMemory`: the EEPROM module 31 | 32 | ## Help & Debug 33 | If you need any help, don't exitate to ask me any question. 34 | 35 | ## Documentation 36 | The library is documented and there's not the wiki page yet. 37 | -------------------------------------------------------------------------------- /Application/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Le informazioni generali relative a un assembly sono controllate dal seguente 6 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni 7 | // associate a un assembly. 8 | [assembly: AssemblyTitle("Application")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Application")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili 18 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da 19 | // COM, impostare su true l'attributo ComVisible per tale tipo. 20 | [assembly: ComVisible(false)] 21 | 22 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi 23 | [assembly: Guid("e59e8624-b7a1-49cc-ae41-e0a58848ceb0")] 24 | 25 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: 26 | // 27 | // Versione principale 28 | // Versione secondaria 29 | // Numero di build 30 | // Revisione 31 | // 32 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build 33 | // usando l'asterisco '*' come illustrato di seguito: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MCP2210/IVolatileRam.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The volatile RAM module, that permits to read/write RAM settings. 28 | /// 29 | public interface IVolatileRam : IRamModule { 30 | /// 31 | /// Setter/Getter for the current pins direction. 32 | /// 33 | PinDirection[] CurrentGpioPinsDirection { get; set; } 34 | 35 | /// 36 | /// Setter/getter for the current GPIO pins value. 37 | /// 38 | bool[] GpioPinsValue { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MCP2210/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // Le informazioni generali relative a un assembly sono controllate dal seguente 7 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni 8 | // associate a un assembly. 9 | [assembly: AssemblyTitle("MCP2210")] 10 | [assembly: AssemblyDescription("MCP2210 library interface")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("MCP2210 library interface")] 14 | [assembly: AssemblyCopyright("Copyright Andrea Cervesato © 2016")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili 19 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da 20 | // COM, impostare su true l'attributo ComVisible per tale tipo. 21 | [assembly: ComVisible(true)] 22 | 23 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi 24 | [assembly: Guid("5c477b5a-a72e-485f-a5e8-964633390cd2")] 25 | 26 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori: 27 | // 28 | // Versione principale 29 | // Versione secondaria 30 | // Numero di build 31 | // Revisione 32 | // 33 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build 34 | // usando l'asterisco '*' come illustrato di seguito: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | [assembly: NeutralResourcesLanguage("en")] 39 | 40 | -------------------------------------------------------------------------------- /MCP2210/IExternalInterruptPin.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The External Interrupt pin event status command is used by the USB host to query 28 | /// the external interrupt events recorded by the MCP2210.In order to have the MCP2210 29 | /// record the number of external interrupt events, GP6 must be configured to have its 30 | /// dedicated function active. 31 | /// 32 | public interface IExternalInterruptPin { 33 | /// 34 | /// This method reads the current number of events from the interrupt pin 35 | /// 36 | /// Is true, the counter will be reset. 37 | /// The number of current events. 38 | int ReadNumberOfEvents(bool resetEventCounter); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MCP2210/IEepromMemory.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The EEPROM memory module. ***USE IT WITH CAUTION*** 28 | /// 29 | public interface IEepromMemory { 30 | /// 31 | /// This method reads a memory address. 32 | /// 33 | /// The memory address to read. 34 | /// The content of the memory address. 35 | byte ReadAddress(byte address); 36 | 37 | /// 38 | /// This method writes a memory address. 39 | /// 40 | /// The memory address to write on. 41 | /// The content to write in the memory address. 42 | void WriteAddress(byte address, byte content); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MCP2210/Constants.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | static class Constants { 27 | /// 28 | /// The vendor ID. 29 | /// 30 | public const int VendorId = 0x04d8; 31 | 32 | /// 33 | /// The product ID. 34 | /// 35 | public const int ProductId = 0x00de; 36 | 37 | /// 38 | /// The Hid packet size. 39 | /// 40 | public const int PacketsSize = 64; 41 | 42 | /// 43 | /// The maximum length of the password. 44 | /// 45 | public const int MaximumPasswordLength = 8; 46 | 47 | /// 48 | /// The number of general purpose lines. 49 | /// 50 | public const int NumberOfGeneralPurposeLines = 9; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MCP2210/IHidCommunicationHandler.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// This is a wrapper around the HID USB communication library. 28 | /// Implement this interface to integrate a new communication library. 29 | /// 30 | interface IHidCommunicationHandler { 31 | /// 32 | /// This method opens the HID device. 33 | /// 34 | void Open(); 35 | 36 | /// 37 | /// This method closes the HID device. 38 | /// 39 | void Close(); 40 | 41 | /// 42 | /// This method writes a command and it reads the reply of the USB device. 43 | /// 44 | /// The command to write. 45 | /// The reply of the device.. 46 | byte[] WriteData(byte[] data); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MCP2210.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCP2210", "MCP2210\MCP2210.csproj", "{5C477B5A-A72E-485F-A5E8-964633390CD2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "Application\Tester.csproj", "{E59E8624-B7A1-49CC-AE41-E0A58848CEB0}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x86 = Debug|x86 14 | Release|Any CPU = Release|Any CPU 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Debug|x86.ActiveCfg = Debug|x86 21 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Debug|x86.Build.0 = Debug|x86 22 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Release|x86.ActiveCfg = Release|x86 25 | {5C477B5A-A72E-485F-A5E8-964633390CD2}.Release|x86.Build.0 = Release|x86 26 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Debug|x86.ActiveCfg = Debug|x86 29 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Debug|x86.Build.0 = Debug|x86 30 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Release|x86.ActiveCfg = Release|x86 33 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0}.Release|x86.Build.0 = Release|x86 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /MCP2210/ExternalInterruptPin.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | class ExternalInterruptPin : IExternalInterruptPin { 29 | private readonly IHidCommunicationHandler _hidHandler; 30 | 31 | public ExternalInterruptPin(IHidCommunicationHandler handler) { 32 | _hidHandler = handler; 33 | } 34 | 35 | public int ReadNumberOfEvents(bool resetEventCounter) { 36 | // create the packet request 37 | byte[] packet = new byte[Constants.PacketsSize]; 38 | packet[0] = CommandCodes.CurrentNumberOfEvents; 39 | packet[1] = (byte)(resetEventCounter ? 0 : 1); 40 | 41 | // write the command on device 42 | byte[] reply = _hidHandler.WriteData(packet); 43 | 44 | // check for reply errors 45 | if (reply[0] != CommandCodes.CurrentNumberOfEvents) { 46 | throw new PacketReplyFormatException(); 47 | } 48 | 49 | // according with the manual, the reply never faults 50 | if (reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 51 | throw new NotImplementedException(); 52 | } 53 | 54 | ushort counts = BitConverter.ToUInt16(packet, 4); 55 | return counts; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MCP2210/INonVoltatileRam.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The non volatile RAM handler. 28 | /// 29 | public interface INonVolatileRam : IRamModule { 30 | /// 31 | /// The manufacter name setter/getter. 32 | /// 33 | string ManufacterName { get; set; } 34 | 35 | /// 36 | /// The product name setter/getter. 37 | /// 38 | string ProductName { get; set; } 39 | 40 | /// 41 | /// This method reads the USB power settings. 42 | /// 43 | UsbKeyPowerSettings ReadUsbSettings(); 44 | 45 | /// 46 | /// This method writes over the USB power-on settings. 47 | /// 48 | /// The USB power-on settings. 49 | void WriteUsbSettings(UsbKeyPowerSettings settings); 50 | } 51 | 52 | /// 53 | /// The USB key power settings. 54 | /// 55 | public struct UsbKeyPowerSettings { 56 | public int PID; 57 | public int VID; 58 | /// 59 | /// The USB requested current in mA. 60 | /// 61 | public int RequestedCurrent; 62 | public bool HostPowered; 63 | public bool SelfPowered; 64 | public bool RemoteWakeUpCapable; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MCP2210/IUsbToSpiDevice.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The MCP2210 device. 28 | /// 29 | public interface IUsbToSpiDevice { 30 | /// 31 | /// This method connects the device. 32 | /// 33 | /// The password to access the device. 34 | void Connect(string password = null); 35 | 36 | /// 37 | /// This method disconnects from the device. 38 | /// 39 | void Disconnect(); 40 | 41 | /// 42 | /// The number of general purpose lines. 43 | /// 44 | int NumberOfGeneralPurposeLines { get; } 45 | 46 | /// 47 | /// The maximum password length. 48 | /// 49 | int MaximumPasswordLength { get; } 50 | 51 | /// 52 | /// This method is used to access the device with a password. 53 | /// 54 | /// The access password. 55 | void AccessWithPassword(string password); 56 | 57 | /// 58 | /// The non volatile RAM module. 59 | /// 60 | INonVolatileRam NonVolatileRam { get; } 61 | 62 | /// 63 | /// The volatile RAM module. 64 | /// 65 | IVolatileRam VolatileRam { get; } 66 | 67 | /// 68 | /// The external interrupt pin module. 69 | /// 70 | IExternalInterruptPin ExternalInterruptPin { get; } 71 | 72 | /// 73 | /// The SPI data transfer module. 74 | /// 75 | ISpiDataTransfer SpiDataTransfer { get; } 76 | 77 | /// 78 | /// The EEPROM handler. 79 | /// 80 | IEepromMemory EEPROM { get; } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /MCP2210/HidSharpCommunicationHandler.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using HidSharp; 26 | using System; 27 | 28 | namespace MCP2210 { 29 | class HidSharpCommunicationHandler : IHidCommunicationHandler { 30 | private static HidDevice _device; 31 | 32 | public HidSharpCommunicationHandler() { 33 | } 34 | 35 | public void Close() { 36 | // No closing methods for the HidDevice. 37 | } 38 | 39 | private static byte[] CreatePacketWithReportId(byte[] packet) { 40 | byte[] dataBytesWithReportId = new byte[packet.Length + 1]; 41 | Array.Copy(packet, 0, dataBytesWithReportId, 1, packet.Length); 42 | return dataBytesWithReportId; 43 | } 44 | 45 | private static byte[] RemoveReportIdFromPacket(byte[] packetWithReportId) { 46 | byte[] usbReplyBytes = new byte[packetWithReportId.Length - 1]; 47 | Array.Copy(packetWithReportId, 1, usbReplyBytes, 0, usbReplyBytes.Length); 48 | return usbReplyBytes; 49 | } 50 | 51 | public byte[] WriteData(byte[] data) { 52 | if (_device == null) { 53 | throw new DeviceNotFoundException(); 54 | } 55 | 56 | HidStream stream; 57 | if (_device.TryOpen(out stream)) { 58 | // get the command with report id 59 | byte[] cmdBytesWithReportId = CreatePacketWithReportId(data); 60 | 61 | // get reply without report id 62 | stream.Write(cmdBytesWithReportId); 63 | byte[] usbReplyBytesWithReportId = stream.Read(); 64 | byte[] usbReplyBytes = RemoveReportIdFromPacket(usbReplyBytesWithReportId); 65 | 66 | return usbReplyBytes; 67 | } 68 | return null; 69 | } 70 | 71 | public void Open() { 72 | HidDeviceLoader loader = new HidDeviceLoader(); 73 | _device = loader.GetDeviceOrDefault(Constants.VendorId, Constants.ProductId); 74 | if (_device == null) { 75 | throw new DeviceNotFoundException(); 76 | } 77 | 78 | _device.Open(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /MCP2210/EepromMemory.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | class EepromMemory : IEepromMemory { 29 | private readonly IHidCommunicationHandler _hidHandler; 30 | 31 | public EepromMemory(IHidCommunicationHandler handler) { 32 | _hidHandler = handler; 33 | } 34 | 35 | public byte ReadAddress(byte address) { 36 | // create the packet 37 | byte[] packet = new byte[Constants.PacketsSize]; 38 | packet[0] = CommandCodes.EEPROMRead; 39 | packet[1] = address; 40 | 41 | // write the packet 42 | byte[] reply = _hidHandler.WriteData(packet); 43 | 44 | // check for reply errors 45 | if (reply[0] != CommandCodes.EEPROMRead || reply[2] != address) { 46 | throw new PacketReplyFormatException(); 47 | } 48 | 49 | // according with the manual, the reply never faults 50 | if (reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 51 | throw new NotImplementedException(); 52 | } 53 | 54 | // return the content of the address 55 | byte content = reply[3]; 56 | return content; 57 | } 58 | 59 | public void WriteAddress(byte address, byte content) { 60 | // create the packet 61 | byte[] packet = new byte[Constants.PacketsSize]; 62 | packet[0] = CommandCodes.EEPROMWrite; 63 | packet[1] = address; 64 | packet[2] = content; 65 | 66 | // write the packet 67 | byte[] reply = _hidHandler.WriteData(packet); 68 | 69 | // check for reply errors 70 | if (reply[0] != CommandCodes.EEPROMWrite) { 71 | throw new PacketReplyFormatException(); 72 | } 73 | 74 | switch (reply[1]) { 75 | case ReplyStatusCodes.CompletedSuccessfully: 76 | break; 77 | case ReplyStatusCodes.EEPROMWriteFailure: 78 | throw new EEPROMWriteFailureException(address); 79 | case ReplyStatusCodes.EEPROMIsPasswordProtectedOrPermanentlyLocked: 80 | throw new EEPROMIsPasswordProtectedOrPermanentlyLockedException(address); 81 | default: 82 | throw new NotImplementedException(); 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Application/Tester.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E59E8624-B7A1-49CC-AE41-E0A58848CEB0} 8 | Exe 9 | Properties 10 | Tester 11 | Tester 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | true 39 | bin\x86\Debug\ 40 | DEBUG;TRACE 41 | full 42 | x86 43 | prompt 44 | MinimumRecommendedRules.ruleset 45 | false 46 | 47 | 48 | bin\x86\Release\ 49 | TRACE 50 | true 51 | pdbonly 52 | x86 53 | prompt 54 | MinimumRecommendedRules.ruleset 55 | false 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | {5c477b5a-a72e-485f-a5e8-964633390cd2} 67 | MCP2210 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /MCP2210/Codes.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | // command codes 27 | internal static class CommandCodes { 28 | public const byte WriteChipParameters = 0x60; 29 | public const byte ReadChipParameters = 0x61; 30 | public const byte GetGpioCurrentChipSettings = 0x20; 31 | public const byte SetGpioCurrentChipSettings = 0x21; 32 | public const byte SetGpioValueSettings = 0x30; 33 | public const byte GetGpioValueSettings = 0x31; 34 | public const byte SetGpioCurrentDirectionSettings = 0x32; 35 | public const byte GetGpioCurrentDirectionSettings = 0x33; 36 | public const byte SetSpiTransferSettings = 0x40; 37 | public const byte GetSpiTransferSettings = 0x41; 38 | public const byte AccessPassword = 0x70; 39 | public const byte ReadCurrentSpiStatus = 0x10; 40 | public const byte CancelCurrentSpiTransfer = 0x11; 41 | public const byte TransferSpiData = 0x42; 42 | public const byte RequestSpiBusRelease = 0x80; 43 | public const byte EEPROMRead = 0x50; 44 | public const byte EEPROMWrite = 0x51; 45 | public const byte CurrentNumberOfEvents = 0x12; 46 | } 47 | 48 | // sub-command codes: used by NVRAM module 49 | internal static class SubCommandCodes { 50 | public const byte SpiPowerUpTransferSettings = 0x10; 51 | public const byte ChipSettingsPowerUpDefault = 0x20; 52 | public const byte UsbPowerUpKeyParameters = 0x30; 53 | public const byte UsbProductName = 0x40; 54 | public const byte UsbManufacturerName = 0x50; 55 | } 56 | 57 | // error codes 58 | internal static class ReplyStatusCodes { 59 | public const byte CompletedSuccessfully = 0x00; 60 | public const byte UnkownCommand = 0xF9; 61 | public const byte BlockedAccess = 0xFB; 62 | public const byte AccessRejected = 0xFC; 63 | public const byte PasswordDoesntMatchChipOnLockedError = 0xFB; 64 | public const byte PasswordDoesntMatchChipOnError = 0xFD; 65 | public const byte SpiBusNotAvailable = 0xF7; 66 | public const byte SpiTransferInProgress = 0xF8; 67 | public const byte SpiBusNotReleased = 0xF8; 68 | public const byte SPITransferFinished = 0x10; 69 | public const byte SPITransferStarted = 0x20; 70 | public const byte SPITransferNotFinished = 0x30; 71 | public const byte UsbTransferInProgress = 0xF8; 72 | public const byte EEPROMWriteFailure = 0xFA; 73 | public const byte EEPROMIsPasswordProtectedOrPermanentlyLocked = 0xFB; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /MCP2210/Exceptions.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | [Serializable] 29 | public class DeviceNotFoundException : Exception { 30 | public DeviceNotFoundException() : 31 | base("Device not found.") { 32 | } 33 | } 34 | 35 | [Serializable] 36 | public class PacketReplyFormatException : Exception { 37 | public PacketReplyFormatException() : 38 | base("The USB reply echoed back the wrong commands. Packet might be corrupted.") { 39 | } 40 | } 41 | 42 | [Serializable] 43 | public class AccessBlockedException : Exception { 44 | public AccessBlockedException() : 45 | base("The access is blocked.") { 46 | } 47 | } 48 | 49 | [Serializable] 50 | public class UsbtransferInProgressException : Exception { 51 | public UsbtransferInProgressException() : 52 | base("Settings not written.") { 53 | } 54 | } 55 | 56 | [Serializable] 57 | public class PasswordAccessRejectedException : Exception { 58 | public PasswordAccessRejectedException() : 59 | base("Password access rejected.") { 60 | } 61 | } 62 | 63 | [Serializable] 64 | public class PasswordDoesntMatchChipOnException : Exception { 65 | public PasswordDoesntMatchChipOnException() : 66 | base("Password doesn't match.") { 67 | } 68 | } 69 | 70 | [Serializable] 71 | public class PasswordMechanismIsLockedException : Exception { 72 | public PasswordMechanismIsLockedException() : 73 | base("Password doesn't match. No more attempts and device is locked.") { 74 | } 75 | } 76 | 77 | [Serializable] 78 | public class SpiBusNotAvailableException : Exception { 79 | public SpiBusNotAvailableException() : 80 | base("SPI bus not available (the external owner has control over it).") { 81 | } 82 | } 83 | 84 | [Serializable] 85 | public class SpiTransferInProgressException : Exception { 86 | public SpiTransferInProgressException() : 87 | base("SPI transfer in progress – cannot accept any data for the moment.") { 88 | } 89 | } 90 | 91 | [Serializable] 92 | public class SpiBusNotReleasedException : Exception { 93 | public SpiBusNotReleasedException() : 94 | base("SPI transfer in process.") { 95 | } 96 | } 97 | 98 | [Serializable] 99 | public class EEPROMIsPasswordProtectedOrPermanentlyLockedException : Exception { 100 | public EEPROMIsPasswordProtectedOrPermanentlyLockedException(byte address) : 101 | base("EEPROM is password protected or permanently locked.\n" + 102 | "Failed to write in the EEPROM \'" + address + "\' address.") { 103 | } 104 | } 105 | 106 | [Serializable] 107 | public class EEPROMWriteFailureException : Exception { 108 | public EEPROMWriteFailureException(byte address) : 109 | base("Failed to write in the EEPROM \'" + address + "\' address.") { 110 | } 111 | } 112 | 113 | [Serializable] 114 | public class UnknownCommandException : Exception { 115 | public UnknownCommandException() : 116 | base("Unknown command.") { 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /MCP2210/MCP2210.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5C477B5A-A72E-485F-A5E8-964633390CD2} 8 | Library 9 | Properties 10 | MCP2210 11 | MCP2210 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | true 37 | Debug %28x86%29\ 38 | DEBUG;TRACE 39 | full 40 | x86 41 | prompt 42 | MinimumRecommendedRules.ruleset 43 | false 44 | false 45 | 46 | 47 | Release %28x86%29\ 48 | TRACE 49 | true 50 | pdbonly 51 | x86 52 | prompt 53 | MinimumRecommendedRules.ruleset 54 | false 55 | Release %28x86%29\MCP2210.xml 56 | true 57 | 58 | 59 | 60 | False 61 | Libs\HidSharp.dll 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 95 | -------------------------------------------------------------------------------- /MCP2210/ISpiDataTransfer.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The SPI data transfer module. 28 | /// 29 | public interface ISpiDataTransfer { 30 | /// 31 | /// This method transfers data into the SPI bus. 32 | /// 33 | /// The data to transfer. 34 | /// The SPI bus return data. 35 | TransferReply Transfer(byte[] data); 36 | 37 | /// 38 | /// This method transfers data into the SPI bus and it waits to read the reply. 39 | /// 40 | /// The data to transfer. 41 | /// Reply timeout. 42 | /// The SPI bus return data. 43 | TransferReply TransferAndRead(byte[] data, int timeoutMS); 44 | 45 | /// 46 | /// This method cancel the current SPI data transfer. 47 | /// 48 | /// The cancel response. 49 | SpiEngineStatus CancelCurrentTransfer(); 50 | 51 | /// 52 | /// This method requests to release the SPI bus. 53 | /// When SPI bus is released and the GP7 is assigned to its dedicated function, 54 | /// the pin will be used by the module to set its digital status. You can choose 55 | /// that particular status with this method. 56 | /// 57 | /// This is the status of the GP7, when it's assigned to its 58 | /// dedicated function. 59 | void RequestSpiBusRelease(bool gp7ReleaseStatus = true); 60 | 61 | /// 62 | /// This method reads the current SPI engine status. 63 | /// 64 | /// The SPI engine status. 65 | SpiEngineStatus ReadEngineStatus(); 66 | } 67 | 68 | public enum SpiTransferStatus { 69 | /// 70 | /// SPI Data Accepted. The SPI Transfer will start afterwards. 71 | /// 72 | Started, 73 | 74 | /// 75 | /// SPI Engine waiting for more data packets to complete the SPI Transfer. 76 | /// 77 | Waiting, 78 | 79 | /// 80 | /// SPI Transfer Ended. The response will contain the last received SPI data 81 | /// packet of the SPI Transfer. 82 | /// 83 | Ended 84 | } 85 | 86 | /// 87 | /// This reply is returned all the times a SPI transfer call is performed. 88 | /// 89 | public struct TransferReply { 90 | /// 91 | /// The SPI transfer status. 92 | /// 93 | public SpiTransferStatus TransferStatus; 94 | 95 | /// 96 | /// The last received SPI data packet. 97 | /// 98 | public byte[] Data; 99 | } 100 | 101 | /// 102 | /// The SPI bus owner. 103 | /// 104 | public enum SpiBusOwner { 105 | NoOwner, 106 | UsbBridge, 107 | ExternalMaster 108 | } 109 | 110 | /// 111 | /// This response contains the status of the SPI bus. 112 | /// 113 | public struct SpiEngineStatus { 114 | /// 115 | /// The status of the bus. 116 | /// 117 | public bool ExternalRequestPending; 118 | 119 | /// 120 | /// The bus owner transfer. 121 | /// 122 | public SpiBusOwner BusOwner; 123 | 124 | /// 125 | /// Informs the USB host on how many times the NVRAM password was tried. 126 | /// 127 | public int AttemptedPasswordAccesses; 128 | 129 | /// 130 | /// True when the password is correct. 131 | /// 132 | public bool PasswordGuessed; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /MCP2210/UsbToSpiDevice.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | public class UsbToSpiDevice : IUsbToSpiDevice { 29 | private readonly IHidCommunicationHandler _hidComHandler; 30 | private readonly IExternalInterruptPin _extInterruptPin; 31 | private readonly ISpiDataTransfer _spiDataTransfer; 32 | private readonly INonVolatileRam _nvram; 33 | private readonly IVolatileRam _ram; 34 | private readonly IEepromMemory _eeprom; 35 | 36 | public UsbToSpiDevice() { 37 | _hidComHandler = new HidSharpCommunicationHandler(); 38 | _nvram = new NonVolatileRam(_hidComHandler); 39 | _ram = new VolatileRam(_hidComHandler); 40 | _extInterruptPin = new ExternalInterruptPin(_hidComHandler); 41 | _spiDataTransfer = new SpiDataTransfer(_hidComHandler); 42 | _eeprom = new EepromMemory(_hidComHandler); 43 | } 44 | 45 | ~UsbToSpiDevice() { 46 | _hidComHandler.Close(); 47 | } 48 | 49 | public IExternalInterruptPin ExternalInterruptPin { 50 | get { return _extInterruptPin; } 51 | } 52 | 53 | public INonVolatileRam NonVolatileRam { 54 | get { return _nvram; } 55 | } 56 | 57 | public IVolatileRam VolatileRam { 58 | get { return _ram; } 59 | } 60 | 61 | public ISpiDataTransfer SpiDataTransfer { 62 | get { return _spiDataTransfer; } 63 | } 64 | 65 | public void Connect(string password = null) { 66 | // open device 67 | _hidComHandler.Open(); 68 | 69 | if (!string.IsNullOrEmpty(password)) { 70 | AccessWithPassword(password); 71 | } 72 | } 73 | 74 | public void Disconnect() { 75 | _hidComHandler.Close(); 76 | } 77 | 78 | public int MaximumPasswordLength { 79 | get { return Constants.MaximumPasswordLength; } 80 | } 81 | 82 | public int NumberOfGeneralPurposeLines { 83 | get { return Constants.NumberOfGeneralPurposeLines; } 84 | } 85 | 86 | public IEepromMemory EEPROM { 87 | get { return _eeprom; } 88 | } 89 | 90 | public void AccessWithPassword(string password) { 91 | // create the packet 92 | byte[] packet = new byte[Constants.PacketsSize]; 93 | packet[0] = CommandCodes.AccessPassword; 94 | 95 | string subPassword = ""; 96 | if (password.Length > Constants.MaximumPasswordLength) { 97 | subPassword = password.Substring(0, Constants.MaximumPasswordLength); 98 | } else { 99 | subPassword = password; 100 | } 101 | 102 | for (int i = 0; i < Constants.MaximumPasswordLength; i++) { 103 | if (password.Length > i) { 104 | packet[i + 4] = BitConverter.GetBytes(password[i])[0]; 105 | } else { 106 | packet[i + 4] = 0x00; 107 | } 108 | } 109 | 110 | // send password access 111 | byte[] reply = _hidComHandler.WriteData(packet); 112 | 113 | if (reply[0] != CommandCodes.AccessPassword) { 114 | throw new PacketReplyFormatException(); 115 | } 116 | 117 | // check for errors 118 | switch (reply[1]) { 119 | case ReplyStatusCodes.CompletedSuccessfully: 120 | break; 121 | case ReplyStatusCodes.AccessRejected: 122 | throw new PasswordAccessRejectedException(); 123 | case ReplyStatusCodes.PasswordDoesntMatchChipOnError: 124 | throw new PasswordDoesntMatchChipOnException(); 125 | case ReplyStatusCodes.PasswordDoesntMatchChipOnLockedError: 126 | throw new PasswordMechanismIsLockedException(); 127 | default: 128 | throw new NotImplementedException(); 129 | } 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /MCP2210/IRamModule.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | namespace MCP2210 { 26 | /// 27 | /// The generic RAM module. 28 | /// 29 | public interface IRamModule { 30 | /// 31 | /// This method configures the chip settings, such as the 32 | /// pins modes and the pins direction (I/O). 33 | /// 34 | /// The chip settings. 35 | void ConfigureChip(ChipSettings settings); 36 | 37 | /// 38 | /// This method reads the current chip configuration. 39 | /// 40 | /// The current chip configuration. 41 | ChipSettings ReadChipConfiguration(); 42 | 43 | /// 44 | /// This method configure the SPI transaction. 45 | /// 46 | /// The SPI setup configuration. 47 | void ConfigureSpi(SpiSetup setup); 48 | 49 | /// 50 | /// This method returns the current SPI configuration. 51 | /// 52 | SpiSetup ReadSpiConfiguration(); 53 | } 54 | 55 | public enum SpiModes { 56 | /// 57 | /// CPOL = 0 58 | /// CPHA = 0 59 | /// 60 | Spi0 = 0, 61 | 62 | /// 63 | /// CPOL = 1 64 | /// CPHA = 0 65 | /// 66 | Spi1, 67 | 68 | /// 69 | /// CPOL = 0 70 | /// CPHA = 1 71 | /// 72 | Spi2, 73 | 74 | /// 75 | /// CPOL = 1 76 | /// CPHA = 1 77 | /// 78 | Spi3 79 | } 80 | 81 | public struct SpiSetup { 82 | /// 83 | /// The SPI mode. 84 | /// 85 | public SpiModes Mode; 86 | 87 | /// 88 | /// The SPI bitrate. 89 | /// 90 | public long BitRate; 91 | 92 | /// 93 | /// The number of bytes to transfer. 94 | /// 95 | public int BytesToTransfer; 96 | 97 | /// 98 | /// An array that represents the status of the chip select lines 99 | /// when they are idle. 100 | /// 101 | public bool[] IdleChipSelectValues; 102 | 103 | /// 104 | /// An array that represents the status of the chip select lines 105 | /// when they are active. 106 | /// 107 | public bool[] ActiveChipSelectValues; 108 | 109 | /// 110 | /// Delay in us between chip select and data byte. Quanta is 100us. 111 | /// i.e. set 5 for 500us. 112 | /// 113 | public int ChipSelectToDataDelay; 114 | 115 | /// 116 | /// Delay in us between data bytes. Quanta is 100us. 117 | /// i.e. set 5 for 500us. 118 | /// 119 | public int BetweenDataDelay; 120 | 121 | /// 122 | /// Delay in us between the last data byte and chip select. Quanta is 100us. 123 | /// i.e. set 5 for 500us. 124 | /// 125 | public int DataToChipSelectDelay; 126 | } 127 | 128 | /// 129 | /// The degital pin modes. 130 | /// 131 | public enum PinMode { 132 | /// 133 | /// General purpose I/O. 134 | /// 135 | GPIO = 0, 136 | 137 | /// 138 | /// SPI chip select. 139 | /// 140 | ChipSelects, 141 | 142 | /// 143 | /// Dedicated device function. 144 | /// 145 | DedicatedFunction 146 | } 147 | 148 | /// 149 | /// The digital pin direction. 150 | /// 151 | public enum PinDirection { 152 | Output = 0, 153 | Input 154 | } 155 | 156 | /// 157 | /// The dedicated functions of the general purpose lines. 158 | /// 159 | public enum DedicatedFunction { 160 | NoInterruptCounting = 0, 161 | CountFallingEdges, 162 | CountRisingEdges, 163 | CountLowPulses, 164 | CountHighPulses 165 | } 166 | 167 | public enum NramChipAccessControl { 168 | /// 169 | /// Chip settings not protected. 170 | /// 171 | NotProtected, 172 | 173 | /// 174 | /// Chip settings protected by password access. 175 | /// 176 | PasswordProtected, 177 | 178 | /// 179 | /// Chip settings permanently locked. 180 | /// 181 | PermanentlyLocked 182 | } 183 | 184 | /// 185 | /// The chip settings. 186 | /// 187 | public struct ChipSettings { 188 | /// 189 | /// The pin modes array. 190 | /// 191 | public PinMode[] PinModes; 192 | 193 | /// 194 | /// The pin directions array. 195 | /// 196 | public PinDirection[] PinDirections; 197 | 198 | /// 199 | /// The default output of the pins. 200 | /// 201 | public bool[] DefaultOutput; 202 | 203 | /// 204 | /// Enable/Disable the remote wake up. 205 | /// 206 | public bool RemoteWakeUpEnabled; 207 | 208 | /// 209 | /// The interrupt bit mode. 210 | /// 211 | public DedicatedFunction InterruptBitMode; 212 | 213 | /// 214 | /// If true, the SPI bus is released between transfer. 215 | /// 216 | public bool SpiBusReleaseEnable; 217 | 218 | /// 219 | /// The password to use for locking the device. 220 | /// This parameters is not used when RAM is volatile, 221 | /// as well when the owner structure is a reply. 222 | /// 223 | public string Password; 224 | 225 | /// 226 | /// This status is used to protected the device. 227 | /// If writing the chip settings, the access control 228 | /// will be used according with the Password setting. 229 | /// If reading the chip settings, the access control 230 | /// will be set with the current access control. 231 | /// 232 | public NramChipAccessControl AccessControl; 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /MCP2210/VolatileRam.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | class VolatileRam : RamBaseModule, IVolatileRam { 29 | private readonly IHidCommunicationHandler _hidHandler; 30 | 31 | public VolatileRam(IHidCommunicationHandler handler) : 32 | base (handler, true) { 33 | _hidHandler = handler; 34 | } 35 | 36 | #region Public 37 | 38 | public PinDirection[] CurrentGpioPinsDirection { 39 | get { 40 | // create the command 41 | byte[] packet = new byte[Constants.PacketsSize]; 42 | packet[0] = CommandCodes.GetGpioCurrentDirectionSettings; 43 | 44 | // send the packet 45 | byte[] reply = _hidHandler.WriteData(packet); 46 | 47 | // according with the manual, this command never faults 48 | if (reply[0] != CommandCodes.GetGpioCurrentDirectionSettings || 49 | reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 50 | throw new NotImplementedException(); 51 | } 52 | 53 | // read the directions 54 | PinDirection[] direction = new PinDirection[Constants.NumberOfGeneralPurposeLines]; 55 | ushort directionValue = BitConverter.ToUInt16(reply, 4); 56 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 57 | int bitMask = (int)Math.Pow(2, i); 58 | if ((directionValue & bitMask) == bitMask) { 59 | direction[i] = PinDirection.Output; 60 | } else { 61 | direction[i] = PinDirection.Input; 62 | } 63 | } 64 | 65 | return direction; 66 | } 67 | 68 | set { 69 | // check input argument 70 | if (value == null || value.Length != Constants.NumberOfGeneralPurposeLines) { 71 | throw new ArgumentException("Expected non-null and " + Constants.NumberOfGeneralPurposeLines + " length digital direction array."); 72 | } 73 | 74 | // create the packet 75 | byte[] packet = new byte[Constants.PacketsSize]; 76 | packet[0] = CommandCodes.SetGpioCurrentDirectionSettings; 77 | 78 | PinDirection[] direction = value; 79 | ushort directionValue = 0; 80 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 81 | ushort bitValue = (ushort)Math.Pow(2, i); 82 | if (direction[i] == PinDirection.Output) { 83 | directionValue |= bitValue; 84 | } 85 | } 86 | 87 | byte[] dirBytes = BitConverter.GetBytes(directionValue); 88 | packet[4] = dirBytes[0]; 89 | packet[5] = dirBytes[1]; 90 | 91 | // send the packet 92 | byte[] reply = _hidHandler.WriteData(packet); 93 | 94 | // according with the manual, this command never faults 95 | if (reply[0] != CommandCodes.SetGpioCurrentDirectionSettings || 96 | reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 97 | throw new NotImplementedException(); 98 | } 99 | } 100 | } 101 | 102 | public bool[] GpioPinsValue { 103 | get { 104 | // create the packet 105 | byte[] packet = new byte[Constants.PacketsSize]; 106 | packet[0] = CommandCodes.GetGpioCurrentDirectionSettings; 107 | 108 | // send the packet 109 | byte[] reply = _hidHandler.WriteData(packet); 110 | 111 | // according with the manual, this command never faults 112 | if (reply[0] != CommandCodes.GetGpioCurrentDirectionSettings || 113 | reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 114 | throw new NotImplementedException(); 115 | } 116 | 117 | // read the directions 118 | bool[] outputValue = new bool[Constants.NumberOfGeneralPurposeLines]; 119 | ushort directionValue = BitConverter.ToUInt16(reply, 4); 120 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 121 | ushort bitMask = (ushort)Math.Pow(2, i); 122 | outputValue[i] = (directionValue & bitMask) == bitMask; 123 | } 124 | 125 | return outputValue; 126 | } 127 | 128 | set { 129 | // check input argument 130 | if (value == null || value.Length != Constants.NumberOfGeneralPurposeLines) { 131 | throw new ArgumentException("Expected non-null and " + Constants.NumberOfGeneralPurposeLines + " length output array."); 132 | } 133 | 134 | // create the packet 135 | byte[] packet = new byte[Constants.PacketsSize]; 136 | packet[0] = CommandCodes.SetGpioCurrentDirectionSettings; 137 | 138 | bool[] outputValue = value; 139 | ushort directionValue = 0; 140 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 141 | ushort bitValue = (ushort)Math.Pow(2, i); 142 | if (outputValue[i]) { 143 | directionValue |= bitValue; 144 | } 145 | } 146 | 147 | byte[] dirBytes = BitConverter.GetBytes(directionValue); 148 | packet[4] = dirBytes[0]; 149 | packet[5] = dirBytes[1]; 150 | 151 | // send the packet 152 | byte[] reply = _hidHandler.WriteData(packet); 153 | 154 | // according with the manual, this command never faults 155 | if (reply[0] != CommandCodes.SetGpioCurrentDirectionSettings || 156 | reply[1] != ReplyStatusCodes.CompletedSuccessfully) { 157 | throw new NotImplementedException(); 158 | } 159 | } 160 | } 161 | 162 | public void ConfigureChip(ChipSettings settings) { 163 | ConfigureChip(settings, CommandCodes.SetGpioCurrentChipSettings); 164 | } 165 | 166 | public void ConfigureSpi(SpiSetup setup) { 167 | ConfigureSpi(setup, CommandCodes.SetSpiTransferSettings); 168 | } 169 | 170 | public ChipSettings ReadChipConfiguration() { 171 | ChipSettings settings = ReadChipConfiguration(CommandCodes.GetGpioCurrentChipSettings); 172 | return settings; 173 | } 174 | 175 | public SpiSetup ReadSpiConfiguration() { 176 | SpiSetup setup = ReadSpiConfiguration(CommandCodes.GetSpiTransferSettings); 177 | return setup; 178 | } 179 | 180 | #endregion 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /MCP2210/SpiDataTransfer.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | using System.Threading; 27 | 28 | namespace MCP2210 { 29 | class SpiDataTransfer : ISpiDataTransfer { 30 | private readonly IHidCommunicationHandler _hidHandler; 31 | 32 | public SpiDataTransfer(IHidCommunicationHandler handler) { 33 | _hidHandler = handler; 34 | } 35 | 36 | private static SpiEngineStatus GetSpiEngineStatusFromBytes(byte[] data) { 37 | // according with the manual, the command never faults 38 | SpiEngineStatus response = new SpiEngineStatus(); 39 | response.ExternalRequestPending = data[2] == 0; 40 | 41 | switch (data[3]) { 42 | case 0: 43 | response.BusOwner = SpiBusOwner.NoOwner; 44 | break; 45 | case 1: 46 | response.BusOwner = SpiBusOwner.UsbBridge; 47 | break; 48 | case 2: 49 | response.BusOwner = SpiBusOwner.ExternalMaster; 50 | break; 51 | default: 52 | throw new NotImplementedException(); 53 | } 54 | 55 | response.AttemptedPasswordAccesses = data[4]; 56 | response.PasswordGuessed = data[5] == 1; 57 | 58 | return response; 59 | } 60 | 61 | public SpiEngineStatus CancelCurrentTransfer() { 62 | // create the packet 63 | byte[] packet = new byte[Constants.PacketsSize]; 64 | packet[0] = CommandCodes.CancelCurrentSpiTransfer; 65 | 66 | // send the packet 67 | byte[] reply = _hidHandler.WriteData(packet); 68 | 69 | // check for errors 70 | if (reply[0] != CommandCodes.CancelCurrentSpiTransfer) { 71 | throw new PacketReplyFormatException(); 72 | } 73 | 74 | // according with the manual, the command never faults 75 | SpiEngineStatus response = GetSpiEngineStatusFromBytes(reply); 76 | return response; 77 | } 78 | 79 | public void RequestSpiBusRelease(bool gp7ReleaseStatus = true) { 80 | // create the packet 81 | byte[] packet = new byte[Constants.PacketsSize]; 82 | packet[0] = CommandCodes.RequestSpiBusRelease; 83 | 84 | // assign the release status bit 85 | packet[1] = (byte)(gp7ReleaseStatus ? 1 : 0); 86 | 87 | // send the packet 88 | byte[] reply = _hidHandler.WriteData(packet); 89 | 90 | // check for errors 91 | switch (reply[1]) { 92 | case ReplyStatusCodes.CompletedSuccessfully: 93 | break; 94 | case ReplyStatusCodes.SpiBusNotReleased: 95 | throw new SpiBusNotReleasedException(); 96 | default: 97 | throw new NotImplementedException(); 98 | } 99 | } 100 | 101 | public TransferReply Transfer(byte[] data) { 102 | // 0 to 60 inclusively is the maximum length of data (64bytes SPI data minus 4bytes header) 103 | if (data == null || data.Length > 60) { 104 | throw new ArgumentException("Spi data transfer must be non-null and should not exceed 60 bytes size."); 105 | } 106 | 107 | // create the packet 108 | byte[] packet = new byte[Constants.PacketsSize]; 109 | packet[0] = CommandCodes.TransferSpiData; 110 | packet[1] = (byte)data.Length; 111 | 112 | for (int i = 0; i < data.Length; i++) { 113 | packet[i + 4] = data[i]; 114 | } 115 | 116 | // write on device and read the reply 117 | byte[] reply = _hidHandler.WriteData(packet); 118 | 119 | // check for errors 120 | if (reply[0] != CommandCodes.TransferSpiData) { 121 | throw new PacketReplyFormatException(); 122 | } 123 | 124 | switch (reply[1]) { 125 | case ReplyStatusCodes.CompletedSuccessfully: 126 | break; 127 | case ReplyStatusCodes.SpiBusNotAvailable: 128 | throw new SpiBusNotAvailableException(); 129 | case ReplyStatusCodes.SpiTransferInProgress: 130 | throw new SpiTransferInProgressException(); 131 | default: 132 | throw new NotImplementedException(); 133 | } 134 | 135 | // create the reply data 136 | TransferReply transfReply = new TransferReply(); 137 | 138 | switch (reply[3]) { 139 | case ReplyStatusCodes.SPITransferStarted: 140 | transfReply.TransferStatus = SpiTransferStatus.Started; 141 | break; 142 | case ReplyStatusCodes.SPITransferNotFinished: 143 | transfReply.TransferStatus = SpiTransferStatus.Waiting; 144 | break; 145 | case ReplyStatusCodes.SPITransferFinished: 146 | transfReply.TransferStatus = SpiTransferStatus.Ended; 147 | break; 148 | default: 149 | throw new NotImplementedException(); 150 | } 151 | 152 | // read the SPI return data 153 | int dataLength = reply[2]; 154 | transfReply.Data = new byte[dataLength]; 155 | for (int i = 0; i < dataLength; i++) { 156 | transfReply.Data[i] = reply[i + 4]; 157 | } 158 | 159 | return transfReply; 160 | } 161 | 162 | public TransferReply TransferAndRead(byte[] data, int timeoutMS) { 163 | // send the first command 164 | // 0 to 60 inclusively is the maximum length of data (64bytes SPI data minus 4bytes header) 165 | if (data == null || data.Length > 60) { 166 | throw new ArgumentException("Spi data transfer must be non-null and should not exceed 60 bytes size."); 167 | } 168 | 169 | // create the packet 170 | byte[] packet = new byte[Constants.PacketsSize]; 171 | packet[0] = CommandCodes.TransferSpiData; 172 | packet[1] = (byte)data.Length; 173 | 174 | for (int i = 0; i < data.Length; i++) { 175 | packet[i + 4] = data[i]; 176 | } 177 | 178 | // write on device and read the reply 179 | byte[] reply = _hidHandler.WriteData(packet); 180 | 181 | // check for errors 182 | if (reply[0] != CommandCodes.TransferSpiData) { 183 | throw new PacketReplyFormatException(); 184 | } 185 | 186 | // continuously read the SPI bus status and wait till the data is ready 187 | DateTime timeout = DateTime.Now.AddMilliseconds(timeoutMS); 188 | 189 | while (reply[3] != ReplyStatusCodes.SPITransferFinished) { 190 | // check for timeout 191 | if (timeout <= DateTime.Now) { 192 | throw new TimeoutException("SPI device is not replying."); 193 | } 194 | 195 | reply = _hidHandler.WriteData(packet); 196 | } 197 | 198 | // create the reply data 199 | TransferReply transfReply = new TransferReply(); 200 | 201 | switch (reply[3]) { 202 | case ReplyStatusCodes.SPITransferStarted: 203 | transfReply.TransferStatus = SpiTransferStatus.Started; 204 | break; 205 | case ReplyStatusCodes.SPITransferNotFinished: 206 | transfReply.TransferStatus = SpiTransferStatus.Waiting; 207 | break; 208 | case ReplyStatusCodes.SPITransferFinished: 209 | transfReply.TransferStatus = SpiTransferStatus.Ended; 210 | break; 211 | default: 212 | throw new NotImplementedException(); 213 | } 214 | 215 | // read the SPI return data 216 | int dataLength = reply[2]; 217 | transfReply.Data = new byte[dataLength]; 218 | for (int i = 0; i < dataLength; i++) { 219 | transfReply.Data[i] = reply[i + 4]; 220 | } 221 | 222 | return transfReply; 223 | } 224 | 225 | public SpiEngineStatus ReadEngineStatus() { 226 | // create the packet 227 | byte[] packet = new byte[Constants.PacketsSize]; 228 | packet[0] = CommandCodes.ReadCurrentSpiStatus; 229 | 230 | // send the packet 231 | byte[] reply = _hidHandler.WriteData(packet); 232 | 233 | // check for errors 234 | if (reply[0] != CommandCodes.ReadCurrentSpiStatus) { 235 | throw new PacketReplyFormatException(); 236 | } 237 | 238 | // get the response 239 | SpiEngineStatus response = GetSpiEngineStatusFromBytes(reply); 240 | return response; 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /MCP2210/NonVolatileRam.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | using System.Text; 27 | 28 | namespace MCP2210 { 29 | class NonVolatileRam : RamBaseModule, INonVolatileRam { 30 | private readonly IHidCommunicationHandler _hidHandler; 31 | 32 | public NonVolatileRam(IHidCommunicationHandler handler) : 33 | base (handler, true) { 34 | _hidHandler = handler; 35 | } 36 | 37 | #region Private 38 | 39 | private string ReadString(byte subcommand) { 40 | // create the packet 41 | byte[] packet = new byte[Constants.PacketsSize]; 42 | packet[0] = CommandCodes.ReadChipParameters; 43 | packet[1] = subcommand; 44 | byte[] reply = _hidHandler.WriteData(packet); 45 | 46 | // check if package format is faulty 47 | if (reply[0] != CommandCodes.ReadChipParameters || reply[2] != subcommand) { 48 | throw new PacketReplyFormatException(); 49 | } 50 | 51 | int length = reply[4]; 52 | string desc = Encoding.Unicode.GetString(reply, 6, length - 2); 53 | return desc; 54 | } 55 | 56 | private void WriteString(byte subcommand, string name) { 57 | // create the packet 58 | // command byte length is 64 59 | byte[] packet = new byte[Constants.PacketsSize]; 60 | 61 | //0x60 – Set Chip NVRAM Parameters – command code 62 | packet[0] = CommandCodes.WriteChipParameters; 63 | //0x50 – Set USB Manufacturer Name – sub-command code 64 | //0x40 – Set USB Product Name – sub-command code 65 | packet[1] = subcommand; 66 | 67 | //0x00 – Reserved 68 | //packet[2] = 0; 69 | //0x00 – Reserved 70 | //packet[3] = 0; 71 | 72 | // set the length of the string 73 | int length = name.Length * 2 + 2; 74 | 75 | //Total USB String Descriptor Length (this is the length of the Manufacturer string, multiplied by 2 + 2) 76 | packet[4] = (byte)(length); 77 | 78 | // from manual DS22288A-page 20: always fill the 6th byte with 0x03 79 | //USB String Descriptor ID – always fill with 0x03 80 | packet[5] = 0x03; 81 | 82 | // set the string 83 | //fill the unicode Character Low Byte followed by High Byte for each char 84 | byte[] nameBytes = Encoding.Unicode.GetBytes(name); 85 | for (int i = 0; i < nameBytes.Length; i++) { 86 | if (i > Constants.PacketsSize) { 87 | break; 88 | } 89 | packet[6 + i] = nameBytes[i]; 90 | } 91 | 92 | // write the data 93 | byte[] reply = _hidHandler.WriteData(packet); 94 | 95 | // check for errors 96 | //0x60 – Set Chip NVRAM Parameters – echos back the given command code 97 | if (reply[0] != CommandCodes.WriteChipParameters) { 98 | throw new PacketReplyFormatException(); 99 | } 100 | 101 | switch (reply[1]) { 102 | //0x00 – Command Completed Successfully – settings written 103 | case ReplyStatusCodes.CompletedSuccessfully: 104 | break; 105 | //0xFB – Blocked Access – The provided password is not matching the one stored in the chip or the 106 | //settings are permanently locked. 107 | case ReplyStatusCodes.BlockedAccess: 108 | throw new AccessBlockedException(); 109 | default: 110 | throw new NotImplementedException(); 111 | } 112 | } 113 | 114 | #endregion 115 | 116 | #region Public 117 | 118 | public string ManufacterName { 119 | get { 120 | string str = ReadString(SubCommandCodes.UsbManufacturerName); 121 | return str; 122 | } 123 | 124 | set { 125 | if (string.IsNullOrEmpty(value)) { 126 | return; 127 | } 128 | 129 | WriteString(SubCommandCodes.UsbManufacturerName, value); 130 | } 131 | } 132 | 133 | public string ProductName { 134 | get { 135 | string str = ReadString(SubCommandCodes.UsbProductName); 136 | return str; 137 | } 138 | 139 | set { 140 | if (string.IsNullOrEmpty(value)) { 141 | return; 142 | } 143 | 144 | WriteString(SubCommandCodes.UsbProductName, value); 145 | } 146 | } 147 | 148 | public void ConfigureChip(ChipSettings settings) { 149 | ConfigureChip( 150 | settings, 151 | CommandCodes.WriteChipParameters, 152 | SubCommandCodes.ChipSettingsPowerUpDefault); 153 | } 154 | 155 | public ChipSettings ReadChipConfiguration() { 156 | ChipSettings settings = ReadChipConfiguration( 157 | CommandCodes.ReadChipParameters, 158 | SubCommandCodes.ChipSettingsPowerUpDefault); 159 | return settings; 160 | } 161 | 162 | public void ConfigureSpi(SpiSetup setup) { 163 | ConfigureSpi( 164 | setup, 165 | CommandCodes.WriteChipParameters, 166 | SubCommandCodes.SpiPowerUpTransferSettings); 167 | } 168 | 169 | public SpiSetup ReadSpiConfiguration() { 170 | SpiSetup setup = ReadSpiConfiguration( 171 | CommandCodes.ReadChipParameters, 172 | SubCommandCodes.SpiPowerUpTransferSettings); 173 | return setup; 174 | } 175 | 176 | public UsbKeyPowerSettings ReadUsbSettings() { 177 | // create the packet 178 | byte[] packet = new byte[Constants.PacketsSize]; 179 | packet[0] = CommandCodes.ReadChipParameters; 180 | packet[1] = SubCommandCodes.UsbPowerUpKeyParameters; 181 | byte[] reply = _hidHandler.WriteData(packet); 182 | 183 | // check if package format is faulty 184 | if (reply[0] != CommandCodes.ReadChipParameters || 185 | reply[2] != SubCommandCodes.UsbPowerUpKeyParameters) { 186 | throw new PacketReplyFormatException(); 187 | } 188 | 189 | // create the settings 190 | UsbKeyPowerSettings settings = new UsbKeyPowerSettings(); 191 | settings.VID = Convert.ToInt32(BitConverter.ToUInt16(reply, 12)); 192 | settings.PID = Convert.ToInt32(BitConverter.ToUInt16(reply, 14)); 193 | settings.RequestedCurrent = Convert.ToInt32(reply[30]) * 2; // 2mA Quanta 194 | settings.RemoteWakeUpCapable = (reply[29] & 32) == 32; 195 | settings.SelfPowered = (reply[29] & 64) == 64; 196 | settings.HostPowered = (reply[29] & 128) == 128; 197 | 198 | return settings; 199 | } 200 | 201 | public void WriteUsbSettings(UsbKeyPowerSettings settings) { 202 | // get VID & pid bytes 203 | byte[] vidBytes = BitConverter.GetBytes(Convert.ToUInt16(settings.VID)); 204 | byte[] pidBytes = BitConverter.GetBytes(Convert.ToUInt16(settings.PID)); 205 | 206 | // get chip power options 207 | byte cpOptionsByte = 0x00; 208 | cpOptionsByte |= (byte)(settings.RemoteWakeUpCapable ? 32 : 0); // 0010 0000 209 | cpOptionsByte |= (byte)(settings.SelfPowered ? 64 : 0); // 0100 0000 210 | cpOptionsByte |= (byte)(settings.HostPowered ? 128 : 0); // 1000 0000 211 | 212 | // get current bytes 213 | byte currentByte = Convert.ToByte(settings.RequestedCurrent / 2); 214 | 215 | // create the package 216 | byte[] packet = new byte[Constants.PacketsSize]; 217 | packet[0] = CommandCodes.WriteChipParameters; 218 | packet[1] = SubCommandCodes.UsbPowerUpKeyParameters; 219 | packet[4] = vidBytes[0]; 220 | packet[5] = vidBytes[1]; 221 | packet[6] = pidBytes[0]; 222 | packet[7] = pidBytes[1]; 223 | packet[8] = cpOptionsByte; 224 | packet[9] = currentByte; 225 | 226 | // write the packet 227 | byte[] reply = _hidHandler.WriteData(packet); 228 | 229 | // check if package format is faulty 230 | if (reply[0] != CommandCodes.WriteChipParameters || 231 | reply[2] != SubCommandCodes.UsbPowerUpKeyParameters) { 232 | throw new PacketReplyFormatException(); 233 | } 234 | 235 | switch (reply[1]) { 236 | case ReplyStatusCodes.CompletedSuccessfully: 237 | break; 238 | case ReplyStatusCodes.BlockedAccess: 239 | throw new AccessBlockedException(); 240 | default: 241 | throw new NotImplementedException(); 242 | } 243 | } 244 | 245 | #endregion 246 | } 247 | } -------------------------------------------------------------------------------- /Application/Program.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using MCP2210; 26 | using System; 27 | using System.Text; 28 | 29 | namespace Application { 30 | class Program { 31 | 32 | private const int NumberOfBytes = 16; 33 | private const string Password = "123456"; 34 | 35 | static void Main() { 36 | // create device 37 | IUsbToSpiDevice device = new UsbToSpiDevice(); 38 | device.Connect(Password); 39 | 40 | // test device modules 41 | TestNonVoltatileRam(device.NonVolatileRam); 42 | TestVoltatileRam(device.VolatileRam); 43 | TestExternalInterruptPin(device.ExternalInterruptPin); 44 | TestSpiDataTransfer(device.SpiDataTransfer); 45 | TestEeprom(device.EEPROM); 46 | 47 | // disconnect the device 48 | device.Disconnect(); 49 | 50 | // close when the user wants to 51 | Console.WriteLine("Press enter to close..."); 52 | Console.ReadLine(); 53 | } 54 | 55 | static void PrintException(Exception ex) { 56 | StringBuilder sb = new StringBuilder(); 57 | sb.AppendLine("\n"); 58 | sb.AppendLine("***************ERRROR**************"); 59 | sb.AppendLine(); 60 | sb.AppendLine(ex.Message); 61 | sb.AppendLine(ex.StackTrace); 62 | sb.AppendLine(); 63 | sb.AppendLine("***********************************"); 64 | sb.AppendLine(); 65 | 66 | Console.WriteLine(sb.ToString()); 67 | } 68 | 69 | static void TestNonVoltatileRam(INonVolatileRam nvram) { 70 | Console.Write("*** Test NVRAM: "); 71 | 72 | try { 73 | // read/write manufacters and product names 74 | string manufacterName = nvram.ManufacterName; 75 | string productName = nvram.ProductName; 76 | 77 | nvram.ManufacterName = "Myself"; 78 | nvram.ProductName = "SomeProduct"; 79 | 80 | string manufacterNameAfter = nvram.ManufacterName; 81 | string productNameAfter = nvram.ProductName; 82 | 83 | nvram.ManufacterName = manufacterName; 84 | nvram.ProductName = productName; 85 | 86 | // read USB settings 87 | UsbKeyPowerSettings usbPowerSettings0 = nvram.ReadUsbSettings(); 88 | nvram.WriteUsbSettings(usbPowerSettings0); 89 | UsbKeyPowerSettings usbPowerSettings1 = nvram.ReadUsbSettings(); 90 | 91 | // set the chip configuration 92 | ChipSettings chipSettings = new ChipSettings(); 93 | chipSettings.InterruptBitMode = DedicatedFunction.NoInterruptCounting; 94 | chipSettings.RemoteWakeUpEnabled = true; 95 | chipSettings.SpiBusReleaseEnable = true; 96 | chipSettings.AccessControl = NramChipAccessControl.PasswordProtected; 97 | chipSettings.Password = Password; 98 | chipSettings.PinDirections = new PinDirection[] { 99 | PinDirection.Output, 100 | PinDirection.Output, 101 | PinDirection.Output, 102 | PinDirection.Output, 103 | PinDirection.Output, 104 | PinDirection.Output, 105 | PinDirection.Output, 106 | PinDirection.Output, 107 | PinDirection.Output 108 | }; 109 | 110 | chipSettings.PinModes = new PinMode[] { 111 | PinMode.GPIO, 112 | PinMode.GPIO, 113 | PinMode.GPIO, 114 | PinMode.GPIO, 115 | PinMode.GPIO, 116 | PinMode.GPIO, 117 | PinMode.GPIO, 118 | PinMode.GPIO, 119 | PinMode.GPIO 120 | }; 121 | 122 | chipSettings.DefaultOutput = new bool[] { 123 | true, 124 | true, 125 | true, 126 | true, 127 | false, 128 | false, 129 | false, 130 | true, 131 | true 132 | }; 133 | 134 | nvram.ConfigureChip(chipSettings); 135 | ChipSettings readSettings = nvram.ReadChipConfiguration(); 136 | 137 | // configure SPI 138 | SpiSetup spiSetup = new SpiSetup(); 139 | spiSetup.BitRate = 300000; 140 | spiSetup.BytesToTransfer = NumberOfBytes; 141 | spiSetup.ChipSelectToDataDelay = 3; 142 | spiSetup.BetweenDataDelay = 3; 143 | spiSetup.DataToChipSelectDelay = 3; 144 | spiSetup.Mode = SpiModes.Spi0; 145 | spiSetup.ActiveChipSelectValues = new bool[] { 146 | true, 147 | true, 148 | true, 149 | true, 150 | true, 151 | true, 152 | true, 153 | true, 154 | true 155 | }; 156 | spiSetup.IdleChipSelectValues = new bool[] { 157 | false, 158 | false, 159 | false, 160 | false, 161 | false, 162 | false, 163 | false, 164 | false, 165 | false 166 | }; 167 | 168 | nvram.ConfigureSpi(spiSetup); 169 | 170 | // read spi configuration 171 | SpiSetup readSpiSetup = nvram.ReadSpiConfiguration(); 172 | 173 | Console.WriteLine("completed successfully"); 174 | } catch (Exception ex) { 175 | PrintException(ex); 176 | } 177 | } 178 | 179 | static void TestVoltatileRam(IVolatileRam ram) { 180 | Console.Write("*** Test RAM: "); 181 | 182 | try { 183 | // set the chip configuration 184 | ChipSettings chipSettings = new ChipSettings(); 185 | chipSettings.InterruptBitMode = DedicatedFunction.NoInterruptCounting; 186 | chipSettings.RemoteWakeUpEnabled = false; 187 | chipSettings.SpiBusReleaseEnable = false; 188 | // these are never used by the volatile RAM 189 | //chipSettings.AccessControl = NramChipAccessControl.PasswordProtected; 190 | //chipSettings.Password = "abaco"; 191 | chipSettings.PinDirections = new PinDirection[] { 192 | PinDirection.Output, 193 | PinDirection.Output, 194 | PinDirection.Output, 195 | PinDirection.Output, 196 | PinDirection.Output, 197 | PinDirection.Output, 198 | PinDirection.Output, 199 | PinDirection.Output, 200 | PinDirection.Output 201 | }; 202 | 203 | chipSettings.PinModes = new PinMode[] { 204 | PinMode.GPIO, 205 | PinMode.GPIO, 206 | PinMode.GPIO, 207 | PinMode.GPIO, 208 | PinMode.GPIO, 209 | PinMode.GPIO, 210 | PinMode.GPIO, 211 | PinMode.DedicatedFunction, // release status bit 212 | PinMode.GPIO 213 | }; 214 | 215 | chipSettings.DefaultOutput = new bool[] { 216 | true, 217 | false, 218 | false, 219 | true, 220 | false, 221 | false, 222 | false, 223 | true, 224 | true 225 | }; 226 | 227 | ram.ConfigureChip(chipSettings); 228 | ChipSettings readSettings = ram.ReadChipConfiguration(); 229 | 230 | // configure SPI 231 | SpiSetup spiSetup = new SpiSetup(); 232 | spiSetup.BitRate = 200000; 233 | spiSetup.BytesToTransfer = NumberOfBytes; 234 | spiSetup.ChipSelectToDataDelay = 0; 235 | spiSetup.BetweenDataDelay = 0; 236 | spiSetup.DataToChipSelectDelay = 0; 237 | spiSetup.Mode = SpiModes.Spi2; 238 | spiSetup.ActiveChipSelectValues = new bool[] { 239 | true, 240 | true, 241 | true, 242 | true, 243 | true, 244 | true, 245 | true, 246 | true, 247 | true 248 | }; 249 | spiSetup.IdleChipSelectValues = new bool[] { 250 | false, 251 | false, 252 | false, 253 | false, 254 | false, 255 | false, 256 | false, 257 | false, 258 | false 259 | }; 260 | 261 | ram.ConfigureSpi(spiSetup); 262 | 263 | // read spi configuration 264 | SpiSetup readSpiSetup = ram.ReadSpiConfiguration(); 265 | 266 | // set the gpio output 267 | bool[] output = new bool[] { 268 | false, 269 | true, 270 | true, 271 | false, 272 | true, 273 | true, 274 | false, 275 | true, 276 | true 277 | }; 278 | 279 | ram.GpioPinsValue = output; 280 | 281 | Console.WriteLine("completed successfully"); 282 | } catch (Exception ex) { 283 | PrintException(ex); 284 | } 285 | } 286 | 287 | static void TestExternalInterruptPin(IExternalInterruptPin extIntPin) { 288 | Console.Write("*** Test External interrupt pin: "); 289 | 290 | try { 291 | int numofEvents = extIntPin.ReadNumberOfEvents(true); 292 | 293 | Console.WriteLine("completed successfully"); 294 | } catch (Exception ex) { 295 | PrintException(ex); 296 | } 297 | } 298 | 299 | static void TestSpiDataTransfer(ISpiDataTransfer spi) { 300 | Console.Write("*** Test SPI data transfer: "); 301 | 302 | try { 303 | // cancel the current transfer 304 | spi.CancelCurrentTransfer(); 305 | 306 | // release the SPI bus, and setthe release status bit to 1 307 | spi.RequestSpiBusRelease(true); 308 | 309 | // read the status 310 | SpiEngineStatus response1 = spi.ReadEngineStatus(); 311 | 312 | // send a SPI word 313 | byte[] data = new byte[NumberOfBytes]; 314 | TransferReply reply = spi.Transfer(data); 315 | 316 | // cancel current spi transfer 317 | SpiEngineStatus response0 = spi.CancelCurrentTransfer(); 318 | 319 | // release the spi bus 320 | spi.RequestSpiBusRelease(); 321 | 322 | Console.WriteLine("completed successfully"); 323 | } catch (Exception ex) { 324 | PrintException(ex); 325 | } 326 | } 327 | 328 | static void TestEeprom(IEepromMemory eeprom) { 329 | Console.Write("*** Test EEPROM reading: "); 330 | try { 331 | byte addr0 = eeprom.ReadAddress(0x00); 332 | byte addr1 = eeprom.ReadAddress(0x10); 333 | byte addr2 = eeprom.ReadAddress(0x20); 334 | byte addr3 = eeprom.ReadAddress(0x30); 335 | byte addr4 = eeprom.ReadAddress(0x40); 336 | byte addr5 = eeprom.ReadAddress(0x50); 337 | byte addr6 = eeprom.ReadAddress(0x60); 338 | 339 | Console.WriteLine("completed successfully"); 340 | } catch (Exception ex) { 341 | PrintException(ex); 342 | } 343 | } 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /MCP2210/RamBaseModule.cs: -------------------------------------------------------------------------------- 1 | 2 | // Copyright(c) 2016 Andrea Cervesato 3 | 4 | // Permission is hereby granted, free of charge, to any person 5 | // obtaining a copy of this software and associated documentation 6 | // files (the "Software"), to deal in the Software without 7 | // restriction, including without limitation the rights to use, 8 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the 10 | // Software is furnished to do so, subject to the following 11 | // conditions: 12 | 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | // OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | using System; 26 | 27 | namespace MCP2210 { 28 | class RamBaseModule { 29 | private readonly bool _nonVolatileRam; 30 | private readonly IHidCommunicationHandler _hidHandler; 31 | 32 | public RamBaseModule(IHidCommunicationHandler handler, bool nonVolatileRam) { 33 | _hidHandler = handler; 34 | _nonVolatileRam = nonVolatileRam; 35 | } 36 | 37 | #region Private conversion routines 38 | 39 | private static SpiSetup FromPacketToSpiConfiguration(byte[] packet) { 40 | SpiSetup setup = new SpiSetup(); 41 | 42 | // read the bitrate 43 | setup.BitRate = Convert.ToInt64(BitConverter.ToUInt32(packet, 4)); 44 | 45 | // read the chip select values 46 | setup.ActiveChipSelectValues = new bool[Constants.NumberOfGeneralPurposeLines]; 47 | setup.IdleChipSelectValues = new bool[Constants.NumberOfGeneralPurposeLines]; 48 | 49 | ushort idle = BitConverter.ToUInt16(packet, 8); 50 | ushort active = BitConverter.ToUInt16(packet, 10); 51 | 52 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 53 | ushort activeMask = (ushort)Math.Pow(2, i); 54 | setup.ActiveChipSelectValues[i] = (active & activeMask) == activeMask; 55 | 56 | ushort idleMask = (ushort)Math.Pow(2, i); 57 | setup.IdleChipSelectValues[i] = (idle & idleMask) == idleMask; 58 | } 59 | 60 | // read the delays 61 | setup.ChipSelectToDataDelay = Convert.ToInt32(BitConverter.ToUInt16(packet, 12)); 62 | setup.DataToChipSelectDelay = Convert.ToInt32(BitConverter.ToUInt16(packet, 14)); 63 | setup.BetweenDataDelay = Convert.ToInt32(BitConverter.ToUInt16(packet, 16)); 64 | 65 | // read the bytes to trasnfer 66 | setup.BytesToTransfer = Convert.ToInt32(BitConverter.ToUInt16(packet, 18)); 67 | 68 | // read the spi mode 69 | switch (packet[20]) { 70 | case 0: 71 | setup.Mode = SpiModes.Spi0; 72 | break; 73 | case 1: 74 | setup.Mode = SpiModes.Spi1; 75 | break; 76 | case 2: 77 | setup.Mode = SpiModes.Spi2; 78 | break; 79 | case 3: 80 | setup.Mode = SpiModes.Spi3; 81 | break; 82 | default: 83 | throw new NotImplementedException(); 84 | } 85 | 86 | return setup; 87 | } 88 | 89 | private static void FromSpiConfigurationToPacket(SpiSetup setup, ref byte[] packet) { 90 | // setup bitrate 91 | byte[] bitrateBytes = BitConverter.GetBytes(Convert.ToUInt32(setup.BitRate)); 92 | packet[4] = bitrateBytes[0]; 93 | packet[5] = bitrateBytes[1]; 94 | packet[6] = bitrateBytes[2]; 95 | packet[7] = bitrateBytes[3]; 96 | 97 | // set chip select status 98 | ushort activeCS = 0; 99 | ushort idleCS = 0; 100 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 101 | if (setup.ActiveChipSelectValues[i]) { 102 | activeCS += (ushort)(1 << i); 103 | } 104 | if (setup.IdleChipSelectValues[i]) { 105 | idleCS += (ushort)(1 << i); 106 | } 107 | } 108 | 109 | byte[] idleCSBytes = BitConverter.GetBytes(Convert.ToUInt16(idleCS)); 110 | packet[8] = idleCSBytes[0]; 111 | packet[9] = idleCSBytes[1]; 112 | 113 | byte[] activeCSBytes = BitConverter.GetBytes(Convert.ToUInt16(activeCS)); 114 | packet[10] = activeCSBytes[0]; 115 | packet[11] = activeCSBytes[1]; 116 | 117 | // convert delay into 16bits data, considering 100us as the quanta 118 | byte[] csToDDelayBytes = BitConverter.GetBytes(Convert.ToUInt16(setup.ChipSelectToDataDelay)); 119 | packet[12] = csToDDelayBytes[0]; 120 | packet[13] = csToDDelayBytes[1]; 121 | 122 | byte[] dToCsDelayBytes = BitConverter.GetBytes(Convert.ToUInt16(setup.DataToChipSelectDelay)); 123 | packet[14] = dToCsDelayBytes[0]; 124 | packet[15] = dToCsDelayBytes[1]; 125 | 126 | byte[] betweenDataDelayBytes = BitConverter.GetBytes(Convert.ToUInt16(setup.BetweenDataDelay)); 127 | packet[16] = betweenDataDelayBytes[0]; 128 | packet[17] = betweenDataDelayBytes[1]; 129 | 130 | // set bytes to transfer 131 | byte[] bytesToTransfBytes = BitConverter.GetBytes(Convert.ToUInt16(setup.BytesToTransfer)); 132 | packet[18] = bytesToTransfBytes[0]; 133 | packet[19] = bytesToTransfBytes[1]; 134 | 135 | // set spi mode 136 | switch (setup.Mode) { 137 | case SpiModes.Spi0: 138 | packet[20] = 0; 139 | break; 140 | case SpiModes.Spi1: 141 | packet[20] = 1; 142 | break; 143 | case SpiModes.Spi2: 144 | packet[20] = 2; 145 | break; 146 | case SpiModes.Spi3: 147 | packet[20] = 3; 148 | break; 149 | default: 150 | throw new NotImplementedException(); 151 | } 152 | } 153 | 154 | private static ChipSettings FromPacketToChipSettings(byte[] packet) { 155 | // create the current settings instance 156 | ChipSettings settings = new ChipSettings(); 157 | settings.PinDirections = new PinDirection[Constants.NumberOfGeneralPurposeLines]; 158 | settings.PinModes = new PinMode[Constants.NumberOfGeneralPurposeLines]; 159 | settings.DefaultOutput = new bool[Constants.NumberOfGeneralPurposeLines]; 160 | 161 | ushort gpioOutput = BitConverter.ToUInt16(packet, 13); 162 | ushort gpioDirection = BitConverter.ToUInt16(packet, 15); 163 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 164 | // set pin modes 165 | switch (packet[4 + i]) { 166 | case 0: 167 | settings.PinModes[i] = PinMode.GPIO; 168 | break; 169 | case 1: 170 | settings.PinModes[i] = PinMode.ChipSelects; 171 | break; 172 | case 2: 173 | settings.PinModes[i] = PinMode.DedicatedFunction; 174 | break; 175 | default: 176 | throw new NotImplementedException(); 177 | } 178 | 179 | // compute the current bit mask 180 | int bitMask =(int)Math.Pow(2, i); 181 | int pinStatus = 0; 182 | 183 | // set pin directions 184 | pinStatus = gpioDirection & bitMask; 185 | settings.PinDirections[i] = pinStatus == bitMask ? 186 | PinDirection.Output : // 0 187 | PinDirection.Input; // 1 188 | 189 | // set the default outputs 190 | pinStatus = gpioOutput & bitMask; 191 | settings.DefaultOutput[i] = pinStatus == bitMask; 192 | } 193 | 194 | // set other chip functionalities 195 | byte otherChipSettingByte = packet[17]; 196 | settings.SpiBusReleaseEnable = (otherChipSettingByte & 1) == 0; 197 | settings.RemoteWakeUpEnabled = (otherChipSettingByte & 8) == 8; 198 | 199 | int dedfunctIndex = (otherChipSettingByte >> 1) & 7; // 0000 0111 mask 200 | switch (dedfunctIndex) { 201 | case 0: 202 | settings.InterruptBitMode = DedicatedFunction.NoInterruptCounting; 203 | break; 204 | case 1: 205 | settings.InterruptBitMode = DedicatedFunction.CountFallingEdges; 206 | break; 207 | case 2: 208 | settings.InterruptBitMode = DedicatedFunction.CountRisingEdges; 209 | break; 210 | case 3: 211 | settings.InterruptBitMode = DedicatedFunction.CountLowPulses; 212 | break; 213 | case 4: 214 | settings.InterruptBitMode = DedicatedFunction.CountHighPulses; 215 | break; 216 | default: 217 | throw new NotImplementedException(); 218 | } 219 | 220 | // set nvram access control 221 | switch (packet[18]) { 222 | case 0x00: 223 | settings.AccessControl = NramChipAccessControl.NotProtected; 224 | break; 225 | case 0x40: 226 | settings.AccessControl = NramChipAccessControl.PasswordProtected; 227 | break; 228 | case 0x80: 229 | settings.AccessControl = NramChipAccessControl.PermanentlyLocked; 230 | break; 231 | } 232 | 233 | return settings; 234 | } 235 | 236 | private static void FromChipSettingstoPacket(ChipSettings settings, ref byte[] packet) { 237 | ushort gpioOut = 0; 238 | ushort gpioDir = 0; 239 | for (int i = 0; i < Constants.NumberOfGeneralPurposeLines; i++) { 240 | PinMode mode = settings.PinModes[i]; 241 | PinDirection direction = settings.PinDirections[i]; 242 | 243 | // setup pin mode 244 | byte mbyte = 0; 245 | switch (mode) { 246 | case PinMode.GPIO: 247 | mbyte = 0; 248 | break; 249 | case PinMode.ChipSelects: 250 | mbyte = 1; 251 | break; 252 | case PinMode.DedicatedFunction: 253 | mbyte = 2; 254 | break; 255 | default: 256 | throw new NotImplementedException(); 257 | } 258 | 259 | packet[i + 4] = mbyte; 260 | 261 | // create the GPIO configuration 262 | byte dirbyte = (byte)(direction == PinDirection.Output ? 0 : 1); 263 | ushort bit = (ushort)(dirbyte << i); 264 | gpioDir |= bit; 265 | 266 | // set the GPIO configuration 267 | if (settings.DefaultOutput[i]) { 268 | gpioOut |= (ushort)(1 << i); 269 | } else { 270 | gpioOut &= (ushort)~(1 << i); 271 | } 272 | } 273 | 274 | byte[] gpioOutBytes = BitConverter.GetBytes(gpioOut); 275 | packet[13] = gpioOutBytes[0]; 276 | packet[14] = gpioOutBytes[1]; 277 | 278 | byte[] gpioDirBytes = BitConverter.GetBytes(gpioDir); 279 | packet[15] = gpioDirBytes[0]; 280 | packet[16] = gpioDirBytes[1]; 281 | 282 | // set the other chip functionalities 283 | byte otherChipSettingsByte = 0x00; 284 | otherChipSettingsByte |= (byte)(settings.SpiBusReleaseEnable ? 0 : 1); // 0000 0001 285 | otherChipSettingsByte |= (byte)(settings.RemoteWakeUpEnabled ? 16 : 0); // 0000 1000 286 | 287 | switch (settings.InterruptBitMode) { 288 | case DedicatedFunction.CountFallingEdges: 289 | otherChipSettingsByte |= 2; // 001 290 | break; 291 | case DedicatedFunction.CountRisingEdges: 292 | otherChipSettingsByte |= 3; // 010 293 | break; 294 | case DedicatedFunction.CountLowPulses: 295 | otherChipSettingsByte |= 4; // 011 296 | break; 297 | case DedicatedFunction.CountHighPulses: 298 | otherChipSettingsByte |= 5; // 100 299 | break; 300 | case DedicatedFunction.NoInterruptCounting: 301 | default: 302 | otherChipSettingsByte |= 0x00; // 000 303 | break; 304 | } 305 | 306 | packet[17] = otherChipSettingsByte; 307 | 308 | // set the Nvram chip parameters access control 309 | switch (settings.AccessControl) { 310 | case NramChipAccessControl.NotProtected: 311 | packet[18] = 0x00; 312 | break; 313 | case NramChipAccessControl.PasswordProtected: 314 | packet[18] = 0x40; 315 | break; 316 | case NramChipAccessControl.PermanentlyLocked: 317 | packet[18] = 0x80; 318 | break; 319 | } 320 | } 321 | 322 | #endregion 323 | 324 | /// 325 | /// This method configures the chip. 326 | /// 327 | /// The chip settings. 328 | /// The writing configuration command. 329 | /// The sub command configuration. If 0, it's not used. 330 | protected void ConfigureChip(ChipSettings settings,byte command, byte subcommand = 0) { 331 | // check if the input argument has 9 length array configuration 332 | if (settings.PinDirections == null || settings.PinDirections.Length != Constants.NumberOfGeneralPurposeLines) { 333 | throw new ArgumentException("Expected non null and " + Constants.NumberOfGeneralPurposeLines + " length pins directions array."); 334 | } 335 | 336 | if (settings.PinModes == null || settings.PinModes.Length != Constants.NumberOfGeneralPurposeLines) { 337 | throw new ArgumentException("Expected non null and " + Constants.NumberOfGeneralPurposeLines + " length pins modes array."); 338 | } 339 | 340 | if (settings.DefaultOutput == null || settings.DefaultOutput.Length != Constants.NumberOfGeneralPurposeLines) { 341 | throw new ArgumentException("Expected non null and " + Constants.NumberOfGeneralPurposeLines + " length pins default output array."); 342 | } 343 | 344 | // create the packet 345 | byte[] packet = new byte[Constants.PacketsSize]; 346 | packet[0] = command; 347 | packet[1] = subcommand; 348 | 349 | FromChipSettingstoPacket(settings, ref packet); 350 | 351 | // set the password according with the access control byte (the 18th byte) 352 | string password = settings.Password; 353 | if (_nonVolatileRam && settings.AccessControl != NramChipAccessControl.NotProtected) { 354 | if (string.IsNullOrEmpty(password)) { 355 | // reset password 356 | for (int i = 0; i < Constants.MaximumPasswordLength; i++) { 357 | packet[i + 19] = 0; 358 | } 359 | } else { 360 | // setup password 361 | string subPassword = ""; 362 | if (password.Length > Constants.MaximumPasswordLength) { 363 | subPassword = password.Substring(0, Constants.MaximumPasswordLength); 364 | } else { 365 | subPassword = password; 366 | } 367 | 368 | for (int i = 0; i < Constants.MaximumPasswordLength; i++) { 369 | if (password.Length > i) { 370 | packet[i + 19] = BitConverter.GetBytes(password[i])[0]; 371 | } else { 372 | packet[i + 19] = 0x00; 373 | } 374 | } 375 | } 376 | } 377 | 378 | // write the new setup and read the reply 379 | byte[] settingsReply = _hidHandler.WriteData(packet); 380 | 381 | // check if package format is faulty 382 | if (settingsReply[0] != command || (subcommand != 0 && settingsReply[2] != subcommand)) { 383 | throw new PacketReplyFormatException(); 384 | } 385 | 386 | // check for errors 387 | switch (settingsReply[1]) { 388 | case ReplyStatusCodes.CompletedSuccessfully: 389 | break; 390 | case ReplyStatusCodes.BlockedAccess: 391 | throw new AccessBlockedException(); 392 | default: 393 | throw new NotImplementedException(); 394 | } 395 | } 396 | 397 | /// 398 | /// This method configures the SPI bus. 399 | /// 400 | /// The SPI setup. 401 | /// The configuration command. 402 | /// The sub command configuration. If 0, it's not used. 403 | protected void ConfigureSpi(SpiSetup setup, byte command, byte subcommand = 0) { 404 | // check input argument 405 | if (setup.ActiveChipSelectValues == null || 406 | setup.ActiveChipSelectValues.Length != Constants.NumberOfGeneralPurposeLines) { 407 | throw new ArgumentException("Expected " + Constants.NumberOfGeneralPurposeLines + " active CS lines."); 408 | } 409 | 410 | if (setup.IdleChipSelectValues == null || 411 | setup.IdleChipSelectValues.Length != Constants.NumberOfGeneralPurposeLines) { 412 | throw new ArgumentException("Expected " + Constants.NumberOfGeneralPurposeLines + " idle CS lines."); 413 | } 414 | 415 | if (setup.BetweenDataDelay < 0) { 416 | setup.BetweenDataDelay = 0; 417 | } 418 | 419 | if (setup.DataToChipSelectDelay < 0) { 420 | setup.DataToChipSelectDelay = 0; 421 | } 422 | 423 | if (setup.ChipSelectToDataDelay < 0) { 424 | setup.ChipSelectToDataDelay = 0; 425 | } 426 | 427 | if (setup.BitRate < 0) { 428 | setup.BitRate = 0; 429 | } 430 | 431 | if (setup.BytesToTransfer < 1) { 432 | setup.BytesToTransfer = 12; // default value 433 | } 434 | 435 | // create the packet 436 | byte[] packet = new byte[Constants.PacketsSize]; 437 | packet[0] = command; 438 | packet[1] = subcommand; 439 | FromSpiConfigurationToPacket(setup, ref packet); 440 | 441 | // write the packet 442 | byte[] reply = _hidHandler.WriteData(packet); 443 | 444 | // check if package format is faulty 445 | if (reply[0] != command || (subcommand != 0 && reply[2] != subcommand)) { 446 | throw new PacketReplyFormatException(); 447 | } 448 | 449 | // check for errors 450 | switch (reply[1]) { 451 | case ReplyStatusCodes.CompletedSuccessfully: 452 | break; 453 | case ReplyStatusCodes.BlockedAccess: 454 | throw new AccessBlockedException(); 455 | case ReplyStatusCodes.UsbTransferInProgress: 456 | throw new UsbtransferInProgressException(); 457 | default: 458 | throw new NotImplementedException(); 459 | } 460 | } 461 | 462 | /// 463 | /// This method reads the chip configuration. 464 | /// 465 | /// The configuration command. 466 | /// The sub command configuration. If 0, it's not used. 467 | /// The chip settings. 468 | protected ChipSettings ReadChipConfiguration(byte command, byte subcommand = 0) { 469 | // create the packet 470 | byte[] packet = new byte[Constants.PacketsSize]; 471 | packet[0] = command; 472 | packet[1] = subcommand; 473 | 474 | // write the packet 475 | byte[] reply = _hidHandler.WriteData(packet); 476 | 477 | // check if package format is faulty 478 | if (reply[0] != command || (subcommand != 0 && reply[2] != subcommand)) { 479 | throw new PacketReplyFormatException(); 480 | } 481 | 482 | // create the current settings instance 483 | ChipSettings settings = FromPacketToChipSettings(reply); 484 | return settings; 485 | } 486 | 487 | /// 488 | /// This method reads the SPI bus configuration. 489 | /// 490 | /// The configuration command. 491 | /// The sub command configuration. If 0, it's not used. 492 | /// The SPI bus configuration. 493 | protected SpiSetup ReadSpiConfiguration(byte command, byte subcommand = 0) { 494 | // create the packet 495 | byte[] packet = new byte[Constants.PacketsSize]; 496 | packet[0] = command; 497 | packet[1] = subcommand; 498 | 499 | // write the packet 500 | byte[] reply = _hidHandler.WriteData(packet); 501 | 502 | // check if package format is faulty 503 | if (reply[0] != command || (subcommand != 0 && reply[2] != subcommand)) { 504 | throw new PacketReplyFormatException(); 505 | } 506 | 507 | // create the spi setup 508 | SpiSetup setup = FromPacketToSpiConfiguration(reply); 509 | return setup; 510 | } 511 | } 512 | } 513 | -------------------------------------------------------------------------------- /MCP2210/Libs/HidSharp.XML: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HidSharp 5 | 6 | 7 | 8 | 9 | Defines the possible units of temperature. 10 | 11 | 12 | 13 | 14 | The unit system has no unit of temperature. 15 | 16 | 17 | 18 | 19 | The unit of temperature is Kelvin (occurs in SI Linear and Rotation unit systems). 20 | 21 | 22 | 23 | 24 | The unit of temperature is Fahrenheit (occurs in English Linear and Rotation unit systems). 25 | 26 | 27 | 28 | 29 | Detects USB HID class devices connected to the system. 30 | 31 | 32 | 33 | 34 | Initializes a new instance of the class. 35 | 36 | 37 | 38 | 39 | Gets a list of connected USB devices. 40 | This overload is meant for Visual Basic 6 and COM clients. 41 | 42 | The device list. 43 | 44 | 45 | 46 | Gets a list of connected USB devices. 47 | 48 | The device list. 49 | 50 | 51 | 52 | Gets a list of connected USB devices, filtered by some criteria. 53 | 54 | The vendor ID, or null to not filter by vendor ID. 55 | The product ID, or null to not filter by product ID. 56 | The product version, or null to not filter by product version. 57 | The serial number, or null to not filter by serial number. 58 | The filtered device list. 59 | 60 | 61 | 62 | Gets the first connected USB device that matches specified criteria. 63 | 64 | The vendor ID, or null to not filter by vendor ID. 65 | The product ID, or null to not filter by product ID. 66 | The product version, or null to not filter by product version. 67 | The serial number, or null to not filter by serial number. 68 | The device, or null if none was found. 69 | 70 | 71 | 72 | Communicates with a USB HID class device. 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Sends a Get Feature setup request. 81 | 82 | The buffer to fill. Place the Report ID in the first byte. 83 | 84 | 85 | 86 | Sends a Get Feature setup request. 87 | 88 | The buffer to fill. Place the Report ID in the byte at index . 89 | The index in the buffer to begin filling with data. 90 | The number of bytes in the feature request. 91 | 92 | 93 | 94 | Reads HID Input Reports. 95 | 96 | The data read. 97 | 98 | 99 | 100 | Reads HID Input Reports. 101 | 102 | The buffer to place the reports into. 103 | The number of bytes read. 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | Sends a Set Feature setup request. 114 | 115 | The buffer of data to send. Place the Report ID in the first byte. 116 | 117 | 118 | 119 | Sends a Set Feature setup request. 120 | 121 | The buffer of data to send. Place the Report ID in the byte at index . 122 | The index in the buffer to start the write from. 123 | The number of bytes in the feature request. 124 | 125 | 126 | 127 | 128 | 129 | 130 | Writes an HID Output Report to the device. 131 | 132 | The buffer containing the report. Place the Report ID in the first byte. 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | Gets the associated with this stream. 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | The maximum amount of time, in milliseconds, to wait for to receive a HID report. 163 | 164 | The default is 3000 milliseconds. 165 | To disable the timeout, set this to . 166 | 167 | 168 | 169 | 170 | The maximum amount of time, in milliseconds, to wait for the device to acknowledge a HID report. 171 | 172 | The default is 3000 milliseconds. 173 | To disable the timeout, set this to . 174 | 175 | 176 | 177 | 178 | Defines the possible units of mass. 179 | 180 | 181 | 182 | 183 | The unit system has no unit of mass. 184 | 185 | 186 | 187 | 188 | The unit of mass is the gram (occurs in the SI Linear and Rotation unit systems). 189 | 190 | 191 | 192 | 193 | The unit of mass is the slug (occurs in the English Linear and Rotation unit systems). 194 | 195 | 196 | 197 | 198 | Describes the manner in which an item affects the descriptor. 199 | 200 | 201 | 202 | 203 | Main items determine the report being described. 204 | For example, a main item switches between Input and Output reports. 205 | 206 | 207 | 208 | 209 | Global items affect all reports later in the descriptor. 210 | 211 | 212 | 213 | 214 | Local items only affect the current report. 215 | 216 | 217 | 218 | 219 | Long items use this type. 220 | 221 | 222 | 223 | 224 | Represents a USB HID class device. 225 | 226 | 227 | 228 | 229 | Makes a connection to the USB HID class device, or throws an exception if the connection cannot be made. 230 | 231 | The stream to use to communicate with the device. 232 | 233 | 234 | 235 | Returns the raw report descriptor of the USB device. 236 | Currently this is only supported on Linux. 237 | 238 | The report descriptor. 239 | 240 | 241 | 242 | Tries to make a connection to the USB HID class device. 243 | 244 | The stream to use to communicate with the device. 245 | True if the connetion was successful. 246 | 247 | 248 | 249 | 250 | 251 | 252 | The operating system's name for the device. 253 | 254 | If you have multiple devices with the same Vendor ID, Product ID, Serial Number. etc., 255 | this may be useful for differentiating them. 256 | 257 | 258 | 259 | 260 | The maximum input report length, including the Report ID byte. 261 | If the device does not use Report IDs, the first byte will always be 0. 262 | 263 | 264 | 265 | 266 | The maximum output report length, including the Report ID byte. 267 | If the device does not use Report IDs, use 0 for the first byte. 268 | 269 | 270 | 271 | 272 | The maximum feature report length, including the Report ID byte. 273 | If the device does not use Report IDs, use 0 for the first byte. 274 | 275 | 276 | 277 | 278 | The manufacturer name. 279 | 280 | 281 | 282 | 283 | The USB product ID. These are listed at: http://usb-ids.gowdy.us 284 | 285 | 286 | 287 | 288 | The product name. 289 | 290 | 291 | 292 | 293 | The product version. 294 | This is a 16-bit number encoding the major and minor versions in the upper and lower 8 bits, respectively. 295 | 296 | 297 | 298 | 299 | The device serial number. 300 | 301 | 302 | 303 | 304 | The USB vendor ID. These are listed at: http://usb-ids.gowdy.us 305 | 306 | 307 | 308 | 309 | Defines the possible unit systems. 310 | 311 | 312 | 313 | 314 | No units are used. 315 | 316 | 317 | 318 | 319 | The SI Linear unit system uses centimeters for length, grams for mass, seconds for time, 320 | Kelvin for temperature, Amperes for current, and candelas for luminous intensity. 321 | 322 | 323 | 324 | 325 | The SI Rotation unit system uses radians for length, grams for mass, seconds for time, 326 | Kelvin for temperature, Amperes for current, and candelas for luminous intensity. 327 | 328 | 329 | 330 | 331 | The English Linear unit system uses inches for length, slugs for mass, seconds for time, 332 | Fahrenheit for temperature, Amperes for current, and candelas for luminous intensity. 333 | 334 | 335 | 336 | 337 | The English Rotation unit system uses degrees for length, slugs for mass, seconds for time, 338 | Fahrenheit for temperature, Amperes for current, and candelas for luminous intensity. 339 | 340 | 341 | 342 | 343 | Defines the possible units of length. 344 | 345 | 346 | 347 | 348 | The unit system has no unit of length. 349 | 350 | 351 | 352 | 353 | The unit of length is the centimeter (occurs in the SI Linear unit system). 354 | 355 | 356 | 357 | 358 | The unit of length is the radian (occurs in the SI Rotation unit system). 359 | 360 | 361 | 362 | 363 | The unit of length is the inch (occurs in the English Linear unit system). 364 | 365 | 366 | 367 | 368 | The unit of length is the degree (occurs in the English Rotation unit system). 369 | 370 | 371 | 372 | 373 | Describes the units of a report value. 374 | 375 | 376 | 377 | 378 | Initializes a new instance of the class. 379 | 380 | The raw HID value describing the units. 381 | 382 | 383 | 384 | Decodes an encoded HID unit exponent. 385 | 386 | The encoded exponent. 387 | The exponent. 388 | 389 | 390 | 391 | Encodes an exponent in HID unit form. 392 | 393 | The exponent. 394 | The encoded exponent. 395 | 396 | 397 | 398 | Gets or sets the unit system. 399 | 400 | 401 | 402 | 403 | Gets or sets the exponent of the report value's units of length. 404 | 405 | 406 | 407 | 408 | Gets the units of length corresponding to . 409 | 410 | 411 | 412 | 413 | Gets or sets the exponent of the report value's units of mass. 414 | 415 | 416 | 417 | 418 | Gets the units of mass corresponding to . 419 | 420 | 421 | 422 | 423 | Gets or sets the exponent of the report value's units of time. 424 | 425 | 426 | 427 | 428 | Gets the units of time corresponding to . 429 | 430 | 431 | 432 | 433 | Gets or sets the exponent of the report value's units of temperature. 434 | 435 | 436 | 437 | 438 | Gets the units of temperature corresponding to . 439 | 440 | 441 | 442 | 443 | Gets or sets the exponent of the report value's units of current. 444 | 445 | 446 | 447 | 448 | Gets the units of current corresponding to . 449 | 450 | 451 | 452 | 453 | Gets or sets the exponent of the report value's units of luminous intensity. 454 | 455 | 456 | 457 | 458 | Gets the units of luminous intensity corresponding to . 459 | 460 | 461 | 462 | 463 | Gets or sets the raw HID value describing the units. 464 | 465 | 466 | 467 | 468 | Defines the possible units of time. 469 | 470 | 471 | 472 | 473 | The unit system has no unit of time. 474 | 475 | 476 | 477 | 478 | The unit of time is seconds. 479 | 480 | 481 | 482 | 483 | No flags are set. 484 | 485 | 486 | 487 | 488 | Constant values cannot be changed. 489 | 490 | 491 | 492 | 493 | Each variable field corresponds to a particular value. 494 | The alternative is an array, where each field specifies an index. 495 | For example, with eight buttons, a variable field would have eight bits. 496 | An array would have an index of which button is pressed. 497 | 498 | 499 | 500 | 501 | Mouse motion is in relative coordinates. 502 | Most sensors -- joysticks, accelerometers, etc. -- output absolute coordinates. 503 | 504 | 505 | 506 | 507 | The value wraps around in a continuous manner. 508 | 509 | 510 | 511 | 512 | Defines the possible units of luminous intensity. 513 | 514 | 515 | 516 | 517 | The unit system has no unit of luminous intensity. 518 | 519 | 520 | 521 | 522 | The unit of luminous intensity is the candela. 523 | 524 | 525 | 526 | 527 | Defines the possible units of current. 528 | 529 | 530 | 531 | 532 | The unit system has no unit of current. 533 | 534 | 535 | 536 | 537 | The unit of current is the Ampere. 538 | 539 | 540 | 541 | 542 | Reads and writes HID reports. 543 | 544 | 545 | 546 | 547 | Initializes a new instance of the class. 548 | 549 | 550 | 551 | 552 | Resets the instance to its initial state. 553 | 554 | 555 | 556 | 557 | Reads a HID report, calling back a provided function for each segment. 558 | 559 | The buffer containing the report. 560 | The offset to begin reading the report at. 561 | 562 | This callback will be called for each report segment. 563 | Use this to read every value you need. 564 | 565 | 566 | 567 | 568 | Writes a HID report, calling back a provided function for each segment. 569 | 570 | 571 | This callback will be called for each report segment. 572 | Write to each segment to write a complete HID report. 573 | 574 | 575 | 576 | 577 | The Report ID. 578 | 579 | 580 | 581 | 582 | The length of this particular report. 583 | The Report ID is not included in this length. 584 | 585 | 586 | 587 | 588 | Parses HID report descriptors. 589 | 590 | 591 | 592 | 593 | Initializes a new instance of the class. 594 | 595 | 596 | 597 | 598 | Resets the parser to its initial state. 599 | 600 | 601 | 602 | 603 | Parses a raw HID report descriptor. 604 | 605 | The buffer containing the report descriptor. 606 | 607 | 608 | 609 | Parses a raw HID report descriptor. 610 | 611 | The buffer containing the report descriptor. 612 | The offset into the buffer to begin parsing from. 613 | The number of bytes to parse. 614 | 615 | 616 | 617 | Parses all of the elements in a report descriptor. 618 | 619 | The items to parse. 620 | 621 | 622 | 623 | Parses a single . 624 | Call this repeatedly for every item to completely decode a report descriptor. 625 | 626 | The item to parse. 627 | 628 | 629 | 630 | The maximum input report length. 631 | The Report ID is not included in this length. 632 | 633 | 634 | 635 | 636 | The maximum output report length. 637 | The Report ID is not included in this length. 638 | 639 | 640 | 641 | 642 | The maximum feature report length. 643 | The Report ID is not included in this length. 644 | 645 | 646 | 647 | 648 | True if the device sends Report IDs. 649 | 650 | 651 | 652 | 653 | --------------------------------------------------------------------------------