Updated to new WiringPi

This commit is contained in:
Philip Howard
2013-05-21 22:25:01 +01:00
parent 97a4f5131e
commit 17c28c2a48
107 changed files with 9837 additions and 1448 deletions

View File

@@ -30,20 +30,20 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
LIBS = -lwiringPi -lpthread -lm
LIBS = -lwiringPi -lwiringPiDev -lpthread -lm
# May not need to alter anything below this line
###############################################################################
SRC = gpio.c
SRC = gpio.c extensions.c
OBJ = $(SRC:.c=.o)
all: gpio
gpio: gpio.o
gpio: $(OBJ)
@echo [Link]
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
@$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
.c.o:
@echo [Compile] $<
@@ -51,7 +51,8 @@ gpio: gpio.o
.PHONEY: clean
clean:
rm -f $(OBJ) gpio *~ core tags *.bak
@echo "[Clean]"
@rm -f $(OBJ) gpio *~ core tags *.bak
.PHONEY: tags
tags: $(SRC)
@@ -78,3 +79,6 @@ depend:
makedepend -Y $(SRC)
# DO NOT DELETE
gpio.o: extensions.h
extensions.o: extensions.h

414
WiringPi/gpio/extensions.c Normal file
View File

@@ -0,0 +1,414 @@
/*
* extensions.c:
* Part of the GPIO program to test, peek, poke and otherwise
* noodle with the GPIO hardware on the Raspberry Pi.
* Copyright (c) 2012-2013 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <wiringPi.h>
#include <mcp23008.h>
#include <mcp23016.h>
#include <mcp23017.h>
#include <mcp23s08.h>
#include <mcp23s17.h>
#include <sr595.h>
#include <pcf8591.h>
#include <pcf8574.h>
#include "extensions.h"
extern int wiringPiDebug ;
#ifndef TRUE
# define TRUE (1==1)
# define FALSE (1==2)
#endif
// Local structure to hold details
struct extensionFunctionStruct
{
const char *name ;
int (*function)(char *progName, int pinBase, char *params) ;
} ;
/*
* extractInt:
* Check & return an integer at the given location (prefixed by a :)
*********************************************************************************
*/
static char *extractInt (char *progName, char *p, int *num)
{
if (*p != ':')
{
fprintf (stderr, "%s: colon expected\n", progName) ;
return NULL ;
}
++p ;
if (!isdigit (*p))
{
fprintf (stderr, "%s: digit expected\n", progName) ;
return NULL ;
}
*num = strtol (p, NULL, 0) ;
while (isdigit (*p))
++p ;
return p ;
}
/*
* doExtensionMcp23008:
* MCP23008 - 8-bit I2C GPIO expansion chip
* mcp23002:base:i2cAddr
*********************************************************************************
*/
static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
{
int i2c ;
if ((params = extractInt (progName, params, &i2c)) == NULL)
return FALSE ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
mcp23008Setup (pinBase, i2c) ;
return TRUE ;
}
/*
* doExtensionMcp23016:
* MCP230016- 16-bit I2C GPIO expansion chip
* mcp23016:base:i2cAddr
*********************************************************************************
*/
static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
{
int i2c ;
if ((params = extractInt (progName, params, &i2c)) == NULL)
return FALSE ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
mcp23016Setup (pinBase, i2c) ;
return TRUE ;
}
/*
* doExtensionMcp23017:
* MCP230017- 16-bit I2C GPIO expansion chip
* mcp23017:base:i2cAddr
*********************************************************************************
*/
static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
{
int i2c ;
if ((params = extractInt (progName, params, &i2c)) == NULL)
return FALSE ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
mcp23017Setup (pinBase, i2c) ;
return TRUE ;
}
/*
* doExtensionMcp23s08:
* MCP23s08 - 8-bit SPI GPIO expansion chip
* mcp23s08:base:spi:port
*********************************************************************************
*/
static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
{
int spi, port ;
if ((params = extractInt (progName, params, &spi)) == NULL)
return FALSE ;
if ((spi < 0) || (spi > 1))
{
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
return FALSE ;
}
if ((params = extractInt (progName, params, &port)) == NULL)
return FALSE ;
if ((port < 0) || (port > 7))
{
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
return FALSE ;
}
mcp23s08Setup (pinBase, spi, port) ;
return TRUE ;
}
/*
* doExtensionMcp23s17:
* MCP23s17 - 16-bit SPI GPIO expansion chip
* mcp23s17:base:spi:port
*********************************************************************************
*/
static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
{
int spi, port ;
if ((params = extractInt (progName, params, &spi)) == NULL)
return FALSE ;
if ((spi < 0) || (spi > 1))
{
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
return FALSE ;
}
if ((params = extractInt (progName, params, &port)) == NULL)
return FALSE ;
if ((port < 0) || (port > 7))
{
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
return FALSE ;
}
mcp23s17Setup (pinBase, spi, port) ;
return TRUE ;
}
/*
* doExtensionSr595:
* Shift Register 74x595
* sr595:base:pins:data:clock:latch
*********************************************************************************
*/
static int doExtensionSr595 (char *progName, int pinBase, char *params)
{
int pins, data, clock, latch ;
// Extract pins
if ((params = extractInt (progName, params, &pins)) == NULL)
return FALSE ;
if ((pins < 8) || (pins > 32))
{
fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
return FALSE ;
}
if ((params = extractInt (progName, params, &data)) == NULL)
return FALSE ;
if ((params = extractInt (progName, params, &clock)) == NULL)
return FALSE ;
if ((params = extractInt (progName, params, &latch)) == NULL)
return FALSE ;
sr595Setup (pinBase, pins, data, clock, latch) ;
return TRUE ;
}
/*
* doExtensionPcf8574:
* Digital IO (Crude!)
* pcf8574:base:i2cAddr
*********************************************************************************
*/
static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
{
int i2c ;
if ((params = extractInt (progName, params, &i2c)) == NULL)
return FALSE ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
pcf8574Setup (pinBase, i2c) ;
return TRUE ;
}
/*
* doExtensionPcf8591:
* Analog IO
* pcf8591:base:i2cAddr
*********************************************************************************
*/
static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
{
int i2c ;
if ((params = extractInt (progName, params, &i2c)) == NULL)
return FALSE ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
pcf8591Setup (pinBase, i2c) ;
return TRUE ;
}
/*
* Function list
*********************************************************************************
*/
struct extensionFunctionStruct extensionFunctions [] =
{
{ "mcp23008", &doExtensionMcp23008 },
{ "mcp23016", &doExtensionMcp23016 },
{ "mcp23017", &doExtensionMcp23017 },
{ "mcp23s08", &doExtensionMcp23s08 },
{ "mcp23s17", &doExtensionMcp23s17 },
{ "sr595", &doExtensionSr595 },
{ "pcf8574", &doExtensionPcf8574 },
{ "pcf8591", &doExtensionPcf8591 },
{ NULL, NULL },
} ;
/*
* doExtension:
* Load in a wiringPi extension
*********************************************************************************
*/
int doExtension (char *progName, char *extensionData)
{
char *p ;
char *extension = extensionData ;
struct extensionFunctionStruct *extensionFn ;
int pinBase = 0 ;
// Get the extension extension name by finding the first colon
p = extension ;
while (*p != ':')
{
if (!*p) // ran out of characters
{
fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
return FALSE ;
}
++p ;
}
*p++ = 0 ;
if (!isdigit (*p))
{
fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
return FALSE ;
}
while (isdigit (*p))
{
if (pinBase > 1000000000)
{
fprintf (stderr, "%s: pinBase too large\n", progName) ;
return FALSE ;
}
pinBase = pinBase * 10 + (*p - '0') ;
++p ;
}
if (pinBase < 64)
{
fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
return FALSE ;
}
// Search for extensions:
for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
{
if (strcmp (extensionFn->name, extension) == 0)
return extensionFn->function (progName, pinBase, p) ;
}
fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;
return FALSE ;
}

