wiringPi Version 2 - First commit (of v2)

This commit is contained in:
Gordon Henderson
2013-05-13 19:43:26 +01:00
parent 98bcb20d93
commit da38443cb2
97 changed files with 11243 additions and 1617 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

329
gpio/extensions.c Normal file
View File

@@ -0,0 +1,329 @@
/*
* 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 <mcp23017.h>
#include <mcp23s08.h>
#include <mcp23s17.h>
#include <sr595.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 ;
}
/*
* doExtensionMcp23017:
* MCP23008 - 16-bit I2C GPIO expansion chip
* mcp23002: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 ;
}
/*
* Function list
*********************************************************************************
*/
struct extensionFunctionStruct extensionFunctions [] =
{
{ "mcp23008", &doExtensionMcp23008 },
{ "mcp23017", &doExtensionMcp23017 },
{ "mcp23s08", &doExtensionMcp23s08 },
{ "mcp23s17", &doExtensionMcp23s17 },
{ "sr595", &doExtensionSr595 },
{ 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 ;
}

26
gpio/extensions.h Normal file
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,15 +1,19 @@
.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
.B \-v
.PP
.B gpio
.B [ \-g ]
.B read/write/wb/pwm/clock/mode ...
.B [ \-g | \-1 ]
.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 ]
@@ -17,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.B ...
.PP
.B gpio
.B readall
.B readall/reset
.PP
.B gpio
.B unexportall/exports
@@ -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
@@ -73,12 +81,28 @@ Output the current version including the board revision of the Raspberry Pi.
.TP
.B \-g
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
\fINOTE:\fR The BCM_GPIO pin numbers are always used with the
\fINote:\fR The BCM_GPIO pin numbers are always used with the
export and edge commands.
.TP
.B \-1
Use the physical pin numbers rather than wiringPi pin numbers.
\fINote:\fR that this applies to the P1 connector only. It is not possible to
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.
Use the PiFace interface board and its corresponding pin numbers. The PiFace
will always appear at pin number 200 in the gpio command. You can assign any
pin numbers you like in your own programs though.
.TP
.B read <pin>
@@ -102,6 +126,11 @@ 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.
.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).
.TP
.B pwm <pin> <value>
Write a PWM value (0-1023) to the given pin. The pin needs to be put
@@ -157,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
@@ -207,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
@@ -272,7 +307,7 @@ pin numbers.
.LP
WiringPi's home page
.IP
https://projects.drogon.net/raspberry-pi/wiringpi/
http://wiringpi.com/
.SH AUTHOR
@@ -284,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

