From f0c493284ccdf8722b4bc398901b1962db6e1ccb Mon Sep 17 00:00:00 2001 From: "pire.lionel@hotmail.be" Date: Fri, 24 Apr 2015 15:50:34 +0200 Subject: [PATCH] - Updated to work on all revisions (Rev1, Rev2, B+ and above) - Removed BroadcomPinNumber no longer public as this numbering was confusing, PhysicalPinNumber is now abstracting it fully --- .../Entities/BroadcomPinNumber.cs | 178 ++++++++--- src/PiSharp.LibGpio/Entities/GpioLayout.cs | 23 ++ .../Entities/PhysicalPinNumber.cs | 93 +++++- .../Entities/RaspberryPinNumber.cs | 67 ---- src/PiSharp.LibGpio/LibGpio.cs | 285 +++++++++++++----- src/PiSharp.LibGpio/PiSharp.LibGpio.csproj | 2 +- 6 files changed, 468 insertions(+), 180 deletions(-) create mode 100644 src/PiSharp.LibGpio/Entities/GpioLayout.cs delete mode 100644 src/PiSharp.LibGpio/Entities/RaspberryPinNumber.cs diff --git a/src/PiSharp.LibGpio/Entities/BroadcomPinNumber.cs b/src/PiSharp.LibGpio/Entities/BroadcomPinNumber.cs index 57c4585..2a7023f 100644 --- a/src/PiSharp.LibGpio/Entities/BroadcomPinNumber.cs +++ b/src/PiSharp.LibGpio/Entities/BroadcomPinNumber.cs @@ -17,51 +17,159 @@ // //----------------------------------------------------------------------- -namespace PiSharp.LibGpio.Entities +namespace PiSharp.LibGpio { - /// - /// The Broadcom GPIO ID - /// - public enum BroadcomPinNumber + public partial class LibGpio { /// - /// GPIO Pin 4 + /// The Broadcom GPIO ID /// - Four = 4, + public enum BroadcomPinNumber + { + /// + /// GPIO Pin 0 (B Rev1 only) + /// + Zero = 0, - /// - /// GPIO Pin 17 - /// - Seventeen = 17, + /// + /// GPIO Pin 1 (B Rev1 only) + /// + One = 1, - /// - /// GPIO Pin 18 - /// - Eighteen = 18, + /// + /// GPIO Pin 2 (A/B Rev2 and above) + /// + Two = 2, - /// - /// GPIO Pin 21 - /// - TwentyOne = 21, + /// + /// GPIO Pin 3 (A/B Rev2 and above) + /// + Three = 3, - /// - /// GPIO Pin 22 - /// - TwentyTwo = 22, + /// + /// GPIO Pin 4 + /// + Four = 4, - /// - /// GPIO Pin 23 - /// - TwentyThree = 23, + /// + /// GPIO Pin 5 (B+ and above) + /// + Five = 5, - /// - /// GPIO Pin 24 - /// - TwentyFour = 24, + /// + /// GPIO Pin 6 (B+ and above) + /// + Six = 6, - /// - /// GPIO Pin 25 - /// - TwentyFive = 25, + /// + /// GPIO Pin 7 + /// + Seven = 7, + + /// + /// GPIO Pin 8 + /// + Eight = 8, + + /// + /// GPIO Pin 9 + /// + Nine = 9, + + /// + /// GPIO Pin 10 + /// + Ten = 10, + + /// + /// GPIO Pin 11 + /// + Eleven = 11, + + /// + /// GPIO Pin 12 (B+ and above) + /// + Twelve = 12, + + /// + /// GPIO Pin 13 (B+ and above) + /// + Thirteen = 13, + + /// + /// GPIO Pin 14 + /// + Fourteen = 14, + + /// + /// GPIO Pin 15 + /// + Fifteen = 15, + + /// + /// GPIO Pin 16 (B+ and above) + /// + Sixteen = 16, + + /// + /// GPIO Pin 17 + /// + Seventeen = 17, + + /// + /// GPIO Pin 18 + /// + Eighteen = 18, + + /// + /// GPIO Pin 19 (B+ and above) + /// + Nineteen = 19, + + /// + /// GPIO Pin 20 (B+ and above) + /// + Twenty = 20, + + /// + /// GPIO Pin 21 (Rev1) + /// + TwentyOne = 21, + + /// + /// GPIO Pin 22 + /// + TwentyTwo = 22, + + /// + /// GPIO Pin 23 + /// + TwentyThree = 23, + + /// + /// GPIO Pin 24 + /// + TwentyFour = 24, + + /// + /// GPIO Pin 25 + /// + TwentyFive = 25, + + /// + /// GPIO Pin 26 (B+ and above) + /// + TwentySix = 26, + + /// + /// GPIO Pin 27 (A/B Rev2 and above) + /// + TwentySeven = 27, + + /// + /// Undefined pin number + /// + Undefined = -1 + } } } diff --git a/src/PiSharp.LibGpio/Entities/GpioLayout.cs b/src/PiSharp.LibGpio/Entities/GpioLayout.cs new file mode 100644 index 0000000..c3dfcec --- /dev/null +++ b/src/PiSharp.LibGpio/Entities/GpioLayout.cs @@ -0,0 +1,23 @@ +namespace PiSharp.LibGpio.Entities +{ + /// + /// The Raspberry Pi GPIO ID + /// + public enum GpioLayout + { + /// + /// Revision numbers : [Beta, 0003] + /// + LayoutOne = 1, + + /// + /// Revision numbers : [0004, 000f] + /// + LayoutTwo = 2, + + /// + /// Revision numbers : [0010, ...] + /// + LayoutThree = 3 + } +} diff --git a/src/PiSharp.LibGpio/Entities/PhysicalPinNumber.cs b/src/PiSharp.LibGpio/Entities/PhysicalPinNumber.cs index 0798cdd..a1619f4 100644 --- a/src/PiSharp.LibGpio/Entities/PhysicalPinNumber.cs +++ b/src/PiSharp.LibGpio/Entities/PhysicalPinNumber.cs @@ -29,11 +29,31 @@ public enum PhysicalPinNumber /// Undefined = 0, + /// + /// GPIO Pin 3 + /// + Three = 3, + + /// + /// GPIO Pin 5 + /// + Five = 5, + /// /// GPIO Pin 7 /// Seven = 7, + /// + /// GPIO Pin 8 + /// + Eight = 8, + + /// + /// GPIO Pin 10 + /// + Ten = 10, + /// /// GPIO Pin 11 /// @@ -64,9 +84,80 @@ public enum PhysicalPinNumber /// Eighteen = 18, + /// + /// GPIO Pin 19 + /// + Nineteen = 19, + + /// + /// GPIO Pin 21 + /// + TwentyOne = 21, + /// /// GPIO Pin 22 /// - TwentyTwo = 22 + TwentyTwo = 22, + + /// + /// GPIO Pin 23 + /// + TwentyThree = 23, + + /// + /// GPIO Pin 24 + /// + TwentyFour = 24, + + /// + /// GPIO Pin 26 + /// + TwentySix = 26, + + /// + /// GPIO Pin 29 (B+ and above) + /// + TwentyNine = 29, + + /// + /// GPIO Pin 31 (B+ and above) + /// + ThirtyOne = 31, + + /// + /// GPIO Pin 32 (B+ and above) + /// + ThirtyTwo = 32, + + /// + /// GPIO Pin 33 (B+ and above) + /// + ThirtyThree = 33, + + /// + /// GPIO Pin 35 (B+ and above) + /// + ThirtyFive = 35, + + /// + /// GPIO Pin 36 (B+ and above) + /// + ThirtySix = 36, + + /// + /// GPIO Pin 37 (B+ and above) + /// + ThirtySeven = 37, + + /// + /// GPIO Pin 38 (B+ and above) + /// + ThirtyEight = 38, + + /// + /// GPIO Pin 40 (B+ and above) + /// + Fourty = 40 + } } diff --git a/src/PiSharp.LibGpio/Entities/RaspberryPinNumber.cs b/src/PiSharp.LibGpio/Entities/RaspberryPinNumber.cs deleted file mode 100644 index be1720f..0000000 --- a/src/PiSharp.LibGpio/Entities/RaspberryPinNumber.cs +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (C) 2012 Andrew Bradford -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -// associated documentation files (the "Software"), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject -// to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- - -namespace PiSharp.LibGpio.Entities -{ - /// - /// The Raspberry Pi GPIO ID - /// - public enum RaspberryPinNumber - { - /// - /// Invalid pin number - used to established a known invalid value to un-initialised variables. - /// - Zero = 0, - - /// - /// GPIO Pin 1 - /// - One, - - /// - /// GPIO Pin 2 - /// - Two, - - /// - /// GPIO Pin 3 - /// - Three, - - /// - /// GPIO Pin 4 - /// - Four, - - /// - /// GPIO Pin 5 - /// - Five, - - /// - /// GPIO Pin 6 - /// - Six, - - /// - /// GPIO Pin 7 - /// - Seven, - } -} diff --git a/src/PiSharp.LibGpio/LibGpio.cs b/src/PiSharp.LibGpio/LibGpio.cs index 5556495..1ff83ae 100644 --- a/src/PiSharp.LibGpio/LibGpio.cs +++ b/src/PiSharp.LibGpio/LibGpio.cs @@ -31,7 +31,7 @@ namespace PiSharp.LibGpio /// Library for interfacing with the Raspberry Pi GPIO ports. /// This class is implemented as a singleton - no attempt should be made to instantiate it /// - public class LibGpio + public partial class LibGpio { /// /// Stores the singleton instance of the class @@ -81,16 +81,6 @@ public bool TestMode set; } - /// - /// Configures a GPIO channel for use - /// - /// The Raspberry Pi pin number to configure - /// The direction to configure the pin for - public void SetupChannel(RaspberryPinNumber pinNumber, Direction direction) - { - this.SetupChannel(ConvertToBroadcom(pinNumber), direction); - } - /// /// Configures a GPIO channel for use /// @@ -108,6 +98,11 @@ public void SetupChannel(PhysicalPinNumber pinNumber, Direction direction) /// The direction to configure the pin for public void SetupChannel(BroadcomPinNumber pinNumber, Direction direction) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + var outputName = string.Format("gpio{0}", (int)pinNumber); var gpioPath = Path.Combine(this.GetGpioPath(), outputName); @@ -126,19 +121,6 @@ public void SetupChannel(BroadcomPinNumber pinNumber, Direction direction) Debug.WriteLine(string.Format("[PiSharp.LibGpio] Broadcom GPIO number '{0}', configured for use", pinNumber)); } - /// - /// Outputs a value to a GPIO pin - /// - /// The pin number to use - /// The value to output - /// - /// Thrown when an attempt to use an incorrectly configured channel is made - /// - public void OutputValue(RaspberryPinNumber pinNumber, bool value) - { - this.OutputValue(ConvertToBroadcom(pinNumber), value); - } - /// /// Outputs a value to a GPIO pin /// @@ -162,6 +144,11 @@ public void OutputValue(PhysicalPinNumber pinNumber, bool value) /// public void OutputValue(BroadcomPinNumber pinNumber, bool value) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + // Check that the output is configured if (!this.directions.ContainsKey(pinNumber)) { @@ -191,19 +178,6 @@ public void OutputValue(BroadcomPinNumber pinNumber, bool value) Debug.WriteLine(string.Format("[PiSharp.LibGpio] Broadcom GPIO number '{0}', outputting value '{1}'", pinNumber, value)); } - /// - /// Reads a value form a GPIO pin - /// - /// The pin number to read - /// The value at that pin - /// - /// Thrown when an attempt to use an incorrectly configured channel is made - /// - public bool ReadValue(RaspberryPinNumber pinNumber) - { - return this.ReadValue(ConvertToBroadcom(pinNumber)); - } - /// /// Reads a value form a GPIO pin /// @@ -227,6 +201,11 @@ public bool ReadValue(PhysicalPinNumber pinNumber) /// public bool ReadValue(BroadcomPinNumber pinNumber) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + // Check that the output is configured if (!this.directions.ContainsKey(pinNumber)) { @@ -259,44 +238,6 @@ public bool ReadValue(BroadcomPinNumber pinNumber) } } - /// - /// Gets the Broadcom GPIO pin number form the Raspberry Pi pin number - /// - /// The Raspberry Pi pin number - /// The equivalent Broadcom ID - private static BroadcomPinNumber ConvertToBroadcom(RaspberryPinNumber pinNumber) - { - switch (pinNumber) - { - case RaspberryPinNumber.Seven: - return BroadcomPinNumber.Four; - - case RaspberryPinNumber.Zero: - return BroadcomPinNumber.Seventeen; - - case RaspberryPinNumber.One: - return BroadcomPinNumber.Eighteen; - - case RaspberryPinNumber.Two: - return BroadcomPinNumber.TwentyOne; - - case RaspberryPinNumber.Three: - return BroadcomPinNumber.TwentyTwo; - - case RaspberryPinNumber.Four: - return BroadcomPinNumber.TwentyThree; - - case RaspberryPinNumber.Five: - return BroadcomPinNumber.TwentyFour; - - case RaspberryPinNumber.Six: - return BroadcomPinNumber.TwentyFive; - - default: - throw new ArgumentOutOfRangeException(); - } - } - /// /// Gets the Broadcom GPIO pin number form the physical pin number /// @@ -304,11 +245,31 @@ private static BroadcomPinNumber ConvertToBroadcom(RaspberryPinNumber pinNumber) /// The equivalent Broadcom ID private static BroadcomPinNumber ConvertToBroadcom(PhysicalPinNumber pinNumber) { + GpioLayout Layout = GetRaspType(); + switch (pinNumber) { + case PhysicalPinNumber.Three: + if (Layout == GpioLayout.LayoutOne) + return BroadcomPinNumber.Zero; + else + return BroadcomPinNumber.Two; + + case PhysicalPinNumber.Five: + if (Layout == GpioLayout.LayoutOne) + return BroadcomPinNumber.One; + else + return BroadcomPinNumber.Three; + case PhysicalPinNumber.Seven: return BroadcomPinNumber.Four; + case PhysicalPinNumber.Eight: + return BroadcomPinNumber.Fourteen; + + case PhysicalPinNumber.Ten: + return BroadcomPinNumber.Fifteen; + case PhysicalPinNumber.Eleven: return BroadcomPinNumber.Seventeen; @@ -316,7 +277,10 @@ private static BroadcomPinNumber ConvertToBroadcom(PhysicalPinNumber pinNumber) return BroadcomPinNumber.Eighteen; case PhysicalPinNumber.Thirteen: - return BroadcomPinNumber.TwentyOne; + if (Layout == GpioLayout.LayoutOne) + return BroadcomPinNumber.TwentyOne; + else + return BroadcomPinNumber.TwentySeven; case PhysicalPinNumber.Fifteen: return BroadcomPinNumber.TwentyTwo; @@ -327,9 +291,78 @@ private static BroadcomPinNumber ConvertToBroadcom(PhysicalPinNumber pinNumber) case PhysicalPinNumber.Eighteen: return BroadcomPinNumber.TwentyFour; + case PhysicalPinNumber.Nineteen: + return BroadcomPinNumber.Ten; + + case PhysicalPinNumber.TwentyOne: + return BroadcomPinNumber.Nine; + case PhysicalPinNumber.TwentyTwo: return BroadcomPinNumber.TwentyFive; + case PhysicalPinNumber.TwentyThree: + return BroadcomPinNumber.Eleven; + + case PhysicalPinNumber.TwentyFour: + return BroadcomPinNumber.Eight; + + case PhysicalPinNumber.TwentySix: + return BroadcomPinNumber.Seven; + + case PhysicalPinNumber.TwentyNine: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Five; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtyOne: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Six; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtyTwo: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Twelve; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtyThree: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Thirteen; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtyFive: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Nineteen; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtySix: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Sixteen; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtySeven: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.TwentySix; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.ThirtyEight: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.Twenty; + else + return BroadcomPinNumber.Undefined; + + case PhysicalPinNumber.Fourty: + if (Layout == GpioLayout.LayoutThree) + return BroadcomPinNumber.TwentyOne; + else + return BroadcomPinNumber.Undefined; + default: throw new ArgumentOutOfRangeException(); } @@ -341,6 +374,11 @@ private static BroadcomPinNumber ConvertToBroadcom(PhysicalPinNumber pinNumber) /// The pin number to unexport private void UnExport(BroadcomPinNumber pinNumber) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + using (var fileStream = new FileStream(Path.Combine(this.GetGpioPath(), "unexport"), FileMode.Open, FileAccess.Write, FileShare.ReadWrite)) { using (var streamWriter = new StreamWriter(fileStream)) @@ -358,6 +396,12 @@ private void UnExport(BroadcomPinNumber pinNumber) /// The pin number to export private void Export(BroadcomPinNumber pinNumber) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + + // The simulator requires directories to be created first, but the RasPi does not and throws an exception. if (this.TestMode || Environment.OSVersion.Platform != PlatformID.Unix) { @@ -390,6 +434,12 @@ private void Export(BroadcomPinNumber pinNumber) /// The direction to set it to private void SetDirection(BroadcomPinNumber pinNumber, Direction direction) { + if (pinNumber == BroadcomPinNumber.Undefined) + { + throw new InvalidOperationException("Attempt to perform action on an undefined pin"); + } + + var gpioId = string.Format("gpio{0}", (int)pinNumber); var filePath = Path.Combine(gpioId, "direction"); using (var streamWriter = new StreamWriter(Path.Combine(this.GetGpioPath(), filePath), false)) @@ -440,5 +490,88 @@ private string GetGpioPath() return "/sys/class/gpio"; } } + + /// + /// Gets the Raspberry Pi revision number (see : http://elinux.org/RPi_HardwareHistory#Board_Revision_History) + /// + /// The revision number of the rasp based on /proc/cpuinfo + private static string GetRevNumber() + { + string[] lines = File.ReadAllLines(@"/proc/cpuinfo"); + + foreach (string line in lines) + { + //"Revision\t: xxxx".Length = 15 (Note : Pi 2 now has 6 digit rev number) + if (line.Length < 15) + continue; + + if (line.Substring(0, 8) == "Revision") + return line.Substring(11); + } + + return null; + } + + /// + /// Convenience method that gets the type of gpio numbering (See : http://1.bp.blogspot.com/-SRF0TOvP2xo/VIKNV_Yk1hI/AAAAAAAAVMk/EJW1gPAZrc4/s1600/Raspberry-Pi-AllModelGPIO-pinouts.png) + /// + /// The revision number of the rasp based on /proc/cpuinfo + private static GpioLayout GetRaspType() + { + string Rev = GetRevNumber(); + + switch(Rev) + { + case "0002": + return GpioLayout.LayoutOne; + + case "0003": + return GpioLayout.LayoutOne; + + case "0004": + return GpioLayout.LayoutTwo; + + case "0005": + return GpioLayout.LayoutTwo; + + case "0006": + return GpioLayout.LayoutTwo; + + case "0007": + return GpioLayout.LayoutTwo; + + case "0008": + return GpioLayout.LayoutTwo; + + case "0009": + return GpioLayout.LayoutTwo; + + case "000d": + return GpioLayout.LayoutTwo; + + case "000e": + return GpioLayout.LayoutTwo; + + case "000f": + return GpioLayout.LayoutTwo; + + case "0010": + return GpioLayout.LayoutThree; + + case "0011": + return GpioLayout.LayoutThree; + + case "0012": + return GpioLayout.LayoutThree; + + case "1041": + return GpioLayout.LayoutThree; + + default: + return GpioLayout.LayoutThree; + + } + } + } } diff --git a/src/PiSharp.LibGpio/PiSharp.LibGpio.csproj b/src/PiSharp.LibGpio/PiSharp.LibGpio.csproj index e39e293..dbc3365 100644 --- a/src/PiSharp.LibGpio/PiSharp.LibGpio.csproj +++ b/src/PiSharp.LibGpio/PiSharp.LibGpio.csproj @@ -47,9 +47,9 @@ - +