wiringpi 0.0.1-armv6l-linux → 1.0.0-armv6l-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,184 @@
1
+ /*
2
+ * serial.c:
3
+ * Handle a serial port
4
+ ***********************************************************************
5
+ * This file is part of wiringPi:
6
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
7
+ *
8
+ * wiringPi is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * wiringPi is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
20
+ ***********************************************************************
21
+ */
22
+
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+ #include <stdint.h>
26
+ #include <string.h>
27
+ #include <termios.h>
28
+ #include <unistd.h>
29
+ #include <fcntl.h>
30
+ #include <sys/ioctl.h>
31
+ #include <sys/types.h>
32
+ #include <sys/stat.h>
33
+
34
+ #include "serial.h"
35
+
36
+ /*
37
+ * serialOpen:
38
+ * Open and initialise the serial port, setting all the right
39
+ * port parameters - or as many as are required - hopefully!
40
+ *********************************************************************************
41
+ */
42
+
43
+ int serialOpen (char *device, int baud)
44
+ {
45
+ struct termios options ;
46
+ speed_t myBaud ;
47
+ int status, fd ;
48
+
49
+ #ifdef DEBUG
50
+ printf ("openSerialPort: <%s> baud: $d\n", device, baud) ;
51
+ #endif
52
+
53
+ switch (baud)
54
+ {
55
+ case 50: myBaud = B50 ; break ;
56
+ case 75: myBaud = B75 ; break ;
57
+ case 110: myBaud = B110 ; break ;
58
+ case 134: myBaud = B134 ; break ;
59
+ case 150: myBaud = B150 ; break ;
60
+ case 200: myBaud = B200 ; break ;
61
+ case 300: myBaud = B300 ; break ;
62
+ case 600: myBaud = B600 ; break ;
63
+ case 1200: myBaud = B1200 ; break ;
64
+ case 1800: myBaud = B1800 ; break ;
65
+ case 2400: myBaud = B2400 ; break ;
66
+ case 9600: myBaud = B9600 ; break ;
67
+ case 19200: myBaud = B19200 ; break ;
68
+ case 38400: myBaud = B38400 ; break ;
69
+ case 57600: myBaud = B57600 ; break ;
70
+ case 115200: myBaud = B115200 ; break ;
71
+ case 230400: myBaud = B230400 ; break ;
72
+
73
+ default:
74
+ return -2 ;
75
+ }
76
+
77
+ if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
78
+ return -1 ;
79
+
80
+ fcntl (fd, F_SETFL, O_RDWR) ;
81
+
82
+ // Get and modify current options:
83
+
84
+ tcgetattr (fd, &options) ;
85
+
86
+ cfmakeraw (&options) ;
87
+ cfsetispeed (&options, myBaud) ;
88
+ cfsetospeed (&options, myBaud) ;
89
+
90
+ options.c_cflag |= (CLOCAL | CREAD) ;
91
+ options.c_cflag &= ~PARENB ;
92
+ options.c_cflag &= ~CSTOPB ;
93
+ options.c_cflag &= ~CSIZE ;
94
+ options.c_cflag |= CS8 ;
95
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
96
+ options.c_oflag &= ~OPOST ;
97
+
98
+ options.c_cc [VMIN] = 0 ;
99
+ options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
100
+
101
+ tcsetattr (fd, TCSANOW, &options) ;
102
+
103
+ ioctl (fd, TIOCMGET, &status);
104
+
105
+ status |= TIOCM_DTR ;
106
+ status |= TIOCM_RTS ;
107
+
108
+ ioctl (fd, TIOCMSET, &status);
109
+
110
+ usleep (10000) ; // 10mS
111
+
112
+ return fd ;
113
+ }
114
+
115
+
116
+ /*
117
+ * serialClose:
118
+ * Release the serial port
119
+ *********************************************************************************
120
+ */
121
+
122
+ void serialClose (int fd)
123
+ {
124
+ close (fd) ;
125
+ }
126
+
127
+
128
+ /*
129
+ * serialPutchar:
130
+ * Send a single character to the serial port
131
+ *********************************************************************************
132
+ */
133
+
134
+ void serialPutchar (int fd, uint8_t c)
135
+ {
136
+ write (fd, &c, 1) ;
137
+ }
138
+
139
+
140
+ /*
141
+ * serialPuts:
142
+ * Send a string to the serial port
143
+ *********************************************************************************
144
+ */
145
+
146
+ void serialPuts (int fd, char *s)
147
+ {
148
+ write (fd, s, strlen (s)) ;
149
+ }
150
+
151
+ /*
152
+ * serialDataAvail:
153
+ * Return the number of bytes of data avalable to be read in the serial port
154
+ *********************************************************************************
155
+ */
156
+
157
+ int serialDataAvail (int fd)
158
+ {
159
+ int result ;
160
+
161
+ if (ioctl (fd, FIONREAD, &result) == -1)
162
+ return -1 ;
163
+
164
+ return result ;
165
+ }
166
+
167
+
168
+ /*
169
+ * serialGetchar:
170
+ * Get a single character from the serial device.
171
+ * Note: Zero is a valid character and this function will time-out after
172
+ * 10 seconds.
173
+ *********************************************************************************
174
+ */
175
+
176
+ int serialGetchar (int fd)
177
+ {
178
+ uint8_t x ;
179
+
180
+ if (read (fd, &x, 1) != 1)
181
+ return -1 ;
182
+
183
+ return ((int)x) & 0xFF ;
184
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * serial.h:
3
+ * Handle a serial port
4
+ ***********************************************************************
5
+ * This file is part of wiringPi:
6
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
7
+ *
8
+ * wiringPi is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * wiringPi is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
20
+ ***********************************************************************
21
+ */
22
+
23
+ #ifndef _STDINT_H
24
+ # include <stdint.h>
25
+ #endif
26
+
27
+ #ifdef __cplusplus
28
+ extern "C" {
29
+ #endif
30
+
31
+ extern int serialOpen (char *device, int baud) ;
32
+ extern void serialClose (int fd) ;
33
+ extern void serialPutchar (int fd, uint8_t c) ;
34
+ extern void serialPuts (int fd, char *s) ;
35
+ extern int serialDataAvail (int fd) ;
36
+ extern int serialGetchar (int fd) ;
37
+
38
+ #ifdef __cplusplus
39
+ }
40
+ #endif
@@ -47,9 +47,10 @@
47
47
  #include <string.h>
48
48
  #include <time.h>
49
49
  #include <fcntl.h>
50
+ #include <sys/time.h>
50
51
  #include <sys/mman.h>
51
52
 
52
- #include "wiringpi.h"
53
+ #include "wiringPi.h"
53
54
 
54
55
  #ifndef TRUE
55
56
  #define TRUE (1==1)
@@ -150,7 +151,7 @@ static int pinToGpio [] =
150
151
  17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
151
152
  0, 1, // I2C - SDA0, SCL0
152
153
  8, 7, // SPI - CE1, CE0
153
- 10, 9, 11, // SPI - MISO, MOSI, SCLK
154
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK
154
155
  14, 15, // UART - Tx, Rx
155
156
  } ;
