4
4
5
5
namespace Clayster . Library . RaspberryPi
6
6
{
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
+
7
17
/// <summary>
8
18
/// Class handling General Purpose Input/Output
9
19
/// </summary>
@@ -14,12 +24,11 @@ namespace Clayster.Library.RaspberryPi
14
24
/// </remarks>
15
25
public static unsafe class GPIO
16
26
{
17
- private const uint BCM2708_PERI_BASE = 0x20000000 ;
18
- private const uint GPIO_BASE = BCM2708_PERI_BASE + 0x200000 ;
19
-
20
27
private const uint PAGE_SIZE = 0x1000 ;
21
28
private const uint BLOCK_SIZE = 0x1000 ;
22
29
30
+ private static Platform platform = Platform . Unknown ;
31
+
23
32
private static int memoryFileHandler ;
24
33
private static readonly void * NULL = ( void * ) 0 ;
25
34
@@ -28,7 +37,9 @@ public static unsafe class GPIO
28
37
private static byte * memoryMapGpio ;
29
38
private static volatile uint * gpio ;
30
39
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 ;
32
43
private const int O_SYNC = 010000 ;
33
44
34
45
private const int PROT_READ = 0x1 ;
@@ -41,20 +52,76 @@ public static unsafe class GPIO
41
52
42
53
static GPIO ( )
43
54
{
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
+
44
111
memoryFileHandler = open ( "/dev/mem" , O_RDWR | O_SYNC ) ;
45
112
if ( memoryFileHandler < 0 )
46
113
{
47
114
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." ) ;
50
117
}
51
118
52
- gpio = MapMemory ( GPIO_BASE , ref memoryBlockGpio , ref memoryPageGpio , ref memoryMapGpio ) ;
119
+ gpio = MapMemory ( Base , ref memoryBlockGpio , ref memoryPageGpio , ref memoryMapGpio ) ;
53
120
54
121
ticksPerSecond = Stopwatch . Frequency ;
55
122
}
56
123
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 )
58
125
{
59
126
MemoryBlock = malloc ( BLOCK_SIZE + ( PAGE_SIZE - 1 ) ) ;
60
127
if ( MemoryBlock == NULL )
@@ -72,7 +139,7 @@ static GPIO ()
72
139
PROT_READ | PROT_WRITE ,
73
140
MAP_SHARED | MAP_FIXED ,
74
141
memoryFileHandler ,
75
- GPIO_BASE ) ;
142
+ Base ) ;
76
143
77
144
if ( ( long ) MemoryMap < 0 )
78
145
throw new Exception ( "Unable to map memory." ) ;
@@ -219,6 +286,14 @@ public static void WaitMicroseconds(uint Microseconds)
219
286
;
220
287
Console . Out . WriteLine ( "Waiting done." ) ;
221
288
}
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
+ }
222
297
}
223
298
}
224
299
0 commit comments