diff --git a/.gitignore b/.gitignore
index 9ac0ec3..0c70bf8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,8 @@
-# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
-bin
-obj
-
-# mstest test results
-TestResults
\ No newline at end of file
+# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
+bin
+obj
+
+# mstest test results
+TestResults
+
+RaspberryPiDotNet.suo
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..22fbe5d
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,339 @@
+GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {description}
+ Copyright (C) {year} {fullname}
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ {signature of Ty Coon}, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
\ No newline at end of file
diff --git a/README.md b/README.md
index ffa276a..37a1b40 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,159 @@
RaspberryPi.Net
===============
-Raspberry PI .NET library
\ No newline at end of file
+Introduction
+------------
+The purpose of this library is to provide a Mono.NET interface to the GPIO pins
+on the Raspberry Pi. All of this code was written using Visual Studio 2010
+Express but the goal is to be fully compatible with Mono. This library is
+written using .NET 4.0 therefore the latest version of Mono (2.10) is
+recommended. At the time of this update, the Raspbian wheezy 2012-07-15 image
+installs Mono 2.10.8.1.
+
+The GPIO pins are best described
+[here](http://elinux.org/Rpi_Low-level_peripherals#General_Purpose_Input.2FOutput_.28GPIO.29).
+They can be accessed in 2 ways, either using the file-based I/O (GPIOFile.cs)
+or direct memory (GPIOMem.cs) using Mike McCauley's BCM2835 library which is
+available [here](http://www.open.com.au/mikem/bcm2835/index.html). There is
+also a GPIODebug.cs class that can be used to test your application without a
+Raspberry Pi.
+
+Here is a sample bit of code to blink an LED attached to pin 12
+```C#
+using System;
+using RaspberryPiDotNet;
+
+namespace Test
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ GPIOMem led = new GPIOMem(GPIOPins.V2_GPIO_12)
+ while(true)
+ {
+ led.Write(PinState.High);
+ System.Threading.Thread.Sleep(500);
+ led.Write(PinState.Low);
+ System.Threading.Thread.Sleep(500);
+ }
+ }
+ }
+}
+```
+
+Installing Mono
+---------------
+To install Mono on your Raspberry Pi, run the following:
+```bash
+$ sudo aptitude update
+$ sudo aptitude install mono-runtime
+```
+
+My preference is for aptitude, however, apt-get can also be used.
+
+Using GPIOMem
+-------------
+The GPIOMem class uses the .NET Interop layer to expose C functions from Mike
+McCauley''s BCM2835 library. This requires the use of a separate shared object
+(.so) but this library is considerably faster than the GPIOFile method.
+
+The Makefile for his library compiles a shared object where a statically linked
+library is required. To compile a statically linked binary, do the following:
+
+```bash
+# tar -zxf bcm2835-1.3.tar.gz
+# cd bcm2835-1.3/src
+# make libbcm2835.a
+# cc -shared bcm2835.o -o libbcm2835.so
+```
+
+You can also try using our own compiled file [here](https://www.dropbox.com/s/716brdf0owbx4tf/libbcm2835.so). If it doesn't work, you must compile yourself. It must be in the same folder as the application.
+
+Liquid Crystal Display
+----------------------
+This class is a port of the MicroLiquidCrystal NetDuino library from
+[here](http://microliquidcrystal.codeplex.com). It provides an interface to
+address HD44780 compatible displays.
+
+Example code:
+```C#
+RaspPiGPIOMemLcdTransferProvider lcdProvider = new RaspPiGPIOMemLcdTransferProvider(
+ GPIOPins.Pin_P1_21,
+ GPIOPins.Pin_P1_18,
+ GPIOPins.Pin_P1_11,
+ GPIOPins.Pin_P1_13,
+ GPIOPins.Pin_P1_15,
+ GPIOPins.Pin_P1_19);
+
+
+Lcd lcd = new Lcd(lcdProvider);
+lcd.Begin(16, 2);
+lcd.Clear();
+lcd.SetCursorPosition(0, 0);
+lcd.Write("Hello World!");
+```
+
+Using MCP3008
+-------------
+This class is a port of a Python Script by Mikey Sklar
+[here](https://raw.github.com/gist/3249416/7689f68f3ddbb74aceecda23e395c729668bd520/adafruit-cosm-temp.py).
+It provides analog to digital conversion to the Raspberry Pi.
+
+The following example shows how to connect an analog temperature sensor to the Pi.
+
+Example code:
+```C#
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using RaspberryPiDotNet;
+
+namespace RPi_Temperature
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ //# set up the SPI interface pins
+ //# SPI port on the ADC to the Cobbler
+ GPIOMem SPICLK = new GPIOMem(GPIOPins.Pin_P1_18, GPIODirection.Out);
+ GPIOMem SPIMISO = new GPIOMem(GPIOPins.Pin_P1_23, GPIODirection.In);
+ GPIOMem SPIMOSI = new GPIOMem(GPIOPins.Pin_P1_24, GPIODirection.Out);
+ GPIOMem SPICS = new GPIOMem(GPIOPins.Pin_P1_22, GPIODirection.Out);
+
+ // temperature sensor connected to channel 0 of mcp3008
+ int adcnum = 0;
+ double read_adc0 = 0.0;
+
+ while (true)
+ {
+ MCP3008 MCP3008 = new MCP3008(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS);
+ // read the analog pin (temperature sensor LM35)
+ read_adc0 = MCP3008.AnalogToDigital;
+ double millivolts = Convert.ToDouble(read_adc0) * (3300.0 / 1024);
+
+ double volts = (Convert.ToDouble(read_adc0) / 1024.0f) * 3.3f;
+ double temp_C = ((millivolts - 100.0) / 10.0) - 40.0;
+ double temp_F = (temp_C * 9.0 / 5.0) + 32;
+
+# if DEBUG
+ System.Console.WriteLine("MCP3008_Channel: " + adcnum);
+ System.Console.WriteLine("read_adc0: " + read_adc0);
+ System.Console.WriteLine("millivolts: " + (float)millivolts);
+ System.Console.WriteLine("tempC: " + (float)temp_C);
+ System.Console.WriteLine("tempF: " + (float)temp_F);
+ System.Console.WriteLine("volts: " + (float)volts);
+ //The following line makes the trick on Raspberry Pi for displaying DateTime.Now
+ //equivalent.
+ Console.WriteLine("Date time stamp: {0}/{1}/{2} {3}:{4}:{5}",now.Month,now.Day,now.Year,
+ now.Hour,now.Minute,now.Second);
+ System.Console.WriteLine("\n");
+# endif
+ Thread.Sleep(3000);
+ }
+ }
+ }
+}
+```
diff --git a/RaspberryPiDotNet.sln.docstates.suo b/RaspberryPiDotNet.sln.docstates.suo
new file mode 100644
index 0000000..f067a31
Binary files /dev/null and b/RaspberryPiDotNet.sln.docstates.suo differ
diff --git a/RaspberryPiDotNet.suo b/RaspberryPiDotNet.suo
index 4e36650..8ee3d78 100644
Binary files a/RaspberryPiDotNet.suo and b/RaspberryPiDotNet.suo differ
diff --git a/RaspberryPiDotNet/DS1620.cs b/RaspberryPiDotNet/DS1620.cs
index 05e6c83..224c241 100644
--- a/RaspberryPiDotNet/DS1620.cs
+++ b/RaspberryPiDotNet/DS1620.cs
@@ -1,10 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-
-// Derived based on work done by AdamS at http://forums.netduino.com/index.php?/topic/3335-netduino-plus-and-ds1620-anyone/page__view__findpost__p__22972
+using System;
+using System.Threading;
+
+// Derived based on work done by AdamS at http://forums.netduino.com/index.php?/topic/3335-netduino-plus-and-ds1620-anyone/page__view__findpost__p__22972
+
namespace RaspberryPiDotNet
{
public class DS1620
@@ -37,11 +35,11 @@ public double Temperature
/// The command
private void SendCommand(int command)
{
- // Sends 8 bit command on DQ output, least sig bit first
- int n, bit;
+ // Sends 8 bit command on DQ output, least sig bit first
+ int n;
for (n = 0; n < 8; n++)
{
- bit = ((command >> n) & (0x01));
+ var bit = ((command >> n) & (0x01));
_dq.Write((bit == 1));
_clk.Write(false);
_clk.Write(true);
@@ -53,17 +51,14 @@ private void SendCommand(int command)
///
/// The temperature in half degree increments
private int ReadData()
- {
- int bit, n;
- int raw_data = 0; // go into input mode
+ {
+ int n;
+ var raw_data = 0; // go into input mode
for (n = 0; n < 9; n++)
{
_clk.Write(false);
- if (_dq.Read() == true)
- bit = 1;
- else
- bit = 0;
+ var bit = _dq.Read() == PinState.High ? 1 : 0;
_clk.Write(true);
raw_data = raw_data | (bit << n);
}
diff --git a/RaspberryPiDotNet/GPIO.cs b/RaspberryPiDotNet/GPIO.cs
index e06ec31..e75ce90 100644
--- a/RaspberryPiDotNet/GPIO.cs
+++ b/RaspberryPiDotNet/GPIO.cs
@@ -1,143 +1,241 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
// Author: Aaron Anderson
+
namespace RaspberryPiDotNet
{
- ///
- /// Abstract class for the GPIO connector on the Pi (P1) (as found next to the yellow RCA video socket on the Rpi circuit board)
- ///
- public abstract class GPIO : IDisposable
- {
- ///
- /// Refer to http://elinux.org/Rpi_Low-level_peripherals for diagram.
- /// P1-01 = bottom left, P1-02 = top left
- /// pi connector P1 pin = GPIOnum
- /// P1-03 = GPIO0
- /// P1-05 = GPIO1
- /// P1-07 = GPIO4
- /// P1-08 = GPIO14 - alt function (UART0_TXD) on boot-up
- /// P1-10 = GPIO15 - alt function (UART0_TXD) on boot-up
- /// P1-11 = GPIO17
- /// P1-12 = GPIO18
- /// P1-13 = GPIO21
- /// P1-15 = GPIO22
- /// P1-16 = GPIO23
- /// P1-18 = GPIO24
- /// P1-19 = GPIO10
- /// P1-21 = GPIO9
- /// P1-22 = GPIO25
- /// P1-23 = GPIO11
- /// P1-24 = GPIO8
- /// P1-26 = GPIO7
- /// So to turn on Pin7 on the GPIO connector, pass in enumGPIOPIN.gpio4 as the pin parameter
- ///
- public enum GPIOPins
- {
- GPIO_NONE = -1,
- GPIO00 = 0,
- GPIO01 = 1,
- GPIO04 = 4,
- GPIO07 = 7,
- GPIO08 = 8,
- GPIO09 = 9,
- GPIO10 = 10,
- GPIO11 = 11,
- GPIO14 = 14,
- GPIO15 = 15,
- GPIO17 = 17,
- GPIO18 = 18,
- GPIO21 = 21,
- GPIO22 = 22,
- GPIO23 = 23,
- GPIO24 = 24,
- GPIO25 = 25,
- Pin03 = 0,
- Pin05 = 1,
- Pin07 = 4,
- Pin08 = 14,
- Pin10 = 15,
- Pin11 = 17,
- Pin12 = 18,
- Pin13 = 21,
- Pin15 = 22,
- Pin16 = 23,
- Pin18 = 24,
- Pin19 = 10,
- Pin21 = 9,
- Pin22 = 25,
- Pin23 = 11,
- Pin24 = 8,
- Pin26 = 7
- };
+ ///
+ /// Abstract class for the GPIO connector on the Pi (P1) (as found next to the yellow RCA video socket on the Rpi circuit board)
+ ///
+ public abstract class GPIO : IDisposable
+ {
+ ///
+ /// Dictionary that stores created (exported) pins that where not disposed.
+ ///
+ private static Dictionary _exportedPins = new Dictionary();
- ///
- /// Specifies the direction of the GPIO port
- ///
- public enum DirectionEnum { IN, OUT };
+ ///
+ /// The currently assigned GPIO pin. Used for class methods.
+ ///
+ protected readonly GPIOPins _pin;
- ///
- /// Dictionary that stores whether a pin is setup or not
- ///
- protected static Dictionary _exportedPins = new Dictionary();
+ ///
+ /// Variable to track the disposed state
+ ///
+ private bool _disposed = false;
///
- /// The currently assigned GPIO pin. Used for class methods and not static methods.
+ /// Direction of the GPIO pin
///
- protected GPIOPins _pin;
+ private GPIODirection _direction;
///
- /// Access to the specified GPIO setup as an output port with an initial value of false (0)
+ /// GPIO pull up-down resistor
///
- /// The GPIO pin
- public GPIO(GPIOPins pin)
- : this(pin,DirectionEnum.OUT,false)
- {
- }
+ // BCM2835_GPIO_PUD_OFF = 0b00 = 0
+ // BCM2835_GPIO_PUD_DOWN = 0b01 = 1
+ // BCM2835_GPIO_PUD_UP = 0b10 = 2
+ public GPIOResistor _resistor = GPIOResistor.OFF;
- ///
- /// Access to the specified GPIO setup with the specified direction with an initial value of false (0)
- ///
- /// The GPIO pin
- /// Direction
- public GPIO(GPIOPins pin, DirectionEnum direction)
- : this(pin, direction, false)
- {
- }
+ ///
+ /// Gets the pin that this GPIO instance represents
+ ///
+ public GPIOPins Pin {
+ get {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+ return _pin;
+ }
+ }
+
+ ///
+ /// Gets the bit mask of this pin.
+ ///
+ public GPIOPinMask Mask {
+ get {
+ return (GPIOPinMask)(1 << (ushort)Pin); //Pin-Value has a low range (0-~32), so even casting to byte would be ok.
+ }
+ }
+
+ ///
+ /// Gets or sets the communication direction for this pin
+ ///
+ public virtual GPIODirection PinDirection {
+ get {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+ return _direction;
+ }
+ set {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+ _direction = value;
+ }
+ }
///
- /// Access to the specified GPIO setup with the specified direction with the specified initial value
+ /// Gets or sets the internal resistor value for the pin
///
- /// The GPIO pin
- /// Direction
- /// Initial Value
- public GPIO(GPIOPins pin, DirectionEnum direction, bool initialValue)
+ public virtual GPIOResistor Resistor
{
- this._pin = pin;
+ get
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+ return _resistor;
+ }
+ set
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+ _resistor = value;
+ }
}
- protected static string GetGPIONumber(GPIOPins pin)
- {
- return ((int)pin).ToString(); //e.g. returns 17 for enum value of gpio17
- }
+ ///
+ /// Gets the disposal state of this GPIO instance
+ ///
+ public bool IsDisposed {
+ get {
+ return _disposed;
+ }
+ }
- ///
- /// Write a value to the pin
- ///
- /// The value to write to the pin
- public abstract void Write(bool value);
+ ///
+ /// Access to the specified GPIO setup with the specified direction with the specified initial value
+ ///
+ /// The GPIO pin
+ /// Direction
+ /// Initial Value
+ protected GPIO(GPIOPins pin, GPIODirection direction, bool initialValue) {
+ if (pin == GPIOPins.GPIO_NONE) throw new ArgumentException("Invalid pin");
+ lock (_exportedPins) {
+ if (_exportedPins.ContainsKey(pin))
+ throw new Exception("Cannot use pin with multiple instances. Unexport the previous instance with Dispose() first! (pin " + (uint)pin + ")");
+ _exportedPins[pin] = this;
- ///
- /// Read a value from the pin
- ///
- /// The value read from the pin
- public abstract bool Read();
+ _pin = pin;
+ try {
+ PinDirection = direction;
+ Write(initialValue);
+ }
+ catch {
+ Dispose();
+ throw;
+ }
+ }
+ }
- ///
- /// Dispose of the GPIO pin
- ///
- public abstract void Dispose();
- }
+ ///
+ /// Finalizer to make sure we cleanup after ourselves.
+ ///
+ ~GPIO() {
+ if (!_disposed)
+ Dispose();
+ }
+
+ ///
+ /// Sets a pin to output the give value.
+ ///
+ /// Creates (exports) the pin if needed, and sets it to Out direction.
+ ///
+ /// The pin who's value to set
+ /// The value to set
+ public static void Write(GPIOPins pin, bool value) {
+ CreatePin(pin, GPIODirection.Out).Write(value);
+ }
+
+ ///
+ /// Gets the value of a given pin.
+ ///
+ /// Creates (exports) the pin if needed, and sets it to In direction.
+ ///
+ /// The pin who's value to get
+ /// The value of the pin
+ public static PinState Read(GPIOPins pin) {
+ return CreatePin(pin, GPIODirection.In).Read();
+ }
+
+ ///
+ /// Creates a pin if it has not already been created (exported), creates a GPIOMem if possible, otherwise falls back to GPIOFile.
+ ///
+ /// The pin to create or export
+ /// The direction the pin is to have
+ /// The GPIO instance representing the pin
+ public static GPIO CreatePin(GPIOPins pin, GPIODirection dir) {
+ lock (_exportedPins)
+ if (_exportedPins.ContainsKey(pin)) {
+ if (_exportedPins[pin].PinDirection != dir)
+ _exportedPins[pin].PinDirection = dir;
+ return _exportedPins[pin];
+ }
+
+ try {
+ return new GPIOMem(pin, dir);
+ }
+#if DEBUG
+ catch (Exception e) {
+ System.Diagnostics.Debug.WriteLine("Unable to create pin " + (uint)pin + " as GPIOMem because: " + e.ToString());
+ }
+#else
+ catch //stuff like lib load problems, wrong exports, etc...
+ {
+ }
+#endif
+ try {
+ return new GPIOFile(pin, dir);
+ }
+#if DEBUG
+ catch (Exception e) {
+ System.Diagnostics.Debug.WriteLine("Unable to create pin " + (uint)pin + " as GPIOFile because: " + e.ToString());
+ }
+#else
+ catch //stuff like GPIO Sys FS does not exist or is not responding, open by another process, etc...
+ {
+ }
+#endif
+
+#if DEBUG
+ System.Diagnostics.Debug.WriteLine("Using debug GPIO pin for pin number " + (uint)pin);
+ return new GPIODebug(pin, dir);
+#else
+ throw new Exception("Cannot access GPIO pin " + (uint)pin + ". Make sure libbcm2835.so is accessible, or that GPIO SYSFS is working and not in use by another process");
+#endif
+ }
+
+ ///
+ /// Write a value to the pin
+ ///
+ /// The value to write to the pin
+ public virtual void Write(bool value) {
+ if (IsDisposed)
+ throw new ObjectDisposedException(string.Empty);
+ if (_direction != GPIODirection.Out)
+ PinDirection = GPIODirection.Out;
+ }
+
+ ///
+ /// Read a value from the pin
+ ///
+ /// The value read from the pin
+ public virtual PinState Read() {
+ if (IsDisposed)
+ throw new ObjectDisposedException(string.Empty);
+ return PinState.Low;
+ }
+
+ ///
+ /// Dispose of the GPIO pin
+ ///
+ public virtual void Dispose() {
+ if (_disposed)
+ throw new ObjectDisposedException(string.Empty);
+
+ _disposed = true;
+ lock (_exportedPins) {
+ _exportedPins.Remove(_pin);
+ }
+ }
+ }
}
diff --git a/RaspberryPiDotNet/GPIODebug.cs b/RaspberryPiDotNet/GPIODebug.cs
new file mode 100644
index 0000000..f00aa0d
--- /dev/null
+++ b/RaspberryPiDotNet/GPIODebug.cs
@@ -0,0 +1,67 @@
+namespace RaspberryPiDotNet
+{
+ ///
+ /// Raspberry Pi GPIO debug class.
+ ///
+// ReSharper disable once InconsistentNaming
+ public class GPIODebug : GPIO
+ {
+ private bool _currentValue;
+
+ #region Constructor
+ ///
+ /// Access to the specified GPIO setup as an output port with an initial value of false (0)
+ ///
+ /// The GPIO pin
+ public GPIODebug(GPIOPins pin)
+ : this(pin,GPIODirection.Out,false)
+ {
+ }
+
+ ///
+ /// Access to the specified GPIO setup with the specified direction with an initial value of false (0)
+ ///
+ /// The GPIO pin
+ /// Direction
+ public GPIODebug(GPIOPins pin, GPIODirection direction)
+ : this(pin, direction, false)
+ {
+ }
+
+ ///
+ /// Access to the specified GPIO setup with the specified direction with the specified initial value
+ ///
+ /// The GPIO pin
+ /// Direction
+ /// Initial Value
+ public GPIODebug(GPIOPins pin, GPIODirection direction, bool initialValue)
+ : base(pin, direction, initialValue)
+ {
+ }
+ #endregion
+
+ #region Class Methods
+ ///
+ /// Write a value to the pin
+ ///
+ /// The value to write to the pin
+ public override void Write(bool value)
+ {
+ System.Diagnostics.Debug.WriteLine("GPIO pin " + _pin + " set to " + value);
+ base.Write(value);
+ _currentValue = value;
+ }
+
+ ///
+ /// Read a value from the pin
+ ///
+ /// The value read from the pin
+ public override PinState Read()
+ {
+ System.Diagnostics.Debug.WriteLine("GPIO pin " + _pin + " reads as " + _currentValue);
+ base.Read();
+ return _currentValue ? PinState.High : PinState.Low;
+ }
+ #endregion
+ }
+}
diff --git a/RaspberryPiDotNet/GPIODirection.cs b/RaspberryPiDotNet/GPIODirection.cs
new file mode 100644
index 0000000..1333a17
--- /dev/null
+++ b/RaspberryPiDotNet/GPIODirection.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RaspberryPiDotNet
+{
+ ///
+ /// Specifies the direction of the GPIO port
+ ///
+ public enum GPIODirection { In, Out };
+}
diff --git a/RaspberryPiDotNet/GPIOFile.cs b/RaspberryPiDotNet/GPIOFile.cs
index 0f1665c..f0e0fa5 100644
--- a/RaspberryPiDotNet/GPIOFile.cs
+++ b/RaspberryPiDotNet/GPIOFile.cs
@@ -1,22 +1,20 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Diagnostics;
-using System.IO;
+using System.IO;
// Author: Aaron Anderson
// Based on work done by x4m and britguy (http://www.raspberrypi.org/phpBB3/viewtopic.php?f=34&t=6720)
+
namespace RaspberryPiDotNet
{
///
/// Raspberry Pi GPIO using the file-based access method.
///
- public class GPIOFile : GPIO, IDisposable
+ // ReSharper disable once InconsistentNaming
+ public class GPIOFile : GPIO
{
///
/// The path on the Raspberry Pi for the GPIO interface
///
+ // ReSharper disable once InconsistentNaming
private const string GPIO_PATH = "/sys/class/gpio/";
#region Constructor
@@ -25,7 +23,7 @@ public class GPIOFile : GPIO, IDisposable
///
/// The GPIO pin
public GPIOFile(GPIOPins pin)
- : base(pin,DirectionEnum.OUT,false)
+ : this(pin,GPIODirection.Out,false)
{
}
@@ -34,10 +32,9 @@ public GPIOFile(GPIOPins pin)
///
/// The GPIO pin
/// Direction
- public GPIOFile(GPIOPins pin, DirectionEnum direction)
- : base(pin, direction, false)
+ public GPIOFile(GPIOPins pin, GPIODirection direction)
+ : this(pin, direction, false)
{
- ExportPin(pin, direction);
}
///
@@ -46,140 +43,68 @@ public GPIOFile(GPIOPins pin, DirectionEnum direction)
/// The GPIO pin
/// Direction
/// Initial Value
- public GPIOFile(GPIOPins pin, DirectionEnum direction, bool initialValue)
+ public GPIOFile(GPIOPins pin, GPIODirection direction, bool initialValue)
: base(pin, direction, initialValue)
{
- ExportPin(pin, direction);
- Write(pin, initialValue);
}
- ~GPIOFile()
- {
- UnexportPin(_pin);
- }
#endregion
- #region Static Methods
- ///
- /// Export the GPIO setting the direction. This creates the /sys/class/gpio/gpioXX directory.
- ///
- /// The GPIO pin
- ///
- private static void ExportPin(GPIOPins pin, DirectionEnum direction)
- {
- // If the pin is already exported, check it's in the proper direction
- if (_exportedPins.Keys.Contains((int)pin))
- // If the direction matches, return out of the function. If not, change the direction
- if (_exportedPins[(int)pin] == direction)
- return;
- else
- {
- // Set the direction on the pin and update the exported list
- File.WriteAllText(GPIO_PATH + "gpio" + GetGPIONumber(pin) + "/direction", direction.ToString().ToLower());
- _exportedPins[(int)pin] = direction;
- return;
- }
-
- if (!Directory.Exists(GPIO_PATH + "gpio" + GetGPIONumber(pin)))
- {
- Debug.WriteLine("Exporting " + GetGPIONumber(pin));
- //export
- File.WriteAllText(GPIO_PATH + "export", GetGPIONumber(pin));
- }
-
- // set i/o direction
- Debug.WriteLine("Setting direction on pin " + pin + "/gpio " + (int)pin + " as " + direction);
- File.WriteAllText(GPIO_PATH + "gpio" + GetGPIONumber(pin) + "/direction", direction.ToString().ToLower());
-
- // Update the list of exported pins
- _exportedPins[(int)pin] = direction;
- }
-
- ///
- /// Unexport the GPIO. This removes the /sys/class/gpio/gpioXX directory.
- ///
- /// The pin to unexport
- private static void UnexportPin(GPIOPins pin)
- {
- Debug.WriteLine("unexporting pin " + pin);
- File.WriteAllText(GPIO_PATH + "unexport", GetGPIONumber(pin));
-
- // Remove the pin from the list of exported pins
- _exportedPins.Remove((int)pin);
- }
+ #region Properties
+
+ ///
+ /// Gets or sets the communication direction for this pin
+ ///
+ public override GPIODirection PinDirection
+ {
+ get
+ {
+ return base.PinDirection;
+ }
+ set
+ {
+ if (PinDirection != (base.PinDirection = value)) // Left to right eval ensures base class gets to check for disposed object access
+ {
+ if (!Directory.Exists(GPIO_PATH + "gpio" + (uint)_pin))
+ File.WriteAllText(GPIO_PATH + "export", ((uint)_pin).ToString());
+
+ // set i/o direction
+ File.WriteAllText(GPIO_PATH + "gpio" + (uint)_pin + "/direction", value.ToString().ToLower());
+ }
+ }
+ }
+
+ #endregion
+ #region Class Methods
///
- /// Static method to write a value to the specified pin. When using the static methods ensure you use the CleanUp() method when done.
+ /// Write a value to the pin
///
- /// The GPIO pin
/// The value to write to the pin
- public static void Write(GPIOPins pin, bool value)
- {
- if (pin == GPIOPins.GPIO_NONE)
- return;
-
- ExportPin(pin, DirectionEnum.OUT);
-
- string writeValue = value ? "1" : "0";
- File.WriteAllText(GPIO_PATH + "gpio" + GetGPIONumber(pin) + "/value", writeValue);
- Debug.WriteLine("output to pin " + pin + "/gpio " + (int)pin + ", value was " + value);
- }
-
- ///
- /// Static method to read a value to the specified pin. When using the static methods ensure you use the CleanUp() method when done.
- ///
- /// The GPIO pin
- /// The value read from the pin
- public static bool Read(GPIOPins pin)
- {
- bool returnValue = false;
-
- ExportPin(pin, DirectionEnum.IN);
-
- string filename = GPIO_PATH + "gpio" + GetGPIONumber(pin) + "/value";
- if (File.Exists(filename))
- {
- string readValue = File.ReadAllText(filename);
- if (readValue.Length > 0 && readValue[0] == '1')
- returnValue = true;
- }
- else
- throw new Exception(string.Format("Cannot read from {0}. File does not exist", pin));
-
- Debug.WriteLine("input from pin " + pin + "/gpio " + (int)pin + ", value was " + returnValue);
-
- return returnValue;
- }
-
- public static void CleanUp()
+ public override void Write(bool value)
{
- // Loop over all exported pins and unexported them
- foreach (GPIOPins pin in _exportedPins.Keys)
- {
- UnexportPin(pin);
- }
+ base.Write(value);
+ File.WriteAllText(GPIO_PATH + "gpio" + (uint)_pin + "/value", value ? "1" : "0");
}
- #endregion
- #region Class Methods
///
/// Write a value to the pin
///
/// The value to write to the pin
- public override void Write(bool value)
+ public void Write(PinState value)
{
- // Call the static method
- Write(_pin, value);
+ Write(value == PinState.High);
}
///
/// Read a value from the pin
///
/// The value read from the pin
- public override bool Read()
+ public override PinState Read()
{
- // Call the static method
- return Read(_pin);
+ base.Read();
+ var readValue = File.ReadAllText(GPIO_PATH + "gpio" + (uint)_pin + "/value");
+ return (readValue.Length > 0 && readValue[0] == '1') ? PinState.High : PinState.Low;
}
///
@@ -187,7 +112,8 @@ public override bool Read()
///
public override void Dispose()
{
- UnexportPin(_pin);
+ base.Dispose();
+ File.WriteAllText(GPIO_PATH + "unexport", ((uint)_pin).ToString());
}
#endregion
}
diff --git a/RaspberryPiDotNet/GPIOMem.cs b/RaspberryPiDotNet/GPIOMem.cs
index c39d14a..d656eb5 100644
--- a/RaspberryPiDotNet/GPIOMem.cs
+++ b/RaspberryPiDotNet/GPIOMem.cs
@@ -1,176 +1,176 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.Runtime.InteropServices;
-using System.Diagnostics;
namespace RaspberryPiDotNet
{
- ///
- /// Raspberry Pi GPIO using the direct memory access method.
- /// This requires the bcm2835 GPIO library provided by
- /// Mike McCauley (mikem@open.com.au) at http://www.open.com.au/mikem/bcm2835/index.html.
- ///
- /// To create the shared object, download the source code from the link above. The standard Makefile compiles a
- /// statically linked library. To build a shared object, do:
- /// tar -zxf bcm2835-1.3.tar.gz
- /// cd bcm2835-1.3/src
- /// make libbcm2835.a
- /// cc -shared bcm2835.o -o libbcm2835.so
- ///
- public class GPIOMem : GPIO, IDisposable
- {
- private static bool _initialized = false;
-
- #region Constructor
- ///
- /// Access to the specified GPIO setup as an output port with an initial value of false (0)
- ///
- /// The GPIO pin
- public GPIOMem(GPIOPins pin)
- : base(pin,DirectionEnum.OUT,false)
- {
- }
-
- ///
- /// Access to the specified GPIO setup with the specified direction with an initial value of false (0)
- ///
- /// The GPIO pin
- /// Direction
- public GPIOMem(GPIOPins pin, DirectionEnum direction)
- : base(pin, direction, false)
- {
- ExportPin(pin, direction);
- }
-
- ///
- /// Access to the specified GPIO setup with the specified direction with the specified initial value
- ///
- /// The GPIO pin
- /// Direction
- /// Initial Value
- public GPIOMem(GPIOPins pin, DirectionEnum direction, bool initialValue)
- : base(pin, direction, initialValue)
- {
- ExportPin(pin, direction);
- Write(pin, initialValue);
- }
- #endregion
+ ///
+ /// Raspberry Pi GPIO using the direct memory access method.
+ /// This requires the bcm2835 GPIO library provided by
+ /// Mike McCauley (mikem@open.com.au) at http://www.open.com.au/mikem/bcm2835/index.html.
+ ///
+ /// To create the shared object, download the source code from the link above. The standard Makefile compiles a
+ /// statically linked library. To build a shared object, do:
+ /// tar -zxf bcm2835-1.3.tar.gz
+ /// cd bcm2835-1.3/src
+ /// make libbcm2835.a
+ /// cc -shared bcm2835.o -o libbcm2835.so
+ /// Place the shared object in the same directory as the executable and other assemblies.
+ ///
+ public class GPIOMem : GPIO
+ {
+ #region Static Constructor
+ static GPIOMem() {
+ // initialize the mapped memory
+ if (!bcm2835_init())
+ throw new Exception("Unable to initialize bcm2835.so library");
+ }
+ #endregion
+
+ #region Constructor
+ ///
+ /// Access to the specified GPIO setup as an output port with an initial value of false (0)
+ ///
+ /// The GPIO pin
+ public GPIOMem(GPIOPins pin)
+ : this(pin, GPIODirection.Out, false) {
+ }
+
+ ///
+ /// Access to the specified GPIO setup with the specified direction with an initial value of false (0)
+ ///
+ /// The GPIO pin
+ /// Direction
+ public GPIOMem(GPIOPins pin, GPIODirection direction)
+ : this(pin, direction, false) {
+ }
+
+ ///
+ /// Access to the specified GPIO setup with the specified direction with the specified initial value
+ ///
+ /// The GPIO pin
+ /// Direction
+ /// Initial Value
+ public GPIOMem(GPIOPins pin, GPIODirection direction, bool initialValue)
+ : base(pin, direction, initialValue) {
+ }
+ #endregion
+
+ #region Properties
+ ///
+ /// Gets or sets the communication direction for this pin
+ ///
+ public override GPIODirection PinDirection {
+ get {
+ return base.PinDirection;
+ }
+ set {
+ if (PinDirection != (base.PinDirection = value)) // Left to right eval ensures base class gets to check for disposed object access
+ {
+ // Set the direction on the pin
+ bcm2835_gpio_fsel(_pin, value == GPIODirection.Out);
+ if (value == GPIODirection.In)
+ Resistor = GPIOResistor.OFF;
+ }
+ }
+ }
- #region Static Methods
///
- /// Initialize the memory access to the GPIO
+ /// Gets or sets the internal resistor value for the pin
///
- ///
- private static bool Initialize()
+ public override GPIOResistor Resistor
{
- int ret = 1;
- if (!_initialized)
- {
- // initialize the mapped memory
- ret = bcm2835_init();
- _initialized = true;
+ get {
+ return base.Resistor;
}
-
- return ret == 0 ? false : true;
- }
-
- ///
- /// Export the GPIO setting the direction. This creates the /sys/class/gpio/gpioXX directory.
- ///
- /// The GPIO pin
- ///
- private static void ExportPin(GPIOPins pin, DirectionEnum direction)
- {
- Initialize();
-
- // If the pin is already exported, check it's in the proper direction
- if (_exportedPins.Keys.Contains((int)pin))
- // If the direction matches, return out of the function. If not, change the direction
- if (_exportedPins[(int)pin] == direction)
- return;
- else
+ set {
+ if (Resistor != (base.Resistor = value)) // Left to right eval ensures base class gets to check for disposed object access
{
- // Set the direction on the pin and update the exported list
- bcm2835_gpio_fsel((uint)pin, direction == DirectionEnum.IN ? (uint)0 : (uint)1);
- _exportedPins[(int)pin] = direction;
- return;
+ bcm2835_gpio_set_pud(_pin, (uint)value);
}
+ }
}
+ #endregion
+
+ #region Class Methods
+ ///
+ /// Write a value to the pin
+ ///
+ /// The value to write to the pin
+ public override void Write(bool value) {
+ base.Write(value);
+ bcm2835_gpio_write(_pin, value);
+ }
- ///
- /// Static method to write a value to the specified pin.
- ///
- /// The GPIO pin
- /// The value to write to the pin
- public static void Write(GPIOPins pin, bool value)
- {
- if (pin == GPIOPins.GPIO_NONE)
- return;
-
- ExportPin(pin, DirectionEnum.OUT);
-
- bcm2835_gpio_write((uint)pin, value ? (uint)1 : (uint)0);
- Debug.WriteLine("output to pin " + pin + "/gpio " + (int)pin + ", value was " + value);
- }
-
- ///
- /// Static method to read a value to the specified pin.
- ///
- /// The GPIO pin
- /// The value read from the pin
- public static bool Read(GPIOPins pin)
- {
- ExportPin(pin, DirectionEnum.IN);
-
- uint value = bcm2835_gpio_lev((uint)pin);
- bool returnValue = value == 0 ? false : true;
- Debug.WriteLine("input from pin " + pin + "/gpio " + (int)pin + ", value was " + returnValue);
-
- return returnValue;
- }
- #endregion
-
- #region Class Methods
///
/// Write a value to the pin
///
- /// The value to write to the pin
- public override void Write(bool value)
+ ///
+ public void Write(PinState pinState)
{
- Write(_pin, value);
+ Write(pinState == PinState.High);
}
- ///
- /// Read a value from the pin
- ///
- /// The value read from the pin
- public override bool Read()
- {
- return Read(_pin);
- }
-
- ///
- /// Dispose of the GPIO pin
- ///
- public override void Dispose()
+ ///
+ /// Read a value from the pin
+ ///
+ /// The value read from the pin
+ public override PinState Read()
{
- }
- #endregion
-
- #region Imported functions
- [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")]
- static extern int bcm2835_init();
-
- [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_fsel")]
- static extern void bcm2835_gpio_fsel(uint pin, uint mode);
-
- [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write")]
- static extern void bcm2835_gpio_write(uint pin, uint value);
-
- [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write")]
- static extern uint bcm2835_gpio_lev(uint pin);
- #endregion
- }
+ base.Read();
+ return bcm2835_gpio_lev(_pin) ? PinState.High : PinState.Low;
+ }
+ #endregion
+
+ #region Imported functions
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_init")]
+ static extern bool bcm2835_init();
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_fsel")]
+ static extern void bcm2835_gpio_fsel(GPIOPins pin, bool mode_out);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write")]
+ static extern void bcm2835_gpio_write(GPIOPins pin, bool value);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_lev")]
+ static extern bool bcm2835_gpio_lev(GPIOPins pin);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_set_pud")]
+ static extern void bcm2835_gpio_set_pud(GPIOPins pin, uint pud);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_set_multi")]
+ static extern void bcm2835_gpio_set_multi(GPIOPinMask mask);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_clr_multi")]
+ static extern void bcm2835_gpio_clr_multi(GPIOPinMask mask);
+
+ [DllImport("libbcm2835.so", EntryPoint = "bcm2835_gpio_write_multi")]
+ static extern void bcm2835_gpio_write_multi(GPIOPinMask mask, bool on);
+
+ #endregion
+
+ ///
+ /// Sets any of the first 32 GPIO output pins specified in the mask to HIGH.
+ ///
+ /// Mask of pins to affect. Use eg: (GPIOPinMask.GPIO_00) | GPIOPinMask.GPIO_01)
+ public static void SetMulti(GPIOPinMask mask) {
+ bcm2835_gpio_set_multi(mask);
+ }
+
+ ///
+ /// Sets any of the first 32 GPIO output pins specified in the mask to LOW.
+ ///
+ /// Mask of pins to affect. Use eg: (GPIOPinMask.GPIO_00) | GPIOPinMask.GPIO_01)
+ public static void ClearMulti(GPIOPinMask mask) {
+ bcm2835_gpio_clr_multi(mask);
+ }
+
+ ///
+ /// Sets any of the first 32 GPIO output pins specified in the mask to value.
+ ///
+ /// Mask of pins to affect. Use eg: (GPIOPinMask.GPIO_00) | GPIOPinMask.GPIO_01)
+ public static void WriteMulti(GPIOPinMask mask, bool value) {
+ bcm2835_gpio_write_multi(mask, value);
+ }
+
+ }
}
diff --git a/RaspberryPiDotNet/GPIOPins.cs b/RaspberryPiDotNet/GPIOPins.cs
new file mode 100644
index 0000000..0e488eb
--- /dev/null
+++ b/RaspberryPiDotNet/GPIOPins.cs
@@ -0,0 +1,243 @@
+namespace RaspberryPiDotNet
+{
+ ///
+ /// Refer to http://elinux.org/Rpi_Low-level_peripherals for diagram.
+ /// P1-01 = bottom left, P1-02 = top left
+ /// pi connector P1 pin = GPIOnum
+ /// P1-03 = GPIO0
+ /// P1-05 = GPIO1
+ /// P1-07 = GPIO4
+ /// P1-08 = GPIO14 - alt function (UART0_TXD) on boot-up
+ /// P1-10 = GPIO15 - alt function (UART0_TXD) on boot-up
+ /// P1-11 = GPIO17
+ /// P1-12 = GPIO18
+ /// P1-13 = GPIO21
+ /// P1-15 = GPIO22
+ /// P1-16 = GPIO23
+ /// P1-18 = GPIO24
+ /// P1-19 = GPIO10
+ /// P1-21 = GPIO9
+ /// P1-22 = GPIO25
+ /// P1-23 = GPIO11
+ /// P1-24 = GPIO8
+ /// P1-26 = GPIO7
+ ///
+ /// P5-03 = GPI28
+ /// P5-04 = GPI29
+ /// P5-05 = GPI30
+ /// P5-06 = GPI31
+ ///
+ /// So to turn on Pin7 on the GPIO connector, pass in enumGPIOPIN.gpio4 as the pin parameter
+ ///
+ public enum GPIOPins : uint
+ {
+
+ GPIO_NONE = uint.MaxValue,
+
+ //Revision 1
+
+ GPIO_00 = 0,
+ GPIO_01 = 1,
+ GPIO_04 = 4,
+ GPIO_07 = 7,
+ GPIO_08 = 8,
+ GPIO_09 = 9,
+ GPIO_10 = 10,
+ GPIO_11 = 11,
+ GPIO_14 = 14,
+ GPIO_15 = 15,
+ GPIO_17 = 17,
+ GPIO_18 = 18,
+ GPIO_21 = 21,
+ GPIO_22 = 22,
+ GPIO_23 = 23,
+ GPIO_24 = 24,
+ GPIO_25 = 25,
+
+ Pin_P1_03 = 0,
+ Pin_P1_05 = 1,
+ Pin_P1_07 = 4,
+ Pin_P1_08 = 14,
+ Pin_P1_10 = 15,
+ Pin_P1_11 = 17,
+ Pin_P1_12 = 18,
+ Pin_P1_13 = 21,
+ Pin_P1_15 = 22,
+ Pin_P1_16 = 23,
+ Pin_P1_18 = 24,
+ Pin_P1_19 = 10,
+ Pin_P1_21 = 9,
+ Pin_P1_22 = 25,
+ Pin_P1_23 = 11,
+ Pin_P1_24 = 8,
+ Pin_P1_26 = 7,
+ LED = 16,
+
+ //Revision 2
+
+ V2_GPIO_00 = 0,
+ V2_GPIO_02 = 2,
+ V2_GPIO_03 = 3,
+ V2_GPIO_01 = 1,
+ V2_GPIO_04 = 4,
+ V2_GPIO_07 = 7,
+ V2_GPIO_08 = 8,
+ V2_GPIO_09 = 9,
+ V2_GPIO_10 = 10,
+ V2_GPIO_11 = 11,
+ V2_GPIO_14 = 14,
+ V2_GPIO_15 = 15,
+ V2_GPIO_17 = 17,
+ V2_GPIO_18 = 18,
+ V2_GPIO_21 = 21,
+ V2_GPIO_22 = 22,
+ V2_GPIO_23 = 23,
+ V2_GPIO_24 = 24,
+ V2_GPIO_25 = 25,
+ V2_GPIO_27 = 27,
+
+ //Revision 2, new plug P5
+ V2_GPIO_28 = 28,
+ V2_GPIO_29 = 29,
+ V2_GPIO_30 = 30,
+ V2_GPIO_31 = 31,
+
+ V2_Pin_P1_03 = 2,
+ V2_Pin_P1_05 = 3,
+ V2_Pin_P1_07 = 4,
+ V2_Pin_P1_08 = 14,
+ V2_Pin_P1_10 = 15,
+ V2_Pin_P1_11 = 17,
+ V2_Pin_P1_12 = 18,
+ V2_Pin_P1_13 = 27,
+ V2_Pin_P1_15 = 22,
+ V2_Pin_P1_16 = 23,
+ V2_Pin_P1_18 = 24,
+ V2_Pin_P1_19 = 10,
+ V2_Pin_P1_21 = 9,
+ V2_Pin_P1_22 = 25,
+ V2_Pin_P1_23 = 11,
+ V2_Pin_P1_24 = 8,
+ V2_Pin_P1_26 = 7,
+ V2_LED = 16,
+
+ //Revision 2, new plug P5
+ V2_Pin_P5_03 = 28,
+ V2_Pin_P5_04 = 29,
+ V2_Pin_P5_05 = 30,
+ V2_Pin_P5_06 = 31,
+
+ //A+ and B+ pins
+ V2Plus_Pin_P1_29 = 5,
+ V2Plus_Pin_P1_31 = 6,
+ V2Plus_Pin_P1_32 = 12,
+ V2Plus_Pin_P1_33 = 13,
+ V2Plus_Pin_P1_35 = 19,
+ V2Plus_Pin_P1_36 = 16,
+ V2Plus_Pin_P1_37 = 26,
+ V2Plus_Pin_P1_38 = 20,
+ V2Plus_Pin_P1_40 = 21,
+
+ };
+
+ public enum GPIOPinMask : uint
+ {
+
+ GPIO_NONE = uint.MaxValue,
+
+ //Revision 1
+
+ GPIO_00 = 0,
+ GPIO_01 = 1,
+ GPIO_04 = 1 << 4,
+ GPIO_07 = 1 << 7,
+ GPIO_08 = 1 << 8,
+ GPIO_09 = 1 << 9,
+ GPIO_10 = 1 << 10,
+ GPIO_11 = 1 << 11,
+ GPIO_14 = 1 << 14,
+ GPIO_15 = 1 << 15,
+ GPIO_17 = 1 << 17,
+ GPIO_18 = 1 << 18,
+ GPIO_21 = 1 << 21,
+ GPIO_22 = 1 << 22,
+ GPIO_23 = 1 << 23,
+ GPIO_24 = 1 << 24,
+ GPIO_25 = 1 << 25,
+
+ Pin_P1_03 = 1 << 0,
+ Pin_P1_05 = 1 << 1,
+ Pin_P1_07 = 1 << 4,
+ Pin_P1_08 = 1 << 14,
+ Pin_P1_10 = 1 << 15,
+ Pin_P1_11 = 1 << 17,
+ Pin_P1_12 = 1 << 18,
+ Pin_P1_13 = 1 << 21,
+ Pin_P1_15 = 1 << 22,
+ Pin_P1_16 = 1 << 23,
+ Pin_P1_18 = 1 << 24,
+ Pin_P1_19 = 1 << 10,
+ Pin_P1_21 = 1 << 9,
+ Pin_P1_22 = 1 << 25,
+ Pin_P1_23 = 1 << 11,
+ Pin_P1_24 = 1 << 8,
+ Pin_P1_26 = 1 << 7,
+ LED = 1 << 16,
+
+ //Revision 2
+
+ V2_GPIO_00 = 1 << 0,
+ V2_GPIO_02 = 1 << 2,
+ V2_GPIO_03 = 1 << 3,
+ V2_GPIO_01 = 1 << 1,
+ V2_GPIO_04 = 1 << 4,
+ V2_GPIO_07 = 1 << 7,
+ V2_GPIO_08 = 1 << 8,
+ V2_GPIO_09 = 1 << 9,
+ V2_GPIO_10 = 1 << 10,
+ V2_GPIO_11 = 1 << 11,
+ V2_GPIO_14 = 1 << 14,
+ V2_GPIO_15 = 1 << 15,
+ V2_GPIO_17 = 1 << 17,
+ V2_GPIO_18 = 1 << 18,
+ V2_GPIO_21 = 1 << 21,
+ V2_GPIO_22 = 1 << 22,
+ V2_GPIO_23 = 1 << 23,
+ V2_GPIO_24 = 1 << 24,
+ V2_GPIO_25 = 1 << 25,
+ V2_GPIO_27 = 1 << 27,
+
+ //Revision 2, new plug P5
+ V2_GPIO_28 = 1 << 28,
+ V2_GPIO_29 = 1 << 29,
+ V2_GPIO_30 = 1 << 30,
+ V2_GPIO_31 = (uint)1 << 31,
+
+ V2_Pin_P1_03 = 1 << 2,
+ V2_Pin_P1_05 = 1 << 3,
+ V2_Pin_P1_07 = 1 << 4,
+ V2_Pin_P1_08 = 1 << 14,
+ V2_Pin_P1_10 = 1 << 15,
+ V2_Pin_P1_11 = 1 << 17,
+ V2_Pin_P1_12 = 1 << 18,
+ V2_Pin_P1_13 = 1 << 27,
+ V2_Pin_P1_15 = 1 << 22,
+ V2_Pin_P1_16 = 1 << 23,
+ V2_Pin_P1_18 = 1 << 24,
+ V2_Pin_P1_19 = 1 << 10,
+ V2_Pin_P1_21 = 1 << 9,
+ V2_Pin_P1_22 = 1 << 25,
+ V2_Pin_P1_23 = 1 << 11,
+ V2_Pin_P1_24 = 1 << 8,
+ V2_Pin_P1_26 = 1 << 7,
+ V2_LED = 1 << 16,
+
+ //Revision 2, new plug P5
+ V2_Pin_P5_03 = 1 << 28,
+ V2_Pin_P5_04 = 1 << 29,
+ V2_Pin_P5_05 = 1 << 30,
+ V2_Pin_P5_06 = (uint)1 << 31,
+
+ };
+
+}
diff --git a/RaspberryPiDotNet/GPIOResistor.cs b/RaspberryPiDotNet/GPIOResistor.cs
new file mode 100644
index 0000000..6065e72
--- /dev/null
+++ b/RaspberryPiDotNet/GPIOResistor.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace RaspberryPiDotNet
+{
+ public enum GPIOResistor
+ {
+ OFF = 0,
+ PULL_DOWN = 1,
+ PULL_UP = 2
+ }
+}
diff --git a/RaspberryPiDotNet/MCP3008.cs b/RaspberryPiDotNet/MCP3008.cs
new file mode 100644
index 0000000..8689c5e
--- /dev/null
+++ b/RaspberryPiDotNet/MCP3008.cs
@@ -0,0 +1,105 @@
+using System;
+
+// Original author: Mikey Sklar - git://gist.github.com/3249416.git
+// Adafruit article: http://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi
+// Ported from python and modified by: Gilberto Garcia ; twitter: @ferraripr
+
+namespace RaspberryPiDotNet
+{
+ ///
+ /// Raspberry Pi using MCP3008 A/D Converters with SPI Serial Interface
+ ///
+ ///
+ public class MCP3008
+ {
+ private int adcnum;
+ private GPIO clockpin;
+ private GPIO mosipin;
+ private GPIO misopin;
+ private GPIO cspin;
+
+ ///
+ /// Connect MCP3008 with clock, Serial Peripheral Interface(SPI) and channel
+ ///
+ /// MCP3008 channel number 0-7 (pin 1-8 on chip).
+ /// Clock pin
+ /// SPI Master Output, Slave Input (MOSI)
+ /// SPI Master Input, Slave Output (MISO)
+ /// SPI Chip Select
+ public MCP3008(int adc_channel, GPIO SPICLK, GPIO SPIMOSI, GPIO SPIMISO, GPIO SPICS)
+ {
+ adcnum = adc_channel;
+ clockpin = SPICLK;
+ mosipin = SPIMOSI;
+ misopin = SPIMISO;
+ cspin = SPICS;
+ //
+ if (adc_channel >= 0 && adc_channel <= 7)
+ {
+ //This is the range we are looking for, from CH0 to CH7.
+ }
+ else
+ {
+ throw new IndexOutOfRangeException("MCP3008 Channel Input is out of range, Channel input should be from 0-7 (8-Channel).");
+ }
+ }
+
+ ///
+ /// Analog to digital conversion
+ ///
+ public int AnalogToDigital
+ {
+ get
+ {
+ return readadc();
+ }
+ }
+
+ private int readadc()
+ {
+ if ((adcnum > 7) || adcnum < 0)
+ {
+ return -1;
+ }
+ cspin.Write(true);
+
+ clockpin.Write(false); // #start clock low
+ cspin.Write(false); // #bring CS low
+
+ int commandout = adcnum;
+ commandout |= 0x18; //# start bit + single-ended bit
+ commandout <<= 3; //# we only need to send 5 bits here
+
+ for (int i = 0; i < 5; i++)
+ {
+ if ((commandout & 0x80) == 128)
+ {
+ mosipin.Write(true);
+ }
+ else
+ {
+ mosipin.Write(false);
+ }
+ commandout <<= 1;
+ clockpin.Write(true);
+ clockpin.Write(false);
+ }
+
+ int adcout = 0;
+ //# read in one empty bit, one null bit and 10 ADC bits
+ for (var i = 0; i < 12; i++)
+ {
+ clockpin.Write(true);
+ clockpin.Write(false);
+ adcout <<= 1;
+ if (misopin.Read() == PinState.High)
+ adcout |= 0x1;
+ }
+
+ cspin.Write(true);
+ adcout /= 2;//# first bit is 'null' so drop it
+ return adcout;
+ }
+
+ }
+}
diff --git a/RaspberryPiDotNet/MicroLiquidCrystal/ILcdTransferProvider.cs b/RaspberryPiDotNet/MicroLiquidCrystal/ILcdTransferProvider.cs
index 86149f9..1c84c71 100644
--- a/RaspberryPiDotNet/MicroLiquidCrystal/ILcdTransferProvider.cs
+++ b/RaspberryPiDotNet/MicroLiquidCrystal/ILcdTransferProvider.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-// Micro Liquid Crystal Library
+// Micro Liquid Crystal Library
// http://microliquidcrystal.codeplex.com
// Appache License Version 2.0
diff --git a/RaspberryPiDotNet/MicroLiquidCrystal/Lcd.cs b/RaspberryPiDotNet/MicroLiquidCrystal/Lcd.cs
index d8538db..26cbb8e 100644
--- a/RaspberryPiDotNet/MicroLiquidCrystal/Lcd.cs
+++ b/RaspberryPiDotNet/MicroLiquidCrystal/Lcd.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Text;
using System.Threading;
diff --git a/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOFileLcdTransferProvider.cs b/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOFileLcdTransferProvider.cs
index 0034e39..0dc89eb 100644
--- a/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOFileLcdTransferProvider.cs
+++ b/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOFileLcdTransferProvider.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
// Code modified from original - GPIOLcdTransferProvider.cs
// Original code uses license:
@@ -22,19 +19,19 @@ public class RaspPiGPIOFileLcdTransferProvider : IDisposable, ILcdTransferProvid
private readonly bool _fourBitMode;
private bool _disposed;
- public RaspPiGPIOFileLcdTransferProvider(GPIOFile.GPIOPins rs, GPIOFile.GPIOPins enable, GPIOFile.GPIOPins d4, GPIOFile.GPIOPins d5, GPIOFile.GPIOPins d6, GPIOFile.GPIOPins d7)
- : this(true, rs, GPIOFile.GPIOPins.GPIO_NONE, enable, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, d4, d5, d6, d7)
+ public RaspPiGPIOFileLcdTransferProvider(GPIOPins rs, GPIOPins enable, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(true, rs, GPIOPins.GPIO_NONE, enable, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, d4, d5, d6, d7)
{ }
- public RaspPiGPIOFileLcdTransferProvider(GPIOFile.GPIOPins rs, GPIOFile.GPIOPins rw, GPIOFile.GPIOPins enable, GPIOFile.GPIOPins d4, GPIOFile.GPIOPins d5, GPIOFile.GPIOPins d6, GPIOFile.GPIOPins d7)
- : this(true, rs, rw, enable, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, GPIOFile.GPIOPins.GPIO_NONE, d4, d5, d6, d7)
+ public RaspPiGPIOFileLcdTransferProvider(GPIOPins rs, GPIOPins rw, GPIOPins enable, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(true, rs, rw, enable, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, d4, d5, d6, d7)
{ }
- public RaspPiGPIOFileLcdTransferProvider(GPIOFile.GPIOPins rs, GPIOFile.GPIOPins enable, GPIOFile.GPIOPins d0, GPIOFile.GPIOPins d1, GPIOFile.GPIOPins d2, GPIOFile.GPIOPins d3, GPIOFile.GPIOPins d4, GPIOFile.GPIOPins d5, GPIOFile.GPIOPins d6, GPIOFile.GPIOPins d7)
- : this(false, rs, GPIOFile.GPIOPins.GPIO_NONE, enable, d0, d1, d2, d3, d4, d5, d6, d7)
+ public RaspPiGPIOFileLcdTransferProvider(GPIOPins rs, GPIOPins enable, GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(false, rs, GPIOPins.GPIO_NONE, enable, d0, d1, d2, d3, d4, d5, d6, d7)
{ }
- public RaspPiGPIOFileLcdTransferProvider(GPIOFile.GPIOPins rs, GPIOFile.GPIOPins rw, GPIOFile.GPIOPins enable, GPIOFile.GPIOPins d0, GPIOFile.GPIOPins d1, GPIOFile.GPIOPins d2, GPIOFile.GPIOPins d3, GPIOFile.GPIOPins d4, GPIOFile.GPIOPins d5, GPIOFile.GPIOPins d6, GPIOFile.GPIOPins d7)
+ public RaspPiGPIOFileLcdTransferProvider(GPIOPins rs, GPIOPins rw, GPIOPins enable, GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
: this(false, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
{ }
@@ -53,27 +50,27 @@ public RaspPiGPIOFileLcdTransferProvider(GPIOFile.GPIOPins rs, GPIOFile.GPIOPins
///
///
///
- public RaspPiGPIOFileLcdTransferProvider(bool fourBitMode, GPIOFile.GPIOPins rs, GPIOFile.GPIOPins rw, GPIOFile.GPIOPins enable,
- GPIOFile.GPIOPins d0, GPIOFile.GPIOPins d1, GPIOFile.GPIOPins d2, GPIOFile.GPIOPins d3,
- GPIOFile.GPIOPins d4, GPIOFile.GPIOPins d5, GPIOFile.GPIOPins d6, GPIOFile.GPIOPins d7)
+ public RaspPiGPIOFileLcdTransferProvider(bool fourBitMode, GPIOPins rs, GPIOPins rw, GPIOPins enable,
+ GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3,
+ GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
{
_fourBitMode = fourBitMode;
- if (rs == GPIOFile.GPIOPins.GPIO_NONE) throw new ArgumentException("rs");
+ if (rs == GPIOPins.GPIO_NONE) throw new ArgumentException("rs");
_rsPort = new GPIOFile(rs);
// we can save 1 pin by not using RW. Indicate by passing GPIO.GPIOPins.GPIO_NONE instead of pin#
- if (rw != GPIOFile.GPIOPins.GPIO_NONE) // (RW is optional)
+ if (rw != GPIOPins.GPIO_NONE) // (RW is optional)
_rwPort = new GPIOFile(rw);
- if (enable == GPIOFile.GPIOPins.GPIO_NONE) throw new ArgumentException("enable");
+ if (enable == GPIOPins.GPIO_NONE) throw new ArgumentException("enable");
_enablePort = new GPIOFile(enable);
var dataPins = new[] { d0, d1, d2, d3, d4, d5, d6, d7};
_dataPorts = new GPIOFile[8];
for (int i = 0; i < 8; i++)
{
- if (dataPins[i] != GPIOFile.GPIOPins.GPIO_NONE)
+ if (dataPins[i] != GPIOPins.GPIO_NONE)
_dataPorts[i] = new GPIOFile(dataPins[i]);
}
}
diff --git a/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOMemLcdTransferProvider.cs b/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOMemLcdTransferProvider.cs
index a891361..680202c 100644
--- a/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOMemLcdTransferProvider.cs
+++ b/RaspberryPiDotNet/MicroLiquidCrystal/RaspPiGPIOMemLcdTransferProvider.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
// Code modified from original - GPIOLcdTransferProvider.cs
// Original code uses license:
@@ -22,19 +19,19 @@ public class RaspPiGPIOMemLcdTransferProvider : IDisposable, ILcdTransferProvide
private readonly bool _fourBitMode;
private bool _disposed;
- public RaspPiGPIOMemLcdTransferProvider(GPIOMem.GPIOPins rs, GPIOMem.GPIOPins enable, GPIOMem.GPIOPins d4, GPIOMem.GPIOPins d5, GPIOMem.GPIOPins d6, GPIOMem.GPIOPins d7)
- : this(true, rs, GPIOMem.GPIOPins.GPIO_NONE, enable, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, d4, d5, d6, d7)
+ public RaspPiGPIOMemLcdTransferProvider(GPIOPins rs, GPIOPins enable, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(true, rs, GPIOPins.GPIO_NONE, enable, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, d4, d5, d6, d7)
{ }
- public RaspPiGPIOMemLcdTransferProvider(GPIOMem.GPIOPins rs, GPIOMem.GPIOPins rw, GPIOMem.GPIOPins enable, GPIOMem.GPIOPins d4, GPIOMem.GPIOPins d5, GPIOMem.GPIOPins d6, GPIOMem.GPIOPins d7)
- : this(true, rs, rw, enable, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, GPIOMem.GPIOPins.GPIO_NONE, d4, d5, d6, d7)
+ public RaspPiGPIOMemLcdTransferProvider(GPIOPins rs, GPIOPins rw, GPIOPins enable, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(true, rs, rw, enable, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, GPIOPins.GPIO_NONE, d4, d5, d6, d7)
{ }
- public RaspPiGPIOMemLcdTransferProvider(GPIOMem.GPIOPins rs, GPIOMem.GPIOPins enable, GPIOMem.GPIOPins d0, GPIOMem.GPIOPins d1, GPIOMem.GPIOPins d2, GPIOMem.GPIOPins d3, GPIOMem.GPIOPins d4, GPIOMem.GPIOPins d5, GPIOMem.GPIOPins d6, GPIOMem.GPIOPins d7)
- : this(false, rs, GPIOMem.GPIOPins.GPIO_NONE, enable, d0, d1, d2, d3, d4, d5, d6, d7)
+ public RaspPiGPIOMemLcdTransferProvider(GPIOPins rs, GPIOPins enable, GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
+ : this(false, rs, GPIOPins.GPIO_NONE, enable, d0, d1, d2, d3, d4, d5, d6, d7)
{ }
- public RaspPiGPIOMemLcdTransferProvider(GPIOMem.GPIOPins rs, GPIOMem.GPIOPins rw, GPIOMem.GPIOPins enable, GPIOMem.GPIOPins d0, GPIOMem.GPIOPins d1, GPIOMem.GPIOPins d2, GPIOMem.GPIOPins d3, GPIOMem.GPIOPins d4, GPIOMem.GPIOPins d5, GPIOMem.GPIOPins d6, GPIOMem.GPIOPins d7)
+ public RaspPiGPIOMemLcdTransferProvider(GPIOPins rs, GPIOPins rw, GPIOPins enable, GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3, GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
: this(false, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
{ }
@@ -53,27 +50,27 @@ public RaspPiGPIOMemLcdTransferProvider(GPIOMem.GPIOPins rs, GPIOMem.GPIOPins rw
///
///
///
- public RaspPiGPIOMemLcdTransferProvider(bool fourBitMode, GPIOMem.GPIOPins rs, GPIOMem.GPIOPins rw, GPIOMem.GPIOPins enable,
- GPIOMem.GPIOPins d0, GPIOMem.GPIOPins d1, GPIOMem.GPIOPins d2, GPIOMem.GPIOPins d3,
- GPIOMem.GPIOPins d4, GPIOMem.GPIOPins d5, GPIOMem.GPIOPins d6, GPIOMem.GPIOPins d7)
+ public RaspPiGPIOMemLcdTransferProvider(bool fourBitMode, GPIOPins rs, GPIOPins rw, GPIOPins enable,
+ GPIOPins d0, GPIOPins d1, GPIOPins d2, GPIOPins d3,
+ GPIOPins d4, GPIOPins d5, GPIOPins d6, GPIOPins d7)
{
_fourBitMode = fourBitMode;
- if (rs == GPIOMem.GPIOPins.GPIO_NONE) throw new ArgumentException("rs");
+ if (rs == GPIOPins.GPIO_NONE) throw new ArgumentException("rs");
_rsPort = new GPIOMem(rs);
// we can save 1 pin by not using RW. Indicate by passing GPIO.GPIOPins.GPIO_NONE instead of pin#
- if (rw != GPIOMem.GPIOPins.GPIO_NONE) // (RW is optional)
+ if (rw != GPIOPins.GPIO_NONE) // (RW is optional)
_rwPort = new GPIOMem(rw);
- if (enable == GPIOMem.GPIOPins.GPIO_NONE) throw new ArgumentException("enable");
+ if (enable == GPIOPins.GPIO_NONE) throw new ArgumentException("enable");
_enablePort = new GPIOMem(enable);
var dataPins = new[] { d0, d1, d2, d3, d4, d5, d6, d7};
_dataPorts = new GPIOMem[8];
for (int i = 0; i < 8; i++)
{
- if (dataPins[i] != GPIOMem.GPIOPins.GPIO_NONE)
+ if (dataPins[i] != GPIOPins.GPIO_NONE)
_dataPorts[i] = new GPIOMem(dataPins[i]);
}
}
diff --git a/RaspberryPiDotNet/PinState.cs b/RaspberryPiDotNet/PinState.cs
new file mode 100644
index 0000000..ac19c22
--- /dev/null
+++ b/RaspberryPiDotNet/PinState.cs
@@ -0,0 +1,11 @@
+namespace RaspberryPiDotNet
+{
+ ///
+ /// This is a cleaner way to write the Pin Status
+ ///
+ public enum PinState
+ {
+ High,
+ Low
+ }
+}
\ No newline at end of file
diff --git a/RaspberryPiDotNet/RaspberryPiDotNet.csproj b/RaspberryPiDotNet/RaspberryPiDotNet.csproj
index a08d16d..5556768 100644
--- a/RaspberryPiDotNet/RaspberryPiDotNet.csproj
+++ b/RaspberryPiDotNet/RaspberryPiDotNet.csproj
@@ -12,6 +12,7 @@
RaspberryPiDotNet
v4.0
512
+
true
@@ -34,23 +35,25 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+