156
157
 
@@ -244,6 +245,10 @@ static uint8_t gpioToPwmPort [] =
244
245
  } ;
245
246
 
246
247
 
248
+ // Time for easy calculations
249
+
250
+ static unsigned long long epoch ;
251
+
247
252
  //////////////////////////////////////////////////////////////////////////////////
248
253
 
249
254
 
@@ -269,6 +274,7 @@ int wiringPiSetup (void)
269
274
  {
270
275
  int fd ;
271
276
  uint8_t *gpioMem, *pwmMem, *clkMem ;
277
+ struct timeval tv ;
272
278
 
273
279
  #ifdef DEBUG_PADS
274
280
  uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ;
@@ -373,6 +379,9 @@ int wiringPiSetup (void)
373
379
  printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ;
374
380
  #endif
375
381
 
382
+ gettimeofday (&tv, NULL) ;
383
+ epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
384
+
376
385
  return 0 ;
377
386
  }
378
387
 
@@ -462,6 +471,9 @@ void digitalWrite (int pin, int value)
462
471
  {
463
472
  int gpioPin ;
464
473
 
474
+ if ((pin < 0) || (pin >= NUM_PINS))
475
+ return ;
476
+
465
477
  if (gpioPinMode == WPI_MODE_PINS)
466
478
  {
467
479
  if ((pin < 0) || (pin >= NUM_PINS))
@@ -585,3 +597,21 @@ void delayMicroseconds (unsigned int howLong)
585
597
 
586
598
  nanosleep (&sleeper, &dummy) ;
587
599
  }
600
+
601
+ /*
602
+ * millis:
603
+ * Return a number of milliseconds as an unsigned int.
604
+ *********************************************************************************
605
+ */
606
+
607
+ unsigned int millis (void)
608
+ {
609
+ struct timeval tv ;
610
+ unsigned long long t1 ;
611
+
612
+ gettimeofday (&tv, NULL) ;
613
+
614
+ t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ;
615
+
616
+ return (uint32_t)(t1 - epoch) ;
617
+ }
@@ -55,8 +55,9 @@ extern void digitalWrite (int pin, int value) ;
55
55
  extern void pwmWrite (int pin, int value) ;
56
56
  extern int digitalRead (int pin) ;
57
57
 
58
- extern void delay (unsigned int howLong) ;
59
- extern void delayMicroseconds (unsigned int howLong) ;
58
+ extern void delay (unsigned int howLong) ;
59
+ extern void delayMicroseconds (unsigned int howLong) ;
60
+ extern unsigned int millis (void) ;
60
61
 
61
62
  #ifdef __cplusplus
62
63
  }
