rpi_gpio 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,53 +1,55 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
5
-
6
- Copyright (c) 2013-2014 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- int setup(void);
28
- void setup_gpio(int gpio, int direction, int pud);
29
- int gpio_function(int gpio);
30
- void output_gpio(int gpio, int value);
31
- int input_gpio(int gpio);
32
- void set_rising_event(int gpio, int enable);
33
- void set_falling_event(int gpio, int enable);
34
- void set_high_event(int gpio, int enable);
35
- void set_low_event(int gpio, int enable);
36
- int eventdetected(int gpio);
37
- void cleanup(void);
38
-
39
- #define SETUP_OK 0
40
- #define SETUP_DEVMEM_FAIL 1
41
- #define SETUP_MALLOC_FAIL 2
42
- #define SETUP_MMAP_FAIL 3
43
-
44
- #define INPUT 1 // is really 0 for control register!
45
- #define OUTPUT 0 // is really 1 for control register!
46
- #define ALT0 4
47
-
48
- #define HIGH 1
49
- #define LOW 0
50
-
51
- #define PUD_OFF 0
52
- #define PUD_DOWN 1
53
- #define PUD_UP 2
1
+ /*
2
+ Original code by Ben Croston modified for Ruby by Nick Lowery
3
+ (github.com/clockvapor)
4
+ Copyright (c) 2014-2020 Nick Lowery
5
+
6
+ Copyright (c) 2013-2015 Ben Croston
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the "Software"), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ of the Software, and to permit persons to whom the Software is furnished to do
13
+ so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+ */
26
+
27
+ int setup(void);
28
+ void setup_gpio(int gpio, int direction, int pud);
29
+ int gpio_function(int gpio);
30
+ void output_gpio(int gpio, int value);
31
+ int input_gpio(int gpio);
32
+ void set_rising_event(int gpio, int enable);
33
+ void set_falling_event(int gpio, int enable);
34
+ void set_high_event(int gpio, int enable);
35
+ void set_low_event(int gpio, int enable);
36
+ int eventdetected(int gpio);
37
+ void cleanup(void);
38
+
39
+ #define SETUP_OK 0
40
+ #define SETUP_DEVMEM_FAIL 1
41
+ #define SETUP_MALLOC_FAIL 2
42
+ #define SETUP_MMAP_FAIL 3
43
+ #define SETUP_CPUINFO_FAIL 4
44
+ #define SETUP_NOT_RPI_FAIL 5
45
+
46
+ #define INPUT 1 // is really 0 for control register!
47
+ #define OUTPUT 0 // is really 1 for control register!
48
+ #define ALT0 4
49
+
50
+ #define HIGH 1
51
+ #define LOW 0
52
+
53
+ #define PUD_OFF 0
54
+ #define PUD_DOWN 1
55
+ #define PUD_UP 2
@@ -1,101 +1,93 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
5
-
6
- Copyright (c) 2013-2014 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- #include "ruby.h"
28
- #include "c_gpio.h"
29
- #include "common.h"
30
-
31
- int gpio_mode = MODE_UNKNOWN;
32
- const int pin_to_gpio_rev1[41] = {-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17,
33
- 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1,
34
- -1, -1, -1, -1, -1, -1, -1, -1, -1 };
35
- const int pin_to_gpio_rev2[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17,
36
- 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1,
37
- -1, -1, -1, -1, -1, -1, -1, -1, -1 };
38
- const int pin_to_gpio_rev3[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17,
39
- 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12,
40
- 13, -1, 19, 16, 26, 20, -1, 21 };
41
- int setup_error = 0;
42
- int module_setup = 0;
43
-
44
- int check_gpio_priv(void)
45
- {
46
- // check module has been imported cleanly
47
- if (setup_error)
48
- {
49
- rb_raise(rb_eRuntimeError, "gem not imported correctly!");
50
- return 1;
51
- }
52
-
53
- // check mmap setup has worked
54
- if (!module_setup)
55
- {
56
- rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try "
57
- "running as root!");
58
- return 2;
59
- }
60
- return 0;
61
- }
62
-
63
- int get_gpio_number(int channel, unsigned int *gpio)
64
- {
65
- // check setmode() has been run
66
- if (gpio_mode != BOARD && gpio_mode != BCM)
67
- {
68
- rb_raise(rb_eRuntimeError, "please set pin numbering mode "
69
- "using RPi::GPIO.set_numbering :board or "
70
- "RPi::GPIO.set_numbering :bcm");
71
- return 3;
72
- }
73
-
74
- // check channel number is in range
75
- if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
76
- || (gpio_mode == BOARD && (channel < 1 || channel > 26) &&
77
- rpiinfo.p1_revision != 3)
78
- || (gpio_mode == BOARD && (channel < 1 || channel > 40) &&
79
- rpiinfo.p1_revision == 3))
80
- {
81
- rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
82
- return 4;
83
- }
84
-
85
- // convert channel to gpio
86
- if (gpio_mode == BOARD)
87
- {
88
- if (*(*pin_to_gpio+channel) == -1)
89
- {
90
- rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry "
91
- "Pi");
92
- return 5;
93
- } else {
94
- *gpio = *(*pin_to_gpio+channel);
95
- }
96
- }
97
- else // gpio_mode == BCM
98
- *gpio = channel;
99
-
100
- return 0;
101
- }
1
+ /*
2
+ Original code by Ben Croston modified for Ruby by Nick Lowery
3
+ (github.com/clockvapor)
4
+ Copyright (c) 2014-2020 Nick Lowery
5
+
6
+ Copyright (c) 2013-2014 Ben Croston
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the "Software"), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ of the Software, and to permit persons to whom the Software is furnished to do
13
+ so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+ */
26
+
27
+ #include "ruby.h"
28
+ #include "c_gpio.h"
29
+ #include "common.h"
30
+
31
+ int gpio_mode = MODE_UNKNOWN;
32
+ const int pin_to_gpio_rev1[41] = {-1, -1, -1, 0, -1, 1, -1, 4, 14, -1, 15, 17, 18, 21, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
33
+ const int pin_to_gpio_rev2[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
34
+ const int pin_to_gpio_rev3[41] = {-1, -1, -1, 2, -1, 3, -1, 4, 14, -1, 15, 17, 18, 27, -1, 22, 23, -1, 24, 10, -1, 9, 25, 11, 8, -1, 7, -1, -1, 5, -1, 6, 12, 13, -1, 19, 16, 26, 20, -1, 21 };
35
+ int setup_error = 0;
36
+ int module_setup = 0;
37
+
38
+ int check_gpio_priv(void)
39
+ {
40
+ // check module has been imported cleanly
41
+ if (setup_error)
42
+ {
43
+ rb_raise(rb_eRuntimeError, "gem not imported correctly!");
44
+ return 1;
45
+ }
46
+
47
+ // check mmap setup has worked
48
+ if (!module_setup)
49
+ {
50
+ rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try running as root!");
51
+ return 2;
52
+ }
53
+ return 0;
54
+ }
55
+
56
+ int get_gpio_number(int channel, unsigned int *gpio)
57
+ {
58
+ // check setmode() has been run
59
+ if (gpio_mode != BOARD && gpio_mode != BCM)
60
+ {
61
+ rb_raise(rb_eRuntimeError, "please set pin numbering mode "
62
+ "using RPi::GPIO.set_numbering :board or "
63
+ "RPi::GPIO.set_numbering :bcm");
64
+ return 3;
65
+ }
66
+
67
+ // check channel number is in range
68
+ if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
69
+ || (gpio_mode == BOARD && (channel < 1 || channel > 26) && rpiinfo.p1_revision != 3)
70
+ || (gpio_mode == BOARD && (channel < 1 || channel > 40) && rpiinfo.p1_revision == 3) )
71
+ {
72
+ rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
73
+ return 4;
74
+ }
75
+
76
+ // convert channel to gpio
77
+ if (gpio_mode == BOARD)
78
+ {
79
+ if (*(*pin_to_gpio+channel) == -1)
80
+ {
81
+ rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
82
+ return 5;
83
+ } else {
84
+ *gpio = *(*pin_to_gpio+channel);
85
+ }
86
+ }
87
+ else // gpio_mode == BCM
88
+ {
89
+ *gpio = channel;
90
+ }
91
+
92
+ return 0;
93
+ }
@@ -1,47 +1,47 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
5
-
6
- Copyright (c) 2013-2014 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- #include "cpuinfo.h"
28
-
29
- #define MODE_UNKNOWN -1
30
- #define BOARD 10
31
- #define BCM 11
32
- #define SERIAL 40
33
- #define SPI 41
34
- #define I2C 42
35
- #define PWM 43
36
-
37
- int gpio_mode;
38
- const int pin_to_gpio_rev1[41];
39
- const int pin_to_gpio_rev2[41];
40
- const int pin_to_gpio_rev3[41];
41
- const int (*pin_to_gpio)[41];
42
- int gpio_direction[54];
43
- rpi_info rpiinfo;
44
- int setup_error;
45
- int module_setup;
46
- int check_gpio_priv(void);
47
- int get_gpio_number(int channel, unsigned int *gpio);
1
+ /*
2
+ Original code by Ben Croston modified for Ruby by Nick Lowery
3
+ (github.com/clockvapor)
4
+ Copyright (c) 2014-2020 Nick Lowery
5
+
6
+ Copyright (c) 2013-2015 Ben Croston
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the "Software"), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ of the Software, and to permit persons to whom the Software is furnished to do
13
+ so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+ */
26
+
27
+ #include "cpuinfo.h"
28
+
29
+ #define MODE_UNKNOWN -1
30
+ #define BOARD 10
31
+ #define BCM 11
32
+ #define SERIAL 40
33
+ #define SPI 41
34
+ #define I2C 42
35
+ #define PWM 43
36
+
37
+ int gpio_mode;
38
+ const int pin_to_gpio_rev1[41];
39
+ const int pin_to_gpio_rev2[41];
40
+ const int pin_to_gpio_rev3[41];
41
+ const int (*pin_to_gpio)[41];
42
+ int gpio_direction[54];
43
+ rpi_info rpiinfo;
44
+ int setup_error;
45
+ int module_setup;
46
+ int check_gpio_priv(void);
47
+ int get_gpio_number(int channel, unsigned int *gpio);
@@ -1,159 +1,272 @@
1
- /*
2
- Original code by Ben Croston modified for Ruby by Nick Lowery
3
- (github.com/clockvapor)
4
- Copyright (c) 2014-2015 Nick Lowery
5
-
6
- Copyright (c) 2013-2014 Ben Croston
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of
9
- this software and associated documentation files (the "Software"), to deal in
10
- the Software without restriction, including without limitation the rights to
11
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
- of the Software, and to permit persons to whom the Software is furnished to do
13
- so, subject to the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be included in all
16
- copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- SOFTWARE.
25
- */
26
-
27
- #include <stdio.h>
28
- #include <stdlib.h>
29
- #include <string.h>
30
- #include "cpuinfo.h"
31
-
32
- int get_rpi_info(rpi_info *info)
33
- {
34
- FILE *fp;
35
- char buffer[1024];
36
- char hardware[1024];
37
- char revision[1024];
38
- char *rev;
39
- int found = 0;
40
- int len;
41
-
42
- if ((fp = fopen("/proc/cpuinfo", "r")) == NULL) {
43
- return -1;
44
- }
45
- while(!feof(fp)) {
46
- fgets(buffer, sizeof(buffer) , fp);
47
- sscanf(buffer, "Hardware : %s", hardware);
48
- if (strcmp(hardware, "BCM2708") == 0 ||
49
- strcmp(hardware, "BCM2709") == 0 ||
50
- strcmp(hardware, "BCM2835") == 0 ||
51
- strcmp(hardware, "BCM2836") == 0) {
52
- found = 1;
53
- }
54
- sscanf(buffer, "Revision : %s", revision);
55
- }
56
- fclose(fp);
57
-
58
- if (!found) {
59
- return -1;
60
- }
61
-
62
- if ((len = strlen(revision)) == 0) {
63
- return -1;
64
- }
65
-
66
- if (len >= 6 && strtol((char[]){revision[len-6],0}, NULL, 16) & 8) {
67
- // new scheme
68
- //info->rev = revision[len-1]-'0';
69
- strcpy(info->revision, revision);
70
- switch (revision[len-2]) {
71
- case '0': info->type = "Model A"; info->p1_revision = 2; break;
72
- case '1': info->type = "Model B"; info->p1_revision = 2; break;
73
- case '2': info->type = "Model A+"; info->p1_revision = 3; break;
74
- case '3': info->type = "Model B+"; info->p1_revision = 3; break;
75
- case '4': info->type = "Pi2 Model B"; info->p1_revision = 3; break;
76
- case '5': info->type = "Alpha"; info->p1_revision = 3; break;
77
- case '6': info->type = "Compute"; info->p1_revision = 0; break;
78
- default : info->type = "Unknown"; info->p1_revision = 3; break;
79
- }
80
- switch (revision[len-4]) {
81
- case '0': info->processor = "BCM2835"; break;
82
- case '1': info->processor = "BCM2836"; break;
83
- default : info->processor = "Unknown"; break;
84
- }
85
- switch (revision[len-5]) {
86
- case '0': info->manufacturer = "Sony"; break;
87
- case '1': info->manufacturer = "Egoman"; break;
88
- case '2': info->manufacturer = "Embest"; break;
89
- case '4': info->manufacturer = "Embest"; break;
90
- default : info->manufacturer = "Unknown"; break;
91
- }
92
- switch (strtol((char[]){revision[len-6],0}, NULL, 16) & 7) {
93
- case 0: info->ram = "256M"; break;
94
- case 1: info->ram = "512M"; break;
95
- case 2: info->ram = "1024M"; break;
96
- default: info->ram = "Unknown"; break;
97
- }
98
- } else {
99
- // old scheme
100
- info->ram = "Unknown";
101
- info->manufacturer = "Unknown";
102
- info->processor = "Unknown";
103
- info->type = "Unknown";
104
- strcpy(info->revision, revision);
105
-
106
- // get last four characters (ignore preceeding 1000 for overvolt)
107
- if (len > 4) {
108
- rev = (char *)&revision+len-4;
109
- } else {
110
- rev = revision;
111
- }
112
-
113
- if ((strcmp(rev, "0002") == 0) ||
114
- (strcmp(rev, "0003") == 0)) {
115
- info->p1_revision = 1;
116
- } else if ((strcmp(rev, "0004") == 0) ||
117
- (strcmp(rev, "0005") == 0) ||
118
- (strcmp(rev, "0006") == 0) ||
119
- (strcmp(rev, "0007") == 0) ||
120
- (strcmp(rev, "0008") == 0) ||
121
- (strcmp(rev, "0009") == 0) ||
122
- (strcmp(rev, "000d") == 0) ||
123
- (strcmp(rev, "000e") == 0) ||
124
- (strcmp(rev, "000f") == 0)) {
125
- info->p1_revision = 2;
126
- } else if (strcmp(rev, "0011") == 0) {
127
- info->p1_revision = 0; // compute module
128
- } else { // assume B+ (0010) or A+ (0012) or RPi2
129
- info->p1_revision = 3;
130
- }
131
- }
132
- return 0;
133
- }
134
-
135
- /*
136
-
137
- 32 bits
138
- NEW 23: will be 1 for the new scheme, 0 for the old scheme
139
- MEMSIZE 20: 0=256M 1=512M 2=1G
140
- MANUFACTURER 16: 0=SONY 1=EGOMAN
141
- PROCESSOR 12: 0=2835 1=2836
142
- TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM
143
- REV 00: 0=REV0 1=REV1 2=REV2
144
-
145
- pi2 = 1<<23 | 2<<20 | 1<<12 | 4<<4 = 0xa01040
146
-
147
- --------------------
148
-
149
- SRRR MMMM PPPP TTTT TTTT VVVV
150
-
151
- S scheme (0=old, 1=new)
152
- R RAM (0=256, 1=512, 2=1024)
153
- M manufacturer (0='SONY',1='EGOMAN',2='EMBEST',3='UNKNOWN',4='EMBEST')
154
- P processor (0=2835, 1=2836)
155
- T type (0='A', 1='B', 2='A+', 3='B+', 4='Pi 2 B', 5='Alpha', 6='Compute Module')
156
- V revision (0-15)
157
-
158
- */
159
-
1
+ /*
2
+ Original code by Ben Croston modified for Ruby by Nick Lowery
3
+ (github.com/clockvapor)
4
+ Copyright (c) 2014-2020 Nick Lowery
5
+
6
+ Copyright (c) 2012-2019 Ben Croston
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the "Software"), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ of the Software, and to permit persons to whom the Software is furnished to do
13
+ so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+ */
26
+
27
+ /* See the following for up to date information:
28
+ * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
29
+ */
30
+
31
+ #include <stdio.h>
32
+ #include <stdint.h>
33
+ #include <stdlib.h>
34
+ #include <string.h>
35
+ #include <arpa/inet.h>
36
+ #include "cpuinfo.h"
37
+
38
+ int get_rpi_info(rpi_info *info)
39
+ {
40
+ FILE *fp;
41
+ char buffer[1024];
42
+ char hardware[1024];
43
+ char revision[1024];
44
+ int found = 0;
45
+ int len;
46
+
47
+ if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
48
+ uint32_t n;
49
+ if (fread(&n, sizeof(n), 1, fp) != 1) {
50
+ fclose(fp);
51
+ return -1;
52
+ }
53
+ sprintf(revision, "%x", ntohl(n));
54
+ found = 1;
55
+ }
56
+ else if ((fp = fopen("/proc/cpuinfo", "r"))) {
57
+ while(!feof(fp) && fgets(buffer, sizeof(buffer), fp)) {
58
+ sscanf(buffer, "Hardware : %s", hardware);
59
+ if (strcmp(hardware, "BCM2708") == 0 ||
60
+ strcmp(hardware, "BCM2709") == 0 ||
61
+ strcmp(hardware, "BCM2835") == 0 ||
62
+ strcmp(hardware, "BCM2836") == 0 ||
63
+ strcmp(hardware, "BCM2837") == 0 ) {
64
+ found = 1;
65
+ }
66
+ sscanf(buffer, "Revision : %s", revision);
67
+ }
68
+ }
69
+ else
70
+ return -1;
71
+ fclose(fp);
72
+
73
+ if (!found)
74
+ return -1;
75
+
76
+ if ((len = strlen(revision)) == 0)
77
+ return -1;
78
+
79
+ if (len >= 6 && strtol((char[]){revision[len-6],0}, NULL, 16) & 8) {
80
+ // new scheme
81
+ //info->rev = revision[len-1]-'0';
82
+ strcpy(info->revision, revision);
83
+ switch (revision[len-3]) {
84
+ case '0' :
85
+ switch (revision[len-2]) {
86
+ case '0': info->type = "Model A"; info->p1_revision = 2; break;
87
+ case '1': info->type = "Model B"; info->p1_revision = 2; break;
88
+ case '2': info->type = "Model A+"; info->p1_revision = 3; break;
89
+ case '3': info->type = "Model B+"; info->p1_revision = 3; break;
90
+ case '4': info->type = "Pi 2 Model B"; info->p1_revision = 3; break;
91
+ case '5': info->type = "Alpha"; info->p1_revision = 3; break;
92
+ case '6': info->type = "Compute Module 1"; info->p1_revision = 0; break;
93
+ case '8': info->type = "Pi 3 Model B"; info->p1_revision = 3; break;
94
+ case '9': info->type = "Zero"; info->p1_revision = 3; break;
95
+ case 'a': info->type = "Compute Module 3"; info->p1_revision = 0; break;
96
+ case 'c': info->type = "Zero W"; info->p1_revision = 3; break;
97
+ case 'd': info->type = "Pi 3 Model B+"; info->p1_revision = 3; break;
98
+ case 'e': info->type = "Pi 3 Model A+"; info->p1_revision = 3; break;
99
+ default : info->type = "Unknown"; info->p1_revision = 3; break;
100
+ } break;
101
+ case '1':
102
+ switch (revision[len-2]) {
103
+ case '0': info->type = "Compute Module 3+"; info->p1_revision = 0; break;
104
+ case '1': info->type = "Pi 4 Model B"; info->p1_revision = 3; break;
105
+ default : info->type = "Unknown"; info->p1_revision = 3; break;
106
+ } break;
107
+ default: info->type = "Unknown"; info->p1_revision = 3; break;
108
+ }
109
+
110
+ switch (revision[len-4]) {
111
+ case '0': info->processor = "BCM2835"; break;
112
+ case '1': info->processor = "BCM2836"; break;
113
+ case '2': info->processor = "BCM2837"; break;
114
+ case '3': info->processor = "BCM2711"; break;
115
+ default : info->processor = "Unknown"; break;
116
+ }
117
+ switch (revision[len-5]) {
118
+ case '0': info->manufacturer = "Sony"; break;
119
+ case '1': info->manufacturer = "Egoman"; break;
120
+ case '2': info->manufacturer = "Embest"; break;
121
+ case '3': info->manufacturer = "Sony Japan"; break;
122
+ case '4': info->manufacturer = "Embest"; break;
123
+ case '5': info->manufacturer = "Stadium"; break;
124
+ default : info->manufacturer = "Unknown"; break;
125
+ }
126
+ switch (strtol((char[]){revision[len-6],0}, NULL, 16) & 7) {
127
+ case 0: info->ram = "256M"; break;
128
+ case 1: info->ram = "512M"; break;
129
+ case 2: info->ram = "1G"; break;
130
+ case 3: info->ram = "2G"; break;
131
+ case 4: info->ram = "4G"; break;
132
+ default: info->ram = "Unknown"; break;
133
+ }
134
+ } else {
135
+ // old scheme
136
+ info->ram = "Unknown";
137
+ info->manufacturer = "Unknown";
138
+ info->processor = "Unknown";
139
+ info->type = "Unknown";
140
+ strcpy(info->revision, revision);
141
+
142
+ uint64_t rev;
143
+ sscanf(revision, "%llx", &rev);
144
+ rev = rev & 0xefffffff; // ignore preceeding 1000 for overvolt
145
+
146
+ if (rev == 0x0002 || rev == 0x0003) {
147
+ info->type = "Model B";
148
+ info->p1_revision = 1;
149
+ info->ram = "256M";
150
+ info->manufacturer = "Egoman";
151
+ info->processor = "BCM2835";
152
+ } else if (rev == 0x0004) {
153
+ info->type = "Model B";
154
+ info->p1_revision = 2;
155
+ info->ram = "256M";
156
+ info->manufacturer = "Sony UK";
157
+ info->processor = "BCM2835";
158
+ } else if (rev == 0x0005) {
159
+ info->type = "Model B";
160
+ info->p1_revision = 2;
161
+ info->ram = "256M";
162
+ info->manufacturer = "Qisda";
163
+ info->processor = "BCM2835";
164
+ } else if (rev == 0x0006) {
165
+ info->type = "Model B";
166
+ info->p1_revision = 2;
167
+ info->ram = "256M";
168
+ info->manufacturer = "Egoman";
169
+ info->processor = "BCM2835";
170
+ } else if (rev == 0x0007) {
171
+ info->type = "Model A";
172
+ info->p1_revision = 2;
173
+ info->ram = "256M";
174
+ info->manufacturer = "Egoman";
175
+ info->processor = "BCM2835";
176
+ } else if (rev == 0x0008) {
177
+ info->type = "Model A";
178
+ info->p1_revision = 2;
179
+ info->ram = "256M";
180
+ info->manufacturer = "Sony UK";
181
+ info->processor = "BCM2835";
182
+ } else if (rev == 0x0009) {
183
+ info->type = "Model A";
184
+ info->p1_revision = 2;
185
+ info->ram = "256M";
186
+ info->manufacturer = "Qisda";
187
+ info->processor = "BCM2835";
188
+ } else if (rev == 0x000d) {
189
+ info->type = "Model B";
190
+ info->p1_revision = 2;
191
+ info->ram = "512M";
192
+ info->manufacturer = "Egoman";
193
+ info->processor = "BCM2835";
194
+ } else if (rev == 0x000e) {
195
+ info->type = "Model B";
196
+ info->p1_revision = 2;
197
+ info->ram = "512M";
198
+ info->manufacturer = "Sony UK";
199
+ info->processor = "BCM2835";
200
+ } else if (rev == 0x000f) {
201
+ info->type = "Model B";
202
+ info->p1_revision = 2;
203
+ info->ram = "512M";
204
+ info->manufacturer = "Qisda";
205
+ info->processor = "BCM2835";
206
+ } else if (rev == 0x0010) {
207
+ info->type = "Model B+";
208
+ info->p1_revision = 3;
209
+ info->ram = "512M";
210
+ info->manufacturer = "Sony UK";
211
+ info->processor = "BCM2835";
212
+ } else if (rev == 0x0011) {
213
+ info->type = "Compute Module 1";
214
+ info->p1_revision = 0;
215
+ info->ram = "512M";
216
+ info->manufacturer = "Sony UK";
217
+ info->processor = "BCM2835";
218
+ } else if (rev == 0x0012) {
219
+ info->type = "Model A+";
220
+ info->p1_revision = 3;
221
+ info->ram = "256M";
222
+ info->manufacturer = "Sony UK";
223
+ info->processor = "BCM2835";
224
+ } else if (rev == 0x0013) {
225
+ info->type = "Model B+";
226
+ info->p1_revision = 3;
227
+ info->ram = "512M";
228
+ info->manufacturer = "Embest";
229
+ info->processor = "BCM2835";
230
+ } else if (rev == 0x0014) {
231
+ info->type = "Compute Module 1";
232
+ info->p1_revision = 0;
233
+ info->ram = "512M";
234
+ info->manufacturer = "Embest";
235
+ info->processor = "BCM2835";
236
+ } else if (rev == 0x0015) {
237
+ info->type = "Model A+";
238
+ info->p1_revision = 3;
239
+ info->ram = "Unknown";
240
+ info->manufacturer = "Embest";
241
+ info->processor = "BCM2835";
242
+ } else { // don't know - assume revision 3 p1 connector
243
+ info->p1_revision = 3;
244
+ }
245
+ }
246
+ return 0;
247
+ }
248
+
249
+ /*
250
+
251
+ 32 bits
252
+ NEW 23: will be 1 for the new scheme, 0 for the old scheme
253
+ MEMSIZE 20: 0=256M 1=512M 2=1G
254
+ MANUFACTURER 16: 0=SONY 1=EGOMAN
255
+ PROCESSOR 12: 0=2835 1=2836
256
+ TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM
257
+ REV 00: 0=REV0 1=REV1 2=REV2
258
+
259
+ pi2 = 1<<23 | 2<<20 | 1<<12 | 4<<4 = 0xa01040
260
+
261
+ --------------------
262
+
263
+ SRRR MMMM PPPP TTTT TTTT VVVV
264
+
265
+ S scheme (0=old, 1=new)
266
+ R RAM (0=256, 1=512, 2=1024)
267
+ M manufacturer (0='SONY',1='EGOMAN',2='EMBEST',3='UNKNOWN',4='EMBEST')
268
+ P processor (0=2835, 1=2836 2=2837)
269
+ T type (0='A', 1='B', 2='A+', 3='B+', 4='Pi 2 B', 5='Alpha', 6='Compute Module')
270
+ V revision (0-15)
271
+
272
+ */