GPIO access via C#

      GPIO access via C#

      Hello,

      since a few days I have my StartKit PicoCom2. It's running and i test some functions.
      I have some problems with the access via C#. I can create simple GUI's but I despair with the GPIO control.
      It is possible to use GPIO and I2C with C# or only with C++/MFC?
      Can you help me and give support? Maybe some samples?

      thanks
      michael

      Re: GPIO access via C#

      yes it is possible to access even all interfaces using C#. You must write you own PInvoke routines to call the required Win32 functions. Alternatively we offer an additional .NET software package that includes classes to access the I2C and other interfaces direclty from C#.
      To get more information, including the pricing, please contact our sales departement (<!-- e --><a href="mailto:sales@fs-net.de">sales@fs-net.de</a><!-- e -->)
      Software developer, F&amp;S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

      Re: GPIO access via C#

      Information for c# users :

      1pcs NetDCU/PicoCOM-SKIT-VS.NET Euro 500,
      C# driver of I2C, SPI, CAN used with PicoCOM2
      C# driver of I/O and other interfaces are not available

      If somebody have c# driver of PICOCOM2 interface please let me know .I can't write good classes to access to I/O.

      Re: GPIO access via C#

      Hello, following class may serve as a template:

      Source Code

      1. using System;
      2. using System.Collections.Generic;
      3. using System.Text;
      4. using System.Runtime.InteropServices;
      5. namespace MyAssembly
      6. {
      7. class DIOSwitch
      8. {
      9. protected IntPtr hPort;
      10. const UInt32 GENERIC_READ= 0x80000000;
      11. const UInt32 GENERIC_WRITE = 0x40000000;
      12. const UInt32 OPEN_EXISTING = 3;
      13. public bool Open(string Port)
      14. {
      15. hPort = CreateFile(Port, GENERIC_READ|GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
      16. if (hPort == (IntPtr)(-1))
      17. return false;
      18. return true;
      19. }
      20. public void Close()
      21. {
      22. CloseHandle(hPort);
      23. }
      24. public bool Read(ref Byte b)
      25. {
      26. Byte[] Data = new Byte[1];
      27. Int32[] Read = new Int32[1];
      28. if (ReadFile(hPort, Data, 1, Read, IntPtr.Zero) > 0)
      29. {
      30. b = Data[0];
      31. return true;
      32. }
      33. return false;
      34. }
      35. public bool Write(Byte b)
      36. {
      37. Byte[] Data = new Byte[1];
      38. Int32[] Written = new Int32[1];
      39. Data[0] = b;
      40. if(WriteFile(hPort, Data, 1, Written, IntPtr.Zero)>0)
      41. return true;
      42. return false;
      43. }
      44. // ******************************************************************
      45. [DllImport("coredll.dll", EntryPoint = "CreateFileW", SetLastError = true)]
      46. public extern static IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr pSecurityAttributes,
      47. uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
      48. [DllImport("coredll.dll", EntryPoint = "CloseHandle", SetLastError = true)]
      49. public extern static int CloseHandle(IntPtr hObject);
      50. [DllImport("coredll.dll", EntryPoint = "ReadFile", SetLastError = true)]
      51. public extern static uint ReadFile(IntPtr hObject, Byte[] lpBuffer, uint NumberOfBytesToRead, Int32[] NumberOfBytes,
      52. IntPtr lpOverLapped);
      53. [DllImport("coredll.dll", EntryPoint = "WriteFile", SetLastError = true)]
      54. public extern static uint WriteFile(IntPtr hObject, Byte[] lpBuffer, uint NumberOfBytesToWrite, Int32[] NumberOfBytes,
      55. IntPtr lpOverLapped);
      56. }
      57. }
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

      Re: GPIO access via C#

      Hello, users.
      In the attachment zip-File ist a smple an a class-bibliothek for port- and pin-I/O without interrupts.
      I have wrote it under VS2008 in C# with cfw3.5. For other configurations please test it by oneself.
      You can use it free!
      I hope it is usefull for you.

      Kommentar in deutsch, denn mein englisch isn't the best:
      Ich habe hier im Forum und bei den Dokumentationen keine vernünftigen Lösungen oder wenigstens Beschreibungen für die Ansteuerung der I/O-Pins in C# gefunden.
      Das ist für einen Neueinsteiger bei WindowsCE (das erste Mal mit OS) schon eine fast unüberwindliche Hürde und hat mich eine Menge Schweiß gekostet.
      Dabei ist es für einen embedded-Entwickler ein riesiger Erfolg wenn er mit einem Stück Draht einen Eingangspin auf Low legen und einlesen oder am programmierten Ausgang mit dem Oszi seinen ersten Rechteck bewundern kann.
      Das ist für ihn dann die Bestätigung doch auf das richtige System gesetzt zu haben!
      Und ich finde, dieser Schritt wird einem doch etwas schwer gemacht.
      Es war z.B. schon schwierig die richtigen Pinnummern zur Registry zu identifizieren. Das gelang erst richtig mit dem Dokument "PicoCOM2 Device Driver Documentation" das 2009-05-29 erschien.
      Im Zusammenhang mit PicoCOM2, .net und C# ist die Antwort von fs-support_ZU auf diesen Beitrag auch der erste leicht nachvollziehbare Beispielcode für das pinvoke.

      PS: Und trotzdem habe ich mich für das richtige System entschieden, denn ich habe es geschafft, meinen ersten draht einzulesen und meinen ersten Rechteck zu sehen ;-).

      Grüße eines Neueisnteigers,
      Hans
      Files
      • DIO-Test.zip

        (36.99 kB, downloaded 293 times, last: )

      Re: GPIO access via C#

      "hkoettel" wrote:

      Ich habe hier im Forum und bei den Dokumentationen keine vernünftigen Lösungen oder wenigstens Beschreibungen für die Ansteuerung der I/O-Pins in C# gefunden.
      Das ist für einen Neueinsteiger bei WindowsCE (das erste Mal mit OS) schon eine fast unüberwindliche Hürde und hat mich eine Menge Schweiß gekostet.

      Two comments:

      1. We offer a 4-hour workshop here that is really inexpensive. During this workshop, the usage and the first steps for programming are explained. Participating in this workshop may help to avoid these frustrating experiences.

      2. We offer our SKIT-VS.NET to also help you to avoid the waste of time to write these wrapper classes yourself. As we implement our drivers in C (this is the only way to add hardware drivers to WinCE), it is actually quite some work to write these additional .NET interfaces -- which is the reason why we can't give away this package for free. For example the CanPort class took about two weeks full-time to implement. Therefore if you need to use CAN only once, the SKIT is already worth all its money. And as time is always a very restricted resource, we haven't had the time to do .NET ports for all our drivers yet. But we will add them in the future, one after the other as time allows.

      In fact there is no need to write a special C# class for DIO to just toggle a pin. Simply create a FileStream object for DIO1: and use ReadByte() and WriteByte() on it. Done! Only if you want to use special features like interrupt handling, then you are required to use DeviceIoControl() which requires Pinvoke in C#. Then it's getting a little more complicated.

      My tip: participate in the workshop here in Stuttgart. It will help you extremely to get along with our boards. Even if you have already some experience with other boards, every manufacturer does it a little bit different and our workshop should help you to overcome the small problems that cost so much time right at the beginning when you start working with our boards.

      Regards,

      H. Keller
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

      Re: GPIO access via C#

      Leider ist der Quellcode für das Beispiel in der ZIP-Datei nicht vollständig (die IO-Bibliothek fehlt - Beispiel kann nicht neu kompiliert werden) und ist so für einen Einsteiger in der Form auch nicht brauchbarer, als die Dokumentation von F&S :(

      Abgesehen davon kann ich die beschriebenen Probleme nur zur Hälfte nachvollziehen. Es gibt hier schon ein VB.NET-Beispiel, in dem das PInvoke für den DIO gemacht wurde (DIO_VBTest). Davon ausgehend, mit Hilfe der Treiber-Dokumentation für PicoCOM2 (die zum Anfang hinsichtlich DIO so einige Fehler hatte) und einem einzigen C#-Beispielprogramm mit PInvoke aus dem Netz, war es nicht sonderlich schwierig, ein Programm in C# zu schreiben, das eine LED am DIO-Ausgang blinken lässt und auf Änderungen an einem DIO-Eingang reagiert. Und nein, ich hatte zu der Zeit auch wenig Kenntnis über Windows CE und überhaupt kein Wissen über VB oder C#. Dementsprechend bescheiden sieht/sah der Quellcode aus, was mich davon abhielt, den hier zu veröffentlichen.
      Andererseits wäre es natürlich schön und einfacher für Neueinsteiger, wenn es Programmbeispiele in allen Sprachvarianten (VB.NET, C# und C++) für alle Hardware-Varianten und alle Schnittstellen geben würde, aber der Aufwand wäre wahrscheinlich viel zu groß. Ein Verweis auf den Workshop oder die vorgefertigten Bibliotheken ist zwar berechtigt, aber jemand, der mal schnell was testen will, wird kaum das Geld für die Bibliotheken ausgeben oder den Tag für den Workshop Zeit haben. Hinsichtlich Beispielen in C# sieht es hier im Forum aber etwas schlecht aus. Die meisten Beispiele sind in C++ oder VB und man muss sich das selbst portieren...
      Kind regards,
      H. Tefs

      Re: GPIO access via C#

      "htefs" wrote:

      Und nein, ich hatte zu der Zeit auch wenig Kenntnis über Windows CE und überhaupt kein Wissen über VB oder C#. Dementsprechend bescheiden sieht/sah der Quellcode aus, was mich davon abhielt, den hier zu veröffentlichen.

      Sehen Sie, uns geht es nicht anders. Wir schreiben unsere Treiber und Anpassungen in C, wir müssen uns ebenfalls erst das Wissen für C# nach und nach aneignen. Dabei ist es bei so einer Treiberklasse unter .NET ja nicht so, dass sie halt irgendwie tun sollte, sondern sie sollte ja einen gewissen Beispielscharakter haben und man sollte sich auch an gewisse Regeln und Nutzungskonzepte halten, die in .NET üblich sind. Eben damit man das dann später einfach im Visual Studio zusammenklicken kann. Das ist aber eben immer nochmal ein bisschen aufwendiger.

      Mal konkret: unter Win32 stellen wir für einen Treiber einfach eine kleine überschaubare Gruppe von Funktionen zur Verfügung. Das sind CreateFile(), CloseHandle(), ReadFile(), WriteFile(), SetFilePointer() und DeviceIoControl(). Mehr gibt es da nicht. Das ist alles, was nach außen sichtbar ist. Die ganze Logik, die sich nicht auf einfaches Lesen und Schreiben abbilden lässt, steckt als eigenständige Kommandos in der Funktion DeviceIoControl(). Für .NET reicht es aber nicht aus, einfach diese Funktionen weiter zu reichen. Das wäre ja nur eine unvollständige Eingliederung in die .NET-Umgebung. Denn dort ist es beispielsweise üblich, mit Stream-Objekten zu arbeiten. Das heißt das Treiberinterface muss nun so erweitert werden, dass man auch wirklich ein Stream-Objekt anlegen kann. Nur dann kann man den Treiber auch wirklich sinnvoll mit allen Möglichkeiten von .NET nutzen. Aber was muss nun alles intern gemacht werden, dass man z.B. ein SPI-Device als ein Stream-Objekt verwenden kann? Das ist nämlich schon ganz schön kompliziert. Und genau diesen Schritt wollen wir eben machen, wenn wir entsprechende Klassen anbieten. Und sowas ist eben nicht mal schnell in ein paar Minuten realisiert. Da muss man sich schlau machen und so einiges ausprobieren. Und diese Zeit wollen wir Ihnen ja mit dem Zusatzpaket für .NET einsparen.

      Andererseits wäre es natürlich schön und einfacher für Neueinsteiger, wenn es Programmbeispiele in allen Sprachvarianten (VB.NET, C# und C++) für alle Hardware-Varianten und alle Schnittstellen geben würde, aber der Aufwand wäre wahrscheinlich viel zu groß.

      Das wird es garantiert nie geben. Ja, man könnte sich überlegen, solche Aufrufe mal anhand eines Treibers in den Sprache C# und Visual Basic durchzuziehen, z.B. dem GPIO, so dass jeder mal schnell einen Test machen kann. Aber genau das ist meines Erachtens doch hier im Windows CE Samples Unterforum schon anhand der Beispiele bereits geschehen.

      Aber alles was darüber hinaus geht, ist ja gerade das Ziel, über das .NET-Zusatzpaket abzuwickeln. Und das ist wie gesagt mehr, als nur die Funktionen des Win32-Treibers 1:1 durchzureichen. Es sollte jedem Entwickler klar sein, wenn er ernsthaft mit .NET entwickeln will, dass dann der Zugriff auf einige der Treiber wie z.B. SPI, I2C oder CAN alles andere als trivial ist und dass das Zusatzpaket allemal billiger ist, als sowas selbst zu entwickeln. Wer auch nur wenige Tage daran sitzt und hier selbst was programmiert -- und dabei seine eigenen Entwicklungskosten halbwegs realistisch ansetzt -- der hat doch schon mehr Geld ausgegeben, als das ganze Zusatzpaket kostet.

      Hinsichtlich Beispielen in C# sieht es hier im Forum aber etwas schlecht aus. Die meisten Beispiele sind in C++ oder VB und man muss sich das selbst portieren...

      Siehe oben. Das kommt daher, dass wir diese Beispiele häufig selbst nicht haben und erst mühsam selbst erstellen müssen. Wir portieren überwiegend das Betriebssystem und die Treiber für die Boards, das geht alles komplett ohne .NET. Da sind die Tests eben in C oder C++ und da diese Tests häufig als Beispiele umfunktioniert werden können, sind eben viele Beispiele nur in C. Endapplikationen und damit C# oder VB-Programme, wo solche Beispiele mal automatisch abfallen würden, entwickeln wir halt nur vergleichsweise selten.

      Für unsere .NET-Klassen, die wir anbieten, haben wir aber schon ausreichend Beispiele. Man muss sich nur mal die entsprechenden Dokumentationen anschauen, z.B. hier, hier oder hier. Und diese Dokus können Sie sich herunterladen, bevor Sie das Zusatzpaket kaufen!
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

      Re: GPIO access via C#

      Leider ist der Quellcode für das Beispiel in der ZIP-Datei nicht vollständig (die IO-Bibliothek fehlt - Beispiel kann nicht neu kompiliert werden) und ist so für einen Einsteiger in der Form auch nicht brauchbarer, als die Dokumentation von F&S :(

      Upps, nicht aufgepasst beim Zippen. Hiermit nachgeholt.
      Files

      Re: GPIO access via C#

      @hkoettel:
      Vielen Dank, jetzt funktioniert alles. ;) Eine interessante Lösung und eine gute Anregung, mein Programm noch einmal zu überarbeiten.

      Thank you, everting is working now ;) A very interesting solution and a nice suggestion, to change my own program...
      Kind regards,
      H. Tefs

      Re: GPIO access via C#

      "fs-support_HK" wrote:

      In fact there is no need to write a special C# class for DIO to just toggle a pin. Simply create a FileStream object for DIO1: and use ReadByte() and WriteByte() on it. Done!

      A good idea! I doesn't see a "stream" on Bit- and Port-Handling.
      I have tested it, it's ok.
      But in the implementation from pc2_DIO.dll must be an error. Using of the method Filestream.Length generate an IOException-Error.
      If you set a breakpoint after

      Source Code

      1. fs = new FileStream("DIO1:", FileMode.Open, FileAccess.Read, FileShare.None, 1);

      an debug then the object fs, you see the problem at "Length".

      I use: VS2008, C#, PicoCOM2, Kernel 1.05 2009-08-17, CF3.5

      Re: GPIO access via C#

      Hello


      Verwenden Sie folgendes:

      FileStream file = new FileStream("DIO1:", FileMode.Open, FileAccess.ReadWrite, FileShare.None, 1);


      Schreiben:
      Code:
      file.Seek(port, SeekOrigin.Begin);
      file.WriteByte((byte)data);


      Lesen:
      Code:
      file.Seek(port, SeekOrigin.Begin);
      byte data = (byte) file.ReadByte();


      DKuhne
      F&amp;S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.
      I'm using an efusA9 with wec2013 in c#.net 2012
      i want to set io pin 82 high or low.
      this is bit 2 at port10

      if (SetFilePointer(FileHandle, port, 0, 0) == -1)

      return false;

      port = 10 here.
      This SetFilePointer function always returns -1 !
      How comes?
      what am i doing wrong?

      do i have to set something in the registry too?
      Hello,

      do i have to set something in the registry too?
      Just for call "SetFilePointer" no registry entry is required! Did you have a valid handle? Can you post the complete code?
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.