@@ -0,0 +1,84 @@
1
+ /*
2
+ * wiringShift.c:
3
+ * Emulate some of the Arduino wiring functionality.
4
+ *
5
+ * Copyright (c) 2009-2012 Gordon Henderson.
6
+ ***********************************************************************
7
+ * This file is part of wiringPi:
8
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
9
+ *
10
+ * wiringPi is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * wiringPi is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License
21
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22
+ ***********************************************************************
23
+ */
24
+
25
+ #include <stdint.h>
26
+
27
+ #include "wiringPi.h"
28
+ #include "wiringShift.h"
29
+
30
+ /*
31
+ * shiftIn:
32
+ * Shift data in from a clocked source
33
+ *********************************************************************************
34
+ */
35
+
36
+ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order)
37
+ {
38
+ uint8_t value = 0 ;
39
+ int8_t i ;
40
+
41
+ if (order == MSBFIRST)
42
+ for (i = 7 ; i >= 0 ; --i)
43
+ {
44
+ digitalWrite (cPin, HIGH) ;
45
+ value |= digitalRead (dPin) << i ;
46
+ digitalWrite (cPin, LOW) ;
47
+ }
48
+ else
49
+ for (i = 0 ; i < 8 ; ++i)
50
+ {
51
+ digitalWrite (cPin, HIGH) ;
52
+ value |= digitalRead (dPin) << i ;
53
+ digitalWrite (cPin, LOW) ;
54
+ }
55
+
56
+ return value;
57
+ }
58
+
59
+
60
+ /*
61
+ * shiftOut:
62
+ * Shift data out to a clocked source
63
+ *********************************************************************************
64
+ */
65
+
66
+ void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val)
67
+ {
68
+ int8_t i;
69
+
70
+ if (order == MSBFIRST)
71
+ for (i = 7 ; i >= 0 ; --i)
72
+ {
73
+ digitalWrite (dPin, val & (1 << i)) ;
74
+ digitalWrite (cPin, HIGH) ;
75
+ digitalWrite (cPin, LOW) ;
76
+ }
77
+ else
78
+ for (i = 0 ; i < 8 ; ++i)
79
+ {
80
+ digitalWrite (dPin, val & (1 << i)) ;
81
+ digitalWrite (cPin, HIGH) ;
82
+ digitalWrite (cPin, LOW) ;
83
+ }
84
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ * wiringShift.h:
3
+ * Emulate some of the Arduino wiring functionality.
4
+ *
5
+ * Copyright (c) 2009-2012 Gordon Henderson.
6
+ ***********************************************************************
7
+ * This file is part of wiringPi:
8
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
9
+ *
10
+ * wiringPi is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * wiringPi is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License
21
+ * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22
+ ***********************************************************************
23
+ */
24
+
25
+ #define LSBFIRST 0
26
+ #define MSBFIRST 1
27
+
28
+ #ifndef _STDINT_H
29
+ # include <stdint.h>
30
+ #endif
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif
35
+
36
+ extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ;
37
+ extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
38
+
39
+ #ifdef __cplusplus
40
+ }
41
+ #endif
@@ -1883,7 +1883,122 @@ SWIG_AsVal_int (VALUE obj, int *val)
1883
1883
  }
1884
1884
 
1885
1885
 
1886
- #include "wiringpi.h"
1886
+ /*@SWIG:/usr/share/swig1.3/ruby/rubyprimtypes.swg,23,%ruby_aux_method@*/
1887
+ SWIGINTERN VALUE SWIG_AUX_NUM2ULONG(VALUE *args)
1888
+ {
1889
+ VALUE obj = args[0];
1890
+ VALUE type = TYPE(obj);
1891
+ unsigned long *res = (unsigned long *)(args[1]);
1892
+ *res = type == T_FIXNUM ? NUM2ULONG(obj) : rb_big2ulong(obj);
1893
+ return obj;
1894
+ }
1895
+ /*@SWIG@*/
1896
+
1897
+ SWIGINTERN int
1898
+ SWIG_AsVal_unsigned_SS_long (VALUE obj, unsigned long *val)
1899
+ {
1900
+ VALUE type = TYPE(obj);
1901
+ if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
1902
+ unsigned long v;
1903
+ VALUE a[2];
1904
+ a[0] = obj;
1905
+ a[1] = (VALUE)(&v);
1906
+ if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
1907
+ if (val) *val = v;
1908
+ return SWIG_OK;
1909
+ }
1910
+ }
1911
+ return SWIG_TypeError;
1912
+ }
1913
+
1914
+
1915
+ SWIGINTERN int
1916
+ SWIG_AsVal_unsigned_SS_char (VALUE obj, unsigned char *val)
1917
+ {
1918
+ unsigned long v;
1919
+ int res = SWIG_AsVal_unsigned_SS_long (obj, &v);
1920
+ if (SWIG_IsOK(res)) {
1921
+ if ((v > UCHAR_MAX)) {
1922
+ return SWIG_OverflowError;
1923
+ } else {
1924
+ if (val) *val = (unsigned char)(v);
1925
+ }
1926
+ }
1927
+ return res;
1928
+ }
1929
+
1930
+
1931
+ SWIGINTERNINLINE VALUE
1932
+ SWIG_From_unsigned_SS_long (unsigned long value)
1933
+ {
1934
+ return ULONG2NUM(value);
1935
+ }
1936
+
1937
+
1938
+ SWIGINTERNINLINE VALUE
1939
+ SWIG_From_unsigned_SS_char (unsigned char value)
1940
+ {
1941
+ return SWIG_From_unsigned_SS_long (value);
1942
+ }
1943
+
1944
+
1945
+ SWIGINTERN swig_type_info*
1946
+ SWIG_pchar_descriptor(void)
1947
+ {
1948
+ static int init = 0;
1949
+ static swig_type_info* info = 0;
1950
+ if (!init) {
1951
+ info = SWIG_TypeQuery("_p_char");
1952
+ init = 1;
1953
+ }
1954
+ return info;
1955
+ }
1956
+
1957
+
1958
+ SWIGINTERN int
1959
+ SWIG_AsCharPtrAndSize(VALUE obj, char** cptr, size_t* psize, int *alloc)
1960
+ {
1961
+ if (TYPE(obj) == T_STRING) {
1962
+ #if defined(StringValuePtr)
1963
+ char *cstr = StringValuePtr(obj);
1964
+ #else
1965
+ char *cstr = STR2CSTR(obj);
1966
+ #endif
1967
+ size_t size = RSTRING_LEN(obj) + 1;
1968
+ if (cptr) {
1969
+ if (alloc) {
1970
+ if (*alloc == SWIG_NEWOBJ) {
1971
+ *cptr = (char *)memcpy((char *)malloc((size)*sizeof(char)), cstr, sizeof(char)*(size));
1972
+ } else {
1973
+ *cptr = cstr;
1974
+ *alloc = SWIG_OLDOBJ;
1975
+ }
1976
+ }
1977
+ }
1978
+ if (psize) *psize = size;
1979
+ return SWIG_OK;
1980
+ } else {
1981
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
1982
+ if (pchar_descriptor) {
1983
+ void* vptr = 0;
1984
+ if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
1985
+ if (cptr) *cptr = (char *)vptr;
1986
+ if (psize) *psize = vptr ? (strlen((char*)vptr) + 1) : 0;
1987
+ if (alloc) *alloc = SWIG_OLDOBJ;
1988
+ return SWIG_OK;
1989
+ }
1990
+ }
1991
+ }
1992
+ return SWIG_TypeError;
1993
+ }
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+ #include "wiringPi.h";
2000
+ #include "wiringShift.h";
2001
+ #include "serial.h";
1887
2002
 
