@@ -19,13 +19,6 @@ then run the ldconfig command. | |||||
sudo ldconfig | sudo ldconfig | ||||
If you want to install a static library, you may need to do this manually: | |||||
cd wiringPi | |||||
make static | |||||
sudo make install-static | |||||
To un-install wiringPi: | To un-install wiringPi: | ||||
./build uninstall | ./build uninstall | ||||
@@ -1 +1 @@ | |||||
2.44 | |||||
2.46 |
@@ -64,6 +64,9 @@ if [ x$1 = "xclean" ]; then | |||||
echo -n "PiGlow: " ; make clean | echo -n "PiGlow: " ; make clean | ||||
cd ../scrollPhat | cd ../scrollPhat | ||||
echo -n "scrollPhat: " ; make clean | echo -n "scrollPhat: " ; make clean | ||||
cd ../.. | |||||
echo -n "Deb: " ; rm -f debian-template/wiringpi*.deb | |||||
echo | |||||
exit | exit | ||||
fi | fi | ||||
@@ -1,5 +1,5 @@ | |||||
Package: wiringpi | Package: wiringpi | ||||
Version: 2.44 | |||||
Version: 2.46 | |||||
Section: libraries | Section: libraries | ||||
Priority: optional | Priority: optional | ||||
Architecture: armhf | Architecture: armhf | ||||
@@ -1,7 +1,9 @@ | |||||
/* | /* | ||||
* pins.c: | |||||
* Just display a handy Pi pinnout diagram. | |||||
* Copyright (c) 2012-2017 Gordon Henderson | |||||
* blink-thread.c: | |||||
* Standard "blink" program in wiringPi. Blinks an LED connected | |||||
* to the first GPIO pin. | |||||
* | |||||
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net> | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -21,13 +23,39 @@ | |||||
*********************************************************************** | *********************************************************************** | ||||
*/ | */ | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <wiringPi.h> | |||||
// LED Pin - wiringPi pin 0 is BCM_GPIO 17. | |||||
void doPins (void) | |||||
#define LED 0 | |||||
PI_THREAD (blinky) | |||||
{ | { | ||||
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") ; | |||||
for (;;) | |||||
{ | |||||
digitalWrite (LED, HIGH) ; // On | |||||
delay (500) ; // mS | |||||
digitalWrite (LED, LOW) ; // Off | |||||
delay (500) ; | |||||
} | |||||
} | } | ||||
int main (void) | |||||
{ | |||||
printf ("Raspberry Pi blink\n") ; | |||||
wiringPiSetup () ; | |||||
pinMode (LED, OUTPUT) ; | |||||
piThreadCreate (blinky) ; | |||||
for (;;) | |||||
{ | |||||
printf ("Hello, world\n") ; | |||||
delay (600) ; | |||||
} | |||||
return 0 ; | |||||
} |
@@ -25,7 +25,6 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <wiringPi.h> | |||||
#include <sys/time.h> | #include <sys/time.h> | ||||
@@ -34,17 +33,13 @@ | |||||
int main() | int main() | ||||
{ | { | ||||
int x ; | int x ; | ||||
struct timeval t1, t2 ; | |||||
struct timeval t1, t2, t3 ; | |||||
int t ; | int t ; | ||||
int max, min ; | int max, min ; | ||||
int del ; | int del ; | ||||
int underRuns, overRuns, exactRuns, total ; | |||||
int underRuns, overRuns, exactRuns, bogusRuns, total ; | |||||
int descheds ; | int descheds ; | ||||
if (wiringPiSetup () == -1) | |||||
return 1 ; | |||||
piHiPri (10) ; sleep (1) ; | |||||
// Baseline test | // Baseline test | ||||
@@ -58,21 +53,22 @@ int main() | |||||
{ | { | ||||
underRuns = overRuns = exactRuns = total = 0 ; | underRuns = overRuns = exactRuns = total = 0 ; | ||||
descheds = 0 ; | descheds = 0 ; | ||||
max = del ; | |||||
min = del ; | |||||
max = 0 ; | |||||
min = 999 ; | |||||
for (x = 0 ; x < CYCLES ; ++x) | for (x = 0 ; x < CYCLES ; ++x) | ||||
{ | { | ||||
for (;;) // Repeat this if we get a delay over 999uS | for (;;) // Repeat this if we get a delay over 999uS | ||||
{ // -> High probability Linux has deschedulled us | { // -> High probability Linux has deschedulled us | ||||
gettimeofday (&t1, NULL) ; | gettimeofday (&t1, NULL) ; | ||||
delayMicroseconds (del) ; | |||||
usleep (del) ; | |||||
// delayMicroseconds (del) ; | |||||
gettimeofday (&t2, NULL) ; | gettimeofday (&t2, NULL) ; | ||||
if (t2.tv_usec < t1.tv_usec) // Counter wrapped | |||||
t = (1000000 + t2.tv_usec) - t1.tv_usec; | |||||
else | |||||
t = t2.tv_usec - t1.tv_usec ; | |||||
timersub (&t2, &t1, &t3) ; | |||||
t = t3.tv_usec ; | |||||
if (t > 999) | if (t > 999) | ||||
{ | { | ||||
++descheds ; | ++descheds ; | ||||
@@ -82,25 +78,24 @@ int main() | |||||
break ; | break ; | ||||
} | } | ||||
if (t == del) | |||||
++exactRuns ; | |||||
else if (t < del) | |||||
++underRuns ; | |||||
else if (t > del) | |||||
++overRuns ; | |||||
if (t > max) | if (t > max) | ||||
{ | |||||
max = t ; | max = t ; | ||||
++overRuns ; | |||||
} | |||||
else if (t < min) | else if (t < min) | ||||
{ | |||||
min = t ; | min = t ; | ||||
++underRuns ; | |||||
} | |||||
else | |||||
++exactRuns ; | |||||
total += t ; | total += t ; | ||||
} | } | ||||
printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n", | printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n", | ||||
del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ; | del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ; | ||||
fflush (stdout) ; | fflush (stdout) ; | ||||
delay (1) ; | |||||
usleep (1000) ; | |||||
} | } | ||||
return 0 ; | return 0 ; | ||||
@@ -42,7 +42,7 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt | |||||
# May not need to alter anything below this line | # May not need to alter anything below this line | ||||
############################################################################### | ############################################################################### | ||||
SRC = gpio.c readall.c pins.c | |||||
SRC = gpio.c readall.c | |||||
OBJ = $(SRC:.c=.o) | OBJ = $(SRC:.c=.o) | ||||
@@ -77,22 +77,22 @@ ifneq ($(WIRINGPI_SUID),0) | |||||
$Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio | $Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio | ||||
$Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio | $Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio | ||||
endif | endif | ||||
$Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1 | |||||
$Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man1 | |||||
$Q mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1 | |||||
$Q cp gpio.1 $(DESTDIR)$(PREFIX)/share/man/man1 | |||||
.PHONY: install-deb | .PHONY: install-deb | ||||
install-deb: gpio | install-deb: gpio | ||||
$Q echo "[Install: deb]" | $Q echo "[Install: deb]" | ||||
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin | $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin | ||||
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin | $Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin | ||||
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/man/man1 | |||||
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/man/man1 | |||||
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/share/man/man1 | |||||
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/usr/share/man/man1 | |||||
.PHONY: uninstall | .PHONY: uninstall | ||||
uninstall: | uninstall: | ||||
$Q echo "[UnInstall]" | $Q echo "[UnInstall]" | ||||
$Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio | $Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio | ||||
$Q rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1 | |||||
$Q rm -f $(DESTDIR)$(PREFIX)/share/man/man1/gpio.1 | |||||
.PHONY: depend | .PHONY: depend | ||||
depend: | depend: | ||||
@@ -1,4 +1,4 @@ | |||||
.TH GPIO 1 "September 2015" wiringPi "Command-Line access to Raspberry Pi's GPIO" | |||||
.TH GPIO 1 "March 2018" wiringPi "Command-Line access to Raspberry Pi's GPIO" | |||||
.SH NAME | .SH NAME | ||||
gpio \- Command-line access to Raspberry Pi's GPIO | gpio \- Command-line access to Raspberry Pi's GPIO | ||||
@@ -9,7 +9,7 @@ gpio \- Command-line access to Raspberry Pi's GPIO | |||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B [ \-g | \-1 ] | .B [ \-g | \-1 ] | ||||
.B mode/read/write/aread/awrite/wb/pwm/clock/toggle/blink ... | |||||
.B mode/read/write/aread/awrite/wb/pwm/pwnTone/clock/toggle/blink ... | |||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B [ \-x extension:params ] | .B [ \-x extension:params ] | ||||
@@ -21,6 +21,11 @@ gpio \- Command-line access to Raspberry Pi's GPIO | |||||
.B ... | .B ... | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
.B [ \-p ] | |||||
.B pwnTone pin frequency | |||||
.B ... | |||||
.PP | |||||
.B gpio | |||||
.B readall | .B readall | ||||
.PP | .PP | ||||
.B gpio | .B gpio | ||||
@@ -257,30 +262,6 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional) | |||||
Change the PWM range register. The default is 1024. | Change the PWM range register. The default is 1024. | ||||
.TP | .TP | ||||
.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 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. | |||||
.TP | |||||
.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. 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. | |||||
.TP | |||||
.B gbr | .B gbr | ||||
channel | channel | ||||
@@ -360,7 +341,7 @@ Please report bugs to <projects@drogon.net> | |||||
.SH COPYRIGHT | .SH COPYRIGHT | ||||
Copyright (c) 2012-2015 Gordon Henderson | |||||
Copyright (c) 2012-2018 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. | ||||
@@ -2,7 +2,7 @@ | |||||
* gpio.c: | * gpio.c: | ||||
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry | * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry | ||||
* Pi's GPIO. | * Pi's GPIO. | ||||
* Copyright (c) 2012-2017 Gordon Henderson | |||||
* Copyright (c) 2012-2018 Gordon Henderson | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -48,7 +48,7 @@ extern int wiringPiDebug ; | |||||
extern void doReadall (void) ; | extern void doReadall (void) ; | ||||
extern void doAllReadall (void) ; | extern void doAllReadall (void) ; | ||||
extern void doPins (void) ; | |||||
extern void doQmode (int argc, char *argv []) ; | |||||
#ifndef TRUE | #ifndef TRUE | ||||
# define TRUE (1==1) | # define TRUE (1==1) | ||||
@@ -56,9 +56,9 @@ extern void doPins (void) ; | |||||
#endif | #endif | ||||
#define PI_USB_POWER_CONTROL 38 | #define PI_USB_POWER_CONTROL 38 | ||||
#define I2CDETECT "/usr/sbin/i2cdetect" | |||||
#define MODPROBE "/sbin/modprobe" | |||||
#define RMMOD "/sbin/rmmod" | |||||
#define I2CDETECT "i2cdetect" | |||||
#define MODPROBE "modprobe" | |||||
#define RMMOD "rmmod" | |||||
int wpMode ; | int wpMode ; | ||||
@@ -68,9 +68,9 @@ char *usage = "Usage: gpio -v\n" | |||||
" gpio [-d] ...\n" | " gpio [-d] ...\n" | ||||
" [-x extension:params] [[ -x ...]] ...\n" | " [-x extension:params] [[ -x ...]] ...\n" | ||||
" gpio [-p] <read/write/wb> ...\n" | " gpio [-p] <read/write/wb> ...\n" | ||||
" gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n" | |||||
" gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n" | |||||
" gpio <toggle/blink> <pin>\n" | " gpio <toggle/blink> <pin>\n" | ||||
" gpio readall/reset\n" | |||||
" gpio readall\n" | |||||
" gpio unexportall/exports\n" | " gpio unexportall/exports\n" | ||||
" gpio export/edge/unexport ...\n" | " gpio export/edge/unexport ...\n" | ||||
" gpio wfi <pin> <mode>\n" | " gpio wfi <pin> <mode>\n" | ||||
@@ -221,9 +221,7 @@ static void checkDevTree (char *argv []) | |||||
fprintf (stderr, | fprintf (stderr, | ||||
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n" | "%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" | " 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]) ; | |||||
" modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ; | |||||
exit (1) ; | exit (1) ; | ||||
} | } | ||||
} | } | ||||
@@ -1270,7 +1268,7 @@ static void doVersion (char *argv []) | |||||
wiringPiVersion (&vMaj, &vMin) ; | wiringPiVersion (&vMaj, &vMin) ; | ||||
printf ("gpio version: %d.%d\n", vMaj, vMin) ; | printf ("gpio version: %d.%d\n", vMaj, vMin) ; | ||||
printf ("Copyright (c) 2012-2017 Gordon Henderson\n") ; | |||||
printf ("Copyright (c) 2012-2018 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 ("\n") ; | ||||
@@ -1320,8 +1318,11 @@ int main (int argc, char *argv []) | |||||
if (argc == 1) | if (argc == 1) | ||||
{ | { | ||||
fprintf (stderr, "%s\n", usage) ; | |||||
return 1 ; | |||||
fprintf (stderr, | |||||
"%s: At your service!\n" | |||||
" Type: gpio -h for full details and\n" | |||||
" gpio readall for a quick printout of your connector details\n", argv [0]) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | } | ||||
// Help | // Help | ||||
@@ -1329,7 +1330,7 @@ int main (int argc, char *argv []) | |||||
if (strcasecmp (argv [1], "-h") == 0) | if (strcasecmp (argv [1], "-h") == 0) | ||||
{ | { | ||||
printf ("%s: %s\n", argv [0], usage) ; | printf ("%s: %s\n", argv [0], usage) ; | ||||
return 0 ; | |||||
exit (EXIT_SUCCESS) ; | |||||
} | } | ||||
// Version & Warranty | // Version & Warranty | ||||
@@ -1338,7 +1339,7 @@ int main (int argc, char *argv []) | |||||
if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0)) | if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0)) | ||||
{ | { | ||||
printf ("%d\n", piGpioLayout ()) ; | printf ("%d\n", piGpioLayout ()) ; | ||||
return 0 ; | |||||
exit (EXIT_SUCCESS) ; | |||||
} | } | ||||
// Version and information | // Version and information | ||||
@@ -1346,13 +1347,13 @@ int main (int argc, char *argv []) | |||||
if (strcmp (argv [1], "-v") == 0) | if (strcmp (argv [1], "-v") == 0) | ||||
{ | { | ||||
doVersion (argv) ; | doVersion (argv) ; | ||||
return 0 ; | |||||
exit (EXIT_SUCCESS) ; | |||||
} | } | ||||
if (strcasecmp (argv [1], "-warranty") == 0) | if (strcasecmp (argv [1], "-warranty") == 0) | ||||
{ | { | ||||
printf ("gpio version: %s\n", VERSION) ; | printf ("gpio version: %s\n", VERSION) ; | ||||
printf ("Copyright (c) 2012-2017 Gordon Henderson\n") ; | |||||
printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ; | |||||
printf ("\n") ; | printf ("\n") ; | ||||
printf (" This program is free software; you can redistribute it and/or modify\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") ; | printf (" it under the terms of the GNU Leser General Public License as published\n") ; | ||||
@@ -1367,13 +1368,13 @@ int main (int argc, char *argv []) | |||||
printf (" You should have received a copy of the GNU Lesser General Public License\n") ; | printf (" You should have received a copy of the GNU Lesser General Public License\n") ; | ||||
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ; | printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ; | ||||
printf ("\n") ; | printf ("\n") ; | ||||
return 0 ; | |||||
exit (EXIT_SUCCESS) ; | |||||
} | } | ||||
if (geteuid () != 0) | if (geteuid () != 0) | ||||
{ | { | ||||
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ; | fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ; | ||||
return 1 ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | } | ||||
// Initial test for /sys/class/gpio operations: | // Initial test for /sys/class/gpio operations: | ||||
@@ -1517,7 +1518,8 @@ int main (int argc, char *argv []) | |||||
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; | else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; | ||||
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; | else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; | ||||
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; | else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; | ||||
else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ; | |||||
else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ; | |||||
else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ; | |||||
else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ; | 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], "i2cd" ) == 0) doI2Cdetect (argc, argv) ; | ||||
else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ; | else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ; | ||||
@@ -1531,5 +1533,6 @@ int main (int argc, char *argv []) | |||||
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; | ||||
exit (EXIT_FAILURE) ; | exit (EXIT_FAILURE) ; | ||||
} | } | ||||
return 0 ; | return 0 ; | ||||
} | } |
@@ -1,7 +1,7 @@ | |||||
/* | /* | ||||
* readall.c: | * readall.c: | ||||
* The readall functions - getting a bit big, so split them out. | * The readall functions - getting a bit big, so split them out. | ||||
* Copyright (c) 2012-2017 Gordon Henderson | |||||
* Copyright (c) 2012-2018 Gordon Henderson | |||||
*********************************************************************** | *********************************************************************** | ||||
* This file is part of wiringPi: | * This file is part of wiringPi: | ||||
* https://projects.drogon.net/raspberry-pi/wiringpi/ | * https://projects.drogon.net/raspberry-pi/wiringpi/ | ||||
@@ -287,16 +287,16 @@ void abReadall (int model, int rev) | |||||
/* | /* | ||||
* piPlusReadall: | * piPlusReadall: | ||||
* Read all the pins on the model A+ or the B+ | |||||
* Read all the pins on the model A+ or the B+ or actually, all 40-pin Pi's | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
static void plus2header (int model) | static void plus2header (int model) | ||||
{ | { | ||||
/**/ if (model == PI_MODEL_AP) | /**/ if (model == PI_MODEL_AP) | ||||
printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ; | |||||
printf (" +-----+-----+---------+------+---+---Pi A+--+---+------+---------+-----+-----+\n") ; | |||||
else if (model == PI_MODEL_BP) | else if (model == PI_MODEL_BP) | ||||
printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; | |||||
printf (" +-----+-----+---------+------+---+---Pi B+--+---+------+---------+-----+-----+\n") ; | |||||
else if (model == PI_MODEL_ZERO) | else if (model == PI_MODEL_ZERO) | ||||
printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; | printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; | ||||
else if (model == PI_MODEL_ZERO_W) | else if (model == PI_MODEL_ZERO_W) | ||||
@@ -305,6 +305,8 @@ static void plus2header (int model) | |||||
printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; | printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; | ||||
else if (model == PI_MODEL_3) | else if (model == PI_MODEL_3) | ||||
printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ; | printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ; | ||||
else if (model == PI_MODEL_3P) | |||||
printf (" +-----+-----+---------+------+---+---Pi 3+--+---+------+---------+-----+-----+\n") ; | |||||
else | else | ||||
printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; | printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; | ||||
} | } | ||||
@@ -348,7 +350,10 @@ void doReadall (void) | |||||
/**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) | /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) | ||||
abReadall (model, rev) ; | abReadall (model, rev) ; | ||||
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_3) || (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) | |||||
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || | |||||
(model == PI_MODEL_2) || | |||||
(model == PI_MODEL_3) || (model == PI_MODEL_3P) || | |||||
(model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) | |||||
piPlusReadall (model) ; | piPlusReadall (model) ; | ||||
else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) | else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) | ||||
allReadall () ; | allReadall () ; | ||||
@@ -356,6 +361,7 @@ void doReadall (void) | |||||
printf ("Oops - unable to determine board type... model: %d\n", model) ; | printf ("Oops - unable to determine board type... model: %d\n", model) ; | ||||
} | } | ||||
/* | /* | ||||
* doAllReadall: | * doAllReadall: | ||||
* Force reading of all pins regardless of Pi model | * Force reading of all pins regardless of Pi model | ||||
@@ -366,3 +372,24 @@ void doAllReadall (void) | |||||
{ | { | ||||
allReadall () ; | allReadall () ; | ||||
} | } | ||||
/* | |||||
* doQmode: | |||||
* Query mode on a pin | |||||
********************************************************************************* | |||||
*/ | |||||
void doQmode (int argc, char *argv []) | |||||
{ | |||||
int pin ; | |||||
if (argc != 3) | |||||
{ | |||||
fprintf (stderr, "Usage: %s qmode pin\n", argv [0]) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | |||||
pin = atoi (argv [2]) ; | |||||
printf ("%s\n", alts [getAlt (pin)]) ; | |||||
} |
@@ -1,3 +1,3 @@ | |||||
#define VERSION "2.44" | |||||
#define VERSION "2.46" | |||||
#define VERSION_MAJOR 2 | #define VERSION_MAJOR 2 | ||||
#define VERSION_MINOR 44 | |||||
#define VERSION_MINOR 46 |
@@ -40,6 +40,7 @@ CC = gcc | |||||
INCLUDE = -I. | INCLUDE = -I. | ||||
DEFS = -D_GNU_SOURCE | DEFS = -D_GNU_SOURCE | ||||
CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC | CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC | ||||
#CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Wconversion -Winline $(INCLUDE) -pipe -fPIC | |||||
LIBS = -lm -lpthread -lrt -lcrypt | LIBS = -lm -lpthread -lrt -lcrypt | ||||
@@ -68,13 +69,9 @@ OBJ = $(SRC:.c=.o) | |||||
all: $(DYNAMIC) | all: $(DYNAMIC) | ||||
static: $(STATIC) | |||||
$(STATIC): $(OBJ) | |||||
$Q echo "[Link (Static)]" | |||||
$Q ar rcs $(STATIC) $(OBJ) | |||||
$Q ranlib $(STATIC) | |||||
# @size $(STATIC) | |||||
.PHONY: static | |||||
static: | |||||
$Q cat noMoreStatic | |||||
$(DYNAMIC): $(OBJ) | $(DYNAMIC): $(OBJ) | ||||
$Q echo "[Link (Dynamic)]" | $Q echo "[Link (Dynamic)]" | ||||
@@ -107,15 +104,6 @@ install: $(DYNAMIC) | |||||
$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so | $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so | ||||
$Q $(LDCONFIG) | $Q $(LDCONFIG) | ||||
.PHONY: install-static | |||||
install-static: $(STATIC) | |||||
$Q echo "[Install Headers]" | |||||
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include | |||||
$Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include | |||||
$Q echo "[Install Static Lib]" | |||||
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib | |||||
$Q install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib | |||||
.PHONY: install-deb | .PHONY: install-deb | ||||
install-deb: $(DYNAMIC) | install-deb: $(DYNAMIC) | ||||
$Q echo "[Install Headers: deb]" | $Q echo "[Install Headers: deb]" | ||||
@@ -0,0 +1,20 @@ | |||||
wiringPi is no-longer shipped with the ability to statically link it. | |||||
Many reasons but the biggest issue is people who have statically linked | |||||
wiringPi into their product - for example a Pi UPS device or a Tetris-like | |||||
game and not subsequently shipped their modified sources. These people are | |||||
no better than common thieves with complete disregard to the conditions | |||||
of the LGPL that wiringPi ships with. | |||||
Additionally, many think it's a good idea to statically link wiringPi | |||||
into their favourite language - like Node, and Java and other itsy bitsy | |||||
little things. These people have a complete and utter disregard to what | |||||
happens underneath when e.g. the Linux kernel changes on the Pi then | |||||
wiringPi stops as it depends on some Pi kernel features, then the poor | |||||
user get in-touch with me and I've had over 10,000 emails so-far and | |||||
it's now beyond a joke. | |||||
DO NOT STATICALLY LINK WIRINGPI. | |||||
Gordon Henderson, March 2018. |
@@ -139,6 +139,9 @@ static volatile unsigned int GPIO_PWM ; | |||||
#define PAGE_SIZE (4*1024) | #define PAGE_SIZE (4*1024) | ||||
#define BLOCK_SIZE (4*1024) | #define BLOCK_SIZE (4*1024) | ||||
static unsigned int usingGpioMem = FALSE ; | |||||
static int wiringPiSetuped = FALSE ; | |||||
// PWM | // PWM | ||||
// Word offsets into the PWM control region | // Word offsets into the PWM control region | ||||
@@ -185,15 +188,22 @@ static volatile unsigned int GPIO_PWM ; | |||||
// Locals to hold pointers to the hardware | // Locals to hold pointers to the hardware | ||||
static volatile uint32_t *gpio ; | |||||
static volatile uint32_t *pwm ; | |||||
static volatile uint32_t *clk ; | |||||
static volatile uint32_t *pads ; | |||||
static volatile unsigned int *gpio ; | |||||
static volatile unsigned int *pwm ; | |||||
static volatile unsigned int *clk ; | |||||
static volatile unsigned int *pads ; | |||||
static volatile unsigned int *timer ; | |||||
static volatile unsigned int *timerIrqRaw ; | |||||
// Export variables for the hardware pointers | |||||
volatile unsigned int *_wiringPiGpio ; | |||||
volatile unsigned int *_wiringPiPwm ; | |||||
volatile unsigned int *_wiringPiClk ; | |||||
volatile unsigned int *_wiringPiPads ; | |||||
volatile unsigned int *_wiringPiTimer ; | |||||
volatile unsigned int *_wiringPiTimerIrqRaw ; | |||||
#ifdef USE_TIMER | |||||
static volatile uint32_t *timer ; | |||||
static volatile uint32_t *timerIrqRaw ; | |||||
#endif | |||||
// Data for use with the boardId functions. | // Data for use with the boardId functions. | ||||
// The order of entries here to correspond with the PI_MODEL_X | // The order of entries here to correspond with the PI_MODEL_X | ||||
@@ -223,7 +233,7 @@ const char *piModelNames [16] = | |||||
"CM3", // 10 | "CM3", // 10 | ||||
"Unknown11", // 11 | "Unknown11", // 11 | ||||
"Pi Zero-W", // 12 | "Pi Zero-W", // 12 | ||||
"Unknown13", // 13 | |||||
"Pi 3+", // 13 | |||||
"Unknown14", // 14 | "Unknown14", // 14 | ||||
"Unknown15", // 15 | "Unknown15", // 15 | ||||
} ; | } ; | ||||
@@ -652,6 +662,41 @@ int wiringPiFailure (int fatal, const char *message, ...) | |||||
/* | /* | ||||
* setupCheck | |||||
* Another sanity check because some users forget to call the setup | |||||
* function. Mosty because they need feeding C drip by drip )-: | |||||
********************************************************************************* | |||||
*/ | |||||
static void setupCheck (const char *fName) | |||||
{ | |||||
if (!wiringPiSetuped) | |||||
{ | |||||
fprintf (stderr, "%s: You have not called one of the wiringPiSetup\n" | |||||
" functions, so I'm aborting your program before it crashes anyway.\n", fName) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | |||||
} | |||||
/* | |||||
* gpioMemCheck: | |||||
* See if we're using the /dev/gpiomem interface, if-so then some operations | |||||
* can't be done and will crash the Pi. | |||||
********************************************************************************* | |||||
*/ | |||||
static void usingGpioMemCheck (const char *what) | |||||
{ | |||||
if (usingGpioMem) | |||||
{ | |||||
fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ; | |||||
exit (EXIT_FAILURE) ; | |||||
} | |||||
} | |||||
/* | |||||
* piGpioLayout: | * piGpioLayout: | ||||
* Return a number representing the hardware revision of the board. | * Return a number representing the hardware revision of the board. | ||||
* This is not strictly the board revision but is used to check the | * This is not strictly the board revision but is used to check the | ||||
@@ -720,6 +765,7 @@ int piGpioLayout (void) | |||||
// I do not support so don't email me your bleating whinges about anything | // I do not support so don't email me your bleating whinges about anything | ||||
// other than a genuine Raspberry Pi. | // other than a genuine Raspberry Pi. | ||||
#ifdef DONT_CARE_ANYMORE | |||||
if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835"))) | if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835"))) | ||||
{ | { | ||||
fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; | fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; | ||||
@@ -730,12 +776,27 @@ int piGpioLayout (void) | |||||
fprintf (stderr, "Raspberry Pi ONLY.\n") ; | fprintf (stderr, "Raspberry Pi ONLY.\n") ; | ||||
exit (EXIT_FAILURE) ; | exit (EXIT_FAILURE) ; | ||||
} | } | ||||
#endif | |||||
// Actually... That has caused me more than 10,000 emails so-far. Mosty by | |||||
// people who think they know better by creating a statically linked | |||||
// version that will not run with a new 4.9 kernel. I utterly hate and | |||||
// despise those people. | |||||
// | |||||
// I also get bleats from people running other than Raspbian with another | |||||
// distros compiled kernel rather than a foundation compiled kernel, so | |||||
// this might actually help them. It might not - I only have the capacity | |||||
// to support Raspbian. | |||||
// | |||||
// However, I've decided to leave this check out and rely purely on the | |||||
// Revision: line for now. It will not work on a non-pi hardware or weird | |||||
// kernels that don't give you a suitable revision line. | |||||
// Right - we're Probably on a Raspberry Pi. Check the revision field for the real | |||||
// So - we're Probably on a Raspberry Pi. Check the revision field for the real | |||||
// hardware type | // hardware type | ||||
// In-future, I ought to use the device tree as there are now Pi entries in | // In-future, I ought to use the device tree as there are now Pi entries in | ||||
// /proc/device-tree/ ... | // /proc/device-tree/ ... | ||||
// but I'll leave that for the next revision. | |||||
// but I'll leave that for the next revision. Or the next. | |||||
// Isolate the Revision line | // Isolate the Revision line | ||||
@@ -938,7 +999,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) | |||||
if ((revision & (1 << 23)) != 0) // New way | if ((revision & (1 << 23)) != 0) // New way | ||||
{ | { | ||||
if (wiringPiDebug) | if (wiringPiDebug) | ||||
printf ("piBoardId: New Way: revision is: 0x%08X\n", revision) ; | |||||
printf ("piBoardId: New Way: revision is: %08X\n", revision) ; | |||||
bRev = (revision & (0x0F << 0)) >> 0 ; | bRev = (revision & (0x0F << 0)) >> 0 ; | ||||
bType = (revision & (0xFF << 4)) >> 4 ; | bType = (revision & (0xFF << 4)) >> 4 ; | ||||
@@ -1183,7 +1244,7 @@ void pwmSetClock (int divisor) | |||||
/* | /* | ||||
* gpioClockSet: | * gpioClockSet: | ||||
* Set the freuency on a GPIO clock pin | |||||
* Set the frequency on a GPIO clock pin | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -1322,6 +1383,8 @@ void pinModeAlt (int pin, int mode) | |||||
{ | { | ||||
int fSel, shift ; | int fSel, shift ; | ||||
setupCheck ("pinModeAlt") ; | |||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin | if ((pin & PI_GPIO_MASK) == 0) // On-board pin | ||||
{ | { | ||||
/**/ if (wiringPiMode == WPI_MODE_PINS) | /**/ if (wiringPiMode == WPI_MODE_PINS) | ||||
@@ -1351,6 +1414,8 @@ void pinMode (int pin, int mode) | |||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
int origPin = pin ; | int origPin = pin ; | ||||
setupCheck ("pinMode") ; | |||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin | if ((pin & PI_GPIO_MASK) == 0) // On-board pin | ||||
{ | { | ||||
/**/ if (wiringPiMode == WPI_MODE_PINS) | /**/ if (wiringPiMode == WPI_MODE_PINS) | ||||
@@ -1384,6 +1449,8 @@ void pinMode (int pin, int mode) | |||||
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin | if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin | ||||
return ; | return ; | ||||
usingGpioMemCheck ("pinMode PWM") ; | |||||
// Set pin to PWM mode | // Set pin to PWM mode | ||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | ||||
@@ -1398,6 +1465,8 @@ void pinMode (int pin, int mode) | |||||
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin | if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin | ||||
return ; | return ; | ||||
usingGpioMemCheck ("pinMode CLOCK") ; | |||||
// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz | // Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz | ||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; | ||||
@@ -1416,10 +1485,7 @@ void pinMode (int pin, int mode) | |||||
/* | /* | ||||
* pullUpDownCtrl: | * pullUpDownCtrl: | ||||
* Control the internal pull-up/down resistors on a GPIO pin | |||||
* The Arduino only has pull-ups and these are enabled by writing 1 | |||||
* to a port when in input mode - this paradigm doesn't quite apply | |||||
* here though. | |||||
* Control the internal pull-up/down resistors on a GPIO pin. | |||||
********************************************************************************* | ********************************************************************************* | ||||
*/ | */ | ||||
@@ -1427,6 +1493,8 @@ void pullUpDnControl (int pin, int pud) | |||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
setupCheck ("pullUpDnControl") ; | |||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | ||||
{ | { | ||||
/**/ if (wiringPiMode == WPI_MODE_PINS) | /**/ if (wiringPiMode == WPI_MODE_PINS) | ||||
@@ -1588,6 +1656,8 @@ void pwmWrite (int pin, int value) | |||||
{ | { | ||||
struct wiringPiNodeStruct *node = wiringPiNodes ; | struct wiringPiNodeStruct *node = wiringPiNodes ; | ||||
setupCheck ("pwmWrite") ; | |||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin | ||||
{ | { | ||||
/**/ if (wiringPiMode == WPI_MODE_PINS) | /**/ if (wiringPiMode == WPI_MODE_PINS) | ||||
@@ -1597,6 +1667,7 @@ void pwmWrite (int pin, int value) | |||||
else if (wiringPiMode != WPI_MODE_GPIO) | else if (wiringPiMode != WPI_MODE_GPIO) | ||||
return ; | return ; | ||||
usingGpioMemCheck ("pwmWrite") ; | |||||
*(pwm + gpioToPwmPort [pin]) = value ; | *(pwm + gpioToPwmPort [pin]) = value ; | ||||
} | } | ||||
else | else | ||||
@@ -1656,6 +1727,8 @@ void pwmToneWrite (int pin, int freq) | |||||
{ | { | ||||
int range ; | int range ; | ||||
setupCheck ("pwmToneWrite") ; | |||||
if (freq == 0) | if (freq == 0) | ||||
pwmWrite (pin, 0) ; // Off | pwmWrite (pin, 0) ; // Off | ||||
else | else | ||||
@@ -2139,16 +2212,15 @@ int wiringPiSetup (void) | |||||
{ | { | ||||
int fd ; | int fd ; | ||||
int model, rev, mem, maker, overVolted ; | int model, rev, mem, maker, overVolted ; | ||||
static int alreadyDoneThis = FALSE ; | |||||
// It's actually a fatal error to call any of the wiringPiSetup routines more than once, | // It's actually a fatal error to call any of the wiringPiSetup routines more than once, | ||||
// (you run out of file handles!) but I'm fed-up with the useless twats who email | // (you run out of file handles!) but I'm fed-up with the useless twats who email | ||||
// me bleating that there is a bug in my code, so screw-em. | // me bleating that there is a bug in my code, so screw-em. | ||||
if (alreadyDoneThis) | |||||
if (wiringPiSetuped) | |||||
return 0 ; | return 0 ; | ||||
alreadyDoneThis = TRUE ; | |||||
wiringPiSetuped = TRUE ; | |||||
if (getenv (ENV_DEBUG) != NULL) | if (getenv (ENV_DEBUG) != NULL) | ||||
wiringPiDebug = TRUE ; | wiringPiDebug = TRUE ; | ||||
@@ -2204,11 +2276,18 @@ int wiringPiSetup (void) | |||||
// Try /dev/mem. If that fails, then | // Try /dev/mem. If that fails, then | ||||
// try /dev/gpiomem. If that fails then game over. | // try /dev/gpiomem. If that fails then game over. | ||||
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) | |||||
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) | |||||
{ | { | ||||
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) | |||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n Try running with sudo?\n", strerror (errno)) ; | |||||
piGpioBase = 0 ; | |||||
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem | |||||
{ | |||||
piGpioBase = 0 ; | |||||
usingGpioMem = TRUE ; | |||||
} | |||||
else | |||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n" | |||||
" Aborting your program because if it can not access the GPIO\n" | |||||
" hardware then it most certianly won't work\n" | |||||
" Try running with sudo?\n", strerror (errno)) ; | |||||
} | } | ||||
// Set the offsets into the memory interface. | // Set the offsets into the memory interface. | ||||
@@ -2245,7 +2324,6 @@ int wiringPiSetup (void) | |||||
if (pads == MAP_FAILED) | if (pads == MAP_FAILED) | ||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; | return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; | ||||
#ifdef USE_TIMER | |||||
// The system timer | // The system timer | ||||
timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; | timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; | ||||
@@ -2259,7 +2337,14 @@ int wiringPiSetup (void) | |||||
*(timer + TIMER_CONTROL) = 0x0000280 ; | *(timer + TIMER_CONTROL) = 0x0000280 ; | ||||
*(timer + TIMER_PRE_DIV) = 0x00000F9 ; | *(timer + TIMER_PRE_DIV) = 0x00000F9 ; | ||||
timerIrqRaw = timer + TIMER_IRQ_RAW ; | timerIrqRaw = timer + TIMER_IRQ_RAW ; | ||||
#endif | |||||
// Export the base addresses for any external software that might need them | |||||
_wiringPiGpio = gpio ; | |||||
_wiringPiPwm = pwm ; | |||||
_wiringPiClk = clk ; | |||||
_wiringPiPads = pads ; | |||||
_wiringPiTimer = timer ; | |||||
initialiseEpoch () ; | initialiseEpoch () ; | ||||
@@ -2325,16 +2410,10 @@ int wiringPiSetupSys (void) | |||||
int pin ; | int pin ; | ||||
char fName [128] ; | char fName [128] ; | ||||
static int alreadyDoneThis = FALSE ; | |||||
// It's actually a fatal error to call any of the wiringPiSetup routines more than once, | |||||
// (you run out of file handles!) but I'm fed-up with the useless twats who email | |||||
// me bleating that there is a bug in my code, so screw-em. | |||||
if (alreadyDoneThis) | |||||
if (wiringPiSetuped) | |||||
return 0 ; | return 0 ; | ||||
alreadyDoneThis = TRUE ; | |||||
wiringPiSetuped = TRUE ; | |||||
if (getenv (ENV_DEBUG) != NULL) | if (getenv (ENV_DEBUG) != NULL) | ||||
wiringPiDebug = TRUE ; | wiringPiDebug = TRUE ; | ||||
@@ -99,6 +99,7 @@ | |||||
#define PI_MODEL_ZERO 9 | #define PI_MODEL_ZERO 9 | ||||
#define PI_MODEL_CM3 10 | #define PI_MODEL_CM3 10 | ||||
#define PI_MODEL_ZERO_W 12 | #define PI_MODEL_ZERO_W 12 | ||||
#define PI_MODEL_3P 13 | |||||
#define PI_VERSION_1 0 | #define PI_VERSION_1 0 | ||||
#define PI_VERSION_1_1 1 | #define PI_VERSION_1_1 1 | ||||
@@ -162,6 +163,15 @@ struct wiringPiNodeStruct | |||||
extern struct wiringPiNodeStruct *wiringPiNodes ; | extern struct wiringPiNodeStruct *wiringPiNodes ; | ||||
// Export variables for the hardware pointers | |||||
extern volatile unsigned int *_wiringPiGpio ; | |||||
extern volatile unsigned int *_wiringPiPwm ; | |||||
extern volatile unsigned int *_wiringPiClk ; | |||||
extern volatile unsigned int *_wiringPiPads ; | |||||
extern volatile unsigned int *_wiringPiTimer ; | |||||
extern volatile unsigned int *_wiringPiTimerIrqRaw ; | |||||
// Function prototypes | // Function prototypes | ||||
// c++ wrappers thanks to a comment by Nick Lott | // c++ wrappers thanks to a comment by Nick Lott | ||||
@@ -871,7 +871,7 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors) | |||||
char *p ; | char *p ; | ||||
char *extension = extensionData ; | char *extension = extensionData ; | ||||
struct extensionFunctionStruct *extensionFn ; | struct extensionFunctionStruct *extensionFn ; | ||||
unsigned pinBase = 0 ; | |||||
int pinBase = 0 ; | |||||
verbose = printErrors ; | verbose = printErrors ; | ||||