From 348bc739d1ba5d8e6bdd5995d91516f6d4f76df9 Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Sat, 25 May 2013 13:02:02 +0100 Subject: [PATCH] Sorted a variable initialisation issue that was giving incorrect results 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) --- build | 17 +++++---- gpio/gpio.1 | 12 +++++-- gpio/gpio.c | 102 ++++++++++++++++++++++++++++++++++++++++------------ wiringPi/wiringPi.c | 35 ++++++++++-------- wiringPi/wiringPi.h | 5 ++- 5 files changed, 122 insertions(+), 49 deletions(-) diff --git a/build b/build index 776c756..f578d4a 100755 --- a/build +++ b/build @@ -1,7 +1,6 @@ -#!/bin/bash +#!/bin/sh -check-make-ok() -{ +check_make_ok() { if [ $? != 0 ]; then echo "" echo "Make Failed..." @@ -51,26 +50,26 @@ fi cd wiringPi sudo make uninstall make - check-make-ok + check_make_ok sudo make install - check-make-ok + check_make_ok echo echo "WiringPi Devices Library" cd ../devLib sudo make uninstall make - check-make-ok + check_make_ok sudo make install - check-make-ok + check_make_ok echo echo "GPIO Utility" cd ../gpio make - check-make-ok + check_make_ok sudo make install - check-make-ok + check_make_ok # echo # echo "Examples" diff --git a/gpio/gpio.1 b/gpio/gpio.1 index ae4df4e..e1cba32 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -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 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 .B reset 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). +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 .B pwm 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] 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 -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 .B load spi [buffer size in KB] diff --git a/gpio/gpio.c b/gpio/gpio.c index 1933a69..7a6ef8e 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -48,7 +48,7 @@ extern int wiringPiDebug ; # define FALSE (1==2) #endif -#define VERSION "2.06" +#define VERSION "2.07" #define I2CDETECT "/usr/sbin/i2cdetect" static int wpMode ; @@ -239,6 +239,10 @@ static void doI2Cdetect (int argc, char *argv []) /* * doReadall: * 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 } ; -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 ; - 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: * Reset the GPIO pins - as much as we can do ********************************************************************************* @@ -624,16 +675,21 @@ static void doReset (char *progName) { 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) ; + } } } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index b8e381a..e97a6d1 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -88,7 +88,7 @@ #define PI_GPIO_MASK (0xFFFFFFC0) -static struct wiringPiNodeStruct *wiringPiNodes = NULL ; +struct wiringPiNodeStruct *wiringPiNodes = NULL ; // BCM Magic @@ -213,7 +213,13 @@ int wiringPiReturnCodes = FALSE ; // sysFds: // 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 @@ -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 ; @@ -1304,7 +1310,8 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) char c ; 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) 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) ; if ((pid = fork ()) < 0) // Fail - return pid ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; if (pid == 0) // Child, exec { 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 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 diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 600b318..84042e9 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -104,6 +104,8 @@ struct wiringPiNodeStruct struct wiringPiNodeStruct *next ; } ; +extern struct wiringPiNodeStruct *wiringPiNodes ; + // Function prototypes // c++ wrappers thanks to a comment by Nick Lott @@ -119,7 +121,8 @@ extern int wiringPiFailure (int fatal, const char *message, ...) ; // 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 wiringPiSetupSys (void) ;