1888
2003
  SWIGINTERN VALUE
1889
2004
  _wrap_wiringPiSetup(int argc, VALUE *argv, VALUE self) {
@@ -2062,6 +2177,256 @@ fail:
2062
2177
  }
2063
2178
 
2064
2179
 
2180
+ SWIGINTERN VALUE
2181
+ _wrap_shiftOut(int argc, VALUE *argv, VALUE self) {
2182
+ uint8_t arg1 ;
2183
+ uint8_t arg2 ;
2184
+ uint8_t arg3 ;
2185
+ uint8_t arg4 ;
2186
+ unsigned char val1 ;
2187
+ int ecode1 = 0 ;
2188
+ unsigned char val2 ;
2189
+ int ecode2 = 0 ;
2190
+ unsigned char val3 ;
2191
+ int ecode3 = 0 ;
2192
+ unsigned char val4 ;
2193
+ int ecode4 = 0 ;
2194
+
2195
+ if ((argc < 4) || (argc > 4)) {
2196
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 4)",argc); SWIG_fail;
2197
+ }
2198
+ ecode1 = SWIG_AsVal_unsigned_SS_char(argv[0], &val1);
2199
+ if (!SWIG_IsOK(ecode1)) {
2200
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "uint8_t","shiftOut", 1, argv[0] ));
2201
+ }
2202
+ arg1 = (uint8_t)(val1);
2203
+ ecode2 = SWIG_AsVal_unsigned_SS_char(argv[1], &val2);
2204
+ if (!SWIG_IsOK(ecode2)) {
2205
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "uint8_t","shiftOut", 2, argv[1] ));
2206
+ }
2207
+ arg2 = (uint8_t)(val2);
2208
+ ecode3 = SWIG_AsVal_unsigned_SS_char(argv[2], &val3);
2209
+ if (!SWIG_IsOK(ecode3)) {
2210
+ SWIG_exception_fail(SWIG_ArgError(ecode3), Ruby_Format_TypeError( "", "uint8_t","shiftOut", 3, argv[2] ));
2211
+ }
2212
+ arg3 = (uint8_t)(val3);
2213
+ ecode4 = SWIG_AsVal_unsigned_SS_char(argv[3], &val4);
2214
+ if (!SWIG_IsOK(ecode4)) {
2215
+ SWIG_exception_fail(SWIG_ArgError(ecode4), Ruby_Format_TypeError( "", "uint8_t","shiftOut", 4, argv[3] ));
2216
+ }
2217
+ arg4 = (uint8_t)(val4);
2218
+ shiftOut(arg1,arg2,arg3,arg4);
2219
+ return Qnil;
2220
+ fail:
2221
+ return Qnil;
2222
+ }
2223
+
2224
+
2225
+ SWIGINTERN VALUE
2226
+ _wrap_shiftIn(int argc, VALUE *argv, VALUE self) {
2227
+ uint8_t arg1 ;
2228
+ uint8_t arg2 ;
2229
+ uint8_t arg3 ;
2230
+ unsigned char val1 ;
2231
+ int ecode1 = 0 ;
2232
+ unsigned char val2 ;
2233
+ int ecode2 = 0 ;
2234
+ unsigned char val3 ;
2235
+ int ecode3 = 0 ;
2236
+ uint8_t result;
2237
+ VALUE vresult = Qnil;
2238
+
2239
+ if ((argc < 3) || (argc > 3)) {
2240
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 3)",argc); SWIG_fail;
2241
+ }
2242
+ ecode1 = SWIG_AsVal_unsigned_SS_char(argv[0], &val1);
2243
+ if (!SWIG_IsOK(ecode1)) {
2244
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "uint8_t","shiftIn", 1, argv[0] ));
2245
+ }
2246
+ arg1 = (uint8_t)(val1);
2247
+ ecode2 = SWIG_AsVal_unsigned_SS_char(argv[1], &val2);
2248
+ if (!SWIG_IsOK(ecode2)) {
2249
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "uint8_t","shiftIn", 2, argv[1] ));
2250
+ }
2251
+ arg2 = (uint8_t)(val2);
2252
+ ecode3 = SWIG_AsVal_unsigned_SS_char(argv[2], &val3);
2253
+ if (!SWIG_IsOK(ecode3)) {
2254
+ SWIG_exception_fail(SWIG_ArgError(ecode3), Ruby_Format_TypeError( "", "uint8_t","shiftIn", 3, argv[2] ));
2255
+ }
2256
+ arg3 = (uint8_t)(val3);
2257
+ result = shiftIn(arg1,arg2,arg3);
2258
+ vresult = SWIG_From_unsigned_SS_char((unsigned char)(result));
2259
+ return vresult;
2260
+ fail:
2261
+ return Qnil;
2262
+ }
2263
+
2264
+
2265
+ SWIGINTERN VALUE
2266
+ _wrap_serialOpen(int argc, VALUE *argv, VALUE self) {
2267
+ char *arg1 = (char *) 0 ;
2268
+ int arg2 ;
2269
+ int res1 ;
2270
+ char *buf1 = 0 ;
2271
+ int alloc1 = 0 ;
2272
+ int val2 ;
2273
+ int ecode2 = 0 ;
2274
+ int result;
2275
+ VALUE vresult = Qnil;
2276
+
2277
+ if ((argc < 2) || (argc > 2)) {
2278
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
2279
+ }
2280
+ res1 = SWIG_AsCharPtrAndSize(argv[0], &buf1, NULL, &alloc1);
2281
+ if (!SWIG_IsOK(res1)) {
2282
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "char *","serialOpen", 1, argv[0] ));
2283
+ }
2284
+ arg1 = (char *)(buf1);
2285
+ ecode2 = SWIG_AsVal_int(argv[1], &val2);
2286
+ if (!SWIG_IsOK(ecode2)) {
2287
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "int","serialOpen", 2, argv[1] ));
2288
+ }
2289
+ arg2 = (int)(val2);
2290
+ result = (int)serialOpen(arg1,arg2);
2291
+ vresult = SWIG_From_int((int)(result));
2292
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
2293
+ return vresult;
2294
+ fail:
2295
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
2296
+ return Qnil;
2297
+ }
2298
+
2299
+
2300
+ SWIGINTERN VALUE
2301
+ _wrap_serialClose(int argc, VALUE *argv, VALUE self) {
2302
+ int arg1 ;
2303
+ int val1 ;
2304
+ int ecode1 = 0 ;
2305
+
2306
+ if ((argc < 1) || (argc > 1)) {
2307
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
2308
+ }
2309
+ ecode1 = SWIG_AsVal_int(argv[0], &val1);
2310
+ if (!SWIG_IsOK(ecode1)) {
2311
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "int","serialClose", 1, argv[0] ));
2312
+ }
2313
+ arg1 = (int)(val1);
2314
+ serialClose(arg1);
2315
+ return Qnil;
2316
+ fail:
2317
+ return Qnil;
2318
+ }
2319
+
2320
+
2321
+ SWIGINTERN VALUE
2322
+ _wrap_serialPutchar(int argc, VALUE *argv, VALUE self) {
2323
+ int arg1 ;
2324
+ uint8_t arg2 ;
2325
+ int val1 ;
2326
+ int ecode1 = 0 ;
2327
+ unsigned char val2 ;
2328
+ int ecode2 = 0 ;
2329
+
2330
+ if ((argc < 2) || (argc > 2)) {
2331
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
2332
+ }
2333
+ ecode1 = SWIG_AsVal_int(argv[0], &val1);
2334
+ if (!SWIG_IsOK(ecode1)) {
2335
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "int","serialPutchar", 1, argv[0] ));
2336
+ }
2337
+ arg1 = (int)(val1);
2338
+ ecode2 = SWIG_AsVal_unsigned_SS_char(argv[1], &val2);
2339
+ if (!SWIG_IsOK(ecode2)) {
2340
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "uint8_t","serialPutchar", 2, argv[1] ));
2341
+ }
2342
+ arg2 = (uint8_t)(val2);
2343
+ serialPutchar(arg1,arg2);
2344
+ return Qnil;
2345
+ fail:
2346
+ return Qnil;
2347
+ }
2348
+
2349
+
2350
+ SWIGINTERN VALUE
2351
+ _wrap_serialPuts(int argc, VALUE *argv, VALUE self) {
2352
+ int arg1 ;
2353
+ char *arg2 = (char *) 0 ;
2354
+ int val1 ;
2355
+ int ecode1 = 0 ;
2356
+ int res2 ;
2357
+ char *buf2 = 0 ;
2358
+ int alloc2 = 0 ;
2359
+
2360
+ if ((argc < 2) || (argc > 2)) {
2361
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
2362
+ }
2363
+ ecode1 = SWIG_AsVal_int(argv[0], &val1);
2364
+ if (!SWIG_IsOK(ecode1)) {
2365
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "int","serialPuts", 1, argv[0] ));
2366
+ }
2367
+ arg1 = (int)(val1);
2368
+ res2 = SWIG_AsCharPtrAndSize(argv[1], &buf2, NULL, &alloc2);
2369
+ if (!SWIG_IsOK(res2)) {
2370
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char *","serialPuts", 2, argv[1] ));
2371
+ }
2372
+ arg2 = (char *)(buf2);
2373
+ serialPuts(arg1,arg2);
2374
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
2375
+ return Qnil;
2376
+ fail:
2377
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
2378
+ return Qnil;
2379
+ }
2380
+
2381
+
2382
+ SWIGINTERN VALUE
2383
+ _wrap_serialDataAvail(int argc, VALUE *argv, VALUE self) {
2384
+ int arg1 ;
2385
+ int val1 ;
2386
+ int ecode1 = 0 ;
2387
+ int result;
2388
+ VALUE vresult = Qnil;
2389
+
2390
+ if ((argc < 1) || (argc > 1)) {
2391
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
2392
+ }
2393
+ ecode1 = SWIG_AsVal_int(argv[0], &val1);
2394
+ if (!SWIG_IsOK(ecode1)) {
2395
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "int","serialDataAvail", 1, argv[0] ));
2396
+ }
2397
+ arg1 = (int)(val1);
2398
+ result = (int)serialDataAvail(arg1);
2399
+ vresult = SWIG_From_int((int)(result));
2400
+ return vresult;
2401
+ fail:
2402
+ return Qnil;
2403
+ }
2404
+
2405
+
2406
+ SWIGINTERN VALUE
2407
+ _wrap_serialGetchar(int argc, VALUE *argv, VALUE self) {
2408
+ int arg1 ;
2409
+ int val1 ;
2410
+ int ecode1 = 0 ;
2411
+ int result;
2412
+ VALUE vresult = Qnil;
2413
+
2414
+ if ((argc < 1) || (argc > 1)) {
2415
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
2416
+ }
2417
+ ecode1 = SWIG_AsVal_int(argv[0], &val1);
2418
+ if (!SWIG_IsOK(ecode1)) {
2419
+ SWIG_exception_fail(SWIG_ArgError(ecode1), Ruby_Format_TypeError( "", "int","serialGetchar", 1, argv[0] ));
2420
+ }
2421
+ arg1 = (int)(val1);
2422
+ result = (int)serialGetchar(arg1);
2423
+ vresult = SWIG_From_int((int)(result));
2424
+ return vresult;
2425
+ fail:
2426
+ return Qnil;
2427
+ }
2428
+
2429
+
2065
2430
 
