Updated from git.drogon.net

This commit is contained in:
Phil Howard
2016-02-27 16:03:10 +00:00
parent ddf1b3ffaa
commit 26c7fe3332
151 changed files with 17346 additions and 1343 deletions

View File

@@ -1,9 +1,10 @@
#
# Makefile:
# wiringPi - Wiring Compatable library for the Raspberry Pi
# The gpio command:
# A swiss-army knige of GPIO shenanigans.
# https://projects.drogon.net/wiring-pi
#
# Copyright (c) 2012 Gordon Henderson
# Copyright (c) 2012-2015 Gordon Henderson
#################################################################################
# This file is part of wiringPi:
# Wiring Compatable library for the Raspberry Pi
@@ -22,59 +23,79 @@
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
#################################################################################
DESTDIR?=/usr
PREFIX?=/local
ifneq ($V,1)
Q ?= @
endif
#DEBUG = -g -O0
DEBUG = -O2
CC = gcc
INCLUDE = -I/usr/local/include
INCLUDE = -I$(DESTDIR)$(PREFIX)/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
LIBS = -lwiringPi -lpthread -lm
LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib
LIBS = -lwiringPi -lwiringPiDev -lpthread
# May not need to alter anything below this line
###############################################################################
SRC = gpio.c
SRC = gpio.c readall.c pins.c
OBJ = $(SRC:.c=.o)
all: gpio
gpio: gpio.o
@echo [Link]
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
version.h: ../VERSION
$Q echo Need to run newVersion above.
gpio: $(OBJ)
$Q echo [Link]
$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
.c.o:
@echo [Compile] $<
@$(CC) -c $(CFLAGS) $< -o $@
$Q echo [Compile] $<
$Q $(CC) -c $(CFLAGS) $< -o $@
.PHONEY: clean
.PHONY: clean
clean:
rm -f $(OBJ) gpio *~ core tags *.bak
$Q echo "[Clean]"
$Q rm -f $(OBJ) gpio *~ core tags *.bak
.PHONEY: tags
.PHONY: tags
tags: $(SRC)
@echo [ctags]
@ctags $(SRC)
$Q echo [ctags]
$Q ctags $(SRC)
.PHONEY: install
install:
@echo "[Install]"
@cp gpio /usr/local/bin
@chown root.root /usr/local/bin/gpio
@chmod 4755 /usr/local/bin/gpio
@mkdir -p /usr/local/man/man1
@cp gpio.1 /usr/local/man/man1
.PHONY: install
install: gpio
$Q echo "[Install]"
$Q cp gpio $(DESTDIR)$(PREFIX)/bin
ifneq ($(WIRINGPI_SUID),0)
$Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio
$Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio
endif
$Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1
$Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man1
.PHONEY: uninstall
.PHONY: install-deb
install-deb: gpio
$Q echo "[Install: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin
.PHONY: uninstall
uninstall:
@echo "[UnInstall]"
@rm -f /usr/local/bin/gpio
@rm -f /usr/local/man/man1/gpio.1
$Q echo "[UnInstall]"
$Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio
$Q rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1
.PHONEY: depend
.PHONY: depend
depend:
makedepend -Y $(SRC)
# DO NOT DELETE
gpio.o: version.h

View File

