From b0a60c3302973ca1878d149d61f2f612c8f27fac Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Mon, 29 Feb 2016 06:57:38 +0000 Subject: [PATCH] Many changes - tidying up the extensions interfaces. Updating the GPIO command - new command - allreadall ScrollPhat code max31855 code (tested with adafruit breakout board) more tests updated rht03 code Raspberry Pi v3 support. --- build | 2 + devLib/maxdetect.c | 131 ++++++++++++++++++++++++++++++--------- devLib/scrollPhatFont.h | 4 +- examples/rht03.c | 47 +++++++++----- gpio/gpio.c | 72 +++++++++++---------- gpio/readall.c | 39 ++++++++++-- wiringPi/ads1115.c | 4 +- wiringPi/drcSerial.c | 13 ++-- wiringPi/max31855.c | 4 +- wiringPi/max5322.c | 4 +- wiringPi/mcp23008.c | 4 +- wiringPi/mcp23016.c | 4 +- wiringPi/mcp23017.c | 4 +- wiringPi/mcp23s08.c | 7 +-- wiringPi/mcp23s17.c | 7 +-- wiringPi/mcp3002.c | 4 +- wiringPi/mcp3004.c | 4 +- wiringPi/mcp3422.c | 51 +++++++++------ wiringPi/mcp3422.h | 12 ++-- wiringPi/mcp4802.c | 4 +- wiringPi/pcf8574.c | 4 +- wiringPi/pcf8591.c | 4 +- wiringPi/sn3218.c | 4 +- wiringPi/sr595.c | 2 +- wiringPi/wiringPi.c | 96 +++++++++++++++++++++++++--- wiringPi/wiringPi.h | 41 +++++++----- wiringPi/wpiExtensions.c | 19 +++--- 27 files changed, 406 insertions(+), 185 deletions(-) diff --git a/build b/build index c2a589c..368e8f4 100755 --- a/build +++ b/build @@ -62,6 +62,8 @@ if [ x$1 = "xclean" ]; then echo -n "Quick2Wire: " ; make clean cd ../PiGlow echo -n "PiGlow: " ; make clean + cd ../scrollPhat + echo -n "scrollPhat: " ; make clean exit fi diff --git a/devLib/maxdetect.c b/devLib/maxdetect.c index 23eabf8..74ff70e 100755 --- a/devLib/maxdetect.c +++ b/devLib/maxdetect.c @@ -22,7 +22,8 @@ *********************************************************************** */ -//#include +#include +#include //#include //#include @@ -38,21 +39,43 @@ /* * maxDetectLowHighWait: - * Wait for a transition from high to low on the bus + * Wait for a transition from low to high on the bus ********************************************************************************* */ -static void maxDetectLowHighWait (const int pin) +static int maxDetectLowHighWait (const int pin) { - unsigned int timeOut = millis () + 2000 ; + struct timeval now, timeOut, timeUp ; + +// If already high then wait for pin to go low + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; while (digitalRead (pin) == HIGH) - if (millis () > timeOut) - return ; + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + +// Wait for it to go HIGH + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; while (digitalRead (pin) == LOW) - if (millis () > timeOut) - return ; + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + + return TRUE ; } @@ -69,7 +92,8 @@ static unsigned int maxDetectClockByte (const int pin) for (bit = 0 ; bit < 8 ; ++bit) { - maxDetectLowHighWait (pin) ; + if (!maxDetectLowHighWait (pin)) + return 0 ; // bit starting now - we need to time it. @@ -95,6 +119,11 @@ int maxDetectRead (const int pin, unsigned char buffer [4]) int i ; unsigned int checksum ; unsigned char localBuf [5] ; + struct timeval now, then, took ; + +// See how long we took + + gettimeofday (&then, NULL) ; // Wake up the RHT03 by pulling the data line low, then high // Low for 10mS, high for 40uS. @@ -106,7 +135,8 @@ int maxDetectRead (const int pin, unsigned char buffer [4]) // Now wait for sensor to pull pin low - maxDetectLowHighWait (pin) ; + if (!maxDetectLowHighWait (pin)) + return FALSE ; // and read in 5 bytes (40 bits) @@ -121,6 +151,22 @@ int maxDetectRead (const int pin, unsigned char buffer [4]) } checksum &= 0xFF ; +// See how long we took + + gettimeofday (&now, NULL) ; + timersub (&now, &then, &took) ; + +// Total time to do this should be: +// 10mS + 40µS - reset +// + 80µS + 80µS - sensor doing its low -> high thing +// + 40 * (50µS + 27µS (0) or 70µS (1) ) +// = 15010µS +// so if we take more than that, we've had a scheduling interruption and the +// reading is probably bogus. + + if ((took.tv_sec != 0) || (took.tv_usec > 16000)) + return FALSE ; + return checksum == localBuf [4] ; } @@ -128,38 +174,65 @@ int maxDetectRead (const int pin, unsigned char buffer [4]) /* * readRHT03: * Read the Temperature & Humidity from an RHT03 sensor + * Values returned are *10, so 123 is 12.3. ********************************************************************************* */ int readRHT03 (const int pin, int *temp, int *rh) { - static unsigned int nextTime = 0 ; - static int lastTemp = 0 ; - static int lastRh = 0 ; - static int lastResult = TRUE ; + static struct timeval then ; // will initialise to zero + static int lastTemp = 0 ; + static int lastRh = 0 ; + int result ; + struct timeval now, timeOut ; unsigned char buffer [4] ; -// Don't read more than once a second +// The data sheets say to not read more than once every 2 seconds, so you +// get the last good reading - if (millis () < nextTime) + gettimeofday (&now, NULL) ; + if (timercmp (&now, &then, <)) { - *temp = lastTemp ; *rh = lastRh ; - return lastResult ; - } - - lastResult = maxDetectRead (pin, buffer) ; - - if (lastResult) - { - *temp = lastTemp = (buffer [2] * 256 + buffer [3]) ; - *rh = lastRh = (buffer [0] * 256 + buffer [1]) ; - nextTime = millis () + 2000 ; + *temp = lastTemp ; return TRUE ; } - else - { + +// Set timeout for next read + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_sec = 2 ; + timeradd (&now, &timeOut, &then) ; + +// Read ... + + result = maxDetectRead (pin, buffer) ; + + if (!result) // Try again, but just once + result = maxDetectRead (pin, buffer) ; + + if (!result) return FALSE ; + + *rh = (buffer [0] * 256 + buffer [1]) ; + *temp = (buffer [2] * 256 + buffer [3]) ; + + if ((*temp & 0x8000) != 0) // Negative + { + *temp &= 0x7FFF ; + *temp = -*temp ; } + +// Discard obviously bogus readings - the checksum can't detect a 2-bit error +// (which does seem to happen - no realtime here) + + if ((*rh > 999) || (*temp > 800) || (*temp < -400)) + return FALSE ; + + lastRh = *rh ; + lastTemp = *temp ; + + return TRUE ; } diff --git a/devLib/scrollPhatFont.h b/devLib/scrollPhatFont.h index 35481f8..92f623a 100644 --- a/devLib/scrollPhatFont.h +++ b/devLib/scrollPhatFont.h @@ -64,11 +64,11 @@ static unsigned char scrollPhatFont [] = // 0x24, $ - 0x1, // ...* + 0x1, // ..*. 0x7, // .*** 0x2, // ..*. 0xE, // ***. - 0x8, // *... + 0x8, // ..*. // 0x25, % diff --git a/examples/rht03.c b/examples/rht03.c index 566e954..854f837 100644 --- a/examples/rht03.c +++ b/examples/rht03.c @@ -27,7 +27,7 @@ #include #include -#define RHT03_PIN 0 +#define RHT03_PIN 7 /* *********************************************************************** @@ -37,32 +37,49 @@ int main (void) { - int temp, rh ; - int newTemp, newRh ; + int result, temp, rh ; + int minT, maxT, minRH, maxRH ; - temp = rh = newTemp = newRh = 0 ; + int numGood, numBad ; wiringPiSetup () ; piHiPri (55) ; + minT = 1000 ; + maxT = -1000 ; + + minRH = 1000 ; + maxRH = -1000 ; + + numGood = numBad = 0 ; + for (;;) { delay (100) ; - if (!readRHT03 (RHT03_PIN, &newTemp, &newRh)) - continue ; + result = readRHT03 (RHT03_PIN, &temp, &rh) ; - if ((temp != newTemp) || (rh != newRh)) + if (!result) { - temp = newTemp ; - rh = newRh ; - if ((temp & 0x8000) != 0) // Negative - { - temp &= 0x7FFF ; - temp = -temp ; - } - printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ; + printf (".") ; + fflush (stdout) ; + ++numBad ; + continue ; } + + ++numGood ; + + if (temp < minT) minT = temp ; + if (temp > maxT) maxT = temp ; + if (rh < minRH) minRH = rh ; + if (rh > maxRH) maxRH = rh ; + + printf ("\r%6d, %6d: ", numGood, numBad) ; + printf ("Temp: %5.1f, RH: %5.1f%%", temp / 10.0, rh / 10.0) ; + printf (" Max/Min Temp: %5.1f:%5.1f", maxT / 10.0, minT / 10.0) ; + printf (" Max/Min RH: %5.1f:%5.1f", maxRH / 10.0, minRH / 10.0) ; + + printf ("\n") ; } return 0 ; diff --git a/gpio/gpio.c b/gpio/gpio.c index 6c95b21..6162090 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -47,6 +47,7 @@ extern int wiringPiDebug ; // External functions I can't be bothered creating a separate .h file for: extern void doReadall (void) ; +extern void doAllReadall (void) ; extern void doPins (void) ; #ifndef TRUE @@ -115,10 +116,12 @@ static void changeOwner (char *cmd, char *file) if (chown (file, uid, gid) != 0) { - if (errno == ENOENT) // Warn that it's not there - fprintf (stderr, "%s: Warning (not an error, do not report): File not present: %s\n", cmd, file) ; - else - fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; + +// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that +// the warning message is an error. + + if (errno != ENOENT) + fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; } } @@ -138,7 +141,7 @@ static int moduleLoaded (char *modName) if (fd == NULL) { - fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ; + fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ; exit (1) ; } @@ -774,13 +777,13 @@ static void doUsbP (int argc, char *argv []) piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if (model != PI_MODEL_BP) + if (!((model == PI_MODEL_BP) || (model == PI_MODEL_2))) { - fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ; + fprintf (stderr, "USB power contol is applicable to B+ and v2 boards only.\n") ; exit (1) ; } -// Need to force BCM_GPIO mode: +// Make sure we start in BCM_GPIO mode wiringPiSetupGpio () ; @@ -1150,7 +1153,8 @@ static void doPwmClock (int argc, char *argv []) /* * doVersion: - * Handle the ever more complicated version command + * Handle the ever more complicated version command and print out + * some usefull information. ********************************************************************************* */ @@ -1166,35 +1170,23 @@ static void doVersion (char *argv []) printf ("\n") ; piBoardId (&model, &rev, &mem, &maker, &warranty) ; -/************* - if (model == PI_MODEL_UNKNOWN) - { - printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ; - printf (" projects@drogon.net\n") ; - printf ("with a copy of your /proc/cpuinfo if possible\n") ; - } - else -***************/ - - { - printf ("Raspberry Pi Details:\n") ; - printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", - piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; + printf ("Raspberry Pi Details:\n") ; + printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", + piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; // Check for device tree - if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... - printf (" Device tree is enabled.\n") ; + if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... + printf (" * Device tree is enabled.\n") ; - if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO - { - printf (" This Raspberry Pi supports user-level GPIO access.\n") ; - printf (" -> See the man-page for more details\n") ; - } - else - printf (" * Root or sudo required for GPIO access.\n") ; - + if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO + { + printf (" * This Raspberry Pi supports user-level GPIO access.\n") ; + printf (" -> See the man-page for more details\n") ; + printf (" -> ie. export WIRINGPI_GPIOMEM=1\n") ; } + else + printf (" * Root or sudo required for GPIO access.\n") ; } @@ -1285,11 +1277,24 @@ int main (int argc, char *argv []) if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; } +// Check for usb power command + + if (strcasecmp (argv [1], "usbp" ) == 0) { doUsbP (argc, argv) ; return 0 ; } + // Gertboard commands if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; } if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; } +// Check for allreadall command, force Gpio mode + + if (strcasecmp (argv [1], "allreadall") == 0) + { + wiringPiSetupGpio () ; + doAllReadall () ; + return 0 ; + } + // Check for -g argument /**/ if (strcasecmp (argv [1], "-g") == 0) @@ -1379,7 +1384,6 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ; else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ; else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; - else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ; else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ; diff --git a/gpio/readall.c b/gpio/readall.c index 278e6ee..cb7e18f 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -215,7 +215,14 @@ static void readallPhys (int physPin) } -void cmReadall (void) +/* + * allReadall: + * Read all the pins regardless of the model. Primarily of use for + * the compute module, but handy for other fiddling... + ********************************************************************************* + */ + +static void allReadall (void) { int pin ; @@ -292,12 +299,16 @@ static void plus2header (int model) printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; else if (model == PI_MODEL_ZERO) printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; - else + else if (model == PI_MODEL_2) printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_3) + printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ; + else + printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; } -void piPlusReadall (int model) +static void piPlusReadall (int model) { int pin ; @@ -314,6 +325,13 @@ void piPlusReadall (int model) } +/* + * doReadall: + * Generic read all pins called from main program. Works out the Pi type + * and calls the appropriate function. + ********************************************************************************* + */ + void doReadall (void) { int model, rev, mem, maker, overVolted ; @@ -328,10 +346,21 @@ void doReadall (void) /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) abReadall (model, rev) ; - else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_ZERO)) + else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_3) || (model == PI_MODEL_ZERO)) piPlusReadall (model) ; else if (model == PI_MODEL_CM) - cmReadall () ; + allReadall () ; else printf ("Oops - unable to determine board type... model: %d\n", model) ; } + +/* + * doAllReadall: + * Force reading of all pins regardless of Pi model + ********************************************************************************* + */ + +void doAllReadall (void) +{ + allReadall () ; +} diff --git a/wiringPi/ads1115.c b/wiringPi/ads1115.c index 62e2a7f..62b92f8 100644 --- a/wiringPi/ads1115.c +++ b/wiringPi/ads1115.c @@ -278,7 +278,7 @@ int ads1115Setup (const int pinBase, int i2cAddr) int fd ; if ((fd = wiringPiI2CSetup (i2cAddr)) < 0) - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 8) ; @@ -289,5 +289,5 @@ int ads1115Setup (const int pinBase, int i2cAddr) node->analogWrite = myAnalogWrite ; node->digitalWrite = myDigitalWrite ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c index 6491a98..db7cc09 100644 --- a/wiringPi/drcSerial.c +++ b/wiringPi/drcSerial.c @@ -1,7 +1,7 @@ /* * drcSerial.c: * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) - * Copyright (c) 2013 Gordon Henderson + * Copyright (c) 2013-2016 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -32,11 +32,6 @@ #include "drcSerial.h" -#ifndef TRUE -# define TRUE (1==1) -# define FALSE (1==2) -#endif - /* * myPinMode: @@ -156,7 +151,7 @@ int drcSetupSerial (const int pinBase, const int numPins, const char *device, co struct wiringPiNodeStruct *node ; if ((fd = serialOpen (device, baud)) < 0) - return wiringPiFailure (WPI_ALMOST, "Unable to open DRC device (%s): %s", device, strerror (errno)) ; + return FALSE ; delay (10) ; // May need longer if it's an Uno that reboots on the open... @@ -184,7 +179,7 @@ int drcSetupSerial (const int pinBase, const int numPins, const char *device, co if (!ok) { serialClose (fd) ; - return wiringPiFailure (WPI_FATAL, "Unable to communicate with DRC serial device") ; + return FALSE ; } node = wiringPiNewNode (pinBase, numPins) ; @@ -197,5 +192,5 @@ int drcSetupSerial (const int pinBase, const int numPins, const char *device, co node->digitalWrite = myDigitalWrite ; node->pwmWrite = myPwmWrite ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/max31855.c b/wiringPi/max31855.c index ea184d8..d86cabd 100644 --- a/wiringPi/max31855.c +++ b/wiringPi/max31855.c @@ -88,12 +88,12 @@ int max31855Setup (const int pinBase, int spiChannel) struct wiringPiNodeStruct *node ; if (wiringPiSPISetup (spiChannel, 5000000) < 0) // 5MHz - prob 4 on the Pi - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 4) ; node->fd = spiChannel ; node->analogRead = myAnalogRead ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/max5322.c b/wiringPi/max5322.c index b7cd6a9..e56b085 100644 --- a/wiringPi/max5322.c +++ b/wiringPi/max5322.c @@ -66,7 +66,7 @@ int max5322Setup (const int pinBase, int spiChannel) unsigned char spiData [2] ; if (wiringPiSPISetup (spiChannel, 8000000) < 0) // 10MHz Max - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 2) ; @@ -80,5 +80,5 @@ int max5322Setup (const int pinBase, int spiChannel) wiringPiSPIDataRW (node->fd, spiData, 2) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c index d21d237..71757a8 100644 --- a/wiringPi/mcp23008.c +++ b/wiringPi/mcp23008.c @@ -132,7 +132,7 @@ int mcp23008Setup (const int pinBase, const int i2cAddress) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ; @@ -145,5 +145,5 @@ int mcp23008Setup (const int pinBase, const int i2cAddress) node->digitalWrite = myDigitalWrite ; node->data2 = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp23016.c b/wiringPi/mcp23016.c index e5cc632..928d9e5 100644 --- a/wiringPi/mcp23016.c +++ b/wiringPi/mcp23016.c @@ -146,7 +146,7 @@ int mcp23016Setup (const int pinBase, const int i2cAddress) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ; wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ; @@ -160,5 +160,5 @@ int mcp23016Setup (const int pinBase, const int i2cAddress) node->data2 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ; node->data3 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp23017.c b/wiringPi/mcp23017.c index 5174195..4c3952d 100644 --- a/wiringPi/mcp23017.c +++ b/wiringPi/mcp23017.c @@ -177,7 +177,7 @@ int mcp23017Setup (const int pinBase, const int i2cAddress) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ; @@ -191,5 +191,5 @@ int mcp23017Setup (const int pinBase, const int i2cAddress) node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ; node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp23s08.c b/wiringPi/mcp23s08.c index d0acb5e..f293f3a 100644 --- a/wiringPi/mcp23s08.c +++ b/wiringPi/mcp23s08.c @@ -167,11 +167,10 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) { - int x ; struct wiringPiNodeStruct *node ; - if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0) - return x ; + if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0) + return FALSE ; writeByte (spiPort, devId, MCP23x08_IOCON, IOCON_INIT) ; @@ -185,5 +184,5 @@ int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) node->digitalWrite = myDigitalWrite ; node->data2 = readByte (spiPort, devId, MCP23x08_OLAT) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp23s17.c b/wiringPi/mcp23s17.c index c2d1be3..42b0358 100644 --- a/wiringPi/mcp23s17.c +++ b/wiringPi/mcp23s17.c @@ -212,11 +212,10 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) int mcp23s17Setup (const int pinBase, const int spiPort, const int devId) { - int x ; struct wiringPiNodeStruct *node ; - if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0) - return x ; + if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0) + return FALSE ; writeByte (spiPort, devId, MCP23x17_IOCON, IOCON_INIT | IOCON_HAEN) ; writeByte (spiPort, devId, MCP23x17_IOCONB, IOCON_INIT | IOCON_HAEN) ; @@ -232,5 +231,5 @@ int mcp23s17Setup (const int pinBase, const int spiPort, const int devId) node->data2 = readByte (spiPort, devId, MCP23x17_OLATA) ; node->data3 = readByte (spiPort, devId, MCP23x17_OLATB) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp3002.c b/wiringPi/mcp3002.c index 5d44940..8e191b6 100644 --- a/wiringPi/mcp3002.c +++ b/wiringPi/mcp3002.c @@ -65,12 +65,12 @@ int mcp3002Setup (const int pinBase, int spiChannel) struct wiringPiNodeStruct *node ; if (wiringPiSPISetup (spiChannel, 1000000) < 0) - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 2) ; node->fd = spiChannel ; node->analogRead = myAnalogRead ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp3004.c b/wiringPi/mcp3004.c index 82c73dd..be8383e 100644 --- a/wiringPi/mcp3004.c +++ b/wiringPi/mcp3004.c @@ -65,12 +65,12 @@ int mcp3004Setup (const int pinBase, int spiChannel) struct wiringPiNodeStruct *node ; if (wiringPiSPISetup (spiChannel, 1000000) < 0) - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 8) ; node->fd = spiChannel ; node->analogRead = myAnalogRead ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp3422.c b/wiringPi/mcp3422.c index 831aece..be14db6 100644 --- a/wiringPi/mcp3422.c +++ b/wiringPi/mcp3422.c @@ -1,8 +1,9 @@ /* * mcp3422.c: - * Extend wiringPi with the MCP3422 I2C ADC chip - * Also works for the MCP3423 and MCP3224 (4 channel) chips - * Copyright (c) 2013 Gordon Henderson + * Extend wiringPi with the MCP3422/3/4 I2C ADC chip + * This code assumes single-ended mode only. + * Tested on actual hardware: 20th Feb 2016. + * Copyright (c) 2013-2016 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -29,7 +30,6 @@ #include #include #include -#include #include #include @@ -37,6 +37,23 @@ #include "mcp3422.h" +/* + * waitForConversion: + * Common code to wait for the ADC to finish conversion + ********************************************************************************* + */ + +void waitForConversion (int fd, unsigned char *buffer, int n) +{ + for (;;) + { + read (fd, buffer, n) ; + if ((buffer [n-1] & 0x80) == 0) + break ; + delay (1) ; + } +} + /* * myAnalogRead: * Read a channel from the device @@ -48,37 +65,34 @@ int myAnalogRead (struct wiringPiNodeStruct *node, int chan) unsigned char config ; unsigned char buffer [4] ; int value = 0 ; + int realChan = (chan & 3) - node->pinBase ; // One-shot mode, trigger plus the other configs. - config = 0x80 | ((chan - node->pinBase) << 5) | (node->data0 << 2) | (node->data1) ; + config = 0x80 | (realChan << 5) | (node->data0 << 2) | (node->data1) ; wiringPiI2CWrite (node->fd, config) ; switch (node->data0) // Sample rate { case MCP3422_SR_3_75: // 18 bits - delay (270) ; - read (node->fd, buffer, 4) ; - value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [0] ; + waitForConversion (node->fd, &buffer [0], 4) ; + value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [2] ; break ; case MCP3422_SR_15: // 16 bits - delay ( 70) ; - read (node->fd, buffer, 3) ; + waitForConversion (node->fd, buffer, 3) ; value = (buffer [0] << 8) | buffer [1] ; break ; case MCP3422_SR_60: // 14 bits - delay ( 17) ; - read (node->fd, buffer, 3) ; + waitForConversion (node->fd, buffer, 3) ; value = ((buffer [0] & 0x3F) << 8) | buffer [1] ; break ; - case MCP3422_SR_240: // 12 bits - delay ( 5) ; - read (node->fd, buffer, 3) ; - value = ((buffer [0] & 0x0F) << 8) | buffer [0] ; + case MCP3422_SR_240: // 12 bits - default + waitForConversion (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x0F) << 8) | buffer [1] ; break ; } @@ -98,13 +112,14 @@ int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; node = wiringPiNewNode (pinBase, 4) ; + node->fd = fd ; node->data0 = sampleRate ; node->data1 = gain ; node->analogRead = myAnalogRead ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/mcp3422.h b/wiringPi/mcp3422.h index bb4692d..72647d4 100644 --- a/wiringPi/mcp3422.h +++ b/wiringPi/mcp3422.h @@ -1,6 +1,6 @@ /* - * mcp3422.c: - * Extend wiringPi with the MCP3422 I2C ADC chip + * mcp3422.h: + * Extend wiringPi with the MCP3422/3/4 I2C ADC chip *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -21,10 +21,10 @@ *********************************************************************** */ -#define MCP3422_SR_3_75 0 -#define MCP3422_SR_15 1 -#define MCP3422_SR_60 2 -#define MCP3422_SR_240 3 +#define MCP3422_SR_240 0 +#define MCP3422_SR_60 1 +#define MCP3422_SR_15 2 +#define MCP3422_SR_3_75 3 #define MCP3422_GAIN_1 0 #define MCP3422_GAIN_2 1 diff --git a/wiringPi/mcp4802.c b/wiringPi/mcp4802.c index 5c5c17a..ef104ed 100644 --- a/wiringPi/mcp4802.c +++ b/wiringPi/mcp4802.c @@ -65,12 +65,12 @@ int mcp4802Setup (const int pinBase, int spiChannel) struct wiringPiNodeStruct *node ; if (wiringPiSPISetup (spiChannel, 1000000) < 0) - return -1 ; + return FALSE ; node = wiringPiNewNode (pinBase, 2) ; node->fd = spiChannel ; node->analogWrite = myAnalogWrite ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/pcf8574.c b/wiringPi/pcf8574.c index c172d1c..e0b686a 100644 --- a/wiringPi/pcf8574.c +++ b/wiringPi/pcf8574.c @@ -112,7 +112,7 @@ int pcf8574Setup (const int pinBase, const int i2cAddress) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; node = wiringPiNewNode (pinBase, 8) ; @@ -122,5 +122,5 @@ int pcf8574Setup (const int pinBase, const int i2cAddress) node->digitalWrite = myDigitalWrite ; node->data2 = wiringPiI2CRead (fd) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/pcf8591.c b/wiringPi/pcf8591.c index 0c86056..0c43d26 100644 --- a/wiringPi/pcf8591.c +++ b/wiringPi/pcf8591.c @@ -78,7 +78,7 @@ int pcf8591Setup (const int pinBase, const int i2cAddress) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) - return fd ; + return FALSE ; node = wiringPiNewNode (pinBase, 4) ; @@ -86,5 +86,5 @@ int pcf8591Setup (const int pinBase, const int i2cAddress) node->analogRead = myAnalogRead ; node->analogWrite = myAnalogWrite ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/sn3218.c b/wiringPi/sn3218.c index 7ceb156..d9b9113 100644 --- a/wiringPi/sn3218.c +++ b/wiringPi/sn3218.c @@ -55,7 +55,7 @@ int sn3218Setup (const int pinBase) struct wiringPiNodeStruct *node ; if ((fd = wiringPiI2CSetup (0x54)) < 0) - return fd ; + return FALSE ; // Setup the chip - initialise all 18 LEDs to off @@ -71,5 +71,5 @@ int sn3218Setup (const int pinBase) node->fd = fd ; node->analogWrite = myAnalogWrite ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c index 87210c2..8280618 100644 --- a/wiringPi/sr595.c +++ b/wiringPi/sr595.c @@ -105,5 +105,5 @@ int sr595Setup (const int pinBase, const int numPins, pinMode (clockPin, OUTPUT) ; pinMode (latchPin, OUTPUT) ; - return 0 ; + return TRUE ; } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 03c97c5..dfd5de4 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -69,17 +69,13 @@ #include #include #include +#include #include "softPwm.h" #include "softTone.h" #include "wiringPi.h" -#ifndef TRUE -#define TRUE (1==1) -#define FALSE (1==2) -#endif - // Environment Variables #define ENV_DEBUG "WIRINGPI_DEBUG" @@ -219,7 +215,7 @@ const char *piModelNames [16] = "Alpha", // 5 "CM", // 6 "Unknown07", // 07 - "Unknown08", // 08 + "Pi 3", // 08 "Pi Zero", // 09 "Unknown10", // 10 "Unknown11", // 11 @@ -894,7 +890,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) *c = 0 ; if (wiringPiDebug) - printf ("piboardId: Revision string: %s\n", line) ; + printf ("piBoardId: Revision string: %s\n", line) ; // Need to work out if it's using the new or old encoding scheme: @@ -1624,16 +1620,21 @@ void pwmToneWrite (int pin, int freq) /* * digitalWriteByte: + * digitalReadByte: * Pi Specific * Write an 8-bit byte to the first 8 GPIO pins - try to do it as * fast as possible. * However it still needs 2 operations to set the bits, so any external * hardware must not rely on seeing a change as there will be a change * to set the outputs bits to zero, then another change to set the 1's + * 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 ********************************************************************************* */ -void digitalWriteByte (int value) +void digitalWriteByte (const int value) { uint32_t pinSet = 0 ; uint32_t pinClr = 0 ; @@ -1644,7 +1645,7 @@ void digitalWriteByte (int value) { for (pin = 0 ; pin < 8 ; ++pin) { - digitalWrite (pin, value & mask) ; + digitalWrite (pinToGpio [pin], value & mask) ; mask <<= 1 ; } return ; @@ -1666,6 +1667,83 @@ void digitalWriteByte (int value) } } +unsigned int digitalReadByte (void) +{ + int pin, x ; + uint32_t raw ; + uint32_t data = 0 ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 0 ; pin < 8 ; ++pin) + { + x = digitalRead (pinToGpio [pin]) ; + data = (data << 1) | x ; + } + } + else + { + raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins + for (pin = 0 ; pin < 8 ; ++pin) + { + x = pinToGpio [pin] ; + data = (data << 1) | (((raw & (1 << x)) == 0) ? 0 : 1) ; + } + } + return data ; +} + + +/* + * digitalWriteByte2: + * digitalReadByte2: + * Pi Specific + * Write an 8-bit byte to the second set of 8 GPIO pins. This is marginally + * faster than the first lot as these are consecutive BCM_GPIO pin numbers. + * However they overlap with the original read/write bytes. + ********************************************************************************* + */ + +void digitalWriteByte2 (const int value) +{ + register int mask = 1 ; + register int pin ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 20 ; pin < 28 ; ++pin) + { + digitalWrite (pin, value & mask) ; + mask <<= 1 ; + } + return ; + } + else + { + *(gpio + gpioToGPCLR [0]) = 0x0FF00000 ; + *(gpio + gpioToGPSET [0]) = (value & 0xFF) << 20 ; + } +} + +unsigned int digitalReadByte2 (void) +{ + int pin, x ; + uint32_t data = 0 ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 20 ; pin < 28 ; ++pin) + { + x = digitalRead (pin) ; + data = (data << 1) | x ; + } + } + else + data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins + + return data ; +} + /* * waitForInterrupt: diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 7b9605f..e11a0be 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -1,7 +1,7 @@ /* - * wiringPi: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012 Gordon Henderson + * wiringPi.h: + * Arduino like Wiring library for the Raspberry Pi. + * Copyright (c) 2012-2016 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -24,6 +24,14 @@ #ifndef __WIRING_PI_H__ #define __WIRING_PI_H__ +// C doesn't have true/false by default and I can never remember which +// way round they are, so ... + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + // Handy defines // wiringPi modes @@ -77,7 +85,7 @@ #define PI_ALPHA 5 #define PI_MODEL_CM 6 #define PI_MODEL_07 7 -#define PI_MODEL_08 8 +#define PI_MODEL_3 8 #define PI_MODEL_ZERO 9 #define PI_VERSION_1 0 @@ -182,18 +190,19 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio // On-Board Raspberry Pi hardware specific stuff -extern int piBoardRev (void) ; -extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; -extern int wpiPinToGpio (int wpiPin) ; -extern int physPinToGpio (int physPin) ; -extern void setPadDrive (int group, int value) ; -extern int getAlt (int pin) ; -extern void pwmToneWrite (int pin, int freq) ; -extern void digitalWriteByte (int value) ; -extern void pwmSetMode (int mode) ; -extern void pwmSetRange (unsigned int range) ; -extern void pwmSetClock (int divisor) ; -extern void gpioClockSet (int pin, int freq) ; +extern int piBoardRev (void) ; +extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; +extern int wpiPinToGpio (int wpiPin) ; +extern int physPinToGpio (int physPin) ; +extern void setPadDrive (int group, int value) ; +extern int getAlt (int pin) ; +extern void pwmToneWrite (int pin, int freq) ; +extern void digitalWriteByte (int value) ; +extern unsigned int digitalReadByte (void) ; +extern void pwmSetMode (int mode) ; +extern void pwmSetRange (unsigned int range) ; +extern void pwmSetClock (int divisor) ; +extern void gpioClockSet (int pin, int freq) ; // Interrupts // (Also Pi hardware specific) diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c index b25428c..62a92d7 100644 --- a/wiringPi/wpiExtensions.c +++ b/wiringPi/wpiExtensions.c @@ -64,11 +64,6 @@ static int verbose ; static char errorMessage [1024] ; -#ifndef TRUE -# define TRUE (1==1) -# define FALSE (1==2) -#endif - // Local structure to hold details struct extensionFunctionStruct @@ -119,7 +114,13 @@ static char *extractInt (char *progName, char *p, int *num) } *num = strtol (p, NULL, 0) ; - while (isdigit (*p)) + +// Increment p, but we need to check for hex 0x + + if ((*p == '0') && (*(p + 1) == 'x')) + p +=2 ; + + while (isxdigit (*p)) ++p ; return p ; @@ -702,7 +703,7 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors) char *p ; char *extension = extensionData ; struct extensionFunctionStruct *extensionFn ; - int pinBase = 0 ; + unsigned pinBase = 0 ; verbose = printErrors ; @@ -724,13 +725,13 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors) if (!isdigit (*p)) { - verbError ("%s: pinBase number expected after extension name", progName) ; + verbError ("%s: decimal pinBase number expected after extension name", progName) ; return FALSE ; } while (isdigit (*p)) { - if (pinBase > 1000000000) // Lets be realistic here... + if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here... { verbError ("%s: pinBase too large", progName) ; return FALSE ;