2066
2431
  /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
2067
2432
 
@@ -2342,5 +2707,13 @@ SWIGEXPORT void Init_wiringpi(void) {
2342
2707
  rb_define_module_function(mWiringpi, "digitalWrite", _wrap_digitalWrite, -1);
2343
2708
  rb_define_module_function(mWiringpi, "pwmWrite", _wrap_pwmWrite, -1);
2344
2709
  rb_define_module_function(mWiringpi, "digitalRead", _wrap_digitalRead, -1);
2710
+ rb_define_module_function(mWiringpi, "shiftOut", _wrap_shiftOut, -1);
2711
+ rb_define_module_function(mWiringpi, "shiftIn", _wrap_shiftIn, -1);
2712
+ rb_define_module_function(mWiringpi, "serialOpen", _wrap_serialOpen, -1);
2713
+ rb_define_module_function(mWiringpi, "serialClose", _wrap_serialClose, -1);
2714
+ rb_define_module_function(mWiringpi, "serialPutchar", _wrap_serialPutchar, -1);
2715
+ rb_define_module_function(mWiringpi, "serialPuts", _wrap_serialPuts, -1);
2716
+ rb_define_module_function(mWiringpi, "serialDataAvail", _wrap_serialDataAvail, -1);
2717
+ rb_define_module_function(mWiringpi, "serialGetchar", _wrap_serialGetchar, -1);
2345
2718
  }