@@ -2,7 +2,7 @@
* gpio.c:
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
* Pi's GPIO.
* Copyright (c) 2012 Gordon Henderson
* Copyright (c) 2012-2013 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,14 +26,20 @@
#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 <sys/types.h>
#include <sys/stat.h>
#include <wiringPi.h>
#include <gertboard.h>
#include <piFace.h>
#include "extensions.h"
extern int wiringPiDebug ;
@@ -42,22 +48,26 @@ extern int wiringPiDebug ;
# define FALSE (1==2)
#endif
#define VERSION "1.12"
#define VERSION "2.02"
#define I2CDETECT "/usr/sbin/i2cdetect"
static int wpMode ;
char *usage = "Usage: gpio -v\n"
" gpio -h\n"
" gpio [-g] <read/write/wb/pwm/clock/mode> ...\n"
" gpio [-g|-1] [-x extension:params] ...\n"
" gpio [-p] <read/write/wb> ...\n"
" gpio readall\n"
" gpio unexportall/exports ...\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.
@@ -195,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
@@ -215,27 +256,39 @@ static char *alts [] =
"IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
} ;
static int wpiToPhys [64] =
{
11, 12, 13, 15, 16, 18, 22, 7, // 0...7
3, 5, // 8...9
24, 26, 19, 21, 23, // 10..14
8, 10, // 15..16
3, 4, 5, 6, // 17..20
0,0,0,0,0,0,0,0,0,0,0, // 20..31
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32..47
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63
} ;
static void doReadall (void)
{
int pin ;
printf ("+----------+------+--------+------+-------+\n") ;
printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ;
printf ("+----------+------+--------+------+-------+\n") ;
printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ;
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 ;
printf ("| %6d | %3d | %s | %s | %s |\n",
pin, wpiPinToGpio (pin),
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") ;
}
@@ -252,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
@@ -386,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
@@ -499,7 +596,7 @@ void doUnexport (int argc, char *argv [])
*********************************************************************************
*/
void doUnexportall (int argc, char *argv [])
void doUnexportall (char *progName)
{
FILE *fd ;
int pin ;
@@ -508,7 +605,7 @@ void doUnexportall (int argc, char *argv [])
{
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
{
fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
exit (1) ;
}
fprintf (fd, "%d\n", pin) ;
@@ -517,6 +614,30 @@ void doUnexportall (int argc, char *argv [])
}
/*
* doReset:
* Reset the GPIO pins - as much as we can do
*********************************************************************************
*/
static void doReset (char *progName)
{
int pin ;
doUnexportall (progName) ;
for (pin = 0 ; pin < 64 ; ++pin)
{
if (wpiPinToGpio (pin) == -1)
continue ;
digitalWrite (pin, LOW) ;
pinMode (pin, INPUT) ;
pullUpDnControl (pin, PUD_OFF) ;
}
}
/*
* doMode:
* gpio mode pin mode ...
@@ -536,9 +657,6 @@ void doMode (int argc, char *argv [])
pin = atoi (argv [2]) ;
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;
mode = argv [3] ;
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
@@ -604,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) ;
}
@@ -613,23 +731,23 @@ 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) ;
}
if (gertboardSPISetup () == -1)
if (gertboardAnalogSetup (64) < 0)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}
gertboardAnalogWrite (channel, value) ;
analogWrite (64 + channel, value) ;
}
@@ -654,21 +772,20 @@ 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) ;
}
if (gertboardSPISetup () == -1)
if (gertboardAnalogSetup (64) < 0)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}
printf ("%d\n",gertboardAnalogRead (channel)) ;
printf ("%d\n", analogRead (64 + channel)) ;
}
/*
* doWrite:
* gpio write pin value
@@ -687,9 +804,6 @@ static void doWrite (int argc, char *argv [])
pin = atoi (argv [2]) ;
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;
/**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
val = 1 ;
else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
@@ -703,6 +817,31 @@ static void doWrite (int argc, char *argv [])
digitalWrite (pin, HIGH) ;
}
/*
* doAwriterite:
* gpio awrite pin value
*********************************************************************************
*/
static void doAwrite (int argc, char *argv [])
{
int pin, val ;
if (argc != 4)
{
fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
exit (1) ;
}
pin = atoi (argv [2]) ;
val = atoi (argv [3]) ;
analogWrite (pin, val) ;
}
/*
* doWriteByte:
* gpio write value
@@ -742,19 +881,57 @@ void doRead (int argc, char *argv [])
}
pin = atoi (argv [2]) ;
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
{
printf ("0\n") ;
return ;
}
val = digitalRead (pin) ;
printf ("%s\n", val == 0 ? "0" : "1") ;
}
/*
* doAread:
* Read an analog pin and return the value
*********************************************************************************
*/
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") ;
}
/*
* 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
@@ -773,9 +950,6 @@ void doClock (int argc, char *argv [])
pin = atoi (argv [2]) ;
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;
freq = atoi (argv [3]) ;
gpioClockSet (pin, freq) ;
@@ -800,9 +974,6 @@ void doPwm (int argc, char *argv [])
pin = atoi (argv [2]) ;
if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
return ;
val = atoi (argv [3]) ;
pwmWrite (pin, val) ;
@@ -885,16 +1056,34 @@ 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 Gordon Henderson\n") ;
printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
@@ -905,7 +1094,7 @@ int main (int argc, char *argv [])
if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
@@ -934,8 +1123,8 @@ int main (int argc, char *argv [])
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
// Check for load command:
@@ -948,13 +1137,9 @@ int main (int argc, char *argv [])
// Check for -g argument
if (strcasecmp (argv [1], "-g") == 0)
/**/ if (strcasecmp (argv [1], "-g") == 0)
{
if (wiringPiSetupGpio () == -1)
{
fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
exit (1) ;
}
wiringPiSetupGpio () ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
@@ -962,15 +1147,23 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_GPIO ;
}
// Check for -1 argument
else if (strcasecmp (argv [1], "-1") == 0)
{
wiringPiSetupPhys () ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
--argc ;
wpMode = WPI_MODE_PHYS ;
}
// Check for -p argument for PiFace
else if (strcasecmp (argv [1], "-p") == 0)
{
if (wiringPiSetupPiFaceForGpioProg () == -1)
{
fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
exit (1) ;
}
piFaceSetup (200) ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
@@ -982,38 +1175,65 @@ int main (int argc, char *argv [])
else
{
if (wiringPiSetup () == -1)
{
fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
exit (1) ;
}
wiringPiSetup () ;
wpMode = WPI_MODE_PINS ;
}
// Check for PWM or Pad Drive operations
// Check for -x argument to load in a new extension
if (wpMode != WPI_MODE_PIFACE)
if (strcasecmp (argv [1], "-x") == 0)
{
if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
if (argc < 3)
{
fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}
if (!doExtension (argv [0], argv [2])) // Prints its own error messages
exit (EXIT_FAILURE) ;
for (i = 3 ; i < argc ; ++i)
argv [i - 2] = argv [i] ;
argc -= 2 ;
}
// Check for wiring commands
if (argc <= 1)
{
fprintf (stderr, "%s: no command given\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}
/**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ;
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ;
else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
// Core wiringPi functions
/**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, 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], "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]) ;
exit (1) ;
exit (EXIT_FAILURE) ;
}
return 0 ;
}

193
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