@@ -0,0 +1,10 @@ | |||
Just a quick note to some people who've provided help, suggestions, | |||
bug-fixes, etc. along the way... | |||
Nick Lott: (And others) | |||
Hints about making it work with C++ | |||
Philipp Stefan Neininger: | |||
Minor bug in the Makefile to do with cross compiling | |||
@@ -39,7 +39,12 @@ SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c | |||
OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o | |||
all: test1 test2 speed lcd wfi piface gertboard nes softPwm | |||
BINS = test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm | |||
all: | |||
@cat README.TXT | |||
@echo " $(BINS)" | fmt | |||
@echo "" | |||
test1: test1.o | |||
@echo [link] | |||
@@ -77,7 +82,6 @@ softPwm: softPwm.o | |||
@echo [link] | |||
$(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread | |||
delayTest: delayTest.o | |||
@echo [link] | |||
$(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS) | |||
@@ -0,0 +1,14 @@ | |||
wiringPi Examples | |||
================= | |||
There are now too many examples to compile them all in a sensible time, | |||
and you probably don't want to compile or run them all anyway, so they | |||
have been separated out. | |||
To compile an individual example, just type | |||
make exampleName | |||
Where exampleName is one of: | |||
@@ -24,7 +24,7 @@ | |||
#DEBUG = -g -O0 | |||
DEBUG = -O3 | |||
DEBUG = -O2 | |||
CC = gcc | |||
INCLUDE = -I/usr/local/include | |||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||
@@ -32,42 +32,49 @@ CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||
LDFLAGS = -L/usr/local/lib | |||
LIBS = -lwiringPi | |||
# Should not alter anything below this line | |||
# May not need to alter anything below this line | |||
############################################################################### | |||
SRC = gpio.c | |||
OBJ = gpio.o | |||
OBJ = $(SRC:.c=.o) | |||
all: gpio | |||
gpio: gpio.o /usr/local/lib/libwiringPi.a | |||
@echo [LD] | |||
gpio: gpio.o | |||
@echo [Link] | |||
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) | |||
.c.o: | |||
@echo [CC] $< | |||
@echo [Compile] $< | |||
@$(CC) -c $(CFLAGS) $< -o $@ | |||
.PHONEY: clean | |||
clean: | |||
rm -f $(OBJ) gpio *~ core tags | |||
rm -f $(OBJ) gpio *~ core tags *.bak | |||
.PHONEY: tags | |||
tags: $(SRC) | |||
@echo [ctags] | |||
@ctags $(SRC) | |||
depend: | |||
makedepend -Y $(SRC) | |||
.PHONEY: install | |||
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 | |||
@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 | |||
.PHONEY: uninstall | |||
uninstall: | |||
@echo "[UnInstall]" | |||
rm -f /usr/local/bin/gpio | |||
rm -f /usr/local/man/man1/gpio.1 | |||
.PHONEY: depend | |||
depend: | |||
makedepend -Y $(SRC) | |||
# DO NOT DELETE |
@@ -1,4 +1,4 @@ | |||
.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" | |||
.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" | |||
.SH NAME | |||
gpio \- Command-line access to Raspberry Pi and PiFace GPIO | |||
@@ -17,6 +17,9 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO | |||
.B ... | |||
.PP | |||
.B gpio | |||
.B readall | |||
.PP | |||
.B gpio | |||
.B unexportall/exports | |||
.PP | |||
.B gpio | |||
@@ -48,9 +51,9 @@ channel value | |||
.SH DESCRIPTION | |||
.B GPIO | |||
is a swiss army knofe of a command line tool to allow the user easy | |||
is a swiss army knife of a command line tool to allow the user easy | |||
access to the GPIO pins on the Raspberry Pi and the SPI A/D and D/A | |||
convertors on the Gertboard. It's designed for simple testing and | |||
converters on the Gertboard. It's designed for simple testing and | |||
diagnostic purposes, but can be used in shell scripts for general if | |||
somewhat slow control of the GPIO pins. | |||
@@ -62,7 +65,7 @@ interface without needing to be run as root. | |||
.TP | |||
.B \-v | |||
Output the current version | |||
Output the current version including the board revision of the Raspberry Pi. | |||
.TP | |||
.B \-g | |||
@@ -73,20 +76,26 @@ Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. | |||
Use the PiFace interface board and its corresponding pin numbers. | |||
.TP | |||
.B read | |||
.B read <pin> | |||
Read the digital value of the given pin and print 0 or 1 to represent the | |||
respective logic levels. | |||
.TP | |||
.B write | |||
.B write <pin> <value> | |||
Write the given value (0 or 1) to the pin. | |||
.TP | |||
.B pwm | |||
.B readall | |||
Output a table of all GPIO pins values. The values represent the actual values read | |||
if the pin is in input mode, or the last value written if the pin is in output | |||
mode. | |||
.TP | |||
.B pwm <pin> <value> | |||
Write a PWM value (0-1023) to the given pin. | |||
.TP | |||
.B mode | |||
.B mode <pin> <mode> | |||
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. | |||
@@ -122,7 +131,7 @@ the direction to input and set the edge interrupt method to \fInone\fR, | |||
above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin | |||
numbering. | |||
Like the export commands abovem ownership is set to that of the | |||
Like the export commands above, ownership is set to that of the | |||
calling user, allowing subsequent access from user programs without | |||
requiring root/sudo. | |||
@@ -155,7 +164,7 @@ the associated /dev/ entries so that the current user has access to them. | |||
.B gbr | |||
channel | |||
This reads the analog to digital convertor on the Gertboard on the given | |||
This reads the analog to digital converter on the Gertboard on the given | |||
channel. The board jumpers need to be in-place to do this operation. | |||
.TP | |||
@@ -163,7 +172,7 @@ channel. The board jumpers need to be in-place to do this operation. | |||
channel value | |||
This writes the supplied value to the output channel on the Gertboards | |||
SPI digital to analogue convertor. | |||
SPI digital to analogue converter. | |||
The board jumpers need to be in-place to do this operation. | |||
@@ -171,26 +180,30 @@ The board jumpers need to be in-place to do this operation. | |||
.PP | |||
.TS | |||
r r l. | |||
WiringPi GPIO Function | |||
r r r l. | |||
WiringPi GPIO-r1 GPIO-r2 Function | |||
_ | |||
0 17 | |||
1 18 (PWM) | |||
2 21 | |||
3 22 | |||
4 23 | |||
5 24 | |||
6 25 | |||
7 4 | |||
8 0 SDA0 | |||
9 1 SCL0 | |||
10 8 SPI CE0 | |||
11 7 SPI CE1 | |||
12 10 SPI MOSI | |||
13 9 SPI MISO | |||
14 11 SPI SCLK | |||
15 14 TxD | |||
16 15 RxD | |||
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 | |||
.SH FILES | |||
@@ -234,10 +247,14 @@ Gordon Henderson | |||
.SH "REPORTING BUGS" | |||
Report bugs to <projects@drogon.net> | |||
Please report bugs to <projects@drogon.net> | |||
.SH COPYRIGHT | |||
Copyright (c) 2012 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. | |||
.SH TRADEMARKS AND ACKNOWLEDGEMENTS | |||
Raspberry Pi is a trademark of the Raspberry Pi Foundation. |
@@ -40,7 +40,7 @@ | |||
# define FALSE (1==2) | |||
#endif | |||
#define VERSION "1.2" | |||
#define VERSION "1.4" | |||
static int wpMode ; | |||
@@ -48,13 +48,16 @@ char *usage = "Usage: gpio -v\n" | |||
" gpio -h\n" | |||
" gpio [-g] <read/write/pwm/mode> ...\n" | |||
" gpio [-p] <read/write/mode> ...\n" | |||
" gpio export/edge/unexport/unexportall/exports ...\n" | |||
" gpio readall\n" | |||
" gpio unexportall/exports ...\n" | |||
" gpio export/edge/unexport ...\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 gbr <channel>\n" | |||
" gpio gbw <channel> <value>\n" ; | |||
" gpio gbw <channel> <value>" ; // No trailing newline needed here. | |||
/* | |||
@@ -171,6 +174,65 @@ static void doLoad (int argc, char *argv []) | |||
} | |||
/* | |||
* doReadall: | |||
* Read all the GPIO pins | |||
********************************************************************************* | |||
*/ | |||
static char *pinNames [] = | |||
{ | |||
"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", | |||
} ; | |||
static void doReadall (void) | |||
{ | |||
int pin ; | |||
printf ("+----------+------+--------+-------+\n") ; | |||
printf ("| wiringPi | GPIO | Name | Value |\n") ; | |||
printf ("+----------+------+--------+-------+\n") ; | |||
for (pin = 0 ; pin < NUM_PINS ; ++pin) | |||
printf ("| %6d | %3d | %s | %s |\n", | |||
pin, wpiPinToGpio (pin), | |||
pinNames [pin], | |||
digitalRead (pin) == HIGH ? "High" : "Low ") ; | |||
printf ("+----------+------+--------+-------+\n") ; | |||
if (piBoardRev () == 1) | |||
return ; | |||
for (pin = 17 ; pin <= 20 ; ++pin) | |||
printf ("| %6d | %3d | %s | %s |\n", | |||
pin, wpiPinToGpio (pin), | |||
pinNames [pin], | |||
digitalRead (pin) == HIGH ? "High" : "Low ") ; | |||
printf ("+----------+------+--------+-------+\n") ; | |||
} | |||
/* | |||
* doExports: | |||
@@ -687,8 +749,8 @@ void doPwm (int argc, char *argv []) | |||
/* | |||
* doPwmMode: doPwmRange: | |||
* Change the PWM mode and Range values | |||
* doPwmMode: doPwmRange: doPwmClock: | |||
* Change the PWM mode, range and clock divider values | |||
********************************************************************************* | |||
*/ | |||
@@ -718,6 +780,27 @@ static void doPwmRange (int argc, char *argv []) | |||
pwmSetRange (range) ; | |||
} | |||
static void doPwmClock (int argc, char *argv []) | |||
{ | |||
unsigned int clock ; | |||
if (argc != 3) | |||
{ | |||
fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ; | |||
exit (1) ; | |||
} | |||
clock = (unsigned int)strtoul (argv [2], NULL, 10) ; | |||
if ((clock < 1) || (clock > 4095)) | |||
{ | |||
fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ; | |||
exit (1) ; | |||
} | |||
pwmSetClock (clock) ; | |||
} | |||
/* | |||
* main: | |||
@@ -731,7 +814,7 @@ int main (int argc, char *argv []) | |||
if (argc == 1) | |||
{ | |||
fprintf (stderr, "%s: %s\n", argv [0], usage) ; | |||
fprintf (stderr, "%s\n", usage) ; | |||
return 1 ; | |||
} | |||
@@ -747,6 +830,8 @@ int main (int argc, char *argv []) | |||
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 ()) ; | |||
return 0 ; | |||
} | |||
@@ -785,9 +870,8 @@ int main (int argc, char *argv []) | |||
else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } | |||
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } | |||
// Check for drive or load commands: | |||
// Check for load command: | |||
if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } | |||
if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } | |||
// Gertboard commands | |||
@@ -839,21 +923,24 @@ int main (int argc, char *argv []) | |||
wpMode = WPI_MODE_PINS ; | |||
} | |||
// Check for PWM operations | |||
// Check for PWM or Pad Drive operations | |||
if (wpMode != WPI_MODE_PIFACE) | |||
{ | |||
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], "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 ; } | |||
} | |||
// Check for wiring commands | |||
/**/ 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], "mode" ) == 0) doMode (argc, argv) ; | |||
/**/ 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], "pwm" ) == 0) doPwm (argc, argv) ; | |||
else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; | |||
else | |||
{ | |||
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | |||
@@ -1,4 +1,25 @@ | |||
#!/bin/bash | |||
# | |||
# test.sh: | |||
# Simple test: Assumes LEDs on Pins 0-7 and lights them | |||
# in-turn. | |||
################################################################################# | |||
# 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/>. | |||
################################################################################# | |||
# Simple test - assumes LEDs on Pins 0-7. | |||
@@ -21,64 +21,93 @@ | |||
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | |||
################################################################################# | |||
DYN_VERS_MAJ=1 | |||
DYN_VERS_MIN=0 | |||
TARGET=libwiringPi.a | |||
STATIC=libwiringPi.a | |||
DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN) | |||
#DEBUG = -g -O0 | |||
DEBUG = -O3 | |||
DEBUG = -O2 | |||
CC = gcc | |||
INCLUDE = -I. | |||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC | |||
LIBS = | |||
# Should not alter anything below this line | |||
############################################################################### | |||
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c lcd.c piHiPri.c piThread.c | |||
SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ | |||
gertboard.c \ | |||
piNes.c \ | |||
lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c | |||
OBJ = wiringPi.o wiringPiFace.o wiringSerial.o wiringShift.o lcd.o piHiPri.o piThread.o | |||
OBJ = $(SRC:.c=.o) | |||
all: $(TARGET) | |||
#all: $(STATIC) $(DYNAMIC) | |||
all: $(DYNAMIC) | |||
$(TARGET): $(OBJ) | |||
@echo [AR] $(OBJ) | |||
@ar rcs $(TARGET) $(OBJ) | |||
@ranlib $(TARGET) | |||
@size $(TARGET) | |||
$(STATIC): $(OBJ) | |||
@echo [Link (Static)] | |||
@ar rcs $(STATIC) $(OBJ) | |||
@ranlib $(STATIC) | |||
@size $(STATIC) | |||
$(DYNAMIC): $(OBJ) | |||
@echo [Link] | |||
@$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) | |||
.c.o: | |||
@echo [CC] $< | |||
@echo [Compile] $< | |||
@$(CC) -c $(CFLAGS) $< -o $@ | |||
.PHONEY: clean | |||
clean: | |||
rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak | |||
rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.* | |||
.PHONEY: tags | |||
tags: $(SRC) | |||
@echo [ctags] | |||
@ctags $(SRC) | |||
depend: | |||
makedepend -Y $(SRC) | |||
.PHONEY: install | |||
install: $(TARGET) | |||
@echo [install] | |||
install -m 0755 -d /usr/local/lib | |||
install -m 0755 -d /usr/local/include | |||
install -m 0644 wiringPi.h /usr/local/include | |||
install -m 0644 wiringSerial.h /usr/local/include | |||
install -m 0644 wiringShift.h /usr/local/include | |||
install -m 0644 lcd.h /usr/local/include | |||
install -m 0644 libwiringPi.a /usr/local/lib | |||
@echo "[Install]" | |||
@install -m 0755 -d /usr/local/lib | |||
@install -m 0755 -d /usr/local/include | |||
@install -m 0644 wiringPi.h /usr/local/include | |||
@install -m 0644 wiringSerial.h /usr/local/include | |||
@install -m 0644 wiringShift.h /usr/local/include | |||
@install -m 0644 gertboard.h /usr/local/include | |||
@install -m 0644 piNes.h /usr/local/include | |||
@install -m 0644 softPwm.h /usr/local/include | |||
@install -m 0644 lcd.h /usr/local/include | |||
@install -m 0644 wiringPiSPI.h /usr/local/include | |||
# @install -m 0644 libwiringPi.a /usr/local/lib | |||
@install -m 0755 libwiringPi.so.1.0 /usr/local/lib | |||
@ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so | |||
@ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so.1 | |||
@ldconfig | |||
.PHONEY: uninstall | |||
uninstall: | |||
@echo [uninstall] | |||
rm -f /usr/local/include/lcd.h | |||
rm -f /usr/local/include/wiringShift.h | |||
rm -f /usr/local/include/wiringPi.h | |||
rm -f /usr/local/lib/libwiringPi.a | |||
@echo "[UnInstall]" | |||
@rm -f /usr/local/include/wiringPi.h | |||
@rm -f /usr/local/include/wiringSerial.h | |||
@rm -f /usr/local/include/wiringShift.h | |||
@rm -f /usr/local/include/gertboard.h | |||
@rm -f /usr/local/include/piNes.h | |||
@rm -f /usr/local/include/softPwm.h | |||
@rm -f /usr/local/include/lcd.h | |||
@rm -f /usr/local/include/wiringPiSPI.h | |||
@rm -f /usr/local/lib/libwiringPi.* | |||
@ldconfig | |||
.PHONEY: depend | |||
depend: | |||
makedepend -Y $(SRC) | |||
# DO NOT DELETE | |||
@@ -86,6 +115,10 @@ wiringPi.o: wiringPi.h | |||
wiringPiFace.o: wiringPi.h | |||
wiringSerial.o: wiringSerial.h | |||
wiringShift.o: wiringPi.h wiringShift.h | |||
gertboard.o: wiringPiSPI.h gertboard.h | |||
piNes.o: wiringPi.h piNes.h | |||
lcd.o: wiringPi.h lcd.h | |||
piHiPri.o: wiringPi.h | |||
piThread.o: wiringPi.h | |||
softPwm.o: wiringPi.h softPwm.h | |||
wiringPiSPI.o: wiringPiSPI.h |
@@ -1,6 +1,8 @@ | |||
WiringPi: An implementation of most of the Arduino Wiring | |||
functions for the Raspberry Pi | |||
functions for the Raspberry Pi, | |||
along with many more features and libraries to support | |||
hardware, etc. on the Raspberry Pi | |||
Full details at: | |||
https://projects.drogon.net/raspberry-pi/wiringpi/ | |||
@@ -75,7 +75,10 @@ struct lcdDataStruct *lcds [MAX_LCDS] ; | |||
static void strobe (struct lcdDataStruct *lcd) | |||
{ | |||
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (1) ; | |||
// Note timing changes for new version of delayMicroseconds () | |||
digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ; | |||
digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; | |||
} | |||
@@ -26,6 +26,10 @@ | |||
#define MAX_LCDS 8 | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
extern void lcdHome (int fd) ; | |||
extern void lcdClear (int fd) ; | |||
extern void lcdPosition (int fd, int x, int y) ; | |||
@@ -33,10 +37,6 @@ extern void lcdPutchar (int fd, uint8_t data) ; | |||
extern void lcdPuts (int fd, char *string) ; | |||
extern void lcdPrintf (int fd, char *message, ...) ; | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
extern int lcdInit (int rows, int cols, int bits, int rs, int strb, | |||
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; | |||
@@ -2,6 +2,7 @@ | |||
* wiringPi: | |||
* Arduino compatable (ish) Wiring library for the Raspberry Pi | |||
* Copyright (c) 2012 Gordon Henderson | |||
* Additional code for pwmSetClock by Chris Hall <chris@kchall.plus.com> | |||
* | |||
* Thanks to code samples from Gert Jan van Loo and the | |||
* BCM2835 ARM Peripherals manual, however it's missing | |||
@@ -56,6 +57,8 @@ | |||
#include <stdio.h> | |||
#include <stdint.h> | |||
#include <stdlib.h> | |||
#include <ctype.h> | |||
#include <poll.h> | |||
#include <unistd.h> | |||
#include <errno.h> | |||
@@ -81,6 +84,7 @@ int (*waitForInterrupt) (int pin, int mS) ; | |||
void (*delayMicroseconds) (unsigned int howLong) ; | |||
void (*pwmSetMode) (int mode) ; | |||
void (*pwmSetRange) (unsigned int range) ; | |||
void (*pwmSetClock) (int divisor) ; | |||
#ifndef TRUE | |||
@@ -166,9 +170,12 @@ static volatile uint32_t *pwm ; | |||
static volatile uint32_t *clk ; | |||
static volatile uint32_t *pads ; | |||
static volatile uint32_t *timer ; | |||
static volatile uint32_t *timerIrqRaw ; | |||
// Debugging | |||
static int wiringPiDebug = FALSE ; | |||
// The BCM2835 has 54 GPIO pins. | |||
// BCM2835 data sheet, Page 90 onwards. | |||
// There are 6 control registers, each control the functions of a block | |||
@@ -198,8 +205,11 @@ static int sysFds [64] ; | |||
// pinToGpio: | |||
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin | |||
// Cope for 2 different board revieions here | |||
static int *pinToGpio ; | |||
static int pinToGpio [64] = | |||
static int pinToGpioR1 [64] = | |||
{ | |||
17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 | |||
0, 1, // I2C - SDA0, SCL0 | |||
@@ -209,11 +219,28 @@ static int pinToGpio [64] = | |||
// Padding: | |||
-1, -1, -1,-1,-1,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 | |||
} ; | |||
static int pinToGpioR2 [64] = | |||
{ | |||
17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 | |||
2, 3, // I2C - SDA0, SCL0 wpi 8 - 9 | |||
8, 7, // SPI - CE1, CE0 wpi 10 - 11 | |||
10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14 | |||
14, 15, // UART - Tx, Rx wpi 15 - 16 | |||
28, 29, 30, 31, // New GPIOs 8 though 11 wpi 17 - 20 | |||
// Padding: | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 | |||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 | |||
} ; | |||
// gpioToGPFSEL: | |||
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5) | |||
@@ -227,6 +254,7 @@ static uint8_t gpioToGPFSEL [] = | |||
5,5,5,5,5,5,5,5,5,5, | |||
} ; | |||
// gpioToShift | |||
// Define the shift up for the 3 bits per pin in each GPFSEL port | |||
@@ -239,6 +267,7 @@ static uint8_t gpioToShift [] = | |||
0,3,6,9,12,15,18,21,24,27, | |||
} ; | |||
// gpioToGPSET: | |||
// (Word) offset to the GPIO Set registers for each GPIO pin | |||
@@ -248,6 +277,7 @@ static uint8_t gpioToGPSET [] = | |||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, | |||
} ; | |||
// gpioToGPCLR: | |||
// (Word) offset to the GPIO Clear registers for each GPIO pin | |||
@@ -257,6 +287,7 @@ static uint8_t gpioToGPCLR [] = | |||
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, | |||
} ; | |||
// gpioToGPLEV: | |||
// (Word) offset to the GPIO Input level registers for each GPIO pin | |||
@@ -266,6 +297,7 @@ static uint8_t gpioToGPLEV [] = | |||
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, | |||
} ; | |||
#ifdef notYetReady | |||
// gpioToEDS | |||
// (Word) offset to the Event Detect Status | |||
@@ -295,6 +327,7 @@ static uint8_t gpioToFEN [] = | |||
} ; | |||
#endif | |||
// gpioToPUDCLK | |||
// (Word) offset to the Pull Up Down Clock regsiter | |||
@@ -306,6 +339,7 @@ static uint8_t gpioToPUDCLK [] = | |||
39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, | |||
} ; | |||
// gpioToPwmALT | |||
// the ALT value to put a GPIO pin into PWM mode | |||
@@ -339,7 +373,122 @@ static uint8_t gpioToPwmPort [] = | |||
static unsigned long long epoch ; | |||
////////////////////////////////////////////////////////////////////////////////// | |||
/* | |||
* Functions | |||
********************************************************************************* | |||
*/ | |||
/* | |||
* wpiPinToGpio: | |||
* Translate a wiringPi Pin number to native GPIO pin number. | |||
* (We don't use this here, prefering to just do the lookup directly, | |||
* but it's been requested!) | |||
********************************************************************************* | |||
*/ | |||
int wpiPinToGpio (int wpiPin) | |||
{ | |||
return pinToGpio [wpiPin & 63] ; | |||
} | |||
/* | |||
* piBoardRev: | |||
* Return a number representing the hardware revision of the board. | |||
* Revision is currently 1 or 2. -1 is returned on error. | |||
* | |||
* Much confusion here )-: | |||
* Seems there ar esome boards with 0000 in them (mistake in manufacture) | |||
* and some board with 0005 in them (another mistake in manufacture). | |||
* So the distinction between boards that I can see is: | |||
* 0000 - Error | |||
* 0001 - Not used | |||
* 0002 - Rev 1 | |||
* 0003 - Rev 1 | |||
* 0004 - Rev 2 | |||
* 0005 - Rev 2 | |||
* 0006 - Rev 2 | |||
* 000f - Rev 2 + 512MB | |||
* | |||
* A small thorn is the olde style overvolting - that will add in | |||
* 1000000 | |||
* | |||
********************************************************************************* | |||
*/ | |||
int piBoardRev (void) | |||
{ | |||
FILE *cpuFd ; | |||
char line [120] ; | |||
char *c, lastChar ; | |||
static int boardRev = -1 ; | |||
// No point checking twice... | |||
if (boardRev != -1) | |||
return boardRev ; | |||
if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) | |||
return -1 ; | |||
while (fgets (line, 120, cpuFd) != NULL) | |||
if (strncmp (line, "Revision", 8) == 0) | |||
break ; | |||
fclose (cpuFd) ; | |||
if (line == NULL) | |||
{ | |||
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; | |||
fprintf (stderr, " (No \"Revision\" line)\n") ; | |||
errno = 0 ; | |||
return -1 ; | |||
} | |||
for (c = line ; *c ; ++c) | |||
if (isdigit (*c)) | |||
break ; | |||
if (!isdigit (*c)) | |||
{ | |||
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; | |||
fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ; | |||
errno = 0 ; | |||
return -1 ; | |||
} | |||
// If you have overvolted the Pi, then it appears that the revision | |||
// has 100000 added to it! | |||
if (wiringPiDebug) | |||
if (strlen (c) != 4) | |||
printf ("piboardRev: This Pi has/is overvolted!\n") ; | |||
lastChar = c [strlen (c) - 2] ; | |||
/**/ if ((lastChar == '2') || (lastChar == '3')) | |||
boardRev = 1 ; | |||
else | |||
boardRev = 2 ; | |||
#ifdef DO_WE_CARE_ABOUT_THIS_NOW | |||
else | |||
{ | |||
fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ; | |||
fprintf (stderr, " -> You may want to check:\n") ; | |||
fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; | |||
fprintf (stderr, " -> Assuming a Rev 1 board\n") ; | |||
boardRev = 1 ; | |||
} | |||
#endif | |||
if (wiringPiDebug) | |||
printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ; | |||
return boardRev ; | |||
} | |||
/* | |||
@@ -350,7 +499,6 @@ static unsigned long long epoch ; | |||
void pinModeGpio (int pin, int mode) | |||
{ | |||
static int pwmRunning = FALSE ; | |||
int fSel, shift, alt ; | |||
pin &= 63 ; | |||
@@ -371,38 +519,28 @@ void pinModeGpio (int pin, int mode) | |||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | |||
// We didn't initialise the PWM hardware at setup time - because it's possible that | |||
// something else is using the PWM - e.g. the Audio systems! So if we use PWM | |||
// here, then we're assuming that nothing else is, otherwise things are going | |||
// to sound a bit funny... | |||
if (!pwmRunning) | |||
{ | |||
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM | |||
delayMicroseconds (10) ; | |||
// Gert/Doms Values | |||
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/32 = 600KHz) | |||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable | |||
delayMicroseconds (10) ; | |||
// Page 107 of the BCM Peripherals manual talks about the GPIO clocks, | |||
// but I'm assuming (hoping!) that this applies to other clocks too. | |||
*(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ; | |||
*(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ; | |||
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM | |||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock | |||
delayMicroseconds (110) ; // See comments in pwmSetClockWPi | |||
// Enable PWMs | |||
(void)*(pwm + PWM_CONTROL) ; | |||
while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY | |||
delayMicroseconds (1) ; | |||
*(pwm + PWM0_DATA) = 512 ; | |||
*(pwm + PWM1_DATA) = 512 ; | |||
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz) | |||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk | |||
// Balanced mode (default) | |||
// Default range regsiter of 1024 | |||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; | |||
*(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ; | |||
*(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ; | |||
pwmRunning = TRUE ; | |||
} | |||
// Enable PWMs in balanced mode (default) | |||
*(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; | |||
} | |||
// When we change mode of any pin, we remove the pull up/downs | |||
@@ -459,6 +597,55 @@ void pwmSetRangeSys (unsigned int range) | |||
return ; | |||
} | |||
/* | |||
* pwmSetClockWPi: | |||
* Set/Change the PWM clock. Originally my code, but changed | |||
* (for the better!) by Chris Hall, <chris@kchall.plus.com> | |||
* after further study of the manual and testing with a 'scope | |||
********************************************************************************* | |||
*/ | |||
void pwmSetClockWPi (int divisor) | |||
{ | |||
unsigned int pwm_control ; | |||
divisor &= 4095 ; | |||
if (wiringPiDebug) | |||
printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; | |||
pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL | |||
// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY | |||
// stays high. | |||
*(pwm + PWM_CONTROL) = 0 ; // Stop PWM | |||
// Stop PWM clock before changing divisor. The delay after this does need to | |||
// this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY | |||
// flag is not working properly in balanced mode. Without the delay when DIV is | |||
// adjusted the clock sometimes switches to very slow, once slow further DIV | |||
// adjustments do nothing and it's difficult to get out of this mode. | |||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock | |||
delayMicroseconds (110) ; // prevents clock going sloooow | |||
while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY | |||
delayMicroseconds (1) ; | |||
*(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ; | |||
*(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock | |||
*(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL | |||
if (wiringPiDebug) | |||
printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; | |||
} | |||
void pwmSetClockSys (int divisor) | |||
{ | |||
return ; | |||
} | |||
#ifdef notYetReady | |||
/* | |||
@@ -518,7 +705,7 @@ void digitalWriteSys (int pin, int value) | |||
/* | |||
* pwnWrite: | |||
* pwmWrite: | |||
* Set an output PWM value | |||
********************************************************************************* | |||
*/ | |||
@@ -699,8 +886,6 @@ int waitForInterruptGpio (int pin, int mS) | |||
} | |||
/* | |||
* delay: | |||
* Wait for some number of milli seconds | |||
@@ -800,9 +985,16 @@ unsigned int millis (void) | |||
int wiringPiSetup (void) | |||
{ | |||
int fd ; | |||
int boardRev ; | |||
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; | |||
struct timeval tv ; | |||
if (getenv ("WIRINGPI_DEBUG") != NULL) | |||
wiringPiDebug = TRUE ; | |||
if (wiringPiDebug) | |||
printf ("wiringPi: wiringPiSetup called\n") ; | |||
pinMode = pinModeWPi ; | |||
pullUpDnControl = pullUpDnControlWPi ; | |||
digitalWrite = digitalWriteWPi ; | |||
@@ -813,7 +1005,16 @@ int wiringPiSetup (void) | |||
delayMicroseconds = delayMicrosecondsWPi ; | |||
pwmSetMode = pwmSetModeWPi ; | |||
pwmSetRange = pwmSetRangeWPi ; | |||
pwmSetClock = pwmSetClockWPi ; | |||
if ((boardRev = piBoardRev ()) < 0) | |||
return -1 ; | |||
if (boardRev == 1) | |||
pinToGpio = pinToGpioR1 ; | |||
else | |||
pinToGpio = pinToGpioR2 ; | |||
// Open the master /dev/memory device | |||
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) | |||
@@ -954,9 +1155,12 @@ int wiringPiSetup (void) | |||
int wiringPiSetupGpio (void) | |||
{ | |||
int x = wiringPiSetup () ; | |||
int x ; | |||
if (wiringPiDebug) | |||
printf ("wiringPi: wiringPiSetupGpio called\n") ; | |||
if (x != 0) | |||
if ((x = wiringPiSetup ()) < 0) | |||
return x ; | |||
pinMode = pinModeGpio ; | |||
@@ -969,6 +1173,7 @@ int wiringPiSetupGpio (void) | |||
delayMicroseconds = delayMicrosecondsWPi ; // Same | |||
pwmSetMode = pwmSetModeWPi ; | |||
pwmSetRange = pwmSetRangeWPi ; | |||
pwmSetClock = pwmSetClockWPi ; | |||
return 0 ; | |||
} | |||
@@ -989,6 +1194,9 @@ int wiringPiSetupSys (void) | |||
struct timeval tv ; | |||
char fName [128] ; | |||
if (wiringPiDebug) | |||
printf ("wiringPi: wiringPiSetupSys called\n") ; | |||
pinMode = pinModeSys ; | |||
pullUpDnControl = pullUpDnControlSys ; | |||
digitalWrite = digitalWriteSys ; | |||
@@ -999,6 +1207,7 @@ int wiringPiSetupSys (void) | |||
delayMicroseconds = delayMicrosecondsSys ; | |||
pwmSetMode = pwmSetModeSys ; | |||
pwmSetRange = pwmSetRangeSys ; | |||
pwmSetClock = pwmSetClockSys ; | |||
// Open and scan the directory, looking for exported GPIOs, and pre-open | |||
@@ -62,6 +62,9 @@ extern int wiringPiSetupSys (void) ; | |||
extern int wiringPiSetupGpio (void) ; | |||
extern int wiringPiSetupPiFace (void) ; | |||
extern int piBoardRev (void) ; | |||
extern int wpiPinToGpio (int wpiPin) ; | |||
extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only | |||
extern void (*pinMode) (int pin, int mode) ; | |||
@@ -73,6 +76,7 @@ extern int (*digitalRead) (int pin) ; | |||
extern void (*delayMicroseconds) (unsigned int howLong) ; | |||
extern void (*pwmSetMode) (int mode) ; | |||
extern void (*pwmSetRange) (unsigned int range) ; | |||
extern void (*pwmSetClock) (int divisor) ; | |||
// Interrupts | |||