2346
2719
 
data/lib/wiringpi.rb CHANGED
@@ -1,111 +1,233 @@
1
1
  require 'wiringpi/wiringpi'
2
2
 
3
- WPI_MODE_PINS = 0
4
- WPI_MODE_GPIO = 1
3
+ WPI_MODE_PINS = 0 # Use sane pin numbering
4
+ WPI_MODE_GPIO = 1 # Use Broadcom barmy GPIO pin numbering
5
5
 
6
- INPUT = 0
7
- OUTPUT = 1
8
- PWM_OUTPUT = 2
6
+ # Constants for mode()
7
+ INPUT = 0
8
+ OUTPUT = 1
9
+ PWM_OUTPUT = 2
9
10
 
10
- HIGH = 1
11
- LOW = 0
11
+ # Constants for digitalWrite()
12
+ HIGH = 1
13
+ LOW = 0
12
14
 
13
- PUD_OFF = 0
14
- PUD_DOWN = 1
15
- PUD_UP = 2
15
+ PUD_OFF = 0
16
+ PUD_DOWN = 1
17
+ PUD_UP = 2
16
18
 
17
- class WiringPi
19
+ # Bit-order for shiftOut and shiftIn
20
+ LSBFIRST = 0 # Least Significant Bit First
21
+ MSBFIRST = 1 # Most Significant Bit First
18
22
 
19
- @@gpioPins = [
20
- 0,1,4,7,8,9,10,11,14,15,17,18,21,22,23,24,25 # seemingly random indeed!
21
- ]
23
+ module WiringPi
22
24
 
23
- @@pins = [
24
- 0,1,2,3,4,5,6,7, # basic IO pins
25
- 8,9, # i2c with 1k8 pull up resistor
26
- 10,11,12,13,14, # SPI pins, can also be used for IO
27
- 15,16,17
28
- ]
25
+ class Serial
29
26
 
30
- @@mode = WPI_MODE_PINS
31
- @@init = false
27
+ @id = 0
28
+ @device = '/dev/ttyAMA0'
29
+ @baud = 9600
32
30
 
33
- def self.readAll
31
+ def initialize(device='/dev/ttyAMA0',baud=9600)
34
32
 
35
- self.wiringPiSetup unless @@init
33
+ @device = device
34
+ @baud = baud
36
35
 
