diff --git a/VERSION b/VERSION index 0f34dc7..90177b7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.32 +2.36 diff --git a/build b/build index 368e8f4..b42a25a 100755 --- a/build +++ b/build @@ -6,7 +6,7 @@ # Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control index 230da07..d9f2658 100644 --- a/debian-template/wiringPi/DEBIAN/control +++ b/debian-template/wiringPi/DEBIAN/control @@ -1,5 +1,5 @@ Package: wiringpi -Version: 2.32 +Version: 2.36 Section: libraries Priority: optional Architecture: armhf diff --git a/devLib/Makefile b/devLib/Makefile index 1b1ebe0..cf665d6 100644 --- a/devLib/Makefile +++ b/devLib/Makefile @@ -1,8 +1,8 @@ # # Makefile: -# wiringPi device - Wiring Compatable library for the Raspberry Pi +# wiringPi device - A "wiring" library for the Raspberry Pi # -# Copyright (c) 2012-2015 Gordon Henderson +# Copyright (c) 2012-2016 Gordon Henderson ################################################################################# # This file is part of wiringPi: # https://projects.drogon.net/raspberry-pi/wiringpi/ diff --git a/devLib/gertboard.c b/devLib/gertboard.c index 5aeaef7..6a84415 100644 --- a/devLib/gertboard.c +++ b/devLib/gertboard.c @@ -101,7 +101,7 @@ int gertboardAnalogRead (const int chan) wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; - return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; + return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ; } diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c index 1b1c0dd..cadbfe8 100644 --- a/devLib/piFaceOld.c +++ b/devLib/piFaceOld.c @@ -1,7 +1,6 @@ /* * piFace.: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012-2013 Gordon Henderson + * Copyright (c) 2012-2016 Gordon Henderson * * This file to interface with the PiFace peripheral device which * has an MCP23S17 GPIO device connected via the SPI bus. diff --git a/examples/Makefile b/examples/Makefile index 4278b6d..d6195b3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,6 +1,6 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# wiringPi - A "wiring" library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # # Copyright (c) 2012-2015 Gordon Henderson diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile index 4685adc..f937c14 100644 --- a/examples/PiFace/Makefile +++ b/examples/PiFace/Makefile @@ -1,12 +1,12 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# wiringPi - A "wiring" library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # # Copyright (c) 2012 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/examples/PiGlow/Makefile b/examples/PiGlow/Makefile index acd4818..f182db7 100644 --- a/examples/PiGlow/Makefile +++ b/examples/PiGlow/Makefile @@ -1,12 +1,12 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# wiringPi - A "wiring" library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # # Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/examples/q2w/Makefile b/examples/q2w/Makefile index 6f50fa0..8f773bf 100644 --- a/examples/q2w/Makefile +++ b/examples/q2w/Makefile @@ -1,12 +1,12 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# wiringPi - A "wiring" library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # # Copyright (c) 2012-2013 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/examples/scrollPhat/Makefile b/examples/scrollPhat/Makefile index c0b7241..2471f69 100644 --- a/examples/scrollPhat/Makefile +++ b/examples/scrollPhat/Makefile @@ -1,12 +1,12 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# wiringPi - A "wiring" library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # # Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/gpio/Makefile b/gpio/Makefile index 7dcd090..cdf954f 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -4,10 +4,10 @@ # A swiss-army knige of GPIO shenanigans. # https://projects.drogon.net/wiring-pi # -# Copyright (c) 2012-2015 Gordon Henderson +# Copyright (c) 2012-2016 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 @@ -34,10 +34,10 @@ endif DEBUG = -O2 CC = gcc INCLUDE = -I$(DESTDIR)$(PREFIX)/include -CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe +CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib -LIBS = -lwiringPi -lwiringPiDev -lpthread +LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm # May not need to alter anything below this line ############################################################################### @@ -85,6 +85,8 @@ install-deb: gpio $Q echo "[Install: deb]" $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin $Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/man/man1 + $Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/man/man1 .PHONY: uninstall uninstall: diff --git a/gpio/gpio.c b/gpio/gpio.c index 6162090..c954f3b 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -57,6 +57,8 @@ extern void doPins (void) ; #define PI_USB_POWER_CONTROL 38 #define I2CDETECT "/usr/sbin/i2cdetect" +#define MODPROBE "/sbin/modprobe" +#define RMMOD "/sbin/rmmod" int wpMode ; @@ -65,6 +67,7 @@ char *usage = "Usage: gpio -v\n" " gpio [-g|-1] [-x extension:params] ...\n" " gpio [-p] ...\n" " gpio ...\n" + " gpio \n" " gpio readall/reset\n" " gpio unexportall/exports\n" " gpio export/edge/unexport ...\n" @@ -76,6 +79,8 @@ char *usage = "Usage: gpio -v\n" " gpio load spi/i2c\n" " gpio unload spi/i2c\n" " gpio i2cd/i2cdetect\n" + " gpio rbx/rbd\n" + " gpio wb \n" " gpio usbp high/low\n" " gpio gbr \n" " gpio gbw " ; // No trailing newline needed here. @@ -102,6 +107,45 @@ static int decodePin (const char *str) #endif +/* + * findExecutable: + * Code to locate the path to the given executable. We have a fixed list + * of locations to try which completely overrides any $PATH environment. + * This may be detrimental, however it avoids the reliance on $PATH + * which may be a security issue when this program is run a set-uid-root. + ********************************************************************************* + */ + +static const char *searchPath [] = +{ + "/sbin", + "/usr/sbin", + "/bin", + "/usr/bin", + NULL, +} ; + +static char *findExecutable (const char *progName) +{ + static char *path = NULL ; + int len = strlen (progName) ; + int i = 0 ; + struct stat statBuf ; + + for (i = 0 ; searchPath [i] != NULL ; ++i) + { + path = malloc (strlen (searchPath [i]) + len + 2) ; + sprintf (path, "%s/%s", searchPath [i], progName) ; + + if (stat (path, &statBuf) == 0) + return path ; + free (path) ; + } + + return NULL ; +} + + /* * changeOwner: * Change the ownership of the file to the real userId of the calling @@ -230,15 +274,18 @@ static void doLoad (int argc, char *argv []) else _doLoadUsage (argv) ; + if (findExecutable ("modprobe") == NULL) + printf ("No found\n") ; + if (!moduleLoaded (module1)) { - sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ; + sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; system (cmd) ; } if (!moduleLoaded (module2)) { - sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ; + sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; system (cmd) ; } @@ -292,13 +339,13 @@ static void doUnLoad (int argc, char *argv []) if (moduleLoaded (module1)) { - sprintf (cmd, "/sbin/rmmod %s", module1) ; + sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ; system (cmd) ; } if (moduleLoaded (module2)) { - sprintf (cmd, "/sbin/rmmod %s", module2) ; + sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ; system (cmd) ; } } @@ -312,11 +359,10 @@ static void doUnLoad (int argc, char *argv []) static void doI2Cdetect (int argc, char *argv []) { - int port = piBoardRev () == 1 ? 0 : 1 ; - char command [128] ; - struct stat statBuf ; + int port = piGpioLayout () == 1 ? 0 : 1 ; + char *c, *command ; - if (stat (I2CDETECT, &statBuf) < 0) + if ((c = findExecutable (I2CDETECT)) == NULL) { fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ; return ; @@ -328,7 +374,8 @@ static void doI2Cdetect (int argc, char *argv []) return ; } - sprintf (command, "%s -y %d", I2CDETECT, port) ; + command = malloc (strlen (c) + 16) ; + sprintf (command, "%s -y %d", c, port) ; if (system (command) < 0) fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ; @@ -943,7 +990,7 @@ static void doAwrite (int argc, char *argv []) /* * doWriteByte: - * gpio write value + * gpio wb value ********************************************************************************* */ @@ -963,6 +1010,30 @@ static void doWriteByte (int argc, char *argv []) } +/* + * doReadByte: + * gpio rbx|rbd value + ********************************************************************************* + */ + +static void doReadByte (int argc, char *argv [], int printHex) +{ + int val ; + + if (argc != 2) + { + fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ; + exit (1) ; + } + + val = digitalReadByte () ; + if (printHex) + printf ("%02X\n", val) ; + else + printf ("%d\n", val) ; +} + + /* * doRead: * Read a pin and return the value @@ -1026,6 +1097,34 @@ void doToggle (int argc, char *argv []) } +/* + * doBlink: + * Blink an IO pin + ********************************************************************************* + */ + +void doBlink (int argc, char *argv []) +{ + int pin ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + pinMode (pin, OUTPUT) ; + for (;;) + { + digitalWrite (pin, !digitalRead (pin)) ; + delay (500) ; + } + +} + + /* * doPwmTone: * Output a tone in a PWM pin @@ -1162,6 +1261,8 @@ static void doVersion (char *argv []) { int model, rev, mem, maker, warranty ; struct stat statBuf ; + char name [80] ; + FILE *fd ; printf ("gpio version: %s\n", VERSION) ; printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ; @@ -1179,12 +1280,18 @@ static void doVersion (char *argv []) if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... printf (" * Device tree is enabled.\n") ; - if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO + if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type { - printf (" * This Raspberry Pi supports user-level GPIO access.\n") ; - printf (" -> See the man-page for more details\n") ; - printf (" -> ie. export WIRINGPI_GPIOMEM=1\n") ; + if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) + { + fgets (name, 80, fd) ; + fclose (fd) ; + printf (" *--> %s\n", name) ; + } } + + if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO + printf (" * This Raspberry Pi supports user-level GPIO access.\n") ; else printf (" * Root or sudo required for GPIO access.\n") ; } @@ -1225,7 +1332,7 @@ int main (int argc, char *argv []) if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0)) { - printf ("%d\n", piBoardRev ()) ; + printf ("%d\n", piGpioLayout ()) ; return 0 ; } @@ -1375,6 +1482,7 @@ int main (int argc, char *argv []) // GPIO Nicies else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ; + else if (strcasecmp (argv [1], "blink" ) == 0) doBlink (argc, argv) ; // Pi Specifics @@ -1391,6 +1499,8 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ; else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ; else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ; + else if (strcasecmp (argv [1], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ; + else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ; else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; else diff --git a/gpio/pintest b/gpio/pintest index 4da3d94..b574361 100755 --- a/gpio/pintest +++ b/gpio/pintest @@ -5,7 +5,7 @@ # Copyright (c) 2013-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/gpio/readall.c b/gpio/readall.c index cb7e18f..c447e5e 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -118,7 +118,7 @@ static char *physNames [64] = NULL, " 3.3v", "5v ", - " SDA.1", "5V ", + " SDA.1", "5v ", " SCL.1", "0v ", "GPIO. 7", "TxD ", " 0v", "RxD ", diff --git a/gpio/test.sh b/gpio/test.sh index a7c2bb2..708f1d3 100755 --- a/gpio/test.sh +++ b/gpio/test.sh @@ -5,7 +5,7 @@ # in-turn. ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/gpio/version.h b/gpio/version.h index 5b92dc9..687cc74 100644 --- a/gpio/version.h +++ b/gpio/version.h @@ -1 +1 @@ -#define VERSION "2.32" +#define VERSION "2.36" diff --git a/newVersion b/newVersion index bab6dc5..299d7a7 100755 --- a/newVersion +++ b/newVersion @@ -7,7 +7,7 @@ # Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: -# Wiring Compatable library for the Raspberry Pi +# A "wiring" 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 diff --git a/update b/update new file mode 100755 index 0000000..0f72243 --- /dev/null +++ b/update @@ -0,0 +1,5 @@ +#!/bin/sh + +# update - update source files from master on yakko + +rsync -aHx --exclude='*.o' --exclude='*~' -v --delete gordon@yakko:rpi/git/wiringPi/ . diff --git a/wiringPi/Makefile b/wiringPi/Makefile index acb6e58..ffe0012 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -39,9 +39,9 @@ DEBUG = -O2 CC = gcc INCLUDE = -I. DEFS = -D_GNU_SOURCE -CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -pipe -fPIC +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC -LIBS = +LIBS = -lm -lpthread -lrt ############################################################################### @@ -57,23 +57,12 @@ SRC = wiringPi.c \ mcp3002.c mcp3004.c mcp4802.c mcp3422.c \ max31855.c max5322.c ads1115.c \ sn3218.c \ + bmp180.c htu21d.c ds18b20.c \ drcSerial.c \ + pseudoPins.c \ wpiExtensions.c -HEADERS = wiringPi.h \ - wiringSerial.h wiringShift.h \ - wiringPiSPI.h wiringPiI2C.h \ - softPwm.h softTone.h \ - mcp23008.h mcp23016.h mcp23017.h \ - mcp23s08.h mcp23s17.h \ - sr595.h \ - pcf8574.h pcf8591.h \ - mcp3002.h mcp3004.h mcp4802.h mcp3422.h \ - max31855.h max5322.h ads1115.h \ - sn3218.h \ - drcSerial.h \ - wpiExtensions.h - +HEADERS = $(shell ls *.h) OBJ = $(SRC:.c=.o) @@ -89,7 +78,7 @@ $(STATIC): $(OBJ) $(DYNAMIC): $(OBJ) $Q echo "[Link (Dynamic)]" - $Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) -lpthread $(OBJ) + $Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) $(LIBS) $(OBJ) .c.o: $Q echo [Compile] $< @@ -174,9 +163,13 @@ mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h max31855.o: wiringPi.h wiringPiSPI.h max31855.h max5322.o: wiringPi.h wiringPiSPI.h max5322.h +ads1115.o: wiringPi.h wiringPiI2C.h ads1115.h sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h +bmp180.o: wiringPi.h wiringPiI2C.h bmp180.h +htu21d.o: wiringPi.h wiringPiI2C.h htu21d.h +ds18b20.o: wiringPi.h ds18b20.h drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h -wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h sn3218.h -wpiExtensions.o: drcSerial.h wpiExtensions.h +wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h ads1115.h sn3218.h +wpiExtensions.o: drcSerial.h bmp180.h htu21d.h ds18b20.h wpiExtensions.h diff --git a/wiringPi/ads1115.c b/wiringPi/ads1115.c index 62b92f8..648e612 100644 --- a/wiringPi/ads1115.c +++ b/wiringPi/ads1115.c @@ -228,7 +228,7 @@ static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data) { if ( (data < 0) || (data > 7) ) // Use default if out of range data = 4 ; - node->data0 = dataRates [data] ; + node->data1 = dataRates [data] ; // Bugfix 0-1 by "Eric de jong (gm)" - Thanks. } } diff --git a/wiringPi/bmp180.c b/wiringPi/bmp180.c new file mode 100644 index 0000000..bad4bb3 --- /dev/null +++ b/wiringPi/bmp180.c @@ -0,0 +1,237 @@ +/* + * bmp180.c: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. This is used in the Pi Weather Station + * Copyright (c) 2016 Gordon Henderson + * + * Information from the document held at: + * http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf + * was very useful when building this code. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "bmp180.h" + +#undef DEBUG + +#define I2C_ADDRESS 0x77 +#define BMP180_OSS 0 + + +// Static calibration data +// The down-side of this is that there can only be one BMP180 in +// a system - which is practice isn't an issue as it's I2C +// address is fixed. + +static int16_t AC1, AC2, AC3 ; +static uint16_t AC4, AC5, AC6 ; +static int16_t VB1, VB2 ; +static int16_t MB, MC, MD ; + +static double c5, c6, mc, md, x0, x1, x2, yy0, yy1, yy2, p0, p1, p2 ; + +// Pressure & Temp variables + +uint32_t cPress, cTemp ; + +static int altitude ; + +/* + * read16: + * Quick hack to read the 16-bit data with the correct endian + ********************************************************************************* + */ + +uint16_t read16 (int fd, int reg) +{ + return (wiringPiI2CReadReg8 (fd, reg) << 8) | wiringPiI2CReadReg8 (fd, reg + 1) ; + +} + + +/* + * bmp180ReadTempPress: + * Does the hard work of reading the sensor + ********************************************************************************* + */ + +static void bmp180ReadTempPress (int fd) +{ + double fTemp, fPress ; + double tu, a ; + double pu, s, x, y, z ; + + uint8_t data [4] ; + +// Start a temperature sensor reading + + wiringPiI2CWriteReg8 (fd, 0xF4, 0x2E) ; + delay (5) ; + +// Read the raw data + + data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ; + data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ; + +// And calculate... + + tu = (data [0] * 256.0) + data [1] ; + + a = c5 * (tu - c6) ; + fTemp = a + (mc / (a + md)) ; + cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ; + +#ifdef DEBUG + printf ("fTemp: %f, cTemp: %6d\n", fTemp, cTemp) ; +#endif + +// Start a pressure snsor reading + + wiringPiI2CWriteReg8 (fd, 0xF4, 0x34 | (BMP180_OSS << 6)) ; + delay (5) ; + +// Read the raw data + + data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ; + data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ; + data [2] = wiringPiI2CReadReg8 (fd, 0xF8) ; + +// And calculate... + + pu = ((double)data [0] * 256.0) + (double)data [1] + ((double)data [2] / 256.0) ; + s = fTemp - 25.0 ; + x = (x2 * pow (s, 2.0)) + (x1 * s) + x0 ; + y = (yy2 * pow (s, 2.0)) + (yy1 * s) + yy0 ; + z = (pu - x) / y ; + fPress = (p2 * pow (z, 2.0)) + (p1 * z) + p0 ; + cPress = (int)rint (((100.0 * fPress) + 0.5) / 10.0) ; + +#ifdef DEBUG + printf ("fPress: %f, cPress: %6d\n", fPress, cPress) ; +#endif +} + + +/* + * myAnalogWrite: + * Write to a fake register to represent the height above sea level + * so that the peudo millibar register can read the pressure in mB + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int chan = pin - node->pinBase ; + + if (chan == 0) + altitude = value ; +} + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + + bmp180ReadTempPress (node->fd) ; + + /**/ if (chan == 0) // Read Temperature + return cTemp ; + else if (chan == 1) // Pressure + return cPress ; + else if (chan == 2) // Pressure in mB + return cPress / pow (1 - ((double)altitude / 44330.0), 5.255) ; + else + return -9999 ; + +} + + +/* + * bmp180Setup: + * Create a new instance of a PCF8591 I2C GPIO interface. We know it + * has 4 pins, (4 analog inputs and 1 analog output which we'll shadow + * input 0) so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int bmp180Setup (const int pinBase) +{ + double c3, c4, b1 ; + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + +// Read calibration data + + AC1 = read16 (fd, 0xAA) ; + AC2 = read16 (fd, 0xAC) ; + AC3 = read16 (fd, 0xAE) ; + AC4 = read16 (fd, 0xB0) ; + AC5 = read16 (fd, 0xB2) ; + AC6 = read16 (fd, 0xB4) ; + VB1 = read16 (fd, 0xB6) ; + VB2 = read16 (fd, 0xB8) ; + MB = read16 (fd, 0xBA) ; + MC = read16 (fd, 0xBC) ; + MD = read16 (fd, 0xBE) ; + +// Calculate coefficients + + c3 = 160.0 * pow (2.0, -15.0) * AC3 ; + c4 = pow (10.0, -3.0) * pow(2.0,-15.0) * AC4 ; + b1 = pow (160.0, 2.0) * pow(2.0,-30.0) * VB1 ; + c5 = (pow (2.0, -15.0) / 160.0) * AC5 ; + c6 = AC6 ; + mc = (pow (2.0, 11.0) / pow(160.0,2.0)) * MC ; + md = MD / 160.0 ; + x0 = AC1 ; + x1 = 160.0 * pow (2.0, -13.0) * AC2 ; + x2 = pow (160.0, 2.0) * pow(2.0,-25.0) * VB2 ; + yy0 = c4 * pow (2.0, 15.0) ; + yy1 = c4 * c3 ; + yy2 = c4 * b1 ; + p0 = (3791.0 - 8.0) / 1600.0 ; + p1 = 1.0 - 7357.0 * pow (2.0, -20.0) ; + p2 = 3038.0 * 100.0 * pow (2.0, -36.0) ; + + return TRUE ; +} diff --git a/wiringPi/bmp180.h b/wiringPi/bmp180.h new file mode 100644 index 0000000..4a6d13a --- /dev/null +++ b/wiringPi/bmp180.h @@ -0,0 +1,34 @@ +/* + * bmp180.h: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int bmp180Setup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/ds18b20.c b/wiringPi/ds18b20.c new file mode 100644 index 0000000..533398e --- /dev/null +++ b/wiringPi/ds18b20.c @@ -0,0 +1,146 @@ +/* + * ds18b20.c: + * Extend wiringPi with the DS18B20 1-Wire temperature sensor. + * This is used in the Pi Weather Station and many other places. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "wiringPi.h" + +#include "ds18b20.h" + +#define W1_PREFIX "/sys/bus/w1/devices/28-" +#define W1_POSTFIX "/w1_slave" + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + int fd = node->fd ; + char buffer [4096] ; + char *p ; + int temp, sign ; + + if (chan != 0) + return -9999 ; + +// Rewind the file - we're keeping it open to keep things going +// smoothly + + lseek (fd, 0, SEEK_SET) ; + +// Read the file - we know it's only a couple of lines, so this ought to be +// more than enough + + if (read (fd, buffer, 4096) <= 0) // Read nothing, or it failed in some odd way + return -9998 ; + +// Look for YES, then t= + + if (strstr (buffer, "YES") == NULL) + return -9997 ; + + if ((p = strstr (buffer, "t=")) == NULL) + return -9996 ; + +// p points to the 't', so we skip over it... + + p += 2 ; + +// and extract the number +// (without caring about overflow) + + + if (*p == '-') // Negative number? + { + sign = -1 ; + ++p ; + } + else + sign = 1 ; + + temp = 0 ; + while (isdigit (*p)) + { + temp = temp * 10 + (*p - '0') ; + ++p ; + } + +// We know it returns temp * 1000, but we only really want temp * 10, so +// do a bit of rounding... + + temp = (temp + 50) / 100 ; + return temp * sign ; +} + + +/* + * ds18b20Setup: + * Create a new instance of a DS18B20 temperature sensor. + ********************************************************************************* + */ + +int ds18b20Setup (const int pinBase, const char *deviceId) +{ + int fd ; + struct wiringPiNodeStruct *node ; + char *fileName ; + +// Allocate space for the filename + + if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL) + return FALSE ; + + sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ; + + fd = open (fileName, O_RDONLY) ; + + free (fileName) ; + + if (fd < 0) + return FALSE ; + +// We'll keep the file open, to make access a little faster +// although it's very slow reading these things anyway )-: + + node = wiringPiNewNode (pinBase, 1) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/ds18b20.h b/wiringPi/ds18b20.h new file mode 100644 index 0000000..a9ea291 --- /dev/null +++ b/wiringPi/ds18b20.h @@ -0,0 +1,34 @@ +/* + * bmp180.h: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ds18b20Setup (const int pinBase, const char *serialNum) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/htu21d.c b/wiringPi/htu21d.c new file mode 100644 index 0000000..9028d60 --- /dev/null +++ b/wiringPi/htu21d.c @@ -0,0 +1,150 @@ +/* + * htu21d.c: + * Extend wiringPi with the HTU21D I2C humidity and Temperature + * sensor. This is used in the Pi Weather station. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "htu21d.h" + +#define DEBUG +#undef FAKE_SENSOR + +#define I2C_ADDRESS 0x40 + +int checksum (uint8_t data [4]) +{ + return TRUE ; +} + + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + int fd = node->fd ; + uint8_t data [4] ; + uint32_t sTemp, sHumid ; + double fTemp, fHumid ; + int cTemp, cHumid ; + + /**/ if (chan == 0) // Read Temperature + { + +// Send read temperature command: + + data [0] = 0xF3 ; + if (write (fd, data, 1) != 1) + return -9999 ; + +// Wait then read the data + + delay (50) ; + if (read (fd, data, 3) != 3) + return -9998 ; + + if (!checksum (data)) + return -9997 ; + +// Do the calculation + + sTemp = (data [0] << 8) | data [1] ; + fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ; + cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ; + return cTemp ; + } + else if (chan == 1) // humidity + { +// Send read humidity command: + + data [0] = 0xF5 ; + if (write (fd, data, 1) != 1) + return -9999 ; + +// Wait then read the data + + delay (50) ; + if (read (fd, data, 3) != 3) + return -9998 ; + + if (!checksum (data)) + return -9997 ; + + sHumid = (data [0] << 8) | data [1] ; + fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ; + cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ; + return cHumid ; + } + else + return -9999 ; +} + + +/* + * htu21dSetup: + * Create a new instance of a HTU21D I2C GPIO interface. + * This chip has a fixed I2C address, so we are not providing any + * allowance to change this. + ********************************************************************************* + */ + +int htu21dSetup (const int pinBase) +{ + int fd ; + struct wiringPiNodeStruct *node ; + uint8_t data ; + int status ; + + if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + +// Send a reset code to it: + + data = 0xFE ; + if (write (fd, &data, 1) != 1) + return FALSE ; + + delay (15) ; + +// Read the status register to check it's really there + + status = wiringPiI2CReadReg8 (fd, 0xE7) ; + + return (status == 0x02) ? TRUE : FALSE ; +} diff --git a/wiringPi/htu21d.h b/wiringPi/htu21d.h new file mode 100644 index 0000000..3965c54 --- /dev/null +++ b/wiringPi/htu21d.h @@ -0,0 +1,34 @@ +/* + * htu21d.h: + * Extend wiringPi with the HTU21D I2C Humidity and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int htu21dSetup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp3002.c b/wiringPi/mcp3002.c index 8e191b6..9ebf3e4 100644 --- a/wiringPi/mcp3002.c +++ b/wiringPi/mcp3002.c @@ -49,7 +49,7 @@ static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) wiringPiSPIDataRW (node->fd, spiData, 2) ; - return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; + return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ; } diff --git a/wiringPi/pseudoPins.c b/wiringPi/pseudoPins.c new file mode 100644 index 0000000..c2bf5e0 --- /dev/null +++ b/wiringPi/pseudoPins.c @@ -0,0 +1,95 @@ +/* + * pseudoPins.c: + * Extend wiringPi with a number of pseudo pins which can be + * digitally or analog written/read. + * + * Note: + * Just one set of pseudo pins can exist per Raspberry Pi. + * These pins are shared between all programs running on + * that Raspberry Pi. The values are also persistant as + * they live in shared RAM. This gives you a means for + * temporary variable storing/sharing between programs, + * or for other cunning things I've not thought of yet.. + * + * Copyright (c) 2012-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define SHARED_NAME "wiringPiPseudoPins" +#define PSEUDO_PINS 64 + +#include +#include +#include +#include +#include + +#include + +#include "pseudoPins.h" + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int *ptr = (int *)node->data0 ; + int myPin = pin - node->pinBase ; + + return *(ptr + myPin) ; +} + + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int *ptr = (int *)node->data0 ; + int myPin = pin - node->pinBase ; + + *(ptr + myPin) = value ; +} + + +/* + * pseudoPinsSetup: + * Create a new wiringPi device node for the pseudoPins driver + ********************************************************************************* + */ + +int pseudoPinsSetup (const int pinBase) +{ + struct wiringPiNodeStruct *node ; + void *ptr ; + + node = wiringPiNewNode (pinBase, PSEUDO_PINS) ; + + node->fd = shm_open (SHARED_NAME, O_CREAT | O_RDWR, 0666) ; + + if (node->fd < 0) + return FALSE ; + + if (ftruncate (node->fd, PSEUDO_PINS * sizeof (int)) < 0) + return FALSE ; + + ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ; + + node->data0 = (unsigned int)ptr ; + + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return TRUE ; +} diff --git a/wiringPi/pseudoPins.h b/wiringPi/pseudoPins.h new file mode 100644 index 0000000..bef4660 --- /dev/null +++ b/wiringPi/pseudoPins.h @@ -0,0 +1,26 @@ +/* + * pseudoPins.h: + * Extend wiringPi with a number of pseudo pins which can be + * digitally or analog written/read. + * Copyright (c) 2012-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +extern int pseudoPinsSetup (const int pinBase) ; diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index 98b408f..5999cc0 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -23,6 +23,7 @@ */ #include +#include #include #include "wiringPi.h" @@ -63,7 +64,7 @@ static volatile int newPin = -1 ; ********************************************************************************* */ -static PI_THREAD (softPwmThread) +static void *softPwmThread (void *arg) { int pin, mark, space ; struct sched_param param ; @@ -71,6 +72,9 @@ static PI_THREAD (softPwmThread) param.sched_priority = sched_get_priority_max (SCHED_RR) ; pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ; + pin = *((int *)arg) ; + free (arg) ; + pin = newPin ; newPin = -1 ; @@ -123,11 +127,16 @@ int softPwmCreate (int pin, int initialValue, int pwmRange) { int res ; pthread_t myThread ; + int *passPin ; if (range [pin] != 0) // Already running on this pin return -1 ; - if (range <= 0) + if (pwmRange <= 0) + return -1 ; + + passPin = malloc (sizeof (*passPin)) ; + if (passPin == NULL) return -1 ; pinMode (pin, OUTPUT) ; @@ -136,8 +145,9 @@ int softPwmCreate (int pin, int initialValue, int pwmRange) marks [pin] = initialValue ; range [pin] = pwmRange ; + *passPin = pin ; newPin = pin ; - res = pthread_create (&myThread, NULL, softPwmThread, NULL) ; + res = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ; while (newPin != -1) delay (1) ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index dfd5de4..5adfe69 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -129,9 +129,8 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ; // that I can find )-: // // Updates in September 2015 - all now static variables (and apologies for the caps) -// due to the Pi v2 and the new /dev/gpiomem interface +// due to the Pi v2, v3, etc. and the new /dev/gpiomem interface -static volatile unsigned int RASPBERRY_PI_PERI_BASE ; static volatile unsigned int GPIO_PADS ; static volatile unsigned int GPIO_CLOCK_BASE ; static volatile unsigned int GPIO_BASE ; @@ -197,13 +196,23 @@ static volatile uint32_t *timer ; static volatile uint32_t *timerIrqRaw ; #endif +// GCC warning suppressor + +#define UNU __attribute__((unused)) + // Data for use with the boardId functions. // The order of entries here to correspond with the PI_MODEL_X // and PI_VERSION_X defines in wiringPi.h // Only intended for the gpio command - use at your own risk! -static int piModel2 = FALSE ; +// piGpioBase: +// The base address of the GPIO memory mapped hardware IO + +#define GPIO_PERI_BASE_OLD 0x20000000 +#define GPIO_PERI_BASE_NEW 0x3F000000 + +static volatile unsigned int piGpioBase = 0 ; const char *piModelNames [16] = { @@ -649,7 +658,7 @@ int wiringPiFailure (int fatal, const char *message, ...) /* - * piBoardRev: + * piGpioLayout: * Return a number representing the hardware revision of the board. * This is not strictly the board revision but is used to check the * layout of the GPIO connector - and there are 2 types that we are @@ -666,30 +675,34 @@ int wiringPiFailure (int fatal, const char *message, ...) * 3 GPIO pins on the (original) 26-way header - BCM_GPIO 22 was dropped and * replaced with 27, and 0 + 1 - I2C bus 0 was changed to 2 + 3; I2C bus 1. * + * Additionally, here we set the piModel2 flag too. This is again, nothing to + * do with the actual model, but the major version numbers - the GPIO base + * hardware address changed at model 2 and above (not the Zero though) + * ********************************************************************************* */ -static void piBoardRevOops (const char *why) +static void piGpioLayoutOops (const char *why) { - fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, "Oops: Unable to determine board revision from /proc/cpuinfo\n") ; fprintf (stderr, " -> %s\n", why) ; - fprintf (stderr, " -> You may want to check:\n") ; - fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; + fprintf (stderr, " -> You'd best google the error to find out why.\n") ; +//fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; exit (EXIT_FAILURE) ; } -int piBoardRev (void) +int piGpioLayout (void) { FILE *cpuFd ; char line [120] ; char *c ; - static int boardRev = -1 ; + static int gpioLayout = -1 ; - if (boardRev != -1) // No point checking twice - return boardRev ; + if (gpioLayout != -1) // No point checking twice + return gpioLayout ; if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) - piBoardRevOops ("Unable to open /proc/cpuinfo") ; + piGpioLayoutOops ("Unable to open /proc/cpuinfo") ; // Start by looking for the Architecture to make sure we're really running // on a Pi. I'm getting fed-up with people whinging at me because @@ -700,23 +713,23 @@ int piBoardRev (void) break ; if (strncmp (line, "Hardware", 8) != 0) - piBoardRevOops ("No hardware line") ; + piGpioLayoutOops ("No \"Hardware\" line") ; if (wiringPiDebug) - printf ("piboardRev: Hardware: %s\n", line) ; + printf ("piGpioLayout: Hardware: %s\n", line) ; -// See if it's BCM2708 or BCM2709 +// See if it's BCM2708 or BCM2709 or the new BCM2835. - if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point - { - piModel2 = TRUE ; - fclose (cpuFd) ; - return boardRev = 2 ; - } - else if (strstr (line, "BCM2708") == NULL) +// OK. As of Kernel 4.8, we have BCM2835 only, regardless of model. +// However I still want to check because it will trap the cheapskates and rip- +// off merchants who want to use wiringPi on non-Raspberry Pi platforms - which +// I do not support so don't email me your bleating whinges about anything +// other than a genuine Raspberry Pi. + + if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835"))) { fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; - fprintf (stderr, " - expecting BCM2708 or BCM2709.\n") ; + fprintf (stderr, " - expecting BCM2708, BCM2709 or BCM2835.\n") ; fprintf (stderr, "If this is a genuine Raspberry Pi then please report this\n") ; fprintf (stderr, "to projects@drogon.net. If this is not a Raspberry Pi then you\n") ; fprintf (stderr, "are on your own as wiringPi is designed to support the\n") ; @@ -724,8 +737,11 @@ int piBoardRev (void) exit (EXIT_FAILURE) ; } -// Now do the rest of it as before - we just need to see if it's an older -// Rev 1 as anything else is rev 2. +// Right - we're Probably on a Raspberry Pi. Check the revision field for the real +// hardware type +// In-future, I ought to use the device tree as there are now Pi entries in +// /proc/device-tree/ ... +// but I'll leave that for the next revision. // Isolate the Revision line @@ -737,7 +753,7 @@ int piBoardRev (void) fclose (cpuFd) ; if (strncmp (line, "Revision", 8) != 0) - piBoardRevOops ("No \"Revision\" line") ; + piGpioLayoutOops ("No \"Revision\" line") ; // Chomp trailing CR/NL @@ -745,7 +761,7 @@ int piBoardRev (void) *c = 0 ; if (wiringPiDebug) - printf ("piboardRev: Revision string: %s\n", line) ; + printf ("piGpioLayout: Revision string: %s\n", line) ; // Scan to the first character of the revision number @@ -754,7 +770,7 @@ int piBoardRev (void) break ; if (*c != ':') - piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ; // Chomp spaces @@ -763,46 +779,46 @@ int piBoardRev (void) ++c ; if (!isxdigit (*c)) - piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; // Make sure its long enough if (strlen (c) < 4) - piBoardRevOops ("Bogus revision line (too small)") ; + piGpioLayoutOops ("Bogus revision line (too small)") ; -// If you have overvolted the Pi, then it appears that the revision -// has 100000 added to it! -// The actual condition for it being set is: -// (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0 - - -// This test is not correct for the new encoding scheme, so we'll remove it here as -// we don't really need it at this point. - -/******************** - if (wiringPiDebug) - if (strlen (c) != 4) - printf ("piboardRev: This Pi has/is (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0\n") ; -*******************/ - -// Isolate last 4 characters: +// Isolate last 4 characters: (in-case of overvolting or new encoding scheme) c = c + strlen (c) - 4 ; if (wiringPiDebug) - printf ("piboardRev: last4Chars are: \"%s\"\n", c) ; + printf ("piGpioLayout: last4Chars are: \"%s\"\n", c) ; if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0)) - boardRev = 1 ; + gpioLayout = 1 ; else - boardRev = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2 and CM's. + gpioLayout = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2, v3, zero and CM's. if (wiringPiDebug) - printf ("piBoardRev: Returning revision: %d\n", boardRev) ; + printf ("piGpioLayoutOops: Returning revision: %d\n", gpioLayout) ; - return boardRev ; + return gpioLayout ; } +/*** + if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point + { + piModel2 = TRUE ; + fclose (cpuFd) ; + return gpioLayout = 2 ; + } + else if (strstr (line, "BCM2708") == NULL) + { + } +***/ + +// Now do the rest of it as before - we just need to see if it's an older +// Rev 1 as anything else is rev 2. + /* * piBoardId: @@ -822,20 +838,32 @@ int piBoardRev (void) * 0003 - Model B, Rev 1.1, 256MB, Egoman, Fuses/D14 removed. * * Newer Pi's with remapped GPIO: - * 0004 - Model B, Rev 2, 256MB, Sony - * 0005 - Model B, Rev 2, 256MB, Qisda - * 0006 - Model B, Rev 2, 256MB, Egoman - * 0007 - Model A, Rev 2, 256MB, Egoman - * 0008 - Model A, Rev 2, 256MB, Sony - * 0009 - Model A, Rev 2, 256MB, Qisda - * 000d - Model B, Rev 2, 512MB, Egoman (Red Pi, Blue Pi?) - * 000e - Model B, Rev 2, 512MB, Sony - * 000f - Model B, Rev 2, 512MB, Qisda + * 0004 - Model B, Rev 1.2, 256MB, Sony + * 0005 - Model B, Rev 1.2, 256MB, Egoman + * 0006 - Model B, Rev 1.2, 256MB, Egoman + * + * 0007 - Model A, Rev 1.2, 256MB, Egoman + * 0008 - Model A, Rev 1.2, 256MB, Sony + * 0009 - Model A, Rev 1.2, 256MB, Egoman + * + * 000d - Model B, Rev 1.2, 512MB, Egoman (Red Pi, Blue Pi?) + * 000e - Model B, Rev 1.2, 512MB, Sony + * 000f - Model B, Rev 1.2, 512MB, Egoman + * * 0010 - Model B+, Rev 1.2, 512MB, Sony - * 0011 - Pi CM, Rev 1.2, 512MB, Sony - * 0012 - Model A+ Rev 1.2, 256MB, Sony - * 0014 - Pi CM, Rev 1.1, 512MB, Sony (Actual Revision might be different) - * 0015 - Model A+ Rev 1.1, 256MB, Sony + * 0013 - Model B+ Rev 1.2, 512MB, Embest + * 0016 - Model B+ Rev 1.2, 512MB, Sony + * 0019 - Model B+ Rev 1.2, 512MB, Egoman + * + * 0011 - Pi CM, Rev 1.1, 512MB, Sony + * 0014 - Pi CM, Rev 1.1, 512MB, Embest + * 0017 - Pi CM, Rev 1.1, 512MB, Sony + * 001a - Pi CM, Rev 1.1, 512MB, Egoman + * + * 0012 - Model A+ Rev 1.1, 256MB, Sony + * 0015 - Model A+ Rev 1.1, 512MB, Embest + * 0018 - Model A+ Rev 1.1, 256MB, Sony + * 001b - Model A+ Rev 1.1, 256MB, Egoman * * A small thorn is the olde style overvolting - that will add in * 1000000 @@ -870,10 +898,10 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) // Will deal with the properly later on - for now, lets just get it going... // unsigned int modelNum ; - (void)piBoardRev () ; // Call this first to make sure all's OK. Don't care about the result. + (void)piGpioLayout () ; // Call this first to make sure all's OK. Don't care about the result. if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) - piBoardRevOops ("Unable to open /proc/cpuinfo") ; + piGpioLayoutOops ("Unable to open /proc/cpuinfo") ; while (fgets (line, 120, cpuFd) != NULL) if (strncmp (line, "Revision", 8) == 0) @@ -882,7 +910,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) fclose (cpuFd) ; if (strncmp (line, "Revision", 8) != 0) - piBoardRevOops ("No \"Revision\" line") ; + piGpioLayoutOops ("No \"Revision\" line") ; // Chomp trailing CR/NL @@ -901,7 +929,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) break ; if (*c != ':') - piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ; // Chomp spaces @@ -910,7 +938,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) ++c ; if (!isxdigit (*c)) - piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x @@ -944,12 +972,12 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) printf ("piBoardId: Old Way: revision is: %s\n", c) ; if (!isdigit (*c)) - piBoardRevOops ("Bogus \"Revision\" line (no digit at start of revision)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (no digit at start of revision)") ; // Make sure its long enough if (strlen (c) < 4) - piBoardRevOops ("Bogus \"Revision\" line (not long enough)") ; + piGpioLayoutOops ("Bogus \"Revision\" line (not long enough)") ; // If longer than 4, we'll assume it's been overvolted @@ -963,21 +991,34 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } - else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } - else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } - else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } - else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } - else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } } } @@ -1022,9 +1063,6 @@ void setPadDrive (int group, int value) if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - if ((group < 0) || (group > 2)) return ; @@ -1098,9 +1136,6 @@ void pwmSetRange (unsigned int range) { if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; } @@ -1122,9 +1157,6 @@ void pwmSetClock (int divisor) if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - if (wiringPiDebug) printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; @@ -1177,9 +1209,6 @@ void gpioClockSet (int pin, int freq) else if (wiringPiMode != WPI_MODE_GPIO) return ; - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - divi = 19200000 / freq ; divr = 19200000 % freq ; divf = (int)((double)divr * 4096.0 / 19200000.0) ; @@ -1222,13 +1251,13 @@ struct wiringPiNodeStruct *wiringPiFindNode (int pin) ********************************************************************************* */ -static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; } -static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; } -static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; } -static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } -static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } -static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; } -static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } +static void pinModeDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } +static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } +static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } +static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } +static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) { @@ -1352,17 +1381,11 @@ void pinMode (int pin, int mode) softToneCreate (origPin) ; else if (mode == PWM_TONE_OUTPUT) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode pwmSetMode (PWM_MODE_MS) ; } else if (mode == PWM_OUTPUT) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin return ; @@ -1377,9 +1400,6 @@ void pinMode (int pin, int mode) } else if (mode == GPIO_CLOCK) { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin return ; @@ -1534,9 +1554,6 @@ void pwmWrite (int pin, int value) if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - /**/ if (wiringPiMode == WPI_MODE_PINS) pin = pinToGpio [pin] ; else if (wiringPiMode == WPI_MODE_PHYS) @@ -1603,9 +1620,6 @@ void pwmToneWrite (int pin, int freq) { int range ; - if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now - return ; - if (freq == 0) pwmWrite (pin, 0) ; // Off else @@ -1630,7 +1644,7 @@ void pwmToneWrite (int pin, int freq) * Reading is just bit fiddling. * These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers * 17, 18, 22, 23, 24, 24, 4 on a Pi v1 rev 0-3 - * 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, zero + * 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, 3, zero ********************************************************************************* */ @@ -1720,8 +1734,8 @@ void digitalWriteByte2 (const int value) } else { - *(gpio + gpioToGPCLR [0]) = 0x0FF00000 ; - *(gpio + gpioToGPSET [0]) = (value & 0xFF) << 20 ; + *(gpio + gpioToGPCLR [0]) = (~value & 0xFF) << 20 ; // 0x0FF00000; ILJ > CHANGE: Old causes glitch + *(gpio + gpioToGPSET [0]) = ( value & 0xFF) << 20 ; } } @@ -1772,18 +1786,20 @@ int waitForInterrupt (int pin, int mS) // Setup poll structure polls.fd = fd ; - polls.events = POLLPRI ; // Urgent data! + polls.events = POLLPRI | POLLERR ; // Wait for it ... x = poll (&polls, 1, mS) ; -// Do a dummy read to clear the interrupt +// If no error, do a dummy read to clear the interrupt // A one character read appars to be enough. -// Followed by a seek to reset it. - (void)read (fd, &c, 1) ; - lseek (fd, 0, SEEK_SET) ; + if (x > 0) + { + lseek (fd, 0, SEEK_SET) ; // Rewind + (void)read (fd, &c, 1) ; // Read & clear + } return x ; } @@ -1797,7 +1813,7 @@ int waitForInterrupt (int pin, int mS) ********************************************************************************* */ -static void *interruptHandler (void *arg) +static void *interruptHandler (UNU void *arg) { int myPin ; @@ -2047,18 +2063,17 @@ unsigned int micros (void) int wiringPiSetup (void) { int fd ; - int boardRev ; int model, rev, mem, maker, overVolted ; - static int alreadyCalled = FALSE ; + static int alreadyDoneThis = FALSE ; -// This is here to trap the unwary - those who's program appears to work then fails some -// time later with a weird error message because you run out of file-handles. +// 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 (alreadyCalled) - (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup*: You must only call this once per program run. This is a fatal error. Please fix your code.\n") ; - - alreadyCalled = TRUE ; + if (alreadyDoneThis) + return 0 ; + alreadyDoneThis = TRUE ; if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; @@ -2066,101 +2081,99 @@ int wiringPiSetup (void) if (getenv (ENV_CODES) != NULL) wiringPiReturnCodes = TRUE ; - if (getenv (ENV_GPIOMEM) != NULL) - wiringPiTryGpioMem = TRUE ; - if (wiringPiDebug) - { printf ("wiringPi: wiringPiSetup called\n") ; - if (wiringPiTryGpioMem) - printf ("wiringPi: Using /dev/gpiomem\n") ; - } - boardRev = piBoardRev () ; +// Get the board ID information. We're not really using the information here, +// but it will give us information like the GPIO layout scheme (2 variants +// on the older 26-pin Pi's) and the GPIO peripheral base address. +// and if we're running on a compute module, then wiringPi pin numbers +// don't really many anything, so force native BCM mode anyway. - /**/ if (boardRev == 1) // A, B, Rev 1, 1.1 + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + if (model == PI_MODEL_CM) + wiringPiMode = WPI_MODE_GPIO ; + else + wiringPiMode = WPI_MODE_PINS ; + + /**/ if (piGpioLayout () == 1) // A, B, Rev 1, 1.1 { pinToGpio = pinToGpioR1 ; physToGpio = physToGpioR1 ; } - else // A, B, Rev 2, B+, CM, Pi2, Zero + else // A2, B2, A+, B+, CM, Pi2, Pi3, Zero { pinToGpio = pinToGpioR2 ; physToGpio = physToGpioR2 ; } -// Note that a Zero is a model 1 +// ... - if (piModel2) - RASPBERRY_PI_PERI_BASE = 0x3F000000 ; - else - RASPBERRY_PI_PERI_BASE = 0x20000000 ; - -// Open the master /dev/ memory control device - -// See if /dev/gpiomem exists and we can open it... - - if (wiringPiTryGpioMem) + switch (model) { - if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", strerror (errno)) ; - RASPBERRY_PI_PERI_BASE = 0 ; + case PI_MODEL_A: case PI_MODEL_B: + case PI_MODEL_AP: case PI_MODEL_BP: + case PI_ALPHA: case PI_MODEL_CM: case PI_MODEL_ZERO: + piGpioBase = GPIO_PERI_BASE_OLD ; + break ; + + default: + piGpioBase = GPIO_PERI_BASE_NEW ; + break ; } -// ... otherwise fall back to the original /dev/mem which requires root level access +// Open the master /dev/ memory control device +// Device strategy: December 2016: +// Try /dev/mem. If that fails, then +// try /dev/gpiomem. If that fails then game over. - else + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) { - -// This check is here because people are too stupid to check for themselves or read -// error messages. - - if (geteuid () != 0) - (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ; - - if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) - return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + 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 ; } // Set the offsets into the memory interface. - GPIO_PADS = RASPBERRY_PI_PERI_BASE + 0x00100000 ; - GPIO_CLOCK_BASE = RASPBERRY_PI_PERI_BASE + 0x00101000 ; - GPIO_BASE = RASPBERRY_PI_PERI_BASE + 0x00200000 ; - GPIO_TIMER = RASPBERRY_PI_PERI_BASE + 0x0000B000 ; - GPIO_PWM = RASPBERRY_PI_PERI_BASE + 0x0020C000 ; + GPIO_PADS = piGpioBase + 0x00100000 ; + GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ; + GPIO_BASE = piGpioBase + 0x00200000 ; + GPIO_TIMER = piGpioBase + 0x0000B000 ; + GPIO_PWM = piGpioBase + 0x0020C000 ; // Map the individual hardware components // GPIO: gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; - if ((int32_t)gpio == -1) + if (gpio == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; // PWM pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; - if ((int32_t)pwm == -1) + if (pwm == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; // Clock control (needed for PWM) clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ; - if ((int32_t)clk == -1) + if (clk == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; // The drive pads pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; - if ((int32_t)pads == -1) + if (pads == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; #ifdef USE_TIMER // The system timer timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; - if ((int32_t)timer == -1) + if (timer == MAP_FAILED) return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ; // Set the timer to free-running, 1MHz. @@ -2174,14 +2187,6 @@ int wiringPiSetup (void) initialiseEpoch () ; -// If we're running on a compute module, then wiringPi pin numbers don't really many anything... - - piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if (model == PI_MODEL_CM) - wiringPiMode = WPI_MODE_GPIO ; - else - wiringPiMode = WPI_MODE_PINS ; - return 0 ; } @@ -2241,18 +2246,19 @@ int wiringPiSetupPhys (void) int wiringPiSetupSys (void) { - int boardRev ; int pin ; char fName [128] ; - static int alreadyCalled = FALSE ; -// This is here to trap the unwary - those who's program appears to work then fails some -// time later with a weird error message because you run out of file-handles. + static int alreadyDoneThis = FALSE ; - if (alreadyCalled) - (void)wiringPiFailure (WPI_FATAL, "wiringPiSetupSys: You must only call this once per program run. This is a fatal error. Please fix your code.\n") ; +// 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. - alreadyCalled = TRUE ; + if (alreadyDoneThis) + return 0 ; + + alreadyDoneThis = TRUE ; if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; @@ -2263,9 +2269,7 @@ int wiringPiSetupSys (void) if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; - boardRev = piBoardRev () ; - - if (boardRev == 1) + if (piGpioLayout () == 1) { pinToGpio = pinToGpioR1 ; physToGpio = physToGpioR1 ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index e11a0be..7926296 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -95,7 +95,7 @@ #define PI_MAKER_SONY 0 #define PI_MAKER_EGOMAN 1 -#define PI_MAKER_MBEST 2 +#define PI_MAKER_EMBEST 2 #define PI_MAKER_UNKNOWN 3 extern const char *piModelNames [16] ; @@ -190,7 +190,7 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio // On-Board Raspberry Pi hardware specific stuff -extern int piBoardRev (void) ; +extern int piGpioLayout (void) ; extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; extern int wpiPinToGpio (int wpiPin) ; extern int physPinToGpio (int physPin) ; diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c index c787bce..b0ee5d3 100644 --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "wiringPi.h" #include "wiringPiI2C.h" @@ -221,7 +222,7 @@ int wiringPiI2CSetup (const int devId) int rev ; const char *device ; - rev = piBoardRev () ; + rev = piGpioLayout () ; if (rev == 1) device = "/dev/i2c-0" ; diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c index 453df31..022b99f 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "wiringPi.h" @@ -38,10 +39,10 @@ // The SPI bus parameters // Variables as they need to be passed as pointers later on -const static char *spiDev0 = "/dev/spidev0.0" ; -const static char *spiDev1 = "/dev/spidev0.1" ; -const static uint8_t spiBPW = 8 ; -const static uint16_t spiDelay = 0 ; +static const char *spiDev0 = "/dev/spidev0.0" ; +static const char *spiDev1 = "/dev/spidev0.1" ; +static const uint8_t spiBPW = 8 ; +static const uint16_t spiDelay = 0 ; static uint32_t spiSpeeds [2] ; static int spiFds [2] ; diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c index ca976a9..09aeb35 100644 --- a/wiringPi/wiringSerial.c +++ b/wiringPi/wiringSerial.c @@ -49,24 +49,35 @@ int serialOpen (const char *device, const int baud) switch (baud) { - case 50: myBaud = B50 ; break ; - case 75: myBaud = B75 ; break ; - case 110: myBaud = B110 ; break ; - case 134: myBaud = B134 ; break ; - case 150: myBaud = B150 ; break ; - case 200: myBaud = B200 ; break ; - case 300: myBaud = B300 ; break ; - case 600: myBaud = B600 ; break ; - case 1200: myBaud = B1200 ; break ; - case 1800: myBaud = B1800 ; break ; - case 2400: myBaud = B2400 ; break ; - case 4800: myBaud = B4800 ; break ; - case 9600: myBaud = B9600 ; break ; - case 19200: myBaud = B19200 ; break ; - case 38400: myBaud = B38400 ; break ; - case 57600: myBaud = B57600 ; break ; - case 115200: myBaud = B115200 ; break ; - case 230400: myBaud = B230400 ; break ; + case 50: myBaud = B50 ; break ; + case 75: myBaud = B75 ; break ; + case 110: myBaud = B110 ; break ; + case 134: myBaud = B134 ; break ; + case 150: myBaud = B150 ; break ; + case 200: myBaud = B200 ; break ; + case 300: myBaud = B300 ; break ; + case 600: myBaud = B600 ; break ; + case 1200: myBaud = B1200 ; break ; + case 1800: myBaud = B1800 ; break ; + case 2400: myBaud = B2400 ; break ; + case 9600: myBaud = B9600 ; break ; + case 19200: myBaud = B19200 ; break ; + case 38400: myBaud = B38400 ; break ; + case 57600: myBaud = B57600 ; break ; + case 115200: myBaud = B115200 ; break ; + case 230400: myBaud = B230400 ; break ; + case 460800: myBaud = B460800 ; break ; + case 500000: myBaud = B500000 ; break ; + case 576000: myBaud = B576000 ; break ; + case 921600: myBaud = B921600 ; break ; + case 1000000: myBaud = B1000000 ; break ; + case 1152000: myBaud = B1152000 ; break ; + case 1500000: myBaud = B1500000 ; break ; + case 2000000: myBaud = B2000000 ; break ; + case 2500000: myBaud = B2500000 ; break ; + case 3000000: myBaud = B3000000 ; break ; + case 3500000: myBaud = B3500000 ; break ; + case 4000000: myBaud = B4000000 ; break ; default: return -2 ; @@ -96,7 +107,7 @@ int serialOpen (const char *device, const int baud) options.c_cc [VMIN] = 0 ; options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds) - tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ; + tcsetattr (fd, TCSANOW, &options) ; ioctl (fd, TIOCMGET, &status); diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c index 62a92d7..96852b7 100644 --- a/wiringPi/wpiExtensions.c +++ b/wiringPi/wpiExtensions.c @@ -55,6 +55,10 @@ #include "ads1115.h" #include "sn3218.h" #include "drcSerial.h" +#include "pseudoPins.h" +#include "bmp180.h" +#include "htu21d.h" +#include "ds18b20.h" #include "wpiExtensions.h" @@ -428,6 +432,70 @@ static int doExtensionPcf8591 (char *progName, int pinBase, char *params) } +/* + * doExtensionPseudoPins: + * 64 Memory resident pseudo pins + * pseudoPins:base + ********************************************************************************* + */ + +static int doExtensionPseudoPins (char *progName, int pinBase, char *params) +{ + pseudoPinsSetup (pinBase) ; +printf ("pseudoPins: %d\n", pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionBmp180: + * Analog Temp + Pressure + * bmp180:base + ********************************************************************************* + */ + +static int doExtensionBmp180 (char *progName, int pinBase, char *params) +{ + bmp180Setup (pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionHtu21d: + * Analog humidity + Pressure + * htu21d:base + ********************************************************************************* + */ + +static int doExtensionHtu21d (char *progName, int pinBase, char *params) +{ + htu21dSetup (pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionDs18b20: + * 1-Wire Temperature + * htu21d:base:serialNum + ********************************************************************************* + */ + +static int doExtensionDs18b20 (char *progName, int pinBase, char *params) +{ + char *serialNum ; + + if ((params = extractStr (progName, params, &serialNum)) == NULL) + return FALSE ; + + return ds18b20Setup (pinBase, serialNum) ; +} + + /* * doExtensionMax31855: * Analog IO @@ -677,6 +745,10 @@ static struct extensionFunctionStruct extensionFunctions [] = { "sr595", &doExtensionSr595 }, { "pcf8574", &doExtensionPcf8574 }, { "pcf8591", &doExtensionPcf8591 }, + { "bmp180", &doExtensionBmp180 }, + { "pseudoPins", &doExtensionPseudoPins }, + { "htu21d", &doExtensionHtu21d }, + { "ds18b20", &doExtensionDs18b20 }, { "mcp3002", &doExtensionMcp3002 }, { "mcp3004", &doExtensionMcp3004 }, { "mcp4802", &doExtensionMcp4802 },