Skip to content

Commit de81585

Browse files
author
Peter Waher
committed
Support for Raspberry Pi 2 added.
GPIO.cs in Clayster.Library.RaspberryPI has been updated to support different memory maps depending on the hardware platform used. Now code implemented using Clayster.Library.RaspberryPi can be run on both Raspberry Pi and Raspberry Pi 2.
1 parent 3b63a75 commit de81585

File tree

1 file changed

+84
-9
lines changed
  • Clayster.Library.RaspberryPi

1 file changed

+84
-9
lines changed

Clayster.Library.RaspberryPi/GPIO.cs

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44

55
namespace Clayster.Library.RaspberryPi
66
{
7+
/// <summary>
8+
/// Enumeration of platforms that can be detected.
9+
/// </summary>
10+
public enum Platform
11+
{
12+
RaspberryPi,
13+
RaspberryPi2,
14+
Unknown
15+
}
16+
717
/// <summary>
818
/// Class handling General Purpose Input/Output
919
/// </summary>
@@ -14,12 +24,11 @@ namespace Clayster.Library.RaspberryPi
1424
/// </remarks>
1525
public static unsafe class GPIO
1626
{
17-
private const uint BCM2708_PERI_BASE = 0x20000000;
18-
private const uint GPIO_BASE = BCM2708_PERI_BASE + 0x200000;
19-
2027
private const uint PAGE_SIZE = 0x1000;
2128
private const uint BLOCK_SIZE = 0x1000;
2229

30+
private static Platform platform = Platform.Unknown;
31+
2332
private static int memoryFileHandler;
2433
private static readonly void* NULL = (void*)0;
2534

@@ -28,7 +37,9 @@ public static unsafe class GPIO
2837
private static byte* memoryMapGpio;
2938
private static volatile uint* gpio;
3039

31-
private const int O_RDWR = 02;
40+
private const int O_RDONLY = 0x0000;
41+
private const int O_WRONLY = 0x0001;
42+
private const int O_RDWR = 0x0002;
3243
private const int O_SYNC = 010000;
3344

3445
private const int PROT_READ = 0x1;
@@ -41,20 +52,76 @@ public static unsafe class GPIO
4152

4253
static GPIO ()
4354
{
55+
string CpuInfo;
56+
57+
try
58+
{
59+
CpuInfo = System.IO.File.ReadAllText("/proc/cpuinfo");
60+
}
61+
catch (Exception)
62+
{
63+
throw new Exception ("Unable to get access to /proc/cpuinfo. To determine how to access GPIO, the application "+
64+
"needs to know of what platform it runs. To get access to this file, the application needs to have " +
65+
"superior access privileges. You can get such privileges by executing the application using the sudo command.");
66+
}
67+
68+
platform = Platform.Unknown;
69+
foreach (string Row in CpuInfo.Split(new char[]{'\r','\n'},StringSplitOptions.RemoveEmptyEntries))
70+
{
71+
if (Row.StartsWith ("Hardware"))
72+
{
73+
int i = Row.IndexOf (':');
74+
if (i > 0)
75+
{
76+
if (Row.IndexOf ("BCM2708", i) > 0 || Row.IndexOf ("BCM2835", i) > 0)
77+
{
78+
platform = Platform.RaspberryPi;
79+
break;
80+
} else if (Row.IndexOf ("BCM2709", i) > 0 || Row.IndexOf ("BCM2836", i) > 0)
81+
{
82+
platform = Platform.RaspberryPi2;
83+
break;
84+
} else
85+
throw new Exception ("Unsupported platform: " + Row.Substring (i + 1).Trim ());
86+
}
87+
88+
break;
89+
}
90+
}
91+
92+
if (platform == Platform.Unknown)
93+
throw new Exception ("Could not determine what hardware platform is being used.");
94+
95+
uint Base;
96+
97+
switch (platform)
98+
{
99+
case Platform.RaspberryPi:
100+
Base = 0x20000000 + 0x200000; // BCM2708/BCM2835 base address + GPIO offset.
101+
break;
102+
103+
case Platform.RaspberryPi2:
104+
Base = 0x3f000000 + 0x200000; // BCM2709/BCM2836 base address + GPIO offset.
105+
break;
106+
107+
default:
108+
throw new Exception ("Unsupported platform: " + platform.ToString());
109+
}
110+
44111
memoryFileHandler = open ("/dev/mem", O_RDWR | O_SYNC);
45112
if (memoryFileHandler < 0)
46113
{
47114
throw new Exception ("Unable to get access to /dev/mem. Access to GPIO is done through direct access to memory, " +
48-
"which is provided through the system file /dev/mem. To get access to this file, the application needs to have " +
49-
"superior access privileges. You can get such privileges by executing the application using the sudo command.");
115+
"which is provided through the system file /dev/mem. To get access to this file, the application needs to have " +
116+
"superior access privileges. You can get such privileges by executing the application using the sudo command.");
50117
}
51118

52-
gpio = MapMemory (GPIO_BASE, ref memoryBlockGpio, ref memoryPageGpio, ref memoryMapGpio);
119+
gpio = MapMemory (Base, ref memoryBlockGpio, ref memoryPageGpio, ref memoryMapGpio);
53120

54121
ticksPerSecond = Stopwatch.Frequency;
55122
}
56123

57-
private static uint* MapMemory (ulong Base, ref byte* MemoryBlock, ref byte* MemoryPage, ref byte* MemoryMap)
124+
private static uint* MapMemory (uint Base, ref byte* MemoryBlock, ref byte* MemoryPage, ref byte* MemoryMap)
58125
{
59126
MemoryBlock = malloc (BLOCK_SIZE + (PAGE_SIZE - 1));
60127
if (MemoryBlock == NULL)
@@ -72,7 +139,7 @@ static GPIO ()
72139
PROT_READ | PROT_WRITE,
73140
MAP_SHARED | MAP_FIXED,
74141
memoryFileHandler,
75-
GPIO_BASE);
142+
Base);
76143

77144
if ((long)MemoryMap < 0)
78145
throw new Exception ("Unable to map memory.");
@@ -219,6 +286,14 @@ public static void WaitMicroseconds(uint Microseconds)
219286
;
220287
Console.Out.WriteLine ("Waiting done.");
221288
}
289+
290+
/// <summary>
291+
/// Contains information about the platform tha thas been detected.
292+
/// </summary>
293+
public static Platform Platform
294+
{
295+
get { return platform; }
296+
}
222297
}
223298
}
224299

0 commit comments

Comments
 (0)