37
- pinValues = Hash.new
36
+ @id = Wiringpi.serialOpen( @device,@baud )
38
37
 
39
- @@pins.each do |pin|
40
-
41
- pinValues[pin] = self.read(pin)
42
-
43
- end
38
+ end
44
39
 
45
- pinValues
40
+ def serialClose
46
41
 
47
- end
42
+ Wiringpi.serialClose( @id )
43
+ @id = 0
48
44
 
49
- def self.wiringPiMode( mode )
45
+ end
50
46
 
51
- @@mode = mode
52
- Wiringpi.wiringPiGpioMode( @@mode )
47
+ def serialPutchar( char )
53
48
 
54
- end
49
+ Wiringpi.serialPutchar( @id, char )
55
50
 
56
- def self.wiringPiSetup
51
+ end
57
52
 
58
- begin
59
- Wiringpi.wiringPiSetup
60
- rescue Exception=>e
61
- raise e
62
- end
53
+ def serialPuts( string )
63
54
 
64
- Wiringpi.wiringPiGpioMode( @@mode )
65
- @@init = true
66
-
67
- end
55
+ Wiringpi.serialPuts( @id, string )
68
56
 
69
- def self.read(pin)
57
+ end
70
58
 
71
- self.wiringPiSetup unless @@init
59
+ def serialDataAvail
60
+
61
+ Wiringpi.serialDataAvail( @id )
72
62
 
73
- raise ArgumentError, "invalid pin, available gpio pins: #{@@pins}" unless ( @@mode = WPI_MODE_PINS and @@pins.include?(pin) ) or ( @@mode = WPI_MODE_GPIO and @@gpioPins.include?(pin) )
63
+ end
74
64
 
75
- Wiringpi.digitalRead(pin)
65
+ def serialGetchar
76
66
 
77
- end
67
+ Wiringpi.serialGetchar( @id )
78
68
 
79
- def self.pwmWrite(pin,value)
69
+ end
80
70
 
81
- self.wiringPiSetup unless @@init
71
+ end
82
72
 
83
- raise ArgumentError, "invalid pin, available gpio pins: #{@@pins}" unless ( @@mode = WPI_MODE_PINS and @@pins.include?(pin) ) or ( @@mode = WPI_MODE_GPIO and @@gpioPins.include?(pin) )
73
+ class GPIO
84
74
 
85
- Wiringpi.pwmWrite(pin,value)
75
+ GPIO_PINS = [
76
+ 0,1,4,7,8,9,10,11,14,15,17,18,21,22,23,24,25 # seemingly random indeed!
77
+ ]
86
78
 
87
- end
79
+ PINS = [
80
+ 0,1,2,3,4,5,6,7, # basic IO pins
81
+ 8,9, # i2c with 1k8 pull up resistor
82
+ 10,11,12,13,14, # SPI pins, can also be used for IO
83
+ 15,16,17
84
+ ]
88
85
 
89
- def self.write(pin,value)
86
+ @mode = WPI_MODE_PINS
90
87
 
91
- self.wiringPiSetup unless @@init
92
-
93
- raise ArgumentError, "invalid pin, available gpio pins: #{@@pins}" unless ( @@mode = WPI_MODE_PINS and @@pins.include?(pin) ) or ( @@mode = WPI_MODE_GPIO and @@gpioPins.include?(pin) )
94
- raise ArgumentError, 'invalid value' unless [0,1].include?(value)
88
+ @@init = false # once wiringPiSetup has been called, we don't have to do it again
95
89
 
96
- Wiringpi.digitalWrite(pin,value)
90
+ def initialize( mode=WPI_MODE_PINS )
97
91
 
98
- end
92
+ @mode = mode
93
+ self.wiringPiSetup unless @@init
99
94
 
100
- def self.mode(pin,mode)
95
+ end
101
96
 
102
- self.wiringPiSetup unless @@init
97
+ def wiringPiMode( mode )
103
98
 
104
- raise ArgumentError, "invalid pin, available gpio pins: #{@@pins}" unless ( @@mode = WPI_MODE_PINS and @@pins.include?(pin) ) or ( @@mode = WPI_MODE_GPIO and @@gpioPins.include?(pin) )
105
- raise ArgumentError, "invalid mode" unless [INPUT,OUTPUT,PWM_OUTPUT].include?(mode)
99
+ @mode = mode
100
+ Wiringpi.wiringPiGpioMode( @mode )
106
101
 
107
- Wiringpi.pinMode(pin, mode)
102
+ end
108
103
 
109
- end
104
+ def wiringPiSetup
110
105
 
