You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
928 lines
20 KiB
928 lines
20 KiB
/* |
|
* extensions.c: |
|
* Originally part of the GPIO program to test, peek, poke and otherwise |
|
* noodle with the GPIO hardware on the Raspberry Pi. |
|
* Now used as a general purpose library to allow systems to dynamically |
|
* add in new devices into wiringPi at program run-time. |
|
* Copyright (c) 2012-2015 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 <http://www.gnu.org/licenses/>. |
|
*********************************************************************** |
|
*/ |
|
|
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <stdint.h> |
|
#include <stdarg.h> |
|
#include <ctype.h> |
|
#include <string.h> |
|
#include <unistd.h> |
|
#include <errno.h> |
|
#include <sys/types.h> |
|
#include <fcntl.h> |
|
|
|
#include <wiringPi.h> |
|
|
|
#include "mcp23008.h" |
|
#include "mcp23016.h" |
|
#include "mcp23017.h" |
|
#include "mcp23s08.h" |
|
#include "mcp23s17.h" |
|
#include "sr595.h" |
|
#include "pcf8574.h" |
|
#include "pcf8591.h" |
|
#include "mcp3002.h" |
|
#include "mcp3004.h" |
|
#include "mcp4802.h" |
|
#include "mcp3422.h" |
|
#include "max31855.h" |
|
#include "max5322.h" |
|
#include "ads1115.h" |
|
#include "sn3218.h" |
|
#include "drcSerial.h" |
|
#include "drcNet.h" |
|
#include "../wiringPiD/drcNetCmd.h" |
|
#include "pseudoPins.h" |
|
#include "bmp180.h" |
|
#include "htu21d.h" |
|
#include "ds18b20.h" |
|
#include "rht03.h" |
|
|
|
#include "wpiExtensions.h" |
|
|
|
extern int wiringPiDebug ; |
|
|
|
static int verbose ; |
|
static char errorMessage [1024] ; |
|
|
|
|
|
// Local structure to hold details |
|
|
|
struct extensionFunctionStruct |
|
{ |
|
const char *name ; |
|
int (*function)(char *progName, int pinBase, char *params) ; |
|
} ; |
|
|
|
|
|
/* |
|
* verbError: |
|
* Convenient error handling |
|
********************************************************************************* |
|
*/ |
|
|
|
static void verbError (const char *message, ...) |
|
{ |
|
va_list argp ; |
|
va_start (argp, message) ; |
|
vsnprintf (errorMessage, 1023, message, argp) ; |
|
va_end (argp) ; |
|
|
|
if (verbose) |
|
fprintf (stderr, "%s\n", errorMessage) ; |
|
} |
|
|
|
|
|
/* |
|
* extractInt: |
|
* Check & return an integer at the given location (prefixed by a :) |
|
********************************************************************************* |
|
*/ |
|
|
|
static char *extractInt (char *progName, char *p, int *num) |
|
{ |
|
if (*p != ':') |
|
{ |
|
verbError ("%s: colon expected", progName) ; |
|
return NULL ; |
|
} |
|
|
|
++p ; |
|
|
|
if (!isdigit (*p)) |
|
{ |
|
verbError ("%s: digit expected", progName) ; |
|
return NULL ; |
|
} |
|
|
|
*num = strtol (p, NULL, 0) ; |
|
|
|
// Increment p, but we need to check for hex 0x |
|
|
|
if ((*p == '0') && (*(p + 1) == 'x')) |
|
p +=2 ; |
|
|
|
while (isxdigit (*p)) |
|
++p ; |
|
|
|
return p ; |
|
} |
|
|
|
|
|
/* |
|
* extractStr: |
|
* Check & return a string at the given location (prefixed by a :) |
|
* Note: The string can be enclosed in []'s to escape colons. This is |
|
* so we can handle IPv6 addresses which contain colons and the []'s is |
|
* a common way to prepresent them. |
|
********************************************************************************* |
|
*/ |
|
|
|
static char *extractStr (char *progName, char *p, char **str) |
|
{ |
|
char *q, *r ; |
|
int quoted = FALSE ; |
|
|
|
if (*p != ':') |
|
{ |
|
verbError ("%s: colon expected", progName) ; |
|
return NULL ; |
|
} |
|
|
|
++p ; |
|
|
|
if (*p == '[') |
|
{ |
|
quoted = TRUE ; |
|
++p ; |
|
} |
|
|
|
if (!isprint (*p)) // Is this needed? |
|
{ |
|
verbError ("%s: character expected", progName) ; |
|
return NULL ; |
|
} |
|
|
|
q = p ; |
|
if (quoted) |
|
{ |
|
while ((*q != 0) && (*q != ']')) |
|
++q ; |
|
} |
|
else |
|
{ |
|
while ((*q != 0) && (*q != ':')) |
|
++q ; |
|
} |
|
|
|
*str = r = calloc (q - p + 2, 1) ; // Zeros it |
|
|
|
while (p != q) |
|
*r++ = *p++ ; |
|
|
|
if (quoted) // Skip over the ] to the : |
|
++p ; |
|
|
|
return p ; |
|
} |
|
|
|
|
|
|
|
/* |
|
* doExtensionMcp23008: |
|
* MCP23008 - 8-bit I2C GPIO expansion chip |
|
* mcp23002:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp23008 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x01) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp23008Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp23016: |
|
* MCP230016- 16-bit I2C GPIO expansion chip |
|
* mcp23016:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp23016 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp23016Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp23017: |
|
* MCP230017- 16-bit I2C GPIO expansion chip |
|
* mcp23017:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp23017 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp23017Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp23s08: |
|
* MCP23s08 - 8-bit SPI GPIO expansion chip |
|
* mcp23s08:base:spi:port |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp23s08 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi, port ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI address (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &port)) == NULL) |
|
return FALSE ; |
|
|
|
if ((port < 0) || (port > 7)) |
|
{ |
|
verbError ("%s: port address (%d) out of range", progName, port) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp23s08Setup (pinBase, spi, port) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp23s17: |
|
* MCP23s17 - 16-bit SPI GPIO expansion chip |
|
* mcp23s17:base:spi:port |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp23s17 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi, port ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI address (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &port)) == NULL) |
|
return FALSE ; |
|
|
|
if ((port < 0) || (port > 7)) |
|
{ |
|
verbError ("%s: port address (%d) out of range", progName, port) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp23s17Setup (pinBase, spi, port) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionSr595: |
|
* Shift Register 74x595 |
|
* sr595:base:pins:data:clock:latch |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionSr595 (char *progName, int pinBase, char *params) |
|
{ |
|
int pins, data, clock, latch ; |
|
|
|
// Extract pins |
|
|
|
if ((params = extractInt (progName, params, &pins)) == NULL) |
|
return FALSE ; |
|
|
|
if ((pins < 8) || (pins > 32)) |
|
{ |
|
verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &data)) == NULL) |
|
return FALSE ; |
|
|
|
if ((params = extractInt (progName, params, &clock)) == NULL) |
|
return FALSE ; |
|
|
|
if ((params = extractInt (progName, params, &latch)) == NULL) |
|
return FALSE ; |
|
|
|
sr595Setup (pinBase, pins, data, clock, latch) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionPcf8574: |
|
* Digital IO (Crude!) |
|
* pcf8574:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionPcf8574 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
pcf8574Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionAds1115: |
|
* Analog Input |
|
* ads1115:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionAds1115 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
ads1115Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionPcf8591: |
|
* Analog IO |
|
* pcf8591:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionPcf8591 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
pcf8591Setup (pinBase, i2c) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionPseudoPins: |
|
* 64 Memory resident pseudo pins |
|
* pseudoPins:base |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionPseudoPins (UNU char *progName, int pinBase, UNU char *params) |
|
{ |
|
pseudoPinsSetup (pinBase) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionBmp180: |
|
* Analog Temp + Pressure |
|
* bmp180:base |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionBmp180 (UNU char *progName, int pinBase, UNU char *params) |
|
{ |
|
bmp180Setup (pinBase) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionHtu21d: |
|
* Analog humidity + Pressure |
|
* htu21d:base |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionHtu21d (UNU char *progName, int pinBase, UNU 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) ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionRht03: |
|
* Maxdetect 1-Wire Temperature & Humidity |
|
* rht03:base:piPin |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionRht03 (char *progName, int pinBase, char *params) |
|
{ |
|
int piPin ; |
|
|
|
if ((params = extractInt (progName, params, &piPin)) == NULL) |
|
return FALSE ; |
|
|
|
return rht03Setup (pinBase, piPin) ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMax31855: |
|
* Analog IO |
|
* max31855:base:spiChan |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMax31855 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI channel (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
max31855Setup (pinBase, spi) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp3002: |
|
* Analog IO |
|
* mcp3002:base:spiChan |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp3002 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI channel (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp3002Setup (pinBase, spi) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp3004: |
|
* Analog IO |
|
* mcp3004:base:spiChan |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp3004 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI channel (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp3004Setup (pinBase, spi) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMax5322: |
|
* Analog O |
|
* max5322:base:spiChan |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMax5322 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI channel (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
max5322Setup (pinBase, spi) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp4802: |
|
* Analog IO |
|
* mcp4802:base:spiChan |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp4802 (char *progName, int pinBase, char *params) |
|
{ |
|
int spi ; |
|
|
|
if ((params = extractInt (progName, params, &spi)) == NULL) |
|
return FALSE ; |
|
|
|
if ((spi < 0) || (spi > 1)) |
|
{ |
|
verbError ("%s: SPI channel (%d) out of range", progName, spi) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp4802Setup (pinBase, spi) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionSn3218: |
|
* Analog Output (LED Driver) |
|
* sn3218:base |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params) |
|
{ |
|
sn3218Setup (pinBase) ; |
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionMcp3422: |
|
* Analog IO |
|
* mcp3422:base:i2cAddr |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionMcp3422 (char *progName, int pinBase, char *params) |
|
{ |
|
int i2c, sampleRate, gain ; |
|
|
|
if ((params = extractInt (progName, params, &i2c)) == NULL) |
|
return FALSE ; |
|
|
|
if ((i2c < 0x03) || (i2c > 0x77)) |
|
{ |
|
verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &sampleRate)) == NULL) |
|
return FALSE ; |
|
|
|
if ((sampleRate < 0) || (sampleRate > 3)) |
|
{ |
|
verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &gain)) == NULL) |
|
return FALSE ; |
|
|
|
if ((gain < 0) || (gain > 3)) |
|
{ |
|
verbError ("%s: gain (%d) out of range", progName, gain) ; |
|
return FALSE ; |
|
} |
|
|
|
mcp3422Setup (pinBase, i2c, sampleRate, gain) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionDrcS: |
|
* Interface to a DRC Serial system |
|
* drcs:base:pins:serialPort:baud |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionDrcS (char *progName, int pinBase, char *params) |
|
{ |
|
char *port ; |
|
int pins, baud ; |
|
|
|
if ((params = extractInt (progName, params, &pins)) == NULL) |
|
return FALSE ; |
|
|
|
if ((pins < 1) || (pins > 1000)) |
|
{ |
|
verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractStr (progName, params, &port)) == NULL) |
|
return FALSE ; |
|
|
|
if (strlen (port) == 0) |
|
{ |
|
verbError ("%s: serial port device name required", progName) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractInt (progName, params, &baud)) == NULL) |
|
return FALSE ; |
|
|
|
if ((baud < 1) || (baud > 4000000)) |
|
{ |
|
verbError ("%s: baud rate (%d) out of range", progName, baud) ; |
|
return FALSE ; |
|
} |
|
|
|
drcSetupSerial (pinBase, pins, port, baud) ; |
|
|
|
return TRUE ; |
|
} |
|
|
|
|
|
/* |
|
* doExtensionDrcNet: |
|
* Interface to a DRC Network system |
|
* drcn:base:pins:ipAddress:port:password |
|
********************************************************************************* |
|
*/ |
|
|
|
static int doExtensionDrcNet (char *progName, int pinBase, char *params) |
|
{ |
|
int pins ; |
|
char *ipAddress, *port, *password ; |
|
char pPort [1024] ; |
|
|
|
if ((params = extractInt (progName, params, &pins)) == NULL) |
|
return FALSE ; |
|
|
|
if ((pins < 1) || (pins > 1000)) |
|
{ |
|
verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractStr (progName, params, &ipAddress)) == NULL) |
|
return FALSE ; |
|
|
|
if (strlen (ipAddress) == 0) |
|
{ |
|
verbError ("%s: ipAddress required", progName) ; |
|
return FALSE ; |
|
} |
|
|
|
if ((params = extractStr (progName, params, &port)) == NULL) |
|
return FALSE ; |
|
|
|
if (strlen (port) == 0) |
|
{ |
|
sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ; |
|
port = pPort ; |
|
} |
|
|
|
if ((params = extractStr (progName, params, &password)) == NULL) |
|
return FALSE ; |
|
|
|
if (strlen (password) == 0) |
|
{ |
|
verbError ("%s: password required", progName) ; |
|
return FALSE ; |
|
} |
|
|
|
return drcSetupNet (pinBase, pins, ipAddress, port, password) ; |
|
} |
|
|
|
|
|
|
|
/* |
|
* Function list |
|
********************************************************************************* |
|
*/ |
|
|
|
static struct extensionFunctionStruct extensionFunctions [] = |
|
{ |
|
{ "mcp23008", &doExtensionMcp23008 }, |
|
{ "mcp23016", &doExtensionMcp23016 }, |
|
{ "mcp23017", &doExtensionMcp23017 }, |
|
{ "mcp23s08", &doExtensionMcp23s08 }, |
|
{ "mcp23s17", &doExtensionMcp23s17 }, |
|
{ "sr595", &doExtensionSr595 }, |
|
{ "pcf8574", &doExtensionPcf8574 }, |
|
{ "pcf8591", &doExtensionPcf8591 }, |
|
{ "bmp180", &doExtensionBmp180 }, |
|
{ "pseudoPins", &doExtensionPseudoPins }, |
|
{ "htu21d", &doExtensionHtu21d }, |
|
{ "ds18b20", &doExtensionDs18b20 }, |
|
{ "rht03", &doExtensionRht03 }, |
|
{ "mcp3002", &doExtensionMcp3002 }, |
|
{ "mcp3004", &doExtensionMcp3004 }, |
|
{ "mcp4802", &doExtensionMcp4802 }, |
|
{ "mcp3422", &doExtensionMcp3422 }, |
|
{ "max31855", &doExtensionMax31855 }, |
|
{ "ads1115", &doExtensionAds1115 }, |
|
{ "max5322", &doExtensionMax5322 }, |
|
{ "sn3218", &doExtensionSn3218 }, |
|
{ "drcs", &doExtensionDrcS }, |
|
{ "drcn", &doExtensionDrcNet }, |
|
{ NULL, NULL }, |
|
} ; |
|
|
|
|
|
/* |
|
* loadWPiExtension: |
|
* Load in a wiringPi extension |
|
* The extensionData always starts with the name, a colon then the pinBase |
|
* number. Other parameters after that are decoded by the module in question. |
|
********************************************************************************* |
|
*/ |
|
|
|
int loadWPiExtension (char *progName, char *extensionData, int printErrors) |
|
{ |
|
char *p ; |
|
char *extension = extensionData ; |
|
struct extensionFunctionStruct *extensionFn ; |
|
int pinBase = 0 ; |
|
|
|
verbose = printErrors ; |
|
|
|
// Get the extension name by finding the first colon |
|
|
|
p = extension ; |
|
while (*p != ':') |
|
{ |
|
if (!*p) // ran out of characters |
|
{ |
|
verbError ("%s: extension name not terminated by a colon", progName) ; |
|
return FALSE ; |
|
} |
|
++p ; |
|
} |
|
*p++ = 0 ; |
|
|
|
// Simple ATOI code |
|
|
|
if (!isdigit (*p)) |
|
{ |
|
verbError ("%s: decimal pinBase number expected after extension name", progName) ; |
|
return FALSE ; |
|
} |
|
|
|
while (isdigit (*p)) |
|
{ |
|
if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here... |
|
{ |
|
verbError ("%s: pinBase too large", progName) ; |
|
return FALSE ; |
|
} |
|
|
|
pinBase = pinBase * 10 + (*p - '0') ; |
|
++p ; |
|
} |
|
|
|
if (pinBase < 64) |
|
{ |
|
verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ; |
|
return FALSE ; |
|
} |
|
|
|
// Search for extensions: |
|
|
|
for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn) |
|
{ |
|
if (strcmp (extensionFn->name, extension) == 0) |
|
return extensionFn->function (progName, pinBase, p) ; |
|
} |
|
|
|
fprintf (stderr, "%s: extension %s not found", progName, extension) ; |
|
return FALSE ; |
|
}
|
|
|