wiringpi-ruby 2.0.0 → 2.0.1
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.
- checksums.yaml +4 -4
- data/ext/wiringpi/WiringPi/devLib/ds1302.c +240 -0
- data/ext/wiringpi/WiringPi/devLib/ds1302.h +44 -0
- data/ext/wiringpi/WiringPi/devLib/font.h +2577 -0
- data/ext/wiringpi/WiringPi/devLib/gertboard.c +164 -0
- data/ext/wiringpi/WiringPi/devLib/gertboard.h +45 -0
- data/ext/wiringpi/WiringPi/devLib/lcd.c +495 -0
- data/ext/wiringpi/WiringPi/devLib/lcd.h +52 -0
- data/ext/wiringpi/WiringPi/devLib/lcd128x64.c +673 -0
- data/ext/wiringpi/WiringPi/devLib/lcd128x64.h +39 -0
- data/ext/wiringpi/WiringPi/devLib/maxdetect.c +238 -0
- data/ext/wiringpi/WiringPi/devLib/maxdetect.h +40 -0
- data/ext/wiringpi/WiringPi/devLib/piFace.c +112 -0
- data/ext/wiringpi/WiringPi/devLib/piFace.h +32 -0
- data/ext/wiringpi/WiringPi/devLib/piFaceOld.c +177 -0
- data/ext/wiringpi/WiringPi/devLib/piGlow.c +118 -0
- data/ext/wiringpi/WiringPi/devLib/piGlow.h +45 -0
- data/ext/wiringpi/WiringPi/devLib/piNes.c +113 -0
- data/ext/wiringpi/WiringPi/devLib/piNes.h +45 -0
- data/ext/wiringpi/WiringPi/devLib/scrollPhat.c +430 -0
- data/ext/wiringpi/WiringPi/devLib/scrollPhat.h +39 -0
- data/ext/wiringpi/WiringPi/devLib/scrollPhatFont.h +544 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/7segments.c +221 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/buttons.c +83 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/gertboard.c +96 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/record.c +60 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/temperature.c +78 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/voltmeter.c +73 -0
- data/ext/wiringpi/WiringPi/examples/Gertboard/vumeter.c +152 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/blink.c +59 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/buttons.c +103 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/ladder.c +337 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/metro.c +111 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/motor.c +120 -0
- data/ext/wiringpi/WiringPi/examples/PiFace/reaction.c +194 -0
- data/ext/wiringpi/WiringPi/examples/PiGlow/piGlow0.c +51 -0
- data/ext/wiringpi/WiringPi/examples/PiGlow/piGlow1.c +258 -0
- data/ext/wiringpi/WiringPi/examples/PiGlow/piglow.c +176 -0
- data/ext/wiringpi/WiringPi/examples/blink-thread.c +61 -0
- data/ext/wiringpi/WiringPi/examples/blink.c +48 -0
- data/ext/wiringpi/WiringPi/examples/blink12.c +111 -0
- data/ext/wiringpi/WiringPi/examples/blink12drcs.c +125 -0
- data/ext/wiringpi/WiringPi/examples/blink6drcs.c +115 -0
- data/ext/wiringpi/WiringPi/examples/blink8-drcn.c +61 -0
- data/ext/wiringpi/WiringPi/examples/blink8.c +57 -0
- data/ext/wiringpi/WiringPi/examples/clock.c +201 -0
- data/ext/wiringpi/WiringPi/examples/delayTest.c +102 -0
- data/ext/wiringpi/WiringPi/examples/ds1302.c +238 -0
- data/ext/wiringpi/WiringPi/examples/header.h +23 -0
- data/ext/wiringpi/WiringPi/examples/isr-osc.c +118 -0
- data/ext/wiringpi/WiringPi/examples/isr.c +110 -0
- data/ext/wiringpi/WiringPi/examples/lcd-adafruit.c +347 -0
- data/ext/wiringpi/WiringPi/examples/lcd.c +286 -0
- data/ext/wiringpi/WiringPi/examples/lowPower.c +68 -0
- data/ext/wiringpi/WiringPi/examples/max31855.c +60 -0
- data/ext/wiringpi/WiringPi/examples/nes.c +67 -0
- data/ext/wiringpi/WiringPi/examples/okLed.c +82 -0
- data/ext/wiringpi/WiringPi/examples/pwm.c +58 -0
- data/ext/wiringpi/WiringPi/examples/q2w/binary.c +79 -0
- data/ext/wiringpi/WiringPi/examples/q2w/blink-io.c +61 -0
- data/ext/wiringpi/WiringPi/examples/q2w/blink.c +50 -0
- data/ext/wiringpi/WiringPi/examples/q2w/bright.c +59 -0
- data/ext/wiringpi/WiringPi/examples/q2w/button.c +63 -0
- data/ext/wiringpi/WiringPi/examples/q2w/volts.c +62 -0
- data/ext/wiringpi/WiringPi/examples/rht03.c +86 -0
- data/ext/wiringpi/WiringPi/examples/scrollPhat/scphat.c +230 -0
- data/ext/wiringpi/WiringPi/examples/scrollPhat/test.c +115 -0
- data/ext/wiringpi/WiringPi/examples/serialRead.c +48 -0
- data/ext/wiringpi/WiringPi/examples/serialTest.c +75 -0
- data/ext/wiringpi/WiringPi/examples/servo.c +57 -0
- data/ext/wiringpi/WiringPi/examples/softPwm.c +89 -0
- data/ext/wiringpi/WiringPi/examples/softTone.c +54 -0
- data/ext/wiringpi/WiringPi/examples/speed.c +95 -0
- data/ext/wiringpi/WiringPi/examples/spiSpeed.c +118 -0
- data/ext/wiringpi/WiringPi/examples/wfi.c +161 -0
- data/ext/wiringpi/WiringPi/gpio/gpio.c +1538 -0
- data/ext/wiringpi/WiringPi/gpio/readall.c +403 -0
- data/ext/wiringpi/WiringPi/version.h +3 -0
- data/ext/wiringpi/WiringPi/wiringPi/ads1115.c +293 -0
- data/ext/wiringpi/WiringPi/wiringPi/ads1115.h +55 -0
- data/ext/wiringpi/WiringPi/wiringPi/bmp180.c +237 -0
- data/ext/wiringpi/WiringPi/wiringPi/bmp180.h +34 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcNet.c +405 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcNet.h +42 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcSerial.c +196 -0
- data/ext/wiringpi/WiringPi/wiringPi/drcSerial.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/ds18b20.c +146 -0
- data/ext/wiringpi/WiringPi/wiringPi/ds18b20.h +34 -0
- data/ext/wiringpi/WiringPi/wiringPi/htu21d.c +150 -0
- data/ext/wiringpi/WiringPi/wiringPi/htu21d.h +34 -0
- data/ext/wiringpi/WiringPi/wiringPi/max31855.c +99 -0
- data/ext/wiringpi/WiringPi/wiringPi/max31855.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/max5322.c +84 -0
- data/ext/wiringpi/WiringPi/wiringPi/max5322.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23008.c +149 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23008.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016.c +164 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23016reg.h +48 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23017.c +195 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23017.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.c +188 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s08.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.c +235 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23s17.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23x08.h +73 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp23x0817.h +87 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3002.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3002.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3004.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3004.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3422.c +125 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp3422.h +43 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp4802.c +76 -0
- data/ext/wiringpi/WiringPi/wiringPi/mcp4802.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8574.c +126 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8574.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8591.c +90 -0
- data/ext/wiringpi/WiringPi/wiringPi/pcf8591.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/piHiPri.c +51 -0
- data/ext/wiringpi/WiringPi/wiringPi/piThread.c +63 -0
- data/ext/wiringpi/WiringPi/wiringPi/pseudoPins.c +95 -0
- data/ext/wiringpi/WiringPi/wiringPi/pseudoPins.h +26 -0
- data/ext/wiringpi/WiringPi/wiringPi/rht03.c +252 -0
- data/ext/wiringpi/WiringPi/wiringPi/rht03.h +25 -0
- data/ext/wiringpi/WiringPi/wiringPi/sn3218.c +75 -0
- data/ext/wiringpi/WiringPi/wiringPi/sn3218.h +33 -0
- data/ext/wiringpi/WiringPi/wiringPi/softPwm.c +186 -0
- data/ext/wiringpi/WiringPi/wiringPi/softPwm.h +35 -0
- data/ext/wiringpi/WiringPi/wiringPi/softServo.c +211 -0
- data/ext/wiringpi/WiringPi/wiringPi/softServo.h +35 -0
- data/ext/wiringpi/WiringPi/wiringPi/softTone.c +150 -0
- data/ext/wiringpi/WiringPi/wiringPi/softTone.h +39 -0
- data/ext/wiringpi/WiringPi/wiringPi/sr595.c +109 -0
- data/ext/wiringpi/WiringPi/wiringPi/sr595.h +34 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPi.c +2507 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPi.h +269 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.c +233 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiI2C.h +42 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.c +144 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringPiSPI.h +36 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.c +225 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringSerial.h +38 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringShift.c +83 -0
- data/ext/wiringpi/WiringPi/wiringPi/wiringShift.h +41 -0
- data/ext/wiringpi/WiringPi/wiringPi/wpiExtensions.c +928 -0
- data/ext/wiringpi/WiringPi/wiringPi/wpiExtensions.h +26 -0
- data/ext/wiringpi/WiringPi/wiringPiD/daemonise.c +82 -0
- data/ext/wiringpi/WiringPi/wiringPiD/daemonise.h +9 -0
- data/ext/wiringpi/WiringPi/wiringPiD/drcNetCmd.h +43 -0
- data/ext/wiringpi/WiringPi/wiringPiD/network.c +330 -0
- data/ext/wiringpi/WiringPi/wiringPiD/network.h +31 -0
- data/ext/wiringpi/WiringPi/wiringPiD/runRemote.c +126 -0
- data/ext/wiringpi/WiringPi/wiringPiD/runRemote.h +29 -0
- data/ext/wiringpi/WiringPi/wiringPiD/wiringpid.c +382 -0
- metadata +155 -1
@@ -0,0 +1,118 @@
|
|
1
|
+
/*
|
2
|
+
* spiSpeed.c:
|
3
|
+
* Code to measure the SPI speed/latency.
|
4
|
+
* Copyright (c) 2014 Gordon Henderson
|
5
|
+
***********************************************************************
|
6
|
+
* This file is part of wiringPi:
|
7
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
8
|
+
*
|
9
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
10
|
+
* it under the terms of the GNU Lesser General Public License as
|
11
|
+
* published by the Free Software Foundation, either version 3 of the
|
12
|
+
* License, or (at your option) any later version.
|
13
|
+
*
|
14
|
+
* wiringPi is distributed in the hope that it will be useful,
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
* GNU Lesser General Public License for more details.
|
18
|
+
*
|
19
|
+
* You should have received a copy of the GNU Lesser General Public
|
20
|
+
* License along with wiringPi.
|
21
|
+
* If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
|
26
|
+
#include <stdio.h>
|
27
|
+
#include <stdlib.h>
|
28
|
+
#include <unistd.h>
|
29
|
+
#include <stdint.h>
|
30
|
+
#include <string.h>
|
31
|
+
#include <errno.h>
|
32
|
+
//#include <fcntl.h>
|
33
|
+
//#include <sys/ioctl.h>
|
34
|
+
//#include <linux/spi/spidev.h>
|
35
|
+
|
36
|
+
#include <wiringPi.h>
|
37
|
+
#include <wiringPiSPI.h>
|
38
|
+
|
39
|
+
#define TRUE (1==1)
|
40
|
+
#define FALSE (!TRUE)
|
41
|
+
|
42
|
+
#define SPI_CHAN 0
|
43
|
+
#define NUM_TIMES 100
|
44
|
+
#define MAX_SIZE (1024*1024)
|
45
|
+
|
46
|
+
static int myFd ;
|
47
|
+
|
48
|
+
|
49
|
+
void spiSetup (int speed)
|
50
|
+
{
|
51
|
+
if ((myFd = wiringPiSPISetup (SPI_CHAN, speed)) < 0)
|
52
|
+
{
|
53
|
+
fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ;
|
54
|
+
exit (EXIT_FAILURE) ;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
int main (void)
|
60
|
+
{
|
61
|
+
int speed, times, size ;
|
62
|
+
unsigned int start, end ;
|
63
|
+
int spiFail ;
|
64
|
+
unsigned char *myData ;
|
65
|
+
double timePerTransaction, perfectTimePerTransaction, dataSpeed ;
|
66
|
+
|
67
|
+
if ((myData = malloc (MAX_SIZE)) == NULL)
|
68
|
+
{
|
69
|
+
fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ;
|
70
|
+
exit (EXIT_FAILURE) ;
|
71
|
+
}
|
72
|
+
|
73
|
+
wiringPiSetup () ;
|
74
|
+
|
75
|
+
for (speed = 1 ; speed <= 32 ; speed *= 2)
|
76
|
+
{
|
77
|
+
printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
|
78
|
+
printf ("| MHz | Size | mS/Trans | TpS | Mb/Sec | Latency mS |\n") ;
|
79
|
+
printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
|
80
|
+
|
81
|
+
spiFail = FALSE ;
|
82
|
+
spiSetup (speed * 1000000) ;
|
83
|
+
for (size = 1 ; size <= MAX_SIZE ; size *= 2)
|
84
|
+
{
|
85
|
+
printf ("| %5d | %6d ", speed, size) ;
|
86
|
+
|
87
|
+
start = millis () ;
|
88
|
+
for (times = 0 ; times < NUM_TIMES ; ++times)
|
89
|
+
if (wiringPiSPIDataRW (SPI_CHAN, myData, size) == -1)
|
90
|
+
{
|
91
|
+
printf ("SPI failure: %s\n", strerror (errno)) ;
|
92
|
+
spiFail = TRUE ;
|
93
|
+
break ;
|
94
|
+
}
|
95
|
+
end = millis () ;
|
96
|
+
|
97
|
+
if (spiFail)
|
98
|
+
break ;
|
99
|
+
|
100
|
+
timePerTransaction = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ;
|
101
|
+
dataSpeed = (double)(size * 8) / (1024.0 * 1024.0) / timePerTransaction ;
|
102
|
+
perfectTimePerTransaction = ((double)(size * 8)) / ((double)(speed * 1000000)) ;
|
103
|
+
|
104
|
+
printf ("| %8.3f ", timePerTransaction * 1000.0) ;
|
105
|
+
printf ("| %8.1f ", 1.0 / timePerTransaction) ;
|
106
|
+
printf ("| %9.5f ", dataSpeed) ;
|
107
|
+
printf ("| %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ;
|
108
|
+
printf ("|\n") ;
|
109
|
+
|
110
|
+
}
|
111
|
+
|
112
|
+
close (myFd) ;
|
113
|
+
printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
|
114
|
+
printf ("\n") ;
|
115
|
+
}
|
116
|
+
|
117
|
+
return 0 ;
|
118
|
+
}
|
@@ -0,0 +1,161 @@
|
|
1
|
+
/*
|
2
|
+
* wfi.c:
|
3
|
+
* Wait for Interrupt test program
|
4
|
+
*
|
5
|
+
* This program demonstrates the use of the waitForInterrupt()
|
6
|
+
* function in wiringPi. It listens to a button input on
|
7
|
+
* BCM_GPIO pin 17 (wiringPi pin 0)
|
8
|
+
*
|
9
|
+
* The biggest issue with this method is that it really only works
|
10
|
+
* well in Sys mode.
|
11
|
+
*
|
12
|
+
* Jan 2013: This way of doing things is sort of deprecated now, see
|
13
|
+
* the wiringPiISR() function instead and the isr.c test program here.
|
14
|
+
*
|
15
|
+
* Copyright (c) 2012-2013 Gordon Henderson.
|
16
|
+
***********************************************************************
|
17
|
+
* This file is part of wiringPi:
|
18
|
+
* https://projects.drogon.net/raspberry-pi/wiringpi/
|
19
|
+
*
|
20
|
+
* wiringPi is free software: you can redistribute it and/or modify
|
21
|
+
* it under the terms of the GNU Lesser General Public License as published by
|
22
|
+
* the Free Software Foundation, either version 3 of the License, or
|
23
|
+
* (at your option) any later version.
|
24
|
+
*
|
25
|
+
* wiringPi is distributed in the hope that it will be useful,
|
26
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
27
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
28
|
+
* GNU Lesser General Public License for more details.
|
29
|
+
*
|
30
|
+
* You should have received a copy of the GNU Lesser General Public License
|
31
|
+
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
|
32
|
+
***********************************************************************
|
33
|
+
*/
|
34
|
+
|
35
|
+
#include <stdio.h>
|
36
|
+
#include <stdlib.h>
|
37
|
+
#include <wiringPi.h>
|
38
|
+
|
39
|
+
// A 'key' which we can lock and unlock - values are 0 through 3
|
40
|
+
// This is interpreted internally as a pthread_mutex by wiringPi
|
41
|
+
// which is hiding some of that to make life simple.
|
42
|
+
|
43
|
+
#define COUNT_KEY 0
|
44
|
+
|
45
|
+
// What BCM_GPIO input are we using?
|
46
|
+
|
47
|
+
#define BUTTON_PIN 17
|
48
|
+
|
49
|
+
// Debounce time in mS
|
50
|
+
|
51
|
+
#define DEBOUNCE_TIME 100
|
52
|
+
|
53
|
+
|
54
|
+
// globalCounter:
|
55
|
+
// Global variable to count interrupts
|
56
|
+
// Should be declared volatile to make sure the compiler doesn't cache it.
|
57
|
+
|
58
|
+
static volatile int globalCounter = 0 ;
|
59
|
+
|
60
|
+
|
61
|
+
/*
|
62
|
+
* waitForIt:
|
63
|
+
* This is a thread created using the wiringPi simplified threading
|
64
|
+
* mechanism. It will wait on an interrupt on the button and increment
|
65
|
+
* a counter.
|
66
|
+
*********************************************************************************
|
67
|
+
*/
|
68
|
+
|
69
|
+
PI_THREAD (waitForIt)
|
70
|
+
{
|
71
|
+
int state = 0 ;
|
72
|
+
int debounceTime = 0 ;
|
73
|
+
|
74
|
+
(void)piHiPri (10) ; // Set this thread to be high priority
|
75
|
+
|
76
|
+
for (;;)
|
77
|
+
{
|
78
|
+
if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it
|
79
|
+
{
|
80
|
+
// Bouncing?
|
81
|
+
|
82
|
+
if (millis () < debounceTime)
|
83
|
+
{
|
84
|
+
debounceTime = millis () + DEBOUNCE_TIME ;
|
85
|
+
continue ;
|
86
|
+
}
|
87
|
+
|
88
|
+
// We have a valid one
|
89
|
+
|
90
|
+
state ^= 1 ;
|
91
|
+
|
92
|
+
piLock (COUNT_KEY) ;
|
93
|
+
++globalCounter ;
|
94
|
+
piUnlock (COUNT_KEY) ;
|
95
|
+
|
96
|
+
// Wait for key to be released
|
97
|
+
|
98
|
+
while (digitalRead (BUTTON_PIN) == LOW)
|
99
|
+
delay (1) ;
|
100
|
+
|
101
|
+
debounceTime = millis () + DEBOUNCE_TIME ;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
/*
|
108
|
+
* setup:
|
109
|
+
* Demo a crude but effective way to initialise the hardware
|
110
|
+
*********************************************************************************
|
111
|
+
*/
|
112
|
+
|
113
|
+
void setup (void)
|
114
|
+
{
|
115
|
+
|
116
|
+
// Use the gpio program to initialise the hardware
|
117
|
+
// (This is the crude, but effective)
|
118
|
+
|
119
|
+
system ("gpio edge 17 falling") ;
|
120
|
+
|
121
|
+
// Setup wiringPi
|
122
|
+
|
123
|
+
wiringPiSetupSys () ;
|
124
|
+
|
125
|
+
// Fire off our interrupt handler
|
126
|
+
|
127
|
+
piThreadCreate (waitForIt) ;
|
128
|
+
|
129
|
+
}
|
130
|
+
|
131
|
+
|
132
|
+
/*
|
133
|
+
* main
|
134
|
+
*********************************************************************************
|
135
|
+
*/
|
136
|
+
|
137
|
+
int main (void)
|
138
|
+
{
|
139
|
+
int lastCounter = 0 ;
|
140
|
+
int myCounter = 0 ;
|
141
|
+
|
142
|
+
setup () ;
|
143
|
+
|
144
|
+
for (;;)
|
145
|
+
{
|
146
|
+
printf ("Waiting ... ") ; fflush (stdout) ;
|
147
|
+
|
148
|
+
while (myCounter == lastCounter)
|
149
|
+
{
|
150
|
+
piLock (COUNT_KEY) ;
|
151
|
+
myCounter = globalCounter ;
|
152
|
+
piUnlock (COUNT_KEY) ;
|
153
|
+
delay (500) ;
|
154
|
+
}
|
155
|
+
|
156
|
+
printf (" Done. myCounter: %5d\n", myCounter) ;
|
157
|
+
lastCounter = myCounter ;
|
158
|
+
}
|
159
|
+
|
160
|
+
return 0 ;
|
161
|
+
}
|
@@ -0,0 +1,1538 @@
|
|
1
|
+
/*
|
2
|
+
* gpio.c:
|
3
|
+
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
|
4
|
+
* Pi's GPIO.
|
5
|
+
* Copyright (c) 2012-2018 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 Lesser 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 Lesser General Public License for more details.
|
19
|
+
*
|
20
|
+
* You should have received a copy of the GNU Lesser General Public License
|
21
|
+
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
***********************************************************************
|
23
|
+
*/
|
24
|
+
|
25
|
+
|
26
|
+
#include <stdio.h>
|
27
|
+
#include <stdlib.h>
|
28
|
+
#include <stdint.h>
|
29
|
+
#include <ctype.h>
|
30
|
+
#include <string.h>
|
31
|
+
#include <unistd.h>
|
32
|
+
#include <errno.h>
|
33
|
+
#include <fcntl.h>
|
34
|
+
#include <sys/types.h>
|
35
|
+
#include <sys/stat.h>
|
36
|
+
|
37
|
+
#include <wiringPi.h>
|
38
|
+
#include <wpiExtensions.h>
|
39
|
+
|
40
|
+
#include <gertboard.h>
|
41
|
+
#include <piFace.h>
|
42
|
+
|
43
|
+
#include "../version.h"
|
44
|
+
|
45
|
+
extern int wiringPiDebug ;
|
46
|
+
|
47
|
+
// External functions I can't be bothered creating a separate .h file for:
|
48
|
+
|
49
|
+
extern void doReadall (void) ;
|
50
|
+
extern void doAllReadall (void) ;
|
51
|
+
extern void doQmode (int argc, char *argv []) ;
|
52
|
+
|
53
|
+
#ifndef TRUE
|
54
|
+
# define TRUE (1==1)
|
55
|
+
# define FALSE (1==2)
|
56
|
+
#endif
|
57
|
+
|
58
|
+
#define PI_USB_POWER_CONTROL 38
|
59
|
+
#define I2CDETECT "i2cdetect"
|
60
|
+
#define MODPROBE "modprobe"
|
61
|
+
#define RMMOD "rmmod"
|
62
|
+
|
63
|
+
int wpMode ;
|
64
|
+
|
65
|
+
char *usage = "Usage: gpio -v\n"
|
66
|
+
" gpio -h\n"
|
67
|
+
" gpio [-g|-1] ...\n"
|
68
|
+
" gpio [-d] ...\n"
|
69
|
+
" [-x extension:params] [[ -x ...]] ...\n"
|
70
|
+
" gpio [-p] <read/write/wb> ...\n"
|
71
|
+
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
|
72
|
+
" gpio <toggle/blink> <pin>\n"
|
73
|
+
" gpio readall\n"
|
74
|
+
" gpio unexportall/exports\n"
|
75
|
+
" gpio export/edge/unexport ...\n"
|
76
|
+
" gpio wfi <pin> <mode>\n"
|
77
|
+
" gpio drive <group> <value>\n"
|
78
|
+
" gpio pwm-bal/pwm-ms \n"
|
79
|
+
" gpio pwmr <range> \n"
|
80
|
+
" gpio pwmc <divider> \n"
|
81
|
+
" gpio load spi/i2c\n"
|
82
|
+
" gpio unload spi/i2c\n"
|
83
|
+
" gpio i2cd/i2cdetect\n"
|
84
|
+
" gpio rbx/rbd\n"
|
85
|
+
" gpio wb <value>\n"
|
86
|
+
" gpio usbp high/low\n"
|
87
|
+
" gpio gbr <channel>\n"
|
88
|
+
" gpio gbw <channel> <value>" ; // No trailing newline needed here.
|
89
|
+
|
90
|
+
|
91
|
+
#ifdef NOT_FOR_NOW
|
92
|
+
/*
|
93
|
+
* decodePin:
|
94
|
+
* Decode a pin "number" which can actually be a pin name to represent
|
95
|
+
* one of the Pi's on-board pins.
|
96
|
+
*********************************************************************************
|
97
|
+
*/
|
98
|
+
|
99
|
+
static int decodePin (const char *str)
|
100
|
+
{
|
101
|
+
|
102
|
+
// The first case - see if it's a number:
|
103
|
+
|
104
|
+
if (isdigit (str [0]))
|
105
|
+
return atoi (str) ;
|
106
|
+
|
107
|
+
return 0 ;
|
108
|
+
}
|
109
|
+
#endif
|
110
|
+
|
111
|
+
|
112
|
+
/*
|
113
|
+
* findExecutable:
|
114
|
+
* Code to locate the path to the given executable. We have a fixed list
|
115
|
+
* of locations to try which completely overrides any $PATH environment.
|
116
|
+
* This may be detrimental, however it avoids the reliance on $PATH
|
117
|
+
* which may be a security issue when this program is run a set-uid-root.
|
118
|
+
*********************************************************************************
|
119
|
+
*/
|
120
|
+
|
121
|
+
static const char *searchPath [] =
|
122
|
+
{
|
123
|
+
"/sbin",
|
124
|
+
"/usr/sbin",
|
125
|
+
"/bin",
|
126
|
+
"/usr/bin",
|
127
|
+
NULL,
|
128
|
+
} ;
|
129
|
+
|
130
|
+
static char *findExecutable (const char *progName)
|
131
|
+
{
|
132
|
+
static char *path = NULL ;
|
133
|
+
int len = strlen (progName) ;
|
134
|
+
int i = 0 ;
|
135
|
+
struct stat statBuf ;
|
136
|
+
|
137
|
+
for (i = 0 ; searchPath [i] != NULL ; ++i)
|
138
|
+
{
|
139
|
+
path = malloc (strlen (searchPath [i]) + len + 2) ;
|
140
|
+
sprintf (path, "%s/%s", searchPath [i], progName) ;
|
141
|
+
|
142
|
+
if (stat (path, &statBuf) == 0)
|
143
|
+
return path ;
|
144
|
+
free (path) ;
|
145
|
+
}
|
146
|
+
|
147
|
+
return NULL ;
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
/*
|
152
|
+
* changeOwner:
|
153
|
+
* Change the ownership of the file to the real userId of the calling
|
154
|
+
* program so we can access it.
|
155
|
+
*********************************************************************************
|
156
|
+
*/
|
157
|
+
|
158
|
+
static void changeOwner (char *cmd, char *file)
|
159
|
+
{
|
160
|
+
uid_t uid = getuid () ;
|
161
|
+
uid_t gid = getgid () ;
|
162
|
+
|
163
|
+
if (chown (file, uid, gid) != 0)
|
164
|
+
{
|
165
|
+
|
166
|
+
// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that
|
167
|
+
// the warning message is an error.
|
168
|
+
|
169
|
+
if (errno != ENOENT)
|
170
|
+
fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
/*
|
176
|
+
* moduleLoaded:
|
177
|
+
* Return true/false if the supplied module is loaded
|
178
|
+
*********************************************************************************
|
179
|
+
*/
|
180
|
+
|
181
|
+
static int moduleLoaded (char *modName)
|
182
|
+
{
|
183
|
+
int len = strlen (modName) ;
|
184
|
+
int found = FALSE ;
|
185
|
+
FILE *fd = fopen ("/proc/modules", "r") ;
|
186
|
+
char line [80] ;
|
187
|
+
|
188
|
+
if (fd == NULL)
|
189
|
+
{
|
190
|
+
fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ;
|
191
|
+
exit (1) ;
|
192
|
+
}
|
193
|
+
|
194
|
+
while (fgets (line, 80, fd) != NULL)
|
195
|
+
{
|
196
|
+
if (strncmp (line, modName, len) != 0)
|
197
|
+
continue ;
|
198
|
+
|
199
|
+
found = TRUE ;
|
200
|
+
break ;
|
201
|
+
}
|
202
|
+
|
203
|
+
fclose (fd) ;
|
204
|
+
|
205
|
+
return found ;
|
206
|
+
}
|
207
|
+
|
208
|
+
|
209
|
+
/*
|
210
|
+
* doLoad:
|
211
|
+
* Load either the spi or i2c modules and change device ownerships, etc.
|
212
|
+
*********************************************************************************
|
213
|
+
*/
|
214
|
+
|
215
|
+
static void checkDevTree (char *argv [])
|
216
|
+
{
|
217
|
+
struct stat statBuf ;
|
218
|
+
|
219
|
+
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
|
220
|
+
{
|
221
|
+
fprintf (stderr,
|
222
|
+
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
|
223
|
+
" You need to run the raspi-config program (as root) and select the\n"
|
224
|
+
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
|
225
|
+
exit (1) ;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
static void _doLoadUsage (char *argv [])
|
230
|
+
{
|
231
|
+
fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
|
232
|
+
exit (1) ;
|
233
|
+
}
|
234
|
+
|
235
|
+
static void doLoad (int argc, char *argv [])
|
236
|
+
{
|
237
|
+
char *module1, *module2 ;
|
238
|
+
char cmd [80] ;
|
239
|
+
char *file1, *file2 ;
|
240
|
+
char args1 [32], args2 [32] ;
|
241
|
+
|
242
|
+
checkDevTree (argv) ;
|
243
|
+
|
244
|
+
if (argc < 3)
|
245
|
+
_doLoadUsage (argv) ;
|
246
|
+
|
247
|
+
args1 [0] = args2 [0] = 0 ;
|
248
|
+
|
249
|
+
/**/ if (strcasecmp (argv [2], "spi") == 0)
|
250
|
+
{
|
251
|
+
module1 = "spidev" ;
|
252
|
+
module2 = "spi_bcm2708" ;
|
253
|
+
file1 = "/dev/spidev0.0" ;
|
254
|
+
file2 = "/dev/spidev0.1" ;
|
255
|
+
if (argc == 4)
|
256
|
+
{
|
257
|
+
fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
|
258
|
+
exit (1) ;
|
259
|
+
}
|
260
|
+
else if (argc > 4)
|
261
|
+
_doLoadUsage (argv) ;
|
262
|
+
}
|
263
|
+
else if (strcasecmp (argv [2], "i2c") == 0)
|
264
|
+
{
|
265
|
+
module1 = "i2c_dev" ;
|
266
|
+
module2 = "i2c_bcm2708" ;
|
267
|
+
file1 = "/dev/i2c-0" ;
|
268
|
+
file2 = "/dev/i2c-1" ;
|
269
|
+
if (argc == 4)
|
270
|
+
sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
|
271
|
+
else if (argc > 4)
|
272
|
+
_doLoadUsage (argv) ;
|
273
|
+
}
|
274
|
+
else
|
275
|
+
_doLoadUsage (argv) ;
|
276
|
+
|
277
|
+
if (findExecutable ("modprobe") == NULL)
|
278
|
+
printf ("No found\n") ;
|
279
|
+
|
280
|
+
if (!moduleLoaded (module1))
|
281
|
+
{
|
282
|
+
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
|
283
|
+
system (cmd) ;
|
284
|
+
}
|
285
|
+
|
286
|
+
if (!moduleLoaded (module2))
|
287
|
+
{
|
288
|
+
sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
|
289
|
+
system (cmd) ;
|
290
|
+
}
|
291
|
+
|
292
|
+
if (!moduleLoaded (module2))
|
293
|
+
{
|
294
|
+
fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
|
295
|
+
exit (1) ;
|
296
|
+
}
|
297
|
+
|
298
|
+
sleep (1) ; // To let things get settled
|
299
|
+
|
300
|
+
changeOwner (argv [0], file1) ;
|
301
|
+
changeOwner (argv [0], file2) ;
|
302
|
+
}
|
303
|
+
|
304
|
+
|
305
|
+
/*
|
306
|
+
* doUnLoad:
|
307
|
+
* Un-Load either the spi or i2c modules and change device ownerships, etc.
|
308
|
+
*********************************************************************************
|
309
|
+
*/
|
310
|
+
|
311
|
+
static void _doUnLoadUsage (char *argv [])
|
312
|
+
{
|
313
|
+
fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
|
314
|
+
exit (1) ;
|
315
|
+
}
|
316
|
+
|
317
|
+
static void doUnLoad (int argc, char *argv [])
|
318
|
+
{
|
319
|
+
char *module1, *module2 ;
|
320
|
+
char cmd [80] ;
|
321
|
+
|
322
|
+
checkDevTree (argv) ;
|
323
|
+
|
324
|
+
if (argc != 3)
|
325
|
+
_doUnLoadUsage (argv) ;
|
326
|
+
|
327
|
+
/**/ if (strcasecmp (argv [2], "spi") == 0)
|
328
|
+
{
|
329
|
+
module1 = "spidev" ;
|
330
|
+
module2 = "spi_bcm2708" ;
|
331
|
+
}
|
332
|
+
else if (strcasecmp (argv [2], "i2c") == 0)
|
333
|
+
{
|
334
|
+
module1 = "i2c_dev" ;
|
335
|
+
module2 = "i2c_bcm2708" ;
|
336
|
+
}
|
337
|
+
else
|
338
|
+
_doUnLoadUsage (argv) ;
|
339
|
+
|
340
|
+
if (moduleLoaded (module1))
|
341
|
+
{
|
342
|
+
sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
|
343
|
+
system (cmd) ;
|
344
|
+
}
|
345
|
+
|
346
|
+
if (moduleLoaded (module2))
|
347
|
+
{
|
348
|
+
sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
|
349
|
+
system (cmd) ;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
|
353
|
+
|
354
|
+
/*
|
355
|
+
* doI2Cdetect:
|
356
|
+
* Run the i2cdetect command with the right runes for this Pi revision
|
357
|
+
*********************************************************************************
|
358
|
+
*/
|
359
|
+
|
360
|
+
static void doI2Cdetect (UNU int argc, char *argv [])
|
361
|
+
{
|
362
|
+
int port = piGpioLayout () == 1 ? 0 : 1 ;
|
363
|
+
char *c, *command ;
|
364
|
+
|
365
|
+
if ((c = findExecutable (I2CDETECT)) == NULL)
|
366
|
+
{
|
367
|
+
fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
|
368
|
+
return ;
|
369
|
+
}
|
370
|
+
|
371
|
+
if (!moduleLoaded ("i2c_dev"))
|
372
|
+
{
|
373
|
+
fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
|
374
|
+
return ;
|
375
|
+
}
|
376
|
+
|
377
|
+
command = malloc (strlen (c) + 16) ;
|
378
|
+
sprintf (command, "%s -y %d", c, port) ;
|
379
|
+
if (system (command) < 0)
|
380
|
+
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
|
381
|
+
|
382
|
+
}
|
383
|
+
|
384
|
+
|
385
|
+
/*
|
386
|
+
* doExports:
|
387
|
+
* List all GPIO exports
|
388
|
+
*********************************************************************************
|
389
|
+
*/
|
390
|
+
|
391
|
+
static void doExports (UNU int argc, UNU char *argv [])
|
392
|
+
{
|
393
|
+
int fd ;
|
394
|
+
int i, l, first ;
|
395
|
+
char fName [128] ;
|
396
|
+
char buf [16] ;
|
397
|
+
|
398
|
+
for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
|
399
|
+
{
|
400
|
+
|
401
|
+
// Try to read the direction
|
402
|
+
|
403
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
|
404
|
+
if ((fd = open (fName, O_RDONLY)) == -1)
|
405
|
+
continue ;
|
406
|
+
|
407
|
+
if (first == 0)
|
408
|
+
{
|
409
|
+
++first ;
|
410
|
+
printf ("GPIO Pins exported:\n") ;
|
411
|
+
}
|
412
|
+
|
413
|
+
printf ("%4d: ", i) ;
|
414
|
+
|
415
|
+
if ((l = read (fd, buf, 16)) == 0)
|
416
|
+
sprintf (buf, "%s", "?") ;
|
417
|
+
|
418
|
+
buf [l] = 0 ;
|
419
|
+
if ((buf [strlen (buf) - 1]) == '\n')
|
420
|
+
buf [strlen (buf) - 1] = 0 ;
|
421
|
+
|
422
|
+
printf ("%-3s", buf) ;
|
423
|
+
|
424
|
+
close (fd) ;
|
425
|
+
|
426
|
+
// Try to Read the value
|
427
|
+
|
428
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
|
429
|
+
if ((fd = open (fName, O_RDONLY)) == -1)
|
430
|
+
{
|
431
|
+
printf ("No Value file (huh?)\n") ;
|
432
|
+
continue ;
|
433
|
+
}
|
434
|
+
|
435
|
+
if ((l = read (fd, buf, 16)) == 0)
|
436
|
+
sprintf (buf, "%s", "?") ;
|
437
|
+
|
438
|
+
buf [l] = 0 ;
|
439
|
+
if ((buf [strlen (buf) - 1]) == '\n')
|
440
|
+
buf [strlen (buf) - 1] = 0 ;
|
441
|
+
|
442
|
+
printf (" %s", buf) ;
|
443
|
+
|
444
|
+
// Read any edge trigger file
|
445
|
+
|
446
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
|
447
|
+
if ((fd = open (fName, O_RDONLY)) == -1)
|
448
|
+
{
|
449
|
+
printf ("\n") ;
|
450
|
+
continue ;
|
451
|
+
}
|
452
|
+
|
453
|
+
if ((l = read (fd, buf, 16)) == 0)
|
454
|
+
sprintf (buf, "%s", "?") ;
|
455
|
+
|
456
|
+
buf [l] = 0 ;
|
457
|
+
if ((buf [strlen (buf) - 1]) == '\n')
|
458
|
+
buf [strlen (buf) - 1] = 0 ;
|
459
|
+
|
460
|
+
printf (" %-8s\n", buf) ;
|
461
|
+
|
462
|
+
close (fd) ;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
|
467
|
+
/*
|
468
|
+
* doExport:
|
469
|
+
* gpio export pin mode
|
470
|
+
* This uses the /sys/class/gpio device interface.
|
471
|
+
*********************************************************************************
|
472
|
+
*/
|
473
|
+
|
474
|
+
void doExport (int argc, char *argv [])
|
475
|
+
{
|
476
|
+
FILE *fd ;
|
477
|
+
int pin ;
|
478
|
+
char *mode ;
|
479
|
+
char fName [128] ;
|
480
|
+
|
481
|
+
if (argc != 4)
|
482
|
+
{
|
483
|
+
fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
|
484
|
+
exit (1) ;
|
485
|
+
}
|
486
|
+
|
487
|
+
pin = atoi (argv [2]) ;
|
488
|
+
|
489
|
+
mode = argv [3] ;
|
490
|
+
|
491
|
+
if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
|
492
|
+
{
|
493
|
+
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
|
494
|
+
exit (1) ;
|
495
|
+
}
|
496
|
+
|
497
|
+
fprintf (fd, "%d\n", pin) ;
|
498
|
+
fclose (fd) ;
|
499
|
+
|
500
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
|
501
|
+
if ((fd = fopen (fName, "w")) == NULL)
|
502
|
+
{
|
503
|
+
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
504
|
+
exit (1) ;
|
505
|
+
}
|
506
|
+
|
507
|
+
/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
|
508
|
+
fprintf (fd, "in\n") ;
|
509
|
+
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
|
510
|
+
fprintf (fd, "out\n") ;
|
511
|
+
else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
|
512
|
+
fprintf (fd, "high\n") ;
|
513
|
+
else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
|
514
|
+
fprintf (fd, "low\n") ;
|
515
|
+
else
|
516
|
+
{
|
517
|
+
fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
|
518
|
+
exit (1) ;
|
519
|
+
}
|
520
|
+
|
521
|
+
fclose (fd) ;
|
522
|
+
|
523
|
+
// Change ownership so the current user can actually use it
|
524
|
+
|
525
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
|
526
|
+
changeOwner (argv [0], fName) ;
|
527
|
+
|
528
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
|
529
|
+
changeOwner (argv [0], fName) ;
|
530
|
+
|
531
|
+
}
|
532
|
+
|
533
|
+
|
534
|
+
/*
|
535
|
+
* doWfi:
|
536
|
+
* gpio wfi pin mode
|
537
|
+
* Wait for Interrupt on a given pin.
|
538
|
+
* Slight cheat here - it's easier to actually use ISR now (which calls
|
539
|
+
* gpio to set the pin modes!) then we simply sleep, and expect the thread
|
540
|
+
* to exit the program. Crude but effective.
|
541
|
+
*********************************************************************************
|
542
|
+
*/
|
543
|
+
|
544
|
+
static void wfi (void)
|
545
|
+
{ exit (0) ; }
|
546
|
+
|
547
|
+
void doWfi (int argc, char *argv [])
|
548
|
+
{
|
549
|
+
int pin, mode ;
|
550
|
+
|
551
|
+
if (argc != 4)
|
552
|
+
{
|
553
|
+
fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
|
554
|
+
exit (1) ;
|
555
|
+
}
|
556
|
+
|
557
|
+
pin = atoi (argv [2]) ;
|
558
|
+
|
559
|
+
/**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
|
560
|
+
else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
|
561
|
+
else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
|
562
|
+
else
|
563
|
+
{
|
564
|
+
fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
|
565
|
+
exit (1) ;
|
566
|
+
}
|
567
|
+
|
568
|
+
if (wiringPiISR (pin, mode, &wfi) < 0)
|
569
|
+
{
|
570
|
+
fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
|
571
|
+
exit (1) ;
|
572
|
+
}
|
573
|
+
|
574
|
+
for (;;)
|
575
|
+
delay (9999) ;
|
576
|
+
}
|
577
|
+
|
578
|
+
|
579
|
+
|
580
|
+
/*
|
581
|
+
* doEdge:
|
582
|
+
* gpio edge pin mode
|
583
|
+
* Easy access to changing the edge trigger on a GPIO pin
|
584
|
+
* This uses the /sys/class/gpio device interface.
|
585
|
+
*********************************************************************************
|
586
|
+
*/
|
587
|
+
|
588
|
+
void doEdge (int argc, char *argv [])
|
589
|
+
{
|
590
|
+
FILE *fd ;
|
591
|
+
int pin ;
|
592
|
+
char *mode ;
|
593
|
+
char fName [128] ;
|
594
|
+
|
595
|
+
if (argc != 4)
|
596
|
+
{
|
597
|
+
fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
|
598
|
+
exit (1) ;
|
599
|
+
}
|
600
|
+
|
601
|
+
pin = atoi (argv [2]) ;
|
602
|
+
mode = argv [3] ;
|
603
|
+
|
604
|
+
// Export the pin and set direction to input
|
605
|
+
|
606
|
+
if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
|
607
|
+
{
|
608
|
+
fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
|
609
|
+
exit (1) ;
|
610
|
+
}
|
611
|
+
|
612
|
+
fprintf (fd, "%d\n", pin) ;
|
613
|
+
fclose (fd) ;
|
614
|
+
|
615
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
|
616
|
+
if ((fd = fopen (fName, "w")) == NULL)
|
617
|
+
{
|
618
|
+
fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
619
|
+
exit (1) ;
|
620
|
+
}
|
621
|
+
|
622
|
+
fprintf (fd, "in\n") ;
|
623
|
+
fclose (fd) ;
|
624
|
+
|
625
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
|
626
|
+
if ((fd = fopen (fName, "w")) == NULL)
|
627
|
+
{
|
628
|
+
fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
|
629
|
+
exit (1) ;
|
630
|
+
}
|
631
|
+
|
632
|
+
/**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
|
633
|
+
else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
|
634
|
+
else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
|
635
|
+
else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
|
636
|
+
else
|
637
|
+
{
|
638
|
+
fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
|
639
|
+
exit (1) ;
|
640
|
+
}
|
641
|
+
|
642
|
+
// Change ownership of the value and edge files, so the current user can actually use it!
|
643
|
+
|
644
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
|
645
|
+
changeOwner (argv [0], fName) ;
|
646
|
+
|
647
|
+
sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
|
648
|
+
changeOwner (argv [0], fName) ;
|
649
|
+
|
650
|
+
fclose (fd) ;
|
651
|
+
}
|
652
|
+
|
653
|
+
|
654
|
+
/*
|
655
|
+
* doUnexport:
|
656
|
+
* gpio unexport pin
|
657
|
+
* This uses the /sys/class/gpio device interface.
|
658
|
+
*********************************************************************************
|
659
|
+
*/
|
660
|
+
|
661
|
+
void doUnexport (int argc, char *argv [])
|
662
|
+
{
|
663
|
+
FILE *fd ;
|
664
|
+
int pin ;
|
665
|
+
|
666
|
+
if (argc != 3)
|
667
|
+
{
|
668
|
+
fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
|
669
|
+
exit (1) ;
|
670
|
+
}
|
671
|
+
|
672
|
+
pin = atoi (argv [2]) ;
|
673
|
+
|
674
|
+
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
|
675
|
+
{
|
676
|
+
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
|
677
|
+
exit (1) ;
|
678
|
+
}
|
679
|
+
|
680
|
+
fprintf (fd, "%d\n", pin) ;
|
681
|
+
fclose (fd) ;
|
682
|
+
}
|
683
|
+
|
684
|
+
|
685
|
+
/*
|
686
|
+
* doUnexportAll:
|
687
|
+
* gpio unexportall
|
688
|
+
* Un-Export all the GPIO pins.
|
689
|
+
* This uses the /sys/class/gpio device interface.
|
690
|
+
*********************************************************************************
|
691
|
+
*/
|
692
|
+
|
693
|
+
void doUnexportall (char *progName)
|
694
|
+
{
|
695
|
+
FILE *fd ;
|
696
|
+
int pin ;
|
697
|
+
|
698
|
+
for (pin = 0 ; pin < 63 ; ++pin)
|
699
|
+
{
|
700
|
+
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
|
701
|
+
{
|
702
|
+
fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
|
703
|
+
exit (1) ;
|
704
|
+
}
|
705
|
+
fprintf (fd, "%d\n", pin) ;
|
706
|
+
fclose (fd) ;
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
|
711
|
+
/*
|
712
|
+
* doReset:
|
713
|
+
* Reset the GPIO pins - as much as we can do
|
714
|
+
*********************************************************************************
|
715
|
+
*/
|
716
|
+
|
717
|
+
static void doReset (UNU char *progName)
|
718
|
+
{
|
719
|
+
printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
|
720
|
+
printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
|
721
|
+
printf (" that you need them in for your applications.\n") ;
|
722
|
+
}
|
723
|
+
|
724
|
+
|
725
|
+
/*
|
726
|
+
* doMode:
|
727
|
+
* gpio mode pin mode ...
|
728
|
+
*********************************************************************************
|
729
|
+
*/
|
730
|
+
|
731
|
+
void doMode (int argc, char *argv [])
|
732
|
+
{
|
733
|
+
int pin ;
|
734
|
+
char *mode ;
|
735
|
+
|
736
|
+
if (argc != 4)
|
737
|
+
{
|
738
|
+
fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
|
739
|
+
exit (1) ;
|
740
|
+
}
|
741
|
+
|
742
|
+
pin = atoi (argv [2]) ;
|
743
|
+
|
744
|
+
mode = argv [3] ;
|
745
|
+
|
746
|
+
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
|
747
|
+
else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
|
748
|
+
else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
|
749
|
+
else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
|
750
|
+
else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
|
751
|
+
else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
|
752
|
+
else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
|
753
|
+
else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
|
754
|
+
else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
|
755
|
+
else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
|
756
|
+
else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
|
757
|
+
else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
|
758
|
+
else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
|
759
|
+
else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
|
760
|
+
else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
|
761
|
+
else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
|
762
|
+
else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
|
763
|
+
else
|
764
|
+
{
|
765
|
+
fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
|
766
|
+
exit (1) ;
|
767
|
+
}
|
768
|
+
}
|
769
|
+
|
770
|
+
|
771
|
+
/*
|
772
|
+
* doPadDrive:
|
773
|
+
* gpio drive group value
|
774
|
+
*********************************************************************************
|
775
|
+
*/
|
776
|
+
|
777
|
+
static void doPadDrive (int argc, char *argv [])
|
778
|
+
{
|
779
|
+
int group, val ;
|
780
|
+
|
781
|
+
if (argc != 4)
|
782
|
+
{
|
783
|
+
fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
|
784
|
+
exit (1) ;
|
785
|
+
}
|
786
|
+
|
787
|
+
group = atoi (argv [2]) ;
|
788
|
+
val = atoi (argv [3]) ;
|
789
|
+
|
790
|
+
if ((group < 0) || (group > 2))
|
791
|
+
{
|
792
|
+
fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
|
793
|
+
exit (1) ;
|
794
|
+
}
|
795
|
+
|
796
|
+
if ((val < 0) || (val > 7))
|
797
|
+
{
|
798
|
+
fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
|
799
|
+
exit (1) ;
|
800
|
+
}
|
801
|
+
|
802
|
+
setPadDrive (group, val) ;
|
803
|
+
}
|
804
|
+
|
805
|
+
|
806
|
+
/*
|
807
|
+
* doUsbP:
|
808
|
+
* Control USB Power - High (1.2A) or Low (600mA)
|
809
|
+
* gpio usbp high/low
|
810
|
+
*********************************************************************************
|
811
|
+
*/
|
812
|
+
|
813
|
+
static void doUsbP (int argc, char *argv [])
|
814
|
+
{
|
815
|
+
int model, rev, mem, maker, overVolted ;
|
816
|
+
|
817
|
+
if (argc != 3)
|
818
|
+
{
|
819
|
+
fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
|
820
|
+
exit (1) ;
|
821
|
+
}
|
822
|
+
|
823
|
+
// Make sure we're on a B+
|
824
|
+
|
825
|
+
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
|
826
|
+
|
827
|
+
if (!((model == PI_MODEL_BP) || (model == PI_MODEL_2)))
|
828
|
+
{
|
829
|
+
fprintf (stderr, "USB power contol is applicable to B+ and v2 boards only.\n") ;
|
830
|
+
exit (1) ;
|
831
|
+
}
|
832
|
+
|
833
|
+
// Make sure we start in BCM_GPIO mode
|
834
|
+
|
835
|
+
wiringPiSetupGpio () ;
|
836
|
+
|
837
|
+
if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
|
838
|
+
{
|
839
|
+
digitalWrite (PI_USB_POWER_CONTROL, 1) ;
|
840
|
+
pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
|
841
|
+
printf ("Switched to HIGH current USB (1.2A)\n") ;
|
842
|
+
return ;
|
843
|
+
}
|
844
|
+
|
845
|
+
if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
|
846
|
+
{
|
847
|
+
digitalWrite (PI_USB_POWER_CONTROL, 0) ;
|
848
|
+
pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
|
849
|
+
printf ("Switched to LOW current USB (600mA)\n") ;
|
850
|
+
return ;
|
851
|
+
}
|
852
|
+
|
853
|
+
fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
|
854
|
+
exit (1) ;
|
855
|
+
}
|
856
|
+
|
857
|
+
|
858
|
+
/*
|
859
|
+
* doGbw:
|
860
|
+
* gpio gbw channel value
|
861
|
+
* Gertboard Write - To the Analog output
|
862
|
+
*********************************************************************************
|
863
|
+
*/
|
864
|
+
|
865
|
+
static void doGbw (int argc, char *argv [])
|
866
|
+
{
|
867
|
+
int channel, value ;
|
868
|
+
|
869
|
+
if (argc != 4)
|
870
|
+
{
|
871
|
+
fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
|
872
|
+
exit (1) ;
|
873
|
+
}
|
874
|
+
|
875
|
+
channel = atoi (argv [2]) ;
|
876
|
+
value = atoi (argv [3]) ;
|
877
|
+
|
878
|
+
if ((channel < 0) || (channel > 1))
|
879
|
+
{
|
880
|
+
fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
|
881
|
+
exit (1) ;
|
882
|
+
}
|
883
|
+
|
884
|
+
if ((value < 0) || (value > 255))
|
885
|
+
{
|
886
|
+
fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
|
887
|
+
exit (1) ;
|
888
|
+
}
|
889
|
+
|
890
|
+
if (gertboardAnalogSetup (64) < 0)
|
891
|
+
{
|
892
|
+
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
|
893
|
+
exit (1) ;
|
894
|
+
}
|
895
|
+
|
896
|
+
analogWrite (64 + channel, value) ;
|
897
|
+
}
|
898
|
+
|
899
|
+
|
900
|
+
/*
|
901
|
+
* doGbr:
|
902
|
+
* gpio gbr channel
|
903
|
+
* From the analog input
|
904
|
+
*********************************************************************************
|
905
|
+
*/
|
906
|
+
|
907
|
+
static void doGbr (int argc, char *argv [])
|
908
|
+
{
|
909
|
+
int channel ;
|
910
|
+
|
911
|
+
if (argc != 3)
|
912
|
+
{
|
913
|
+
fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
|
914
|
+
exit (1) ;
|
915
|
+
}
|
916
|
+
|
917
|
+
channel = atoi (argv [2]) ;
|
918
|
+
|
919
|
+
if ((channel < 0) || (channel > 1))
|
920
|
+
{
|
921
|
+
fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
|
922
|
+
exit (1) ;
|
923
|
+
}
|
924
|
+
|
925
|
+
if (gertboardAnalogSetup (64) < 0)
|
926
|
+
{
|
927
|
+
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
|
928
|
+
exit (1) ;
|
929
|
+
}
|
930
|
+
|
931
|
+
printf ("%d\n", analogRead (64 + channel)) ;
|
932
|
+
}
|
933
|
+
|
934
|
+
|
935
|
+
/*
|
936
|
+
* doWrite:
|
937
|
+
* gpio write pin value
|
938
|
+
*********************************************************************************
|
939
|
+
*/
|
940
|
+
|
941
|
+
static void doWrite (int argc, char *argv [])
|
942
|
+
{
|
943
|
+
int pin, val ;
|
944
|
+
|
945
|
+
if (argc != 4)
|
946
|
+
{
|
947
|
+
fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
|
948
|
+
exit (1) ;
|
949
|
+
}
|
950
|
+
|
951
|
+
pin = atoi (argv [2]) ;
|
952
|
+
|
953
|
+
/**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
|
954
|
+
val = 1 ;
|
955
|
+
else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
|
956
|
+
val = 0 ;
|
957
|
+
else
|
958
|
+
val = atoi (argv [3]) ;
|
959
|
+
|
960
|
+
/**/ if (val == 0)
|
961
|
+
digitalWrite (pin, LOW) ;
|
962
|
+
else
|
963
|
+
digitalWrite (pin, HIGH) ;
|
964
|
+
}
|
965
|
+
|
966
|
+
|
967
|
+
/*
|
968
|
+
* doAwriterite:
|
969
|
+
* gpio awrite pin value
|
970
|
+
*********************************************************************************
|
971
|
+
*/
|
972
|
+
|
973
|
+
static void doAwrite (int argc, char *argv [])
|
974
|
+
{
|
975
|
+
int pin, val ;
|
976
|
+
|
977
|
+
if (argc != 4)
|
978
|
+
{
|
979
|
+
fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
|
980
|
+
exit (1) ;
|
981
|
+
}
|
982
|
+
|
983
|
+
pin = atoi (argv [2]) ;
|
984
|
+
|
985
|
+
val = atoi (argv [3]) ;
|
986
|
+
|
987
|
+
analogWrite (pin, val) ;
|
988
|
+
}
|
989
|
+
|
990
|
+
|
991
|
+
/*
|
992
|
+
* doWriteByte:
|
993
|
+
* gpio wb value
|
994
|
+
*********************************************************************************
|
995
|
+
*/
|
996
|
+
|
997
|
+
static void doWriteByte (int argc, char *argv [])
|
998
|
+
{
|
999
|
+
int val ;
|
1000
|
+
|
1001
|
+
if (argc != 3)
|
1002
|
+
{
|
1003
|
+
fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
|
1004
|
+
exit (1) ;
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
val = (int)strtol (argv [2], NULL, 0) ;
|
1008
|
+
|
1009
|
+
digitalWriteByte (val) ;
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
|
1013
|
+
/*
|
1014
|
+
* doReadByte:
|
1015
|
+
* gpio rbx|rbd value
|
1016
|
+
*********************************************************************************
|
1017
|
+
*/
|
1018
|
+
|
1019
|
+
static void doReadByte (int argc, char *argv [], int printHex)
|
1020
|
+
{
|
1021
|
+
int val ;
|
1022
|
+
|
1023
|
+
if (argc != 2)
|
1024
|
+
{
|
1025
|
+
fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ;
|
1026
|
+
exit (1) ;
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
val = digitalReadByte () ;
|
1030
|
+
if (printHex)
|
1031
|
+
printf ("%02X\n", val) ;
|
1032
|
+
else
|
1033
|
+
printf ("%d\n", val) ;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
|
1037
|
+
/*
|
1038
|
+
* doRead:
|
1039
|
+
* Read a pin and return the value
|
1040
|
+
*********************************************************************************
|
1041
|
+
*/
|
1042
|
+
|
1043
|
+
void doRead (int argc, char *argv [])
|
1044
|
+
{
|
1045
|
+
int pin, val ;
|
1046
|
+
|
1047
|
+
if (argc != 3)
|
1048
|
+
{
|
1049
|
+
fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
|
1050
|
+
exit (1) ;
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
pin = atoi (argv [2]) ;
|
1054
|
+
val = digitalRead (pin) ;
|
1055
|
+
|
1056
|
+
printf ("%s\n", val == 0 ? "0" : "1") ;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
|
1060
|
+
/*
|
1061
|
+
* doAread:
|
1062
|
+
* Read an analog pin and return the value
|
1063
|
+
*********************************************************************************
|
1064
|
+
*/
|
1065
|
+
|
1066
|
+
void doAread (int argc, char *argv [])
|
1067
|
+
{
|
1068
|
+
if (argc != 3)
|
1069
|
+
{
|
1070
|
+
fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
|
1071
|
+
exit (1) ;
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
printf ("%d\n", analogRead (atoi (argv [2]))) ;
|
1075
|
+
}
|
1076
|
+
|
1077
|
+
|
1078
|
+
/*
|
1079
|
+
* doToggle:
|
1080
|
+
* Toggle an IO pin
|
1081
|
+
*********************************************************************************
|
1082
|
+
*/
|
1083
|
+
|
1084
|
+
void doToggle (int argc, char *argv [])
|
1085
|
+
{
|
1086
|
+
int pin ;
|
1087
|
+
|
1088
|
+
if (argc != 3)
|
1089
|
+
{
|
1090
|
+
fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
|
1091
|
+
exit (1) ;
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
pin = atoi (argv [2]) ;
|
1095
|
+
|
1096
|
+
digitalWrite (pin, !digitalRead (pin)) ;
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
|
1100
|
+
/*
|
1101
|
+
* doBlink:
|
1102
|
+
* Blink an IO pin
|
1103
|
+
*********************************************************************************
|
1104
|
+
*/
|
1105
|
+
|
1106
|
+
void doBlink (int argc, char *argv [])
|
1107
|
+
{
|
1108
|
+
int pin ;
|
1109
|
+
|
1110
|
+
if (argc != 3)
|
1111
|
+
{
|
1112
|
+
fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ;
|
1113
|
+
exit (1) ;
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
pin = atoi (argv [2]) ;
|
1117
|
+
|
1118
|
+
pinMode (pin, OUTPUT) ;
|
1119
|
+
for (;;)
|
1120
|
+
{
|
1121
|
+
digitalWrite (pin, !digitalRead (pin)) ;
|
1122
|
+
delay (500) ;
|
1123
|
+
}
|
1124
|
+
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
|
1128
|
+
/*
|
1129
|
+
* doPwmTone:
|
1130
|
+
* Output a tone in a PWM pin
|
1131
|
+
*********************************************************************************
|
1132
|
+
*/
|
1133
|
+
|
1134
|
+
void doPwmTone (int argc, char *argv [])
|
1135
|
+
{
|
1136
|
+
int pin, freq ;
|
1137
|
+
|
1138
|
+
if (argc != 4)
|
1139
|
+
{
|
1140
|
+
fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
|
1141
|
+
exit (1) ;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
pin = atoi (argv [2]) ;
|
1145
|
+
freq = atoi (argv [3]) ;
|
1146
|
+
|
1147
|
+
pwmToneWrite (pin, freq) ;
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
|
1151
|
+
/*
|
1152
|
+
* doClock:
|
1153
|
+
* Output a clock on a pin
|
1154
|
+
*********************************************************************************
|
1155
|
+
*/
|
1156
|
+
|
1157
|
+
void doClock (int argc, char *argv [])
|
1158
|
+
{
|
1159
|
+
int pin, freq ;
|
1160
|
+
|
1161
|
+
if (argc != 4)
|
1162
|
+
{
|
1163
|
+
fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
|
1164
|
+
exit (1) ;
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
pin = atoi (argv [2]) ;
|
1168
|
+
|
1169
|
+
freq = atoi (argv [3]) ;
|
1170
|
+
|
1171
|
+
gpioClockSet (pin, freq) ;
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
|
1175
|
+
/*
|
1176
|
+
* doPwm:
|
1177
|
+
* Output a PWM value on a pin
|
1178
|
+
*********************************************************************************
|
1179
|
+
*/
|
1180
|
+
|
1181
|
+
void doPwm (int argc, char *argv [])
|
1182
|
+
{
|
1183
|
+
int pin, val ;
|
1184
|
+
|
1185
|
+
if (argc != 4)
|
1186
|
+
{
|
1187
|
+
fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
|
1188
|
+
exit (1) ;
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
pin = atoi (argv [2]) ;
|
1192
|
+
|
1193
|
+
val = atoi (argv [3]) ;
|
1194
|
+
|
1195
|
+
pwmWrite (pin, val) ;
|
1196
|
+
}
|
1197
|
+
|
1198
|
+
|
1199
|
+
/*
|
1200
|
+
* doPwmMode: doPwmRange: doPwmClock:
|
1201
|
+
* Change the PWM mode, range and clock divider values
|
1202
|
+
*********************************************************************************
|
1203
|
+
*/
|
1204
|
+
|
1205
|
+
static void doPwmMode (int mode)
|
1206
|
+
{
|
1207
|
+
pwmSetMode (mode) ;
|
1208
|
+
}
|
1209
|
+
|
1210
|
+
static void doPwmRange (int argc, char *argv [])
|
1211
|
+
{
|
1212
|
+
unsigned int range ;
|
1213
|
+
|
1214
|
+
if (argc != 3)
|
1215
|
+
{
|
1216
|
+
fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
|
1217
|
+
exit (1) ;
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
range = (unsigned int)strtoul (argv [2], NULL, 10) ;
|
1221
|
+
|
1222
|
+
if (range == 0)
|
1223
|
+
{
|
1224
|
+
fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
|
1225
|
+
exit (1) ;
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
pwmSetRange (range) ;
|
1229
|
+
}
|
1230
|
+
|
1231
|
+
static void doPwmClock (int argc, char *argv [])
|
1232
|
+
{
|
1233
|
+
unsigned int clock ;
|
1234
|
+
|
1235
|
+
if (argc != 3)
|
1236
|
+
{
|
1237
|
+
fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
|
1238
|
+
exit (1) ;
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
|
1242
|
+
|
1243
|
+
if ((clock < 1) || (clock > 4095))
|
1244
|
+
{
|
1245
|
+
fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
|
1246
|
+
exit (1) ;
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
pwmSetClock (clock) ;
|
1250
|
+
}
|
1251
|
+
|
1252
|
+
|
1253
|
+
/*
|
1254
|
+
* doVersion:
|
1255
|
+
* Handle the ever more complicated version command and print out
|
1256
|
+
* some usefull information.
|
1257
|
+
*********************************************************************************
|
1258
|
+
*/
|
1259
|
+
|
1260
|
+
static void doVersion (char *argv [])
|
1261
|
+
{
|
1262
|
+
int model, rev, mem, maker, warranty ;
|
1263
|
+
struct stat statBuf ;
|
1264
|
+
char name [80] ;
|
1265
|
+
FILE *fd ;
|
1266
|
+
|
1267
|
+
int vMaj, vMin ;
|
1268
|
+
|
1269
|
+
wiringPiVersion (&vMaj, &vMin) ;
|
1270
|
+
printf ("gpio version: %d.%d\n", vMaj, vMin) ;
|
1271
|
+
printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
|
1272
|
+
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
|
1273
|
+
printf ("For details type: %s -warranty\n", argv [0]) ;
|
1274
|
+
printf ("\n") ;
|
1275
|
+
piBoardId (&model, &rev, &mem, &maker, &warranty) ;
|
1276
|
+
|
1277
|
+
printf ("Raspberry Pi Details:\n") ;
|
1278
|
+
printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
|
1279
|
+
piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
|
1280
|
+
|
1281
|
+
// Check for device tree
|
1282
|
+
|
1283
|
+
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
|
1284
|
+
printf (" * Device tree is enabled.\n") ;
|
1285
|
+
|
1286
|
+
if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
|
1287
|
+
{
|
1288
|
+
if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
|
1289
|
+
{
|
1290
|
+
fgets (name, 80, fd) ;
|
1291
|
+
fclose (fd) ;
|
1292
|
+
printf (" *--> %s\n", name) ;
|
1293
|
+
}
|
1294
|
+
}
|
1295
|
+
|
1296
|
+
if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO
|
1297
|
+
printf (" * This Raspberry Pi supports user-level GPIO access.\n") ;
|
1298
|
+
else
|
1299
|
+
printf (" * Root or sudo required for GPIO access.\n") ;
|
1300
|
+
}
|
1301
|
+
|
1302
|
+
|
1303
|
+
/*
|
1304
|
+
* main:
|
1305
|
+
* Start here
|
1306
|
+
*********************************************************************************
|
1307
|
+
*/
|
1308
|
+
|
1309
|
+
int main (int argc, char *argv [])
|
1310
|
+
{
|
1311
|
+
int i ;
|
1312
|
+
|
1313
|
+
if (getenv ("WIRINGPI_DEBUG") != NULL)
|
1314
|
+
{
|
1315
|
+
printf ("gpio: wiringPi debug mode enabled\n") ;
|
1316
|
+
wiringPiDebug = TRUE ;
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
if (argc == 1)
|
1320
|
+
{
|
1321
|
+
fprintf (stderr,
|
1322
|
+
"%s: At your service!\n"
|
1323
|
+
" Type: gpio -h for full details and\n"
|
1324
|
+
" gpio readall for a quick printout of your connector details\n", argv [0]) ;
|
1325
|
+
exit (EXIT_FAILURE) ;
|
1326
|
+
}
|
1327
|
+
|
1328
|
+
// Help
|
1329
|
+
|
1330
|
+
if (strcasecmp (argv [1], "-h") == 0)
|
1331
|
+
{
|
1332
|
+
printf ("%s: %s\n", argv [0], usage) ;
|
1333
|
+
exit (EXIT_SUCCESS) ;
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
// Version & Warranty
|
1337
|
+
// Wish I could remember why I have both -R and -V ...
|
1338
|
+
|
1339
|
+
if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
|
1340
|
+
{
|
1341
|
+
printf ("%d\n", piGpioLayout ()) ;
|
1342
|
+
exit (EXIT_SUCCESS) ;
|
1343
|
+
}
|
1344
|
+
|
1345
|
+
// Version and information
|
1346
|
+
|
1347
|
+
if (strcmp (argv [1], "-v") == 0)
|
1348
|
+
{
|
1349
|
+
doVersion (argv) ;
|
1350
|
+
exit (EXIT_SUCCESS) ;
|
1351
|
+
}
|
1352
|
+
|
1353
|
+
if (strcasecmp (argv [1], "-warranty") == 0)
|
1354
|
+
{
|
1355
|
+
printf ("gpio version: %s\n", VERSION) ;
|
1356
|
+
printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
|
1357
|
+
printf ("\n") ;
|
1358
|
+
printf (" This program is free software; you can redistribute it and/or modify\n") ;
|
1359
|
+
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
|
1360
|
+
printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
|
1361
|
+
printf (" (at your option) any later version.\n") ;
|
1362
|
+
printf ("\n") ;
|
1363
|
+
printf (" This program is distributed in the hope that it will be useful,\n") ;
|
1364
|
+
printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
|
1365
|
+
printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
|
1366
|
+
printf (" GNU Lesser General Public License for more details.\n") ;
|
1367
|
+
printf ("\n") ;
|
1368
|
+
printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
|
1369
|
+
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
|
1370
|
+
printf ("\n") ;
|
1371
|
+
exit (EXIT_SUCCESS) ;
|
1372
|
+
}
|
1373
|
+
|
1374
|
+
if (geteuid () != 0)
|
1375
|
+
{
|
1376
|
+
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
|
1377
|
+
exit (EXIT_FAILURE) ;
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
// Initial test for /sys/class/gpio operations:
|
1381
|
+
|
1382
|
+
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
|
1383
|
+
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
|
1384
|
+
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
|
1385
|
+
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
|
1386
|
+
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
|
1387
|
+
|
1388
|
+
// Check for load command:
|
1389
|
+
|
1390
|
+
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
|
1391
|
+
if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
|
1392
|
+
|
1393
|
+
// Check for usb power command
|
1394
|
+
|
1395
|
+
if (strcasecmp (argv [1], "usbp" ) == 0) { doUsbP (argc, argv) ; return 0 ; }
|
1396
|
+
|
1397
|
+
// Gertboard commands
|
1398
|
+
|
1399
|
+
if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
|
1400
|
+
if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
|
1401
|
+
|
1402
|
+
// Check for allreadall command, force Gpio mode
|
1403
|
+
|
1404
|
+
if (strcasecmp (argv [1], "allreadall") == 0)
|
1405
|
+
{
|
1406
|
+
wiringPiSetupGpio () ;
|
1407
|
+
doAllReadall () ;
|
1408
|
+
return 0 ;
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
// Check for -g argument
|
1412
|
+
|
1413
|
+
/**/ if (strcasecmp (argv [1], "-g") == 0)
|
1414
|
+
{
|
1415
|
+
wiringPiSetupGpio () ;
|
1416
|
+
|
1417
|
+
for (i = 2 ; i < argc ; ++i)
|
1418
|
+
argv [i - 1] = argv [i] ;
|
1419
|
+
--argc ;
|
1420
|
+
wpMode = WPI_MODE_GPIO ;
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
// Check for -1 argument
|
1424
|
+
|
1425
|
+
else if (strcasecmp (argv [1], "-1") == 0)
|
1426
|
+
{
|
1427
|
+
wiringPiSetupPhys () ;
|
1428
|
+
|
1429
|
+
for (i = 2 ; i < argc ; ++i)
|
1430
|
+
argv [i - 1] = argv [i] ;
|
1431
|
+
--argc ;
|
1432
|
+
wpMode = WPI_MODE_PHYS ;
|
1433
|
+
}
|
1434
|
+
|
1435
|
+
// Check for -p argument for PiFace
|
1436
|
+
|
1437
|
+
else if (strcasecmp (argv [1], "-p") == 0)
|
1438
|
+
{
|
1439
|
+
piFaceSetup (200) ;
|
1440
|
+
|
1441
|
+
for (i = 2 ; i < argc ; ++i)
|
1442
|
+
argv [i - 1] = argv [i] ;
|
1443
|
+
--argc ;
|
1444
|
+
wpMode = WPI_MODE_PIFACE ;
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
// Check for -z argument so we don't actually initialise wiringPi
|
1448
|
+
|
1449
|
+
else if (strcasecmp (argv [1], "-z") == 0)
|
1450
|
+
{
|
1451
|
+
for (i = 2 ; i < argc ; ++i)
|
1452
|
+
argv [i - 1] = argv [i] ;
|
1453
|
+
--argc ;
|
1454
|
+
wpMode = WPI_MODE_UNINITIALISED ;
|
1455
|
+
}
|
1456
|
+
|
1457
|
+
// Default to wiringPi mode
|
1458
|
+
|
1459
|
+
else
|
1460
|
+
{
|
1461
|
+
wiringPiSetup () ;
|
1462
|
+
wpMode = WPI_MODE_PINS ;
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
// Check for -x argument to load in a new extension
|
1466
|
+
// -x extension:base:args
|
1467
|
+
// Can load many modules, but unless daemon mode we can only send one
|
1468
|
+
// command at a time.
|
1469
|
+
|
1470
|
+
while (strcasecmp (argv [1], "-x") == 0)
|
1471
|
+
{
|
1472
|
+
if (argc < 3)
|
1473
|
+
{
|
1474
|
+
fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ;
|
1475
|
+
exit (EXIT_FAILURE) ;
|
1476
|
+
}
|
1477
|
+
|
1478
|
+
if (!loadWPiExtension (argv [0], argv [2], TRUE))
|
1479
|
+
{
|
1480
|
+
fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ;
|
1481
|
+
exit (EXIT_FAILURE) ;
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
// Shift args down by 2
|
1485
|
+
|
1486
|
+
for (i = 3 ; i < argc ; ++i)
|
1487
|
+
argv [i - 2] = argv [i] ;
|
1488
|
+
argc -= 2 ;
|
1489
|
+
}
|
1490
|
+
|
1491
|
+
if (argc <= 1)
|
1492
|
+
{
|
1493
|
+
fprintf (stderr, "%s: no command given\n", argv [0]) ;
|
1494
|
+
exit (EXIT_FAILURE) ;
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
// Core wiringPi functions
|
1498
|
+
|
1499
|
+
/**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
|
1500
|
+
else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
|
1501
|
+
else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
|
1502
|
+
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
|
1503
|
+
else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
|
1504
|
+
else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
|
1505
|
+
|
1506
|
+
// GPIO Nicies
|
1507
|
+
|
1508
|
+
else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
|
1509
|
+
else if (strcasecmp (argv [1], "blink" ) == 0) doBlink (argc, argv) ;
|
1510
|
+
|
1511
|
+
// Pi Specifics
|
1512
|
+
|
1513
|
+
else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
|
1514
|
+
else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
|
1515
|
+
else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
|
1516
|
+
else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
|
1517
|
+
else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
|
1518
|
+
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
|
1519
|
+
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
|
1520
|
+
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
|
1521
|
+
else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ;
|
1522
|
+
else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ;
|
1523
|
+
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
|
1524
|
+
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
|
1525
|
+
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
|
1526
|
+
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
|
1527
|
+
else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ;
|
1528
|
+
else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ;
|
1529
|
+
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
|
1530
|
+
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
|
1531
|
+
else
|
1532
|
+
{
|
1533
|
+
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
|
1534
|
+
exit (EXIT_FAILURE) ;
|
1535
|
+
}
|
1536
|
+
|
1537
|
+
return 0 ;
|
1538
|
+
}
|