111
- end
106
+ begin
107
+ Wiringpi.wiringPiSetup
108
+ rescue Exception=>e
109
+ raise e
110
+ end
111
+
112
+ Wiringpi.wiringPiGpioMode( @mode )
113
+ @@init = true
114
+
115
+ end
116
+
117
+ def checkPin(pin)
118
+
119
+ ( @mode = WPI_MODE_PINS and PINS.include?(pin) ) or ( @mode = WPI_MODE_GPIO and GPIO_PINS.include?(pin) )
120
+
121
+ end
122
+
123
+ def pinError(pin)
124
+ "invalid #{pin}, available gpio pins: #{PINS}" if @mode == WPI_MODE_PINS
125
+ "invalid #{pin}, available gpio pins: #{GPIO_PINS}" if @mode == WPI_MODE_GPIO
126
+ end
127
+
128
+ def read(pin)
129
+
130
+ raise ArgumentError, pinError(pin) unless checkPin(pin)
131
+
132
+ Wiringpi.digitalRead(pin)
133
+
134
+ end
135
+
136
+ def pwmWrite(pin,value)
137
+
138
+ raise ArgumentError, pinError(pin) unless checkPin(pin)
139
+
140
+ Wiringpi.pwmWrite(pin,value)
141
+
142
+ end
143
+
144
+ def write(pin,value)
145
+
146
+ raise ArgumentError, pinError(pin) unless checkPin(pin)
147
+ raise ArgumentError, 'invalid value' unless [0,1].include?(value)
148
+
149
+ Wiringpi.digitalWrite(pin,value)
150
+
151
+ end
152
+
153
+ def mode(pin,mode)
154
+
155
+ raise ArgumentError, pinError(pin) unless checkPin(pin)
156
+ raise ArgumentError, "invalid mode" unless [INPUT,OUTPUT,PWM_OUTPUT].include?(mode)
157
+
158
+ Wiringpi.pinMode(pin, mode)
159
+
160
+ end
161
+
162
+ =begin
163
+ shiftOutArray int dataPin, int clockPin, int latchPin, int[] bits
164
+ Shifts out an array of ints by converting them into bytes
165
+ and handing to Wiringpi.shiftOut, must contain only 1s or 0s
166
+ =end
167
+ def shiftOutArray(dataPin, clockPin, latchPin, bits)
168
+
169
+ raise ArgumentError, "invalid data pin, available gpio pins: #{PINS}" unless checkPin(dataPin)
170
+ raise ArgumentError, "invalid clock pin, available gpio pins: #{PINS}" unless checkPin(clockPin)
171
+ raise ArgumentError, "invalid latch pin, available gpio pins: #{PINS}" unless checkPin(latchPin)
172
+
173
+ WiringPi.write( latchPin, LOW )
174
+
175
+ bits.each_slice(8) do |slice|
176
+ Wiringpi.shiftOut(dataPin, clockPin, LSBFIRST, slice.reverse.join.to_i(2))
177
+ end
178
+
179
+ WiringPi.write( latchPin, HIGH )
180
+
181
+ end
182
+
183
+ =begin
184
+ shiftOut int dataPin, int clockPin, int latchPin, char
185
+ Shift out a single 8-bit integer 0-255
186
+ =end
187
+ def shiftOut(dataPin, clockPin, latchPin, char)
188
+
189
+ raise ArgumentError, "invalid data pin, available gpio pins: #{PINS}" unless checkPin(dataPin)
190
+ raise ArgumentError, "invalid clock pin, available gpio pins: #{PINS}" unless checkPin(clockPin)
191
+ raise ArgumentError, "invalid latch pin, available gpio pins: #{PINS}" unless checkPin(latchPin)
192
+
193
+ WiringPi.write( latchPin, LOW )
194
+
195
+ Wiringpi.shiftOut(dataPin, clockPin, LSBFIRST, char)
196
+
197
+ WiringPi.write( latchPin, HIGH )
198
+
199
+ end
200
+
201
+ =begin
202
+ readAll
203
+ Reads values of all pins and returns them as a hash
204
+ =end
205
+ def readAll
206
+
207
+ pinValues = Hash.new
208
+
209
+ if @mode == WPI_MODE_GPIO
210
+
211
+ GPIO_PINS.each do |pin|
212
+
213
+ pinValues[pin] = self.read(pin)
214
+
215
+ end
216
+
217
+ else
218
+
219
+ PINS.each do |pin|
220
+
221
+ pinValues[pin] = self.read(pin)
222
+
223
+ end
224
+
225
+ end
226
+
227
+ pinValues
228
+
229
+ end
230
+
231
+ end
232
+
233
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wiringpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: armv6l-linux
7
7
  authors:
@@ -12,8 +12,10 @@ bindir: bin
12
12
  cert_chain: []
13
13
  date: 2012-06-22 00:00:00.000000000 Z
14
14
  dependencies: []
15
- description: ! 'Alpha version of the WiringPi library wrapper. WiringPi can be found
16
- here: http://projects.drogon.net/raspberry-pi/wiringpi/'
15
+ description: ! 'WiringPi library wrapper for the Raspberry Pi only. Wraps up the Arduino
16
+ wiring-like WiringPi library into a convinient Ruby gem. Currently includes GPIO
17
+ functionality, serial and shiftOut/shiftIn support. Credit to Gordon for the WiringPi
18
+ library, which can be found here: http://projects.drogon.net/raspberry-pi/wiringpi/'
17
19
  email: phil@gadgetoid.com
18
20
  executables: []
19
21
  extensions:
@@ -21,9 +23,13 @@ extensions:
21
23
  extra_rdoc_files: []
22
24
  files:
23
25
  - lib/wiringpi.rb
24
- - ext/wiringpi/wiringpi.c
26
+ - ext/wiringpi/wiringShift.c
27
+ - ext/wiringpi/wiringPi.c
28
+ - ext/wiringpi/serial.c
25
29
  - ext/wiringpi/wiringpi_wrap.c
26
- - ext/wiringpi/wiringpi.h
30
+ - ext/wiringpi/wiringShift.h
31
+ - ext/wiringpi/serial.h
32
+ - ext/wiringpi/wiringPi.h
27
33
  - ext/wiringpi/extconf.rb
28
34
  homepage: http://rubygems.org/gems/wiringpi
29
35
  licenses: