with wiringPiISR. Added the ability to readall/reset from extension modules. Changed the build script to use /bin/sh rather than /bin/bash as it seems some installations don't have /bin/bash (or if they do, then the people who are telling me that ./build gives them command not found are wrong)pull/22/head
@@ -1,7 +1,6 @@ | |||||
#!/bin/bash | |||||
#!/bin/sh | |||||
check-make-ok() | |||||
{ | |||||
check_make_ok() { | |||||
if [ $? != 0 ]; then | if [ $? != 0 ]; then | ||||
echo "" | echo "" | ||||
echo "Make Failed..." | echo "Make Failed..." | ||||
@@ -51,26 +50,26 @@ fi | |||||
cd wiringPi | cd wiringPi | ||||
sudo make uninstall | sudo make uninstall | ||||
make | make | ||||
check-make-ok | |||||
check_make_ok | |||||
sudo make install | sudo make install | ||||
check-make-ok | |||||
check_make_ok | |||||
echo | echo | ||||
echo "WiringPi Devices Library" | echo "WiringPi Devices Library" | ||||
cd ../devLib | cd ../devLib | ||||
sudo make uninstall | sudo make uninstall | ||||
make | make | ||||
check-make-ok | |||||
check_make_ok | |||||
sudo make install | sudo make install | ||||
check-make-ok | |||||
check_make_ok | |||||
echo | echo | ||||
echo "GPIO Utility" | echo "GPIO Utility" | ||||
cd ../gpio | cd ../gpio | ||||
make | make | ||||
check-make-ok | |||||
check_make_ok | |||||
sudo make install | sudo make install | ||||
check-make-ok | |||||
check_make_ok | |||||
# echo | # echo | ||||
# echo "Examples" | # echo "Examples" | ||||
@@ -126,11 +126,19 @@ Output a table of all GPIO pins values. The values represent the actual values r | |||||
if the pin is in input mode, or the last value written if the pin is in output | if the pin is in input mode, or the last value written if the pin is in output | ||||
mode. | mode. | ||||
The readall command is usable with an extension module (via the -x parameter), | |||||
but it's unable to determine pin modes or states, so will perform both a | |||||
digital and analog read on each pin in-turn. | |||||
.TP | .TP | ||||
.B reset | .B reset | ||||
Resets the GPIO - As much as it's possible to do. All pins are set to input | Resets the GPIO - As much as it's possible to do. All pins are set to input | ||||
mode and all the internal pull-up/down resistors are disconnected (tristate mode). | mode and all the internal pull-up/down resistors are disconnected (tristate mode). | ||||
The reset command is usable with an extension module (via the -x parameter), | |||||
but it's limited to turning the pin into input mode (if applicable) and | |||||
removing any pull up/down resistor. | |||||
.TP | .TP | ||||
.B pwm <pin> <value> | .B pwm <pin> <value> | ||||
Write a PWM value (0-1023) to the given pin. The pin needs to be put | Write a PWM value (0-1023) to the given pin. The pin needs to be put | ||||
@@ -212,8 +220,8 @@ Change the PWM range register. The default is 1024. | |||||
.B load i2c [baudrate] | .B load i2c [baudrate] | ||||
This loads the i2c or drivers into the kernel and changes the permissions | This loads the i2c or drivers into the kernel and changes the permissions | ||||
on the associated /dev/ entries so that the current user has access to | on the associated /dev/ entries so that the current user has access to | ||||
them. Optionally it will set the I2C baudrate to that supplied (or as | |||||
close as the Pi can manage) The default speed is 100Kb/sec. | |||||
them. Optionally it will set the I2C baudrate to that supplied in Kb/sec | |||||
(or as close as the Pi can manage) The default speed is 100Kb/sec. | |||||
.TP | .TP | ||||
.B load spi [buffer size in KB] | .B load spi [buffer size in KB] | ||||
@@ -48,7 +48,7 @@ extern int wiringPiDebug ; | |||||
# define FALSE (1==2) | # define FALSE (1==2) | ||||
#endif | #endif | ||||
#define VERSION "2.06" | |||||
#define VERSION "2.07" | |||||
#define I2CDETECT "/usr/sbin/i2cdetect" | #define I2CDETECT "/usr/sbin/i2cdetect" | ||||
static int wpMode ; | static int wpMode ; | ||||
@@ -239,6 +239,10 @@ static void doI2Cdetect (int argc, char *argv []) | |||||
/* | /* | ||||
* doReadall: | * doReadall: | ||||
* Read all the GPIO pins | * Read all the GPIO pins | ||||
* We also want to use this to read the state of pins on an externally | |||||
* connected device, so we need to do some fiddling with the internal | |||||
* wiringPi node structures - since the gpio command can only use | |||||
* one external device at a time, we'll use that to our advantage... | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -268,27 +272,56 @@ static int wpiToPhys [64] = | |||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63 | ||||
} ; | } ; | ||||
static void doReadall (void) | |||||
/* | |||||
* doReadallExternal: | |||||
* A relatively crude way to read the pins on an external device. | |||||
* We don't know the input/output mode of pins, but we can tell | |||||
* if it's an analog pin or a digital one... | |||||
********************************************************************************* | |||||
*/ | |||||
static void doReadallExternal (void) | |||||
{ | { | ||||
int pin ; | int pin ; | ||||
printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ; | |||||
printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ; | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
printf ("+------+---------+--------+\n") ; | |||||
printf ("| Pin | Digital | Analog |\n") ; | |||||
printf ("+------+---------+--------+\n") ; | |||||
for (pin = 0 ; pin < 64 ; ++pin) // Crude, but effective | |||||
for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin) | |||||
printf ("| %4d | %4d | %4d |\n", pin, digitalRead (pin), analogRead (pin)) ; | |||||
printf ("+------+---------+--------+\n") ; | |||||
} | |||||
static void doReadall (void) | |||||
{ | |||||
int pin ; | |||||
if (wiringPiNodes != NULL) // External readall | |||||
doReadallExternal () ; | |||||
else | |||||
{ | { | ||||
if (wpiPinToGpio (pin) == -1) | |||||
continue ; | |||||
printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ; | |||||
printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ; | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
printf ("| %6d | %3d | %3d | %s | %s | %s |\n", | |||||
pin, wpiPinToGpio (pin), wpiToPhys [pin], | |||||
pinNames [pin], | |||||
alts [getAlt (pin)], | |||||
digitalRead (pin) == HIGH ? "High" : "Low ") ; | |||||
} | |||||
for (pin = 0 ; pin < 64 ; ++pin) // Crude, but effective | |||||
{ | |||||
if (wpiPinToGpio (pin) == -1) | |||||
continue ; | |||||
printf ("| %6d | %3d | %3d | %s | %s | %s |\n", | |||||
pin, wpiPinToGpio (pin), wpiToPhys [pin], | |||||
pinNames [pin], | |||||
alts [getAlt (pin)], | |||||
digitalRead (pin) == HIGH ? "High" : "Low ") ; | |||||
} | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
printf ("+----------+------+------+--------+------+-------+\n") ; | |||||
} | |||||
} | } | ||||
@@ -615,6 +648,24 @@ void doUnexportall (char *progName) | |||||
/* | /* | ||||
* doResetExternal: | |||||
* Load readallExternal, we try to do this with an external device. | |||||
********************************************************************************* | |||||
*/ | |||||
static void doResetExternal (void) | |||||
{ | |||||
int pin ; | |||||
for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin) | |||||
{ | |||||
pinMode (pin, INPUT) ; | |||||
pullUpDnControl (pin, PUD_OFF) ; | |||||
} | |||||
} | |||||
/* | |||||
* doReset: | * doReset: | ||||
* Reset the GPIO pins - as much as we can do | * Reset the GPIO pins - as much as we can do | ||||
********************************************************************************* | ********************************************************************************* | ||||
@@ -624,16 +675,21 @@ static void doReset (char *progName) | |||||
{ | { | ||||
int pin ; | int pin ; | ||||
doUnexportall (progName) ; | |||||
for (pin = 0 ; pin < 64 ; ++pin) | |||||
if (wiringPiNodes != NULL) // External reset | |||||
doResetExternal () ; | |||||
else | |||||
{ | { | ||||
if (wpiPinToGpio (pin) == -1) | |||||
continue ; | |||||
doUnexportall (progName) ; | |||||
digitalWrite (pin, LOW) ; | |||||
pinMode (pin, INPUT) ; | |||||
pullUpDnControl (pin, PUD_OFF) ; | |||||
for (pin = 0 ; pin < 64 ; ++pin) | |||||
{ | |||||
if (wpiPinToGpio (pin) == -1) | |||||
continue ; | |||||
digitalWrite (pin, LOW) ; | |||||
pinMode (pin, INPUT) ; | |||||
pullUpDnControl (pin, PUD_OFF) ; | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -88,7 +88,7 @@ | |||||
#define PI_GPIO_MASK (0xFFFFFFC0) | #define PI_GPIO_MASK (0xFFFFFFC0) | ||||
static struct wiringPiNodeStruct *wiringPiNodes = NULL ; | |||||
struct wiringPiNodeStruct *wiringPiNodes = NULL ; | |||||
// BCM Magic | // BCM Magic | ||||
@@ -213,7 +213,13 @@ int wiringPiReturnCodes = FALSE ; | |||||
// sysFds: | // sysFds: | ||||
// Map a file descriptor from the /sys/class/gpio/gpioX/value | // Map a file descriptor from the /sys/class/gpio/gpioX/value | ||||
static int sysFds [64] ; | |||||
static int sysFds [64] = | |||||
{ | |||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |||||
} ; | |||||
// ISR Data | // ISR Data | ||||
@@ -833,7 +839,7 @@ void gpioClockSet (int pin, int freq) | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
static struct wiringPiNodeStruct *wiringPiFindNode (int pin) | |||||
struct wiringPiNodeStruct *wiringPiFindNode (int pin) | |||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
@@ -1304,7 +1310,8 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) | |||||
char c ; | char c ; | ||||
int bcmGpioPin ; | int bcmGpioPin ; | ||||
pin &= 63 ; | |||||
if ((pin < 0) || (pin > 63)) | |||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; | |||||
/**/ if (wiringPiMode == WPI_MODE_UNINITIALISED) | /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED) | ||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; | return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; | ||||
@@ -1333,26 +1340,26 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) | |||||
sprintf (pinS, "%d", bcmGpioPin) ; | sprintf (pinS, "%d", bcmGpioPin) ; | ||||
if ((pid = fork ()) < 0) // Fail | if ((pid = fork ()) < 0) // Fail | ||||
return pid ; | |||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; | |||||
if (pid == 0) // Child, exec | if (pid == 0) // Child, exec | ||||
{ | { | ||||
execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; | execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; | ||||
return -1 ; // Failure ... | |||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; | |||||
} | } | ||||
else // Parent, wait | else // Parent, wait | ||||
wait (NULL) ; | wait (NULL) ; | ||||
} | } | ||||
// Now pre-open the /sys/class node - it may already be open if | |||||
// we are in Sys mode or if we call here twice, if-so, we'll close it. | |||||
if (sysFds [bcmGpioPin] != -1) | |||||
close (sysFds [bcmGpioPin]) ; | |||||
// Now pre-open the /sys/class node - but it may already be open if | |||||
// we are in Sys mode... | |||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; | |||||
if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) | |||||
return -1 ; | |||||
if (sysFds [bcmGpioPin] == -1) | |||||
{ | |||||
sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; | |||||
if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) | |||||
return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; | |||||
} | |||||
// Clear any initial pending interrupt | // Clear any initial pending interrupt | ||||
@@ -104,6 +104,8 @@ struct wiringPiNodeStruct | |||||
struct wiringPiNodeStruct *next ; | struct wiringPiNodeStruct *next ; | ||||
} ; | } ; | ||||
extern struct wiringPiNodeStruct *wiringPiNodes ; | |||||
// Function prototypes | // Function prototypes | ||||
// c++ wrappers thanks to a comment by Nick Lott | // c++ wrappers thanks to a comment by Nick Lott | ||||
@@ -119,7 +121,8 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; | |||||
// Core wiringPi functions | // Core wiringPi functions | ||||
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; | |||||
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; | |||||
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; | |||||
extern int wiringPiSetup (void) ; | extern int wiringPiSetup (void) ; | ||||
extern int wiringPiSetupSys (void) ; | extern int wiringPiSetupSys (void) ; | ||||