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.pull/62/head
@@ -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 | |||
@@ -22,7 +22,8 @@ | |||
*********************************************************************** | |||
*/ | |||
//#include <stdio.h> | |||
#include <sys/time.h> | |||
#include <stdio.h> | |||
//#include <stdlib.h> | |||
//#include <unistd.h> | |||
@@ -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 ; | |||
*temp = lastTemp ; | |||
return TRUE ; | |||
} | |||
// Set timeout for next read | |||
gettimeofday (&now, NULL) ; | |||
timerclear (&timeOut) ; | |||
timeOut.tv_sec = 2 ; | |||
timeradd (&now, &timeOut, &then) ; | |||
// Read ... | |||
lastResult = maxDetectRead (pin, buffer) ; | |||
result = maxDetectRead (pin, buffer) ; | |||
if (!result) // Try again, but just once | |||
result = maxDetectRead (pin, buffer) ; | |||
if (!result) | |||
return FALSE ; | |||
if (lastResult) | |||
*rh = (buffer [0] * 256 + buffer [1]) ; | |||
*temp = (buffer [2] * 256 + buffer [3]) ; | |||
if ((*temp & 0x8000) != 0) // Negative | |||
{ | |||
*temp = lastTemp = (buffer [2] * 256 + buffer [3]) ; | |||
*rh = lastRh = (buffer [0] * 256 + buffer [1]) ; | |||
nextTime = millis () + 2000 ; | |||
return TRUE ; | |||
*temp &= 0x7FFF ; | |||
*temp = -*temp ; | |||
} | |||
else | |||
{ | |||
// 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 ; | |||
} |
@@ -64,11 +64,11 @@ static unsigned char scrollPhatFont [] = | |||
// 0x24, $ | |||
0x1, // ...* | |||
0x1, // ..*. | |||
0x7, // .*** | |||
0x2, // ..*. | |||
0xE, // ***. | |||
0x8, // *... | |||
0x8, // ..*. | |||
// 0x25, % | |||
@@ -27,7 +27,7 @@ | |||
#include <wiringPi.h> | |||
#include <maxdetect.h> | |||
#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 ; | |||
@@ -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 () ; | |||
@@ -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 () ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 <stdint.h> | |||
#include <fcntl.h> | |||
#include <sys/ioctl.h> | |||
#include <linux/spi/spidev.h> | |||
#include <wiringPi.h> | |||
#include <wiringPiI2C.h> | |||
@@ -38,6 +38,23 @@ | |||
/* | |||
* 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 ; | |||
} |
@@ -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 | |||
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -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 ; | |||
} |
@@ -105,5 +105,5 @@ int sr595Setup (const int pinBase, const int numPins, | |||
pinMode (clockPin, OUTPUT) ; | |||
pinMode (latchPin, OUTPUT) ; | |||
return 0 ; | |||
return TRUE ; | |||
} |
@@ -69,17 +69,13 @@ | |||
#include <sys/stat.h> | |||
#include <sys/wait.h> | |||
#include <sys/ioctl.h> | |||
#include <asm/ioctl.h> | |||
#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: | |||
@@ -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) | |||
@@ -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 ; | |||