@@ -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 | 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 | test1: test1.o | ||||
@echo [link] | @echo [link] | ||||
@@ -77,7 +82,6 @@ softPwm: softPwm.o | |||||
@echo [link] | @echo [link] | ||||
$(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread | $(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread | ||||
delayTest: delayTest.o | delayTest: delayTest.o | ||||
@echo [link] | @echo [link] | ||||
$(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS) | $(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 = -g -O0 | ||||
DEBUG = -O3 | |||||
DEBUG = -O2 | |||||
CC = gcc | CC = gcc | ||||
INCLUDE = -I/usr/local/include | INCLUDE = -I/usr/local/include | ||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | ||||
@@ -32,42 +32,49 @@ CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||||
LDFLAGS = -L/usr/local/lib | LDFLAGS = -L/usr/local/lib | ||||
LIBS = -lwiringPi | LIBS = -lwiringPi | ||||
# Should not alter anything below this line | |||||
# May not need to alter anything below this line | |||||
############################################################################### | ############################################################################### | ||||
SRC = gpio.c | SRC = gpio.c | ||||
OBJ = gpio.o | |||||
OBJ = $(SRC:.c=.o) | |||||
all: gpio | all: gpio | ||||
gpio: gpio.o /usr/local/lib/libwiringPi.a | |||||
@echo [LD] | |||||
gpio: gpio.o | |||||
@echo [Link] | |||||
@$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) | @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) | ||||
.c.o: | .c.o: | ||||
@echo [CC] $< | |||||
@echo [Compile] $< | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | @$(CC) -c $(CFLAGS) $< -o $@ | ||||
.PHONEY: clean | |||||
clean: | clean: | ||||
rm -f $(OBJ) gpio *~ core tags | |||||
rm -f $(OBJ) gpio *~ core tags *.bak | |||||
.PHONEY: tags | |||||
tags: $(SRC) | tags: $(SRC) | ||||
@echo [ctags] | @echo [ctags] | ||||
@ctags $(SRC) | @ctags $(SRC) | ||||
depend: | |||||
makedepend -Y $(SRC) | |||||
.PHONEY: install | |||||
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: | uninstall: | ||||
@echo "[UnInstall]" | |||||
rm -f /usr/local/bin/gpio | rm -f /usr/local/bin/gpio | ||||
rm -f /usr/local/man/man1/gpio.1 | rm -f /usr/local/man/man1/gpio.1 | ||||
.PHONEY: depend | |||||
depend: | |||||
makedepend -Y $(SRC) | |||||
# DO NOT DELETE | # 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 | .SH NAME | ||||
gpio \- Command-line access to Raspberry Pi and PiFace GPIO | 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 ... | .B ... | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B readall | |||||
.PP | |||||
.B gpio | |||||
.B unexportall/exports | .B unexportall/exports | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
@@ -48,9 +51,9 @@ channel value | |||||
.SH DESCRIPTION | .SH DESCRIPTION | ||||
.B GPIO | .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 | 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 | diagnostic purposes, but can be used in shell scripts for general if | ||||
somewhat slow control of the GPIO pins. | somewhat slow control of the GPIO pins. | ||||
@@ -62,7 +65,7 @@ interface without needing to be run as root. | |||||
.TP | .TP | ||||
.B \-v | .B \-v | ||||
Output the current version | |||||
Output the current version including the board revision of the Raspberry Pi. | |||||
.TP | .TP | ||||
.B \-g | .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. | Use the PiFace interface board and its corresponding pin numbers. | ||||
.TP | .TP | ||||
.B read | |||||
.B read <pin> | |||||
Read the digital value of the given pin and print 0 or 1 to represent the | Read the digital value of the given pin and print 0 or 1 to represent the | ||||
respective logic levels. | respective logic levels. | ||||
.TP | .TP | ||||
.B write | |||||
.B write <pin> <value> | |||||
Write the given value (0 or 1) to the pin. | Write the given value (0 or 1) to the pin. | ||||
.TP | .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. | Write a PWM value (0-1023) to the given pin. | ||||
.TP | .TP | ||||
.B mode | |||||
.B mode <pin> <mode> | |||||
Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also | 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 | use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal | ||||
pull-up, pull-down or tristate (off) controls. | 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 | above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin | ||||
numbering. | 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 | calling user, allowing subsequent access from user programs without | ||||
requiring root/sudo. | requiring root/sudo. | ||||
@@ -155,7 +164,7 @@ the associated /dev/ entries so that the current user has access to them. | |||||
.B gbr | .B gbr | ||||
channel | 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. | channel. The board jumpers need to be in-place to do this operation. | ||||
.TP | .TP | ||||
@@ -163,7 +172,7 @@ channel. The board jumpers need to be in-place to do this operation. | |||||
channel value | channel value | ||||
This writes the supplied value to the output channel on the Gertboards | 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. | 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 | .PP | ||||
.TS | .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 | .TE | ||||
.SH FILES | .SH FILES | ||||
@@ -234,10 +247,14 @@ Gordon Henderson | |||||
.SH "REPORTING BUGS" | .SH "REPORTING BUGS" | ||||
Report bugs to <projects@drogon.net> | |||||
Please report bugs to <projects@drogon.net> | |||||
.SH COPYRIGHT | .SH COPYRIGHT | ||||
Copyright (c) 2012 Gordon Henderson | Copyright (c) 2012 Gordon Henderson | ||||
This is free software; see the source for copying conditions. There is NO | This is free software; see the source for copying conditions. There is NO | ||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 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) | # define FALSE (1==2) | ||||
#endif | #endif | ||||
#define VERSION "1.2" | |||||
#define VERSION "1.4" | |||||
static int wpMode ; | static int wpMode ; | ||||
@@ -48,13 +48,16 @@ char *usage = "Usage: gpio -v\n" | |||||
" gpio -h\n" | " gpio -h\n" | ||||
" gpio [-g] <read/write/pwm/mode> ...\n" | " gpio [-g] <read/write/pwm/mode> ...\n" | ||||
" gpio [-p] <read/write/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 drive <group> <value>\n" | ||||
" gpio pwm-bal/pwm-ms \n" | " gpio pwm-bal/pwm-ms \n" | ||||
" gpio pwmr <range> \n" | " gpio pwmr <range> \n" | ||||
" gpio pwmc <divider> \n" | |||||
" gpio load spi/i2c\n" | " gpio load spi/i2c\n" | ||||
" gpio gbr <channel>\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: | * 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) ; | 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: | * main: | ||||
@@ -731,7 +814,7 @@ int main (int argc, char *argv []) | |||||
if (argc == 1) | if (argc == 1) | ||||
{ | { | ||||
fprintf (stderr, "%s: %s\n", argv [0], usage) ; | |||||
fprintf (stderr, "%s\n", usage) ; | |||||
return 1 ; | return 1 ; | ||||
} | } | ||||
@@ -747,6 +830,8 @@ int main (int argc, char *argv []) | |||||
printf ("Copyright (c) 2012 Gordon Henderson\n") ; | printf ("Copyright (c) 2012 Gordon Henderson\n") ; | ||||
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; | printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; | ||||
printf ("For details type: %s -warranty\n", argv [0]) ; | printf ("For details type: %s -warranty\n", argv [0]) ; | ||||
printf ("\n") ; | |||||
printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ; | |||||
return 0 ; | 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], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } | ||||
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (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 ; } | if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } | ||||
// Gertboard commands | // Gertboard commands | ||||
@@ -839,21 +923,24 @@ int main (int argc, char *argv []) | |||||
wpMode = WPI_MODE_PINS ; | wpMode = WPI_MODE_PINS ; | ||||
} | } | ||||
// Check for PWM operations | |||||
// Check for PWM or Pad Drive operations | |||||
if (wpMode != WPI_MODE_PIFACE) | 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 | // 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 | else | ||||
{ | { | ||||
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | ||||
@@ -1,4 +1,25 @@ | |||||
#!/bin/bash | #!/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. | # Simple test - assumes LEDs on Pins 0-7. | ||||
@@ -21,64 +21,93 @@ | |||||
# along with wiringPi. If not, see <http://www.gnu.org/licenses/>. | # 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 = -g -O0 | ||||
DEBUG = -O3 | |||||
DEBUG = -O2 | |||||
CC = gcc | CC = gcc | ||||
INCLUDE = -I. | INCLUDE = -I. | ||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe | |||||
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC | |||||
LIBS = | LIBS = | ||||
# Should not alter anything below this line | # 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: | .c.o: | ||||
@echo [CC] $< | |||||
@echo [Compile] $< | |||||
@$(CC) -c $(CFLAGS) $< -o $@ | @$(CC) -c $(CFLAGS) $< -o $@ | ||||
.PHONEY: clean | |||||
clean: | clean: | ||||
rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak | |||||
rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.* | |||||
.PHONEY: tags | |||||
tags: $(SRC) | tags: $(SRC) | ||||
@echo [ctags] | @echo [ctags] | ||||
@ctags $(SRC) | @ctags $(SRC) | ||||
depend: | |||||
makedepend -Y $(SRC) | |||||
.PHONEY: install | |||||
install: $(TARGET) | 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: | 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 | # DO NOT DELETE | ||||
@@ -86,6 +115,10 @@ wiringPi.o: wiringPi.h | |||||
wiringPiFace.o: wiringPi.h | wiringPiFace.o: wiringPi.h | ||||
wiringSerial.o: wiringSerial.h | wiringSerial.o: wiringSerial.h | ||||
wiringShift.o: wiringPi.h wiringShift.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 | lcd.o: wiringPi.h lcd.h | ||||
piHiPri.o: wiringPi.h | piHiPri.o: wiringPi.h | ||||
piThread.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 | 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: | Full details at: | ||||
https://projects.drogon.net/raspberry-pi/wiringpi/ | https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -75,7 +75,10 @@ struct lcdDataStruct *lcds [MAX_LCDS] ; | |||||
static void strobe (struct lcdDataStruct *lcd) | 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) ; | digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; | ||||
} | } | ||||
@@ -26,6 +26,10 @@ | |||||
#define MAX_LCDS 8 | #define MAX_LCDS 8 | ||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
extern void lcdHome (int fd) ; | extern void lcdHome (int fd) ; | ||||
extern void lcdClear (int fd) ; | extern void lcdClear (int fd) ; | ||||
extern void lcdPosition (int fd, int x, int y) ; | 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 lcdPuts (int fd, char *string) ; | ||||
extern void lcdPrintf (int fd, char *message, ...) ; | 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, | 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) ; | int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; | ||||
@@ -2,6 +2,7 @@ | |||||
* wiringPi: | * wiringPi: | ||||
* Arduino compatable (ish) Wiring library for the Raspberry Pi | * Arduino compatable (ish) Wiring library for the Raspberry Pi | ||||
* Copyright (c) 2012 Gordon Henderson | * 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 | * Thanks to code samples from Gert Jan van Loo and the | ||||
* BCM2835 ARM Peripherals manual, however it's missing | * BCM2835 ARM Peripherals manual, however it's missing | ||||
@@ -56,6 +57,8 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | |||||
#include <ctype.h> | |||||
#include <poll.h> | #include <poll.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
@@ -81,6 +84,7 @@ int (*waitForInterrupt) (int pin, int mS) ; | |||||
void (*delayMicroseconds) (unsigned int howLong) ; | void (*delayMicroseconds) (unsigned int howLong) ; | ||||
void (*pwmSetMode) (int mode) ; | void (*pwmSetMode) (int mode) ; | ||||
void (*pwmSetRange) (unsigned int range) ; | void (*pwmSetRange) (unsigned int range) ; | ||||
void (*pwmSetClock) (int divisor) ; | |||||
#ifndef TRUE | #ifndef TRUE | ||||
@@ -166,9 +170,12 @@ static volatile uint32_t *pwm ; | |||||
static volatile uint32_t *clk ; | static volatile uint32_t *clk ; | ||||
static volatile uint32_t *pads ; | static volatile uint32_t *pads ; | ||||
static volatile uint32_t *timer ; | static volatile uint32_t *timer ; | ||||
static volatile uint32_t *timerIrqRaw ; | static volatile uint32_t *timerIrqRaw ; | ||||
// Debugging | |||||
static int wiringPiDebug = FALSE ; | |||||
// The BCM2835 has 54 GPIO pins. | // The BCM2835 has 54 GPIO pins. | ||||
// BCM2835 data sheet, Page 90 onwards. | // BCM2835 data sheet, Page 90 onwards. | ||||
// There are 6 control registers, each control the functions of a block | // There are 6 control registers, each control the functions of a block | ||||
@@ -198,8 +205,11 @@ static int sysFds [64] ; | |||||
// pinToGpio: | // pinToGpio: | ||||
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin | // 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 | 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 | ||||
0, 1, // I2C - SDA0, SCL0 | 0, 1, // I2C - SDA0, SCL0 | ||||
@@ -209,11 +219,28 @@ static int pinToGpio [64] = | |||||
// Padding: | // 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, // ... 47 | ||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 | ||||
} ; | } ; | ||||
// gpioToGPFSEL: | // gpioToGPFSEL: | ||||
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5) | // 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, | 5,5,5,5,5,5,5,5,5,5, | ||||
} ; | } ; | ||||
// gpioToShift | // gpioToShift | ||||
// Define the shift up for the 3 bits per pin in each GPFSEL port | // 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, | 0,3,6,9,12,15,18,21,24,27, | ||||
} ; | } ; | ||||
// gpioToGPSET: | // gpioToGPSET: | ||||
// (Word) offset to the GPIO Set registers for each GPIO pin | // (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, | 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: | // gpioToGPCLR: | ||||
// (Word) offset to the GPIO Clear registers for each GPIO pin | // (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, | 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: | // gpioToGPLEV: | ||||
// (Word) offset to the GPIO Input level registers for each GPIO pin | // (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, | 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 | #ifdef notYetReady | ||||
// gpioToEDS | // gpioToEDS | ||||
// (Word) offset to the Event Detect Status | // (Word) offset to the Event Detect Status | ||||
@@ -295,6 +327,7 @@ static uint8_t gpioToFEN [] = | |||||
} ; | } ; | ||||
#endif | #endif | ||||
// gpioToPUDCLK | // gpioToPUDCLK | ||||
// (Word) offset to the Pull Up Down Clock regsiter | // (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, | 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 | // gpioToPwmALT | ||||
// the ALT value to put a GPIO pin into PWM mode | // the ALT value to put a GPIO pin into PWM mode | ||||
@@ -339,7 +373,122 @@ static uint8_t gpioToPwmPort [] = | |||||
static unsigned long long epoch ; | 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) | void pinModeGpio (int pin, int mode) | ||||
{ | { | ||||
static int pwmRunning = FALSE ; | |||||
int fSel, shift, alt ; | int fSel, shift, alt ; | ||||
pin &= 63 ; | pin &= 63 ; | ||||
@@ -371,38 +519,28 @@ void pinModeGpio (int pin, int mode) | |||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | *(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 | // When we change mode of any pin, we remove the pull up/downs | ||||
@@ -459,6 +597,55 @@ void pwmSetRangeSys (unsigned int range) | |||||
return ; | 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 | #ifdef notYetReady | ||||
/* | /* | ||||
@@ -518,7 +705,7 @@ void digitalWriteSys (int pin, int value) | |||||
/* | /* | ||||
* pwnWrite: | |||||
* pwmWrite: | |||||
* Set an output PWM value | * Set an output PWM value | ||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -699,8 +886,6 @@ int waitForInterruptGpio (int pin, int mS) | |||||
} | } | ||||
/* | /* | ||||
* delay: | * delay: | ||||
* Wait for some number of milli seconds | * Wait for some number of milli seconds | ||||
@@ -800,9 +985,16 @@ unsigned int millis (void) | |||||
int wiringPiSetup (void) | int wiringPiSetup (void) | ||||
{ | { | ||||
int fd ; | int fd ; | ||||
int boardRev ; | |||||
uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; | uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; | ||||
struct timeval tv ; | struct timeval tv ; | ||||
if (getenv ("WIRINGPI_DEBUG") != NULL) | |||||
wiringPiDebug = TRUE ; | |||||
if (wiringPiDebug) | |||||
printf ("wiringPi: wiringPiSetup called\n") ; | |||||
pinMode = pinModeWPi ; | pinMode = pinModeWPi ; | ||||
pullUpDnControl = pullUpDnControlWPi ; | pullUpDnControl = pullUpDnControlWPi ; | ||||
digitalWrite = digitalWriteWPi ; | digitalWrite = digitalWriteWPi ; | ||||
@@ -813,7 +1005,16 @@ int wiringPiSetup (void) | |||||
delayMicroseconds = delayMicrosecondsWPi ; | delayMicroseconds = delayMicrosecondsWPi ; | ||||
pwmSetMode = pwmSetModeWPi ; | pwmSetMode = pwmSetModeWPi ; | ||||
pwmSetRange = pwmSetRangeWPi ; | pwmSetRange = pwmSetRangeWPi ; | ||||
pwmSetClock = pwmSetClockWPi ; | |||||
if ((boardRev = piBoardRev ()) < 0) | |||||
return -1 ; | |||||
if (boardRev == 1) | |||||
pinToGpio = pinToGpioR1 ; | |||||
else | |||||
pinToGpio = pinToGpioR2 ; | |||||
// Open the master /dev/memory device | // Open the master /dev/memory device | ||||
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) | if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) | ||||
@@ -954,9 +1155,12 @@ int wiringPiSetup (void) | |||||
int wiringPiSetupGpio (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 ; | return x ; | ||||
pinMode = pinModeGpio ; | pinMode = pinModeGpio ; | ||||
@@ -969,6 +1173,7 @@ int wiringPiSetupGpio (void) | |||||
delayMicroseconds = delayMicrosecondsWPi ; // Same | delayMicroseconds = delayMicrosecondsWPi ; // Same | ||||
pwmSetMode = pwmSetModeWPi ; | pwmSetMode = pwmSetModeWPi ; | ||||
pwmSetRange = pwmSetRangeWPi ; | pwmSetRange = pwmSetRangeWPi ; | ||||
pwmSetClock = pwmSetClockWPi ; | |||||
return 0 ; | return 0 ; | ||||
} | } | ||||
@@ -989,6 +1194,9 @@ int wiringPiSetupSys (void) | |||||
struct timeval tv ; | struct timeval tv ; | ||||
char fName [128] ; | char fName [128] ; | ||||
if (wiringPiDebug) | |||||
printf ("wiringPi: wiringPiSetupSys called\n") ; | |||||
pinMode = pinModeSys ; | pinMode = pinModeSys ; | ||||
pullUpDnControl = pullUpDnControlSys ; | pullUpDnControl = pullUpDnControlSys ; | ||||
digitalWrite = digitalWriteSys ; | digitalWrite = digitalWriteSys ; | ||||
@@ -999,6 +1207,7 @@ int wiringPiSetupSys (void) | |||||
delayMicroseconds = delayMicrosecondsSys ; | delayMicroseconds = delayMicrosecondsSys ; | ||||
pwmSetMode = pwmSetModeSys ; | pwmSetMode = pwmSetModeSys ; | ||||
pwmSetRange = pwmSetRangeSys ; | pwmSetRange = pwmSetRangeSys ; | ||||
pwmSetClock = pwmSetClockSys ; | |||||
// Open and scan the directory, looking for exported GPIOs, and pre-open | // 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 wiringPiSetupGpio (void) ; | ||||
extern int wiringPiSetupPiFace (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 int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only | ||||
extern void (*pinMode) (int pin, int mode) ; | extern void (*pinMode) (int pin, int mode) ; | ||||
@@ -73,6 +76,7 @@ extern int (*digitalRead) (int pin) ; | |||||
extern void (*delayMicroseconds) (unsigned int howLong) ; | extern void (*delayMicroseconds) (unsigned int howLong) ; | ||||
extern void (*pwmSetMode) (int mode) ; | extern void (*pwmSetMode) (int mode) ; | ||||
extern void (*pwmSetRange) (unsigned int range) ; | extern void (*pwmSetRange) (unsigned int range) ; | ||||
extern void (*pwmSetClock) (int divisor) ; | |||||
// Interrupts | // Interrupts | ||||