View File

@@ -0,0 +1,26 @@
/*
* extensions.h:
* Part of the GPIO program to test, peek, poke and otherwise
* noodle with the GPIO hardware on the Raspberry Pi.
* Copyright (c) 2012-2013 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
extern int doExtension (char *progName, char *extensionData) ;

View File

@@ -1,7 +1,7 @@
.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"
.TH "GPIO" "March 2013" "Command-Line access to Raspberry Pi's GPIO"
.SH NAME
gpio \- Command-line access to Raspberry Pi and PiFace GPIO
gpio \- Command-line access to Raspberry Pi's GPIO
.SH SYNOPSIS
.B gpio
@@ -9,7 +9,11 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.PP
.B gpio
.B [ \-g | \-1 ]
.B read/write/aread/awrite/wb/pwm/clock/mode ...
.B mode/read/write/aread/awrite/wb/pwm/clock ...
.PP
.B gpio
.B [ \-x extension:params ]
.B mode/read/write/aread/awrite/pwm ...
.PP
.B gpio
.B [ \-p ]
@@ -27,6 +31,10 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.B ...
.PP
.B gpio
.B wfi
.B ...
.PP
.B gpio
.B drive
group value
.PP
@@ -83,6 +91,13 @@ Use the physical pin numbers rather than wiringPi pin numbers.
use pins on the Revision 2 P5 connector this way, and as with \-g the
BCM_GPIO pin numbers are always used with the export and edge commands.
.TP
.B \-x extension
This causes the named extension to be initialised. Extensions
comprise of a name (e.g. mcp23017) followed by a colon, then the
pin-base, then more optional parameters depending on the extension type.
See the web page on http://wiringpi.com/the-gpio-utility/
.TP
.B \-p
Use the PiFace interface board and its corresponding pin numbers. The PiFace
@@ -171,6 +186,12 @@ requiring root/sudo.
.B unexport
Un-Export a GPIO pin in the /sys/class/gpio directory.
.TP
.B wfi <pin> <mode>
This set the given pin to the supplied interrupt mode: rising, falling
or both then waits for the interrupt to happen. It's a non-busy wait,
so does not consume and CPU while it's waiting.
.TP
.B drive
group value
@@ -221,26 +242,26 @@ The board jumpers need to be in-place to do this operation.
.PP
.TS
r r r l.
WiringPi GPIO-r1 GPIO-r2 Function
c c c c l.
WiringPi GPIO-r1 GPIO-r2 P1-Phys Function
_
0 17 17
1 18 18 (PWM)
2 21 27
3 22 22
4 23 23
5 24 24
6 25 25
7 4 4
8 0 2 I2C: SDA0
9 1 3 I2C: SCL0
10 8 8 SPI: CE0
11 7 7 SPI: CE1
12 10 10 SPI: MOSI
13 9 9 SPI: MISO
14 11 11 SPI: SCLK
15 14 14 TxD
16 15 16 RxD
0 17 17 11
1 18 18 12 (PWM)
2 21 27 13
3 22 22 15
4 23 23 16
5 24 24 18
6 25 25 22
7 4 4 7
8 0 2 3 I2C: SDA0
9 1 3 5 I2C: SCL0
10 8 8 24 SPI: CE0
11 7 7 26 SPI: CE1
12 10 10 19 SPI: MOSI
13 9 9 21 SPI: MISO
14 11 11 23 SPI: SCLK
15 14 14 8 TxD
16 15 16 10 RxD
17 - 28
18 - 29
19 - 30
@@ -286,7 +307,7 @@ pin numbers.
.LP
WiringPi's home page
.IP
https://projects.drogon.net/raspberry-pi/wiringpi/
http://wiringpi.com/
.SH AUTHOR
@@ -298,7 +319,7 @@ Please report bugs to <projects@drogon.net>
.SH COPYRIGHT
Copyright (c) 2012 Gordon Henderson
Copyright (c) 2012-2013 Gordon Henderson
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -30,18 +30,16 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <wiringPi.h>
#include <gertboard.h>
#include <piFace.h>
#include <sr595.h>
#include <mcp23008.h>
#include <mcp23017.h>
#include <mcp23s08.h>
#include <mcp23s17.h>
#include "extensions.h"
extern int wiringPiDebug ;
@@ -50,213 +48,29 @@ extern int wiringPiDebug ;
# define FALSE (1==2)
#endif
#define VERSION "2.00"
#define VERSION "2.05"
#define I2CDETECT "/usr/sbin/i2cdetect"
static int wpMode ;
char *usage = "Usage: gpio -v\n"
" gpio -h\n"
" gpio [-g|-1] [-x module:params] ...\n"
" gpio [-g|-1] [-x extension:params] ...\n"
" gpio [-p] <read/write/wb> ...\n"
" gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
" gpio readall/reset\n"
" gpio unexportall/exports\n"
" gpio export/edge/unexport ...\n"
" gpio wfi <pin> <mode>\n"
" gpio drive <group> <value>\n"
" gpio pwm-bal/pwm-ms \n"
" gpio pwmr <range> \n"
" gpio pwmc <divider> \n"
" gpio load spi/i2c\n"
" gpio i2cd/i2cdetect\n"
" gpio gbr <channel>\n"
" gpio gbw <channel> <value>" ; // No trailing newline needed here.
struct moduleFunctionStruct
{
const char *name ;
int (*function)(char *progName, int pinBase, char *params) ;
} ;
static int doModuleMcp23008 (char *progName, int pinBase, char *params)
{
int i2c ;
// Extract the I2C address:
if (*params != ':')
{
fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
return FALSE ;
}
i2c = strtol (params, NULL, 0) ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
mcp23008Setup (pinBase, i2c) ;
return TRUE ;
}
static int doModuleMcp23017 (char *progName, int pinBase, char *params)
{
int i2c ;
// Extract the I2C address:
if (*params != ':')
{
fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
return FALSE ;
}
i2c = strtol (params, NULL, 0) ;
if ((i2c < 0x03) || (i2c > 0x77))
{
fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
return FALSE ;
}
mcp23017Setup (pinBase, i2c) ;
return TRUE ;
}
static int doModuleMcp23s08 (char *progName, int pinBase, char *params)
{
int spi, port ;
// Extract the SPI address:
if (*params != ':')
{
fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
return FALSE ;
}
spi = *params - '0' ;
if ((spi < 0) || (spi > 1))
{
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
return FALSE ;
}
// Extract the port:
if (*++params != ':')
{
fprintf (stderr, "%s: colon expected after SPI address\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after SPI address\n", progName) ;
return FALSE ;
}
port = strtol (params, NULL, 0) ;
if ((port < 0) || (port > 7))
{
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
return FALSE ;
}
mcp23s08Setup (pinBase, spi, port) ;
return TRUE ;
}
static int doModuleMcp23s17 (char *progName, int pinBase, char *params)
{
int spi, port ;
// Extract the SPI address:
if (*params != ':')
{
fprintf (stderr, "%s: colon expected after pin-base number\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after pin-base number\n", progName) ;
return FALSE ;
}
spi = *params - '0' ;
if ((spi < 0) || (spi > 1))
{
fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
return FALSE ;
}
// Extract the port:
if (*++params != ':')
{
fprintf (stderr, "%s: colon expected after SPI address\n", progName) ;
return FALSE ;
}
++params ;
if (!isdigit (*params))
{
fprintf (stderr, "%s: digit expected after SPI address\n", progName) ;
return FALSE ;
}
port = strtol (params, NULL, 0) ;
if ((port < 0) || (port > 7))
{
fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
return FALSE ;
}
mcp23s17Setup (pinBase, spi, port) ;
return TRUE ;
}
struct moduleFunctionStruct moduleFunctions [] =
{
{ "mcp23008", &doModuleMcp23008 },
{ "mcp23017", &doModuleMcp23017 },
{ "mcp23s08", &doModuleMcp23s08 },
{ "mcp23s17", &doModuleMcp23s17 },
{ NULL, NULL },
} ;
/*
* changeOwner:
@@ -391,6 +205,37 @@ static void doLoad (int argc, char *argv [])
}
/*
* doI2Cdetect:
* Run the i2cdetect command with the right runes for this Pi revision
*********************************************************************************
*/
static void doI2Cdetect (int argc, char *argv [])
{
int port = piBoardRev () == 1 ? 0 : 1 ;
char command [128] ;
struct stat statBuf ;
if (stat (I2CDETECT, &statBuf) < 0)
{
fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
return ;
}
if (!moduleLoaded ("i2c_dev"))
{
fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
return ;
}
sprintf (command, "%s -y %d", I2CDETECT, port) ;
if (system (command) < 0)
fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
}
/*
* doReadall:
* Read all the GPIO pins
@@ -431,7 +276,7 @@ static void doReadall (void)
printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ;
printf ("+----------+------+------+--------+------+-------+\n") ;
for (pin = 0 ; pin < 64 ; ++pin)
for (pin = 0 ; pin < 64 ; ++pin) // Crude, but effective
{
if (wpiPinToGpio (pin) == -1)
continue ;
@@ -460,9 +305,7 @@ static void doExports (int argc, char *argv [])
char fName [128] ;
char buf [16] ;
// Rather crude, but who knows what others are up to...
for (first = 0, i = 0 ; i < 64 ; ++i)
for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
{
// Try to read the direction
@@ -594,6 +437,52 @@ void doExport (int argc, char *argv [])
}
/*
* doWfi:
* gpio wfi pin mode
* Wait for Interrupt on a given pin.
* Slight cheat here - it's easier to actually use ISR now (which calls
* gpio to set the pin modes!) then we simply sleep, and expect the thread
* to exit the program. Crude but effective.
*********************************************************************************
*/
static void wfi (void)
{ exit (0) ; }
void doWfi (int argc, char *argv [])
{
int pin, mode ;
if (argc != 4)
{
fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
exit (1) ;
}
pin = atoi (argv [2]) ;
/**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ;
else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ;
else
{
fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
exit (1) ;
}
if (wiringPiISR (pin, mode, &wfi) < 0)
{
fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
exit (1) ;
}
for (;;)
delay (9999) ;
}
/*
* doEdge:
* gpio edge pin mode
@@ -833,7 +722,7 @@ static void doGbw (int argc, char *argv [])
if (argc != 4)
{
fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
exit (1) ;
}
@@ -842,13 +731,13 @@ static void doGbw (int argc, char *argv [])
if ((channel < 0) || (channel > 1))
{
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
exit (1) ;
}
if ((value < 0) || (value > 1023))
{
fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
exit (1) ;
}
@@ -883,7 +772,7 @@ static void doGbr (int argc, char *argv [])
if ((channel < 0) || (channel > 1))
{
fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
exit (1) ;
}
@@ -992,7 +881,6 @@ void doRead (int argc, char *argv [])
}
pin = atoi (argv [2]) ;
val = digitalRead (pin) ;
printf ("%s\n", val == 0 ? "0" : "1") ;
@@ -1007,22 +895,37 @@ void doRead (int argc, char *argv [])
void doAread (int argc, char *argv [])
{
int pin, val ;
if (argc != 3)
{
fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
exit (1) ;
}
pin = atoi (argv [2]) ;
val = analogRead (pin) ;
printf ("%s\n", val == 0 ? "0" : "1") ;
printf ("%d\n", analogRead (atoi (argv [2]))) ;
}
/*
* doToggle:
* Toggle an IO pin
*********************************************************************************
*/
void doToggle (int argc, char *argv [])
{
int pin ;
if (argc != 3)
{
fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
exit (1) ;
}
pin = atoi (argv [2]) ;
digitalWrite (pin, !digitalRead (pin)) ;
}
/*
* doClock:
* Output a clock on a pin
@@ -1125,72 +1028,6 @@ static void doPwmClock (int argc, char *argv [])
}
/*
* doModule:
* Load in a wiringPi extension module
*********************************************************************************
*/
static int doModule (char *progName, char *moduleData)
{
char *p ;
char *module = moduleData ;
struct moduleFunctionStruct *modFn ;
int pinBase = 0 ;
// Get the module name by finding the first :
p = module ;
while (*p != ':')
{
if (!*p) // ran out of characters
{
fprintf (stderr, "%s: module name not terminated by a colon\n", progName) ;
return FALSE ;
}
++p ;
}
*p++ = 0 ;
if (!isdigit (*p))
{
fprintf (stderr, "%s: pinBase number expected after module name\n", progName) ;
return FALSE ;
}
while (isdigit (*p))
{
if (pinBase > 1000000000)
{
fprintf (stderr, "%s: pinBase too large\n", progName) ;
return FALSE ;
}
pinBase = pinBase * 10 + (*p - '0') ;
++p ;
}
if (pinBase < 64)
{
fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
return FALSE ;
}
// Search for modules:
for (modFn = moduleFunctions ; modFn->name != NULL ; ++modFn)
{
if (strcmp (modFn->name, module) == 0)
return modFn->function (progName, pinBase, p) ;
}
fprintf (stderr, "%s: module %s not found\n", progName, module) ;
return FALSE ;
}
/*
* main:
* Start here
@@ -1213,13 +1050,31 @@ int main (int argc, char *argv [])
return 1 ;
}
// Help
if (strcasecmp (argv [1], "-h") == 0)
{
printf ("%s: %s\n", argv [0], usage) ;
return 0 ;
}
if (strcasecmp (argv [1], "-v") == 0)
// Sort of a special:
if (strcmp (argv [1], "-R") == 0)
{
printf ("%d\n", piBoardRev ()) ;
return 0 ;
}
// Version & Warranty
if (strcmp (argv [1], "-V") == 0)
{
printf ("%d\n", piBoardRev ()) ;
return 0 ;
}
if (strcmp (argv [1], "-v") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
@@ -1318,17 +1173,17 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_PINS ;
}
// Check for -x argument to load in a new module
// Check for -x argument to load in a new extension
if (strcasecmp (argv [1], "-x") == 0)
{
if (argc < 3)
{
fprintf (stderr, "%s: -x missing module specification.\n", argv [0]) ;
fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}
if (!doModule (argv [0], argv [2])) // Prints its own error messages
if (!doExtension (argv [0], argv [2])) // Prints its own error messages
exit (EXIT_FAILURE) ;
for (i = 3 ; i < argc ; ++i)
@@ -1351,17 +1206,24 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
// GPIO Nicies
else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
// Pi Specifics
else if (strcasecmp (argv [1], "pwm-bal") == 0) doPwmMode (PWM_MODE_BAL) ;
else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "readall") == 0) doReadall () ;
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
else
{
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;

193
WiringPi/gpio/pintest Executable file
View File

@@ -0,0 +1,193 @@
#!/bin/bash
#
# pintest
# Test the Pi's GPIO port
# Copyright (c) 2013 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
#
# wiringPi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wiringPi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################
# logErr pin, expected got
################################################################################
logErr ()
{
if [ $errs = 0 ]; then
echo ""
fi
echo " --> Pin $1 failure. Expected $2, got $3"
let errs+=1
}
# printErrorCount
################################################################################
printErrCount()
{
if [ $errs = 0 ]; then
echo "No faults detected."
elif [ $errs = 1 ]; then
echo "One fault detected."
else
echo "$errs faults detected"
fi
}
# testPins start end
################################################################################
testPins()
{
start=$1
end=$2
errs=0
printf "%30s %2d:%2d: " "$3" $1 $2
# Set range to inputs
for i in `seq $start $end`; do
gpio mode $i in
done
# Enable internal pull-ups and expect to read high
for i in `seq $start $end`; do
gpio mode $i up
if [ `gpio read $i` = 0 ]; then
logErr $i 1 0
fi
done
# Enable internal pull-downs and expect to read low
for i in `seq $start $end`; do
gpio mode $i down
if [ `gpio read $i` = 1 ]; then
echo "Pin $i failure - expected 0, got 1"
let errs+=1
fi
done
# Remove the internal pull up/downs
for i in `seq $start $end`; do
gpio mode $i tri
done
if [ $errs = 0 ]; then
echo " OK"
else
printErrCount
fi
let totErrs+=errs
}
intro()
{
revision=`gpio -V`
cat <<EOF
PinTest
=======
This is a simple utility to test the GPIO pins on your revision $revision
Raspberry Pi.
NOTE: All GPIO peripherals must be removed to perform this test. This
includes serial, I2C and SPI connections. You may get incorrect results
if something is connected and it interferes with the test.
This test can only test the input side of things. It uses the internal
pull-up and pull-down resistors to simulate inputs. It does not test
the output drivers.
You will need to reboot your Pi after this test if you wish to use the
serial port as it will be left in GPIO mode rather than serial mode.
Please make sure everything is removed and press the ENTER key to continue,
EOF
echo -n "or Control-C to abort... "
read a
}
# Start here
################################################################################
intro
gpio unexportall
gpio reset
errs=0
totErrs=0
echo ""
# Main pins
testPins 0 7 "The main 8 GPIO pins"
# P5 pins, if a rev 2:
if [ $revision = 2 ]; then
testPins 17 20 "The 4 pins on the P5 connector"
fi
# SPI
testPins 10 14 "The 5 SPI pins"
# Serial
testPins 15 16 "The serial pins"
# I2C - Needs somewhat different testing
# due to the on-board pull-up's
echo -n " The I2C pins 8: 9: "
errs=0
gpio mode 8 in
gpio mode 9 in
if [ `gpio read 8` = 0 ]; then
echo "Pin 8 failure - expected 1, got 0"
let errs+=1
fi
if [ `gpio read 9` = 0 ]; then
echo "Pin 9 failure - expected 1, got 0"
let errs+=1
fi
if [ $errs = 0 ]; then
echo " OK"
else
printErrCount
fi
echo ""
if [ $totErrs != 0 ]; then
echo ""
echo "Faults detected! Output of 'readall':"
gpio readall
fi