@@ -1,19 +1,23 @@
.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"
.TH GPIO 1 "September 2015" wiringPi "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/pwmTone ...
.PP
.B gpio
.B [ \-p ]
.B read/write/wb
.B read/write/toggle/wb
.B ...
.PP
.B gpio
@@ -27,10 +31,18 @@ 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
.B gpio
.B usbp
high | low
.PP
.B gpio
.B pwm-bal/pwm-ms
.PP
.B gpio
@@ -73,12 +85,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>
@@ -90,6 +118,28 @@ respective logic levels.
Write the given value (0 or 1) to the pin. You need to set the pin
to output mode first.
.TP
.B aread <pin>
Read the analog value of the given pin. This needs to be uses in
conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels.
e.g. gpio -x mcp3002:200:0 aread 200
will read the first analog input on an mcp3002 SPI ADC chip.
.TP
.B awrite <pin> <value>
Write the analog value to the given pin. This needs to be used in
conjunction with a -x flag to add in an extension that handles analog
inputs. respective logic levels.
e.g. gpio -x mcp4802:200:0 awrite 200 128
will write the value 128 to the first DAC port on an mcp4802 chip on
the Pi's SPI bus 0.
.TP
.B wb <value>
Write the given byte to the 8 main GPIO pins. You can prefix it with 0x
@@ -102,6 +152,10 @@ 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 pwm <pin> <value>
Write a PWM value (0-1023) to the given pin. The pin needs to be put
@@ -118,6 +172,8 @@ Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also
use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal
pull-up, pull-down or tristate (off) controls.
The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR.
.TP
.B unexportall
Un-Export all the GPIO pins in the /sys/class/gpio directory.
@@ -129,9 +185,11 @@ Print a list (if any) of all the exported GPIO pins and their current values.
.TP
.B export
Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the
mode command above however only \fIin\fR and \fIout\fR are supported at
this time. Note that the pin number is the \fBBCM_GPIO\fR number and
not the wiringPi number.
mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and
\fRlow\fR are supported at this time. Note that the pin number is the
\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and
\fIlow\fR commands pre-set the output value at the same time as the
export to output mode.
Once a GPIO pin has been exported, the \fBgpio\fR program changes the
ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in
@@ -157,6 +215,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
@@ -165,6 +229,13 @@ Change the pad driver value for the given pad group to the supplied drive
value. Group is 0, 1 or 2 and value is 0-7. Do not use unless you are
absolutely sure you know what you're doing.
.TP
.B usbp
high | low
Change the USB current limiter to high (1.2 amps) or low (the default, 600mA)
This is only applicable to the model B+
.TP
.B pwm-bal/pwm-ms
Change the PWM mode to balanced (the default) or mark:space ratio (traditional)
@@ -177,15 +248,27 @@ 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.
Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the I2C device at boot time.
(or disable the device tree to continue to use this method)
.TP
.B load spi [buffer size in KB]
.B load spi
This loads the spi 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 SPI buffer size to that supplied. The
default is 4KB.
them. It used to have the ability to change the buffer size from the
default of 4096 bytes to an arbitrary value, however for some time the
Pi Foundation have compiled the SPI device driver into the kernel and
this has fixed the buffer size. The way to change it now is to edit
the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to
e.g. 8192 bytes then reboot.
Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the SPI device at boot time.
(or disable the device tree to continue to use this method)
.TP
.B gbr
@@ -203,41 +286,12 @@ SPI digital to analogue converter.
The board jumpers need to be in-place to do this operation.
.SH "WiringPi vs. BCM_GPIO Pin numbering"
.SH "WiringPi vs. BCM_GPIO Pin numbering vs. Physical pin numbering"
.PP
.TS
r r r l.
WiringPi GPIO-r1 GPIO-r2 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
17 - 28
18 - 29
19 - 30
20 - 31
.TE
Note that "r1" and "r2" above refers to the board revision. Normally
wiringPi detects the correct board revision with use for it's own
numbering scheme, but if you are using a Revision 2 board with some
of the pins which change numbers between revisions you will need
to alter your software.
The quickest way to get a list of the pin differences is to run the command
.TP
gpio readall
.SH FILES
@@ -267,12 +321,24 @@ When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the
pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi
pin numbers.
As of kernels 4.1.7, a user-level GPIO access mechanism is available,
however wiringPi will not use this by default - because at this time
there appears to be issues when trying to program the PWM or clock output
hardware. If you can live without PWM or GPIO clocks and you want to use
the GPIO from a non-root program, then you need to make sure that the
module \fIbcm2835_gpiomem\fR is loaded at boot time. This should happen
automatically when you enable the device tree in raspi-config. You may
also need some additional information in /etc/udev/rules.d/ to change the
mode and ownership of the /dev/gpiomem file. Finally, you need to set
the environment variable \fIWIRINGPI_GPIOMEM\fR. This will go-away
in future releases once the /dev/gpiomem interface is fully operational.
.SH "SEE ALSO"
.LP
WiringPi's home page
.IP
https://projects.drogon.net/raspberry-pi/wiringpi/
http://wiringpi.com/
.SH AUTHOR
@@ -284,7 +350,7 @@ Please report bugs to <projects@drogon.net>
.SH COPYRIGHT
Copyright (c) 2012 Gordon Henderson
Copyright (c) 2012-2015 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-2015 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,42 +26,81 @@
#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 <wpiExtensions.h>
#include <gertboard.h>
#include <piFace.h>
#include "version.h"
extern int wiringPiDebug ;
// External functions I can't be bothered creating a separate .h file for:
extern void doReadall (void) ;
extern void doPins (void) ;
#ifndef TRUE
# define TRUE (1==1)
# define FALSE (1==2)
#endif
#define VERSION "1.12"
#define PI_USB_POWER_CONTROL 38
#define I2CDETECT "/usr/sbin/i2cdetect"
static int wpMode ;
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 unload spi/i2c\n"
" gpio i2cd/i2cdetect\n"
" gpio usbp high/low\n"
" gpio gbr <channel>\n"
" gpio gbw <channel> <value>" ; // No trailing newline needed here.
#ifdef NOT_FOR_NOW
/*
* decodePin:
* Decode a pin "number" which can actually be a pin name to represent
* one of the Pi's on-board pins.
*********************************************************************************
*/
static int decodePin (const char *str)
{
// The first case - see if it's a number:
if (isdigit (str [0]))
return atoi (str) ;
return 0 ;
}
#endif
/*
* changeOwner:
* Change the ownership of the file to the real userId of the calling
@@ -77,12 +116,9 @@ static void changeOwner (char *cmd, char *file)
if (chown (file, uid, gid) != 0)
{
if (errno == ENOENT) // Warn that it's not there
fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
fprintf (stderr, "%s: Warning (not an error, do not report): File not present: %s\n", cmd, file) ;
else
{
fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
exit (1) ;
}
fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
}
}
@@ -127,9 +163,25 @@ static int moduleLoaded (char *modName)
*********************************************************************************
*/
static void checkDevTree (char *argv [])
{
struct stat statBuf ;
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
{
fprintf (stderr,
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n"
" You need to run the raspi-config program (as root) and select the\n"
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n"
" There is more information here:\n"
" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ;
exit (1) ;
}
}
static void _doLoadUsage (char *argv [])
{
fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
exit (1) ;
}
@@ -140,6 +192,8 @@ static void doLoad (int argc, char *argv [])
char *file1, *file2 ;
char args1 [32], args2 [32] ;
checkDevTree (argv) ;
if (argc < 3)
_doLoadUsage (argv) ;
@@ -152,7 +206,10 @@ static void doLoad (int argc, char *argv [])
file1 = "/dev/spidev0.0" ;
file2 = "/dev/spidev0.1" ;
if (argc == 4)
sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
{
fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
exit (1) ;
}
else if (argc > 4)
_doLoadUsage (argv) ;
}
@@ -172,13 +229,13 @@ static void doLoad (int argc, char *argv [])
if (!moduleLoaded (module1))
{
sprintf (cmd, "modprobe %s%s", module1, args1) ;
sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
system (cmd) ;
}
if (!moduleLoaded (module2))
{
sprintf (cmd, "modprobe %s%s", module2, args2) ;
sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
system (cmd) ;
}
@@ -196,46 +253,82 @@ static void doLoad (int argc, char *argv [])
/*
* doReadall:
* Read all the GPIO pins
* doUnLoad:
* Un-Load either the spi or i2c modules and change device ownerships, etc.
*********************************************************************************
*/
static char *pinNames [] =
static void _doUnLoadUsage (char *argv [])
{
"GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7",
"SDA ", "SCL ",
"CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ",
"TxD ", "RxD ",
"GPIO 8", "GPIO 9", "GPIO10", "GPIO11",
} ;
fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
exit (1) ;
}
static char *alts [] =
static void doUnLoad (int argc, char *argv [])
{
"IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
} ;
char *module1, *module2 ;
char cmd [80] ;
static void doReadall (void)
{
int pin ;
checkDevTree (argv) ;
printf ("+----------+------+--------+------+-------+\n") ;
printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ;
printf ("+----------+------+--------+------+-------+\n") ;
if (argc != 3)
_doUnLoadUsage (argv) ;
for (pin = 0 ; pin < 64 ; ++pin)
/**/ if (strcasecmp (argv [2], "spi") == 0)
{
if (wpiPinToGpio (pin) == -1)
continue ;
module1 = "spidev" ;
module2 = "spi_bcm2708" ;
}
else if (strcasecmp (argv [2], "i2c") == 0)
{
module1 = "i2c_dev" ;
module2 = "i2c_bcm2708" ;
}
else
_doUnLoadUsage (argv) ;
printf ("| %6d | %3d | %s | %s | %s |\n",
pin, wpiPinToGpio (pin),
pinNames [pin],
alts [getAlt (pin)],
digitalRead (pin) == HIGH ? "High" : "Low ") ;
if (moduleLoaded (module1))
{
sprintf (cmd, "/sbin/rmmod %s", module1) ;
system (cmd) ;
}
printf ("+----------+------+--------+------+-------+\n") ;
if (moduleLoaded (module2))
{
sprintf (cmd, "/sbin/rmmod %s", module2) ;
system (cmd) ;
}
}
/*
* 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)) ;
}
@@ -252,9 +345,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
@@ -363,19 +454,23 @@ void doExport (int argc, char *argv [])
exit (1) ;
}
/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
/**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
fprintf (fd, "in\n") ;
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
fprintf (fd, "out\n") ;
else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0))
fprintf (fd, "high\n") ;
else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0))
fprintf (fd, "low\n") ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ;
exit (1) ;
}
fclose (fd) ;
// Change ownership so the current user can actually use it!
// Change ownership so the current user can actually use it
sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
changeOwner (argv [0], fName) ;
@@ -386,6 +481,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 +640,7 @@ void doUnexport (int argc, char *argv [])
*********************************************************************************
*/
void doUnexportall (int argc, char *argv [])
void doUnexportall (char *progName)
{
FILE *fd ;
int pin ;
@@ -508,7 +649,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 +658,20 @@ void doUnexportall (int argc, char *argv [])
}
/*
* doReset:
* Reset the GPIO pins - as much as we can do
*********************************************************************************
*/
static void doReset (char *progName)
{
printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
printf (" that you need them in for your applications.\n") ;
}
/*
* doMode:
* gpio mode pin mode ...
@@ -536,18 +691,25 @@ 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) ;
else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ;
else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ;
else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ;
else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ;
else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ;
else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ;
else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ;
else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ;
else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ;
else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ;
else
{
fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
@@ -591,6 +753,58 @@ static void doPadDrive (int argc, char *argv [])
}
/*
* doUsbP:
* Control USB Power - High (1.2A) or Low (600mA)
* gpio usbp high/low
*********************************************************************************
*/
static void doUsbP (int argc, char *argv [])
{
int model, rev, mem, maker, overVolted ;
if (argc != 3)
{
fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
exit (1) ;
}
// Make sure we're on a B+
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
if (model != PI_MODEL_BP)
{
fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ;
exit (1) ;
}
// Need to force BCM_GPIO mode:
wiringPiSetupGpio () ;
if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0))
{
digitalWrite (PI_USB_POWER_CONTROL, 1) ;
pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
printf ("Switched to HIGH current USB (1.2A)\n") ;
return ;
}
if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0))
{
digitalWrite (PI_USB_POWER_CONTROL, 0) ;
pinMode (PI_USB_POWER_CONTROL, OUTPUT) ;
printf ("Switched to LOW current USB (600mA)\n") ;
return ;
}
fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ;
exit (1) ;
}
/*
* doGbw:
* gpio gbw channel value
@@ -604,7 +818,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 +827,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))
if ((value < 0) || (value > 255))
{
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 +868,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 +900,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 +913,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 +977,75 @@ 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 [])
{
if (argc != 3)
{
fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
exit (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)) ;
}
/*
* doPwmTone:
* Output a tone in a PWM pin
*********************************************************************************
*/
void doPwmTone (int argc, char *argv [])
{
int pin, freq ;
if (argc != 4)
{
fprintf (stderr, "Usage: %s pwmTone <pin> <freq>\n", argv [0]) ;
exit (1) ;
}
pin = atoi (argv [2]) ;
freq = atoi (argv [3]) ;
pwmToneWrite (pin, freq) ;
}
/*
* doClock:
* Output a clock on a pin
@@ -773,9 +1064,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 +1088,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) ;
@@ -863,6 +1148,56 @@ static void doPwmClock (int argc, char *argv [])
}
/*
* doVersion:
* Handle the ever more complicated version command
*********************************************************************************
*/
static void doVersion (char *argv [])
{
int model, rev, mem, maker, warranty ;
struct stat statBuf ;
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
piBoardId (&model, &rev, &mem, &maker, &warranty) ;
/*************
if (model == PI_MODEL_UNKNOWN)
{
printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ;
printf (" projects@drogon.net\n") ;
printf ("with a copy of your /proc/cpuinfo if possible\n") ;
}
else
***************/
{
printf ("Raspberry Pi Details:\n") ;
printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n",
piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ;
// Check for device tree
if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ...
printf (" Device tree is enabled.\n") ;
if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO
{
printf (" This Raspberry Pi supports user-level GPIO access.\n") ;
printf (" -> See the man-page for more details\n") ;
}
else
printf (" * Root or sudo required for GPIO access.\n") ;
}
}
/*
* main:
* Start here
@@ -885,27 +1220,35 @@ 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)
// Version & Warranty
// Wish I could remember why I have both -R and -V ...
if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
printf ("%d\n", piBoardRev ()) ;
return 0 ;
}
// Version and information
if (strcmp (argv [1], "-v") == 0)
{
doVersion (argv) ;
return 0 ;
}
if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012 Gordon Henderson\n") ;
printf ("Copyright (c) 2012-2015 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,12 +1277,13 @@ 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:
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; }
// Gertboard commands
@@ -948,13 +1292,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 +1302,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 +1330,69 @@ 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 (!loadWPiExtension (argv [0], argv [2], TRUE)) // 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], "pwmTone" ) == 0) doPwmTone (argc, argv) ;
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ;
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ;
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 ;
}

33
gpio/pins.c Normal file
View File

@@ -0,0 +1,33 @@
/*
* pins.c:
* Just display a handy Pi pinnout diagram.
* Copyright (c) 2012-2015 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>
void doPins (void)
{
printf ("The pins command has been deprecated - sorry. Please use the\n") ;
printf (" gpio readall\n") ;
printf ("command to get a list of the pinnouts for your Pi.\n") ;
}

187
gpio/pintest Normal file
View File

@@ -0,0 +1,187 @@
#!/bin/bash
#
# pintest
# Test the Pi's GPIO port
# Copyright (c) 2013-2015 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()
{
cat <<EOF
PinTest
=======
This is a simple utility to test the GPIO pins on your 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.
This test only tests the original pins present on the Rev A and B. It
does not test the extra pins on the Revision A2, B2 nor the A+ or B+
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
errs=0
totErrs=0
echo ""
# Main pins
testPins 0 7 "The main 8 GPIO pins"
# 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

336
gpio/readall.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* readall.c:
* The readall functions - getting a bit big, so split them out.
* Copyright (c) 2012-2015 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 <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <wiringPi.h>
extern int wpMode ;
#ifndef TRUE
# define TRUE (1==1)
# define FALSE (1==2)
#endif
/*
* 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 ("+------+---------+--------+\n") ;
printf ("| Pin | Digital | Analog |\n") ;
printf ("+------+---------+--------+\n") ;
for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin)
printf ("| %4d | %4d | %4d |\n", pin, digitalRead (pin), analogRead (pin)) ;
printf ("+------+---------+--------+\n") ;
}
/*
* 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...
*********************************************************************************
*/
static char *alts [] =
{
"IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
} ;
static int physToWpi [64] =
{
-1, // 0
-1, -1, // 1, 2
8, -1,
9, -1,
7, 15,
-1, 16,
0, 1,
2, -1,
3, 4,
-1, 5,
12, -1,
13, 6,
14, 10,
-1, 11, // 25, 26
30, 31, // Actually I2C, but not used
21, -1,
22, 26,
23, -1,
24, 27,
25, 28,
-1, 29,
-1, -1,
-1, -1,
-1, -1,
-1, -1,
-1, -1,
17, 18,
19, 20,
-1, -1, -1, -1, -1, -1, -1, -1, -1
} ;
static char *physNames [64] =
{
NULL,
" 3.3v", "5v ",
" SDA.1", "5V ",
" SCL.1", "0v ",
"GPIO. 7", "TxD ",
" 0v", "RxD ",
"GPIO. 0", "GPIO. 1",
"GPIO. 2", "0v ",
"GPIO. 3", "GPIO. 4",
" 3.3v", "GPIO. 5",
" MOSI", "0v ",
" MISO", "GPIO. 6",
" SCLK", "CE0 ",
" 0v", "CE1 ",
" SDA.0", "SCL.0 ",
"GPIO.21", "0v ",
"GPIO.22", "GPIO.26",
"GPIO.23", "0v ",
"GPIO.24", "GPIO.27",
"GPIO.25", "GPIO.28",
" 0v", "GPIO.29",
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
"GPIO.17", "GPIO.18",
"GPIO.19", "GPIO.20",
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
} ;
/*
* readallPhys:
* Given a physical pin output the data on it and the next pin:
*| BCM | wPi | Name | Mode | Val| Physical |Val | Mode | Name | wPi | BCM |
*********************************************************************************
*/
static void readallPhys (int physPin)
{
int pin ;
if (physPinToGpio (physPin) == -1)
printf (" | | ") ;
else
printf (" | %3d | %3d", physPinToGpio (physPin), physToWpi [physPin]) ;
printf (" | %s", physNames [physPin]) ;
if (physToWpi [physPin] == -1)
printf (" | | ") ;
else
{
/**/ if (wpMode == WPI_MODE_GPIO)
pin = physPinToGpio (physPin) ;
else if (wpMode == WPI_MODE_PHYS)
pin = physPin ;
else
pin = physToWpi [physPin] ;
printf (" | %4s", alts [getAlt (pin)]) ;
printf (" | %d", digitalRead (pin)) ;
}
// Pin numbers:
printf (" | %2d", physPin) ;
++physPin ;
printf (" || %-2d", physPin) ;
// Same, reversed
if (physToWpi [physPin] == -1)
printf (" | | ") ;
else
{
/**/ if (wpMode == WPI_MODE_GPIO)
pin = physPinToGpio (physPin) ;
else if (wpMode == WPI_MODE_PHYS)
pin = physPin ;
else
pin = physToWpi [physPin] ;
printf (" | %d", digitalRead (pin)) ;
printf (" | %-4s", alts [getAlt (pin)]) ;
}
printf (" | %-5s", physNames [physPin]) ;
if (physToWpi [physPin] == -1)
printf (" | | ") ;
else
printf (" | %-3d | %-3d", physToWpi [physPin], physPinToGpio (physPin)) ;
printf (" |\n") ;
}
void cmReadall (void)
{
int pin ;
printf ("+-----+------+-------+ +-----+------+-------+\n") ;
printf ("| Pin | Mode | Value | | Pin | Mode | Value |\n") ;
printf ("+-----+------+-------+ +-----+------+-------+\n") ;
for (pin = 0 ; pin < 28 ; ++pin)
{
printf ("| %3d ", pin) ;
printf ("| %-4s ", alts [getAlt (pin)]) ;
printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ;
printf ("| ") ;
printf ("| %3d ", pin + 28) ;
printf ("| %-4s ", alts [getAlt (pin + 28)]) ;
printf ("| %s ", digitalRead (pin + 28) == HIGH ? "High" : "Low ") ;
printf ("|\n") ;
}
printf ("+-----+------+-------+ +-----+------+-------+\n") ;
}
/*
* abReadall:
* Read all the pins on the model A or B.
*********************************************************************************
*/
void abReadall (int model, int rev)
{
int pin ;
char *type ;
if (model == PI_MODEL_A)
type = " A" ;
else
if (rev == PI_VERSION_2)
type = "B2" ;
else
type = "B1" ;
printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ;
printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ;
printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
for (pin = 1 ; pin <= 26 ; pin += 2)
readallPhys (pin) ;
if (rev == PI_VERSION_2) // B version 2
{
printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
for (pin = 51 ; pin <= 54 ; pin += 2)
readallPhys (pin) ;
}
printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ;
printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ;
}
/*
* piPlusReadall:
* Read all the pins on the model A+ or the B+
*********************************************************************************
*/
static void plus2header (int model)
{
/**/ if (model == PI_MODEL_AP)
printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_BP)
printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_ZERO)
printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ;
else
printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ;
}
void piPlusReadall (int model)
{
int pin ;
plus2header (model) ;
printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ;
printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
for (pin = 1 ; pin <= 40 ; pin += 2)
readallPhys (pin) ;
printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ;
plus2header (model) ;
}
void doReadall (void)
{
int model, rev, mem, maker, overVolted ;
if (wiringPiNodes != NULL) // External readall
{
doReadallExternal () ;
return ;
}
piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
/**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B))
abReadall (model, rev) ;
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_ZERO))
piPlusReadall (model) ;
else if (model == PI_MODEL_CM)
cmReadall () ;
else
printf ("Oops - unable to determine board type... model: %d\n", model) ;
}

1
gpio/version.h Normal file
View File

@@ -0,0 +1 @@
#define VERSION "2.31"