3 * Originally part of the GPIO program to test, peek, poke and otherwise
4 * noodle with the GPIO hardware on the Raspberry Pi.
5 * Now used as a general purpose library to allow systems to dynamically
6 * add in new devices into wiringPi at program run-time.
7 * Copyright (c) 2012-2015 Gordon Henderson
8 ***********************************************************************
9 * This file is part of wiringPi:
10 * https://projects.drogon.net/raspberry-pi/wiringpi/
12 * wiringPi is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * wiringPi is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
24 ***********************************************************************
36 #include <sys/types.h>
56 #include "drcSerial.h"
58 #include "wpiExtensions.h"
60 extern int wiringPiDebug ;
63 static char errorMessage [1024] ;
71 // Local structure to hold details
73 struct extensionFunctionStruct
76 int (*function)(char *progName, int pinBase, char *params) ;
82 * Convenient error handling
83 *********************************************************************************
86 static void verbError (const char *message, ...)
89 va_start (argp, message) ;
90 vsnprintf (errorMessage, 1023, message, argp) ;
94 fprintf (stderr, "%s\n", errorMessage) ;
100 * Check & return an integer at the given location (prefixed by a :)
101 *********************************************************************************
104 static char *extractInt (char *progName, char *p, int *num)
108 verbError ("%s: colon expected", progName) ;
116 verbError ("%s: digit expected", progName) ;
120 *num = strtol (p, NULL, 0) ;
130 * Check & return a string at the given location (prefixed by a :)
131 *********************************************************************************
134 static char *extractStr (char *progName, char *p, char **str)
140 verbError ("%s: colon expected", progName) ;
148 verbError ("%s: character expected", progName) ;
153 while ((*q != 0) && (*q != ':'))
156 *str = r = calloc (q - p + 2, 1) ; // Zeros it
167 * doExtensionMcp23008:
168 * MCP23008 - 8-bit I2C GPIO expansion chip
169 * mcp23002:base:i2cAddr
170 *********************************************************************************
173 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
177 if ((params = extractInt (progName, params, &i2c)) == NULL)
180 if ((i2c < 0x01) || (i2c > 0x77))
182 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
186 mcp23008Setup (pinBase, i2c) ;
193 * doExtensionMcp23016:
194 * MCP230016- 16-bit I2C GPIO expansion chip
195 * mcp23016:base:i2cAddr
196 *********************************************************************************
199 static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
203 if ((params = extractInt (progName, params, &i2c)) == NULL)
206 if ((i2c < 0x03) || (i2c > 0x77))
208 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
212 mcp23016Setup (pinBase, i2c) ;
219 * doExtensionMcp23017:
220 * MCP230017- 16-bit I2C GPIO expansion chip
221 * mcp23017:base:i2cAddr
222 *********************************************************************************
225 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
229 if ((params = extractInt (progName, params, &i2c)) == NULL)
232 if ((i2c < 0x03) || (i2c > 0x77))
234 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
238 mcp23017Setup (pinBase, i2c) ;
245 * doExtensionMcp23s08:
246 * MCP23s08 - 8-bit SPI GPIO expansion chip
247 * mcp23s08:base:spi:port
248 *********************************************************************************
251 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
255 if ((params = extractInt (progName, params, &spi)) == NULL)
258 if ((spi < 0) || (spi > 1))
260 verbError ("%s: SPI address (%d) out of range", progName, spi) ;
264 if ((params = extractInt (progName, params, &port)) == NULL)
267 if ((port < 0) || (port > 7))
269 verbError ("%s: port address (%d) out of range", progName, port) ;
273 mcp23s08Setup (pinBase, spi, port) ;
280 * doExtensionMcp23s17:
281 * MCP23s17 - 16-bit SPI GPIO expansion chip
282 * mcp23s17:base:spi:port
283 *********************************************************************************
286 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
290 if ((params = extractInt (progName, params, &spi)) == NULL)
293 if ((spi < 0) || (spi > 1))
295 verbError ("%s: SPI address (%d) out of range", progName, spi) ;
299 if ((params = extractInt (progName, params, &port)) == NULL)
302 if ((port < 0) || (port > 7))
304 verbError ("%s: port address (%d) out of range", progName, port) ;
308 mcp23s17Setup (pinBase, spi, port) ;
316 * Shift Register 74x595
317 * sr595:base:pins:data:clock:latch
318 *********************************************************************************
321 static int doExtensionSr595 (char *progName, int pinBase, char *params)
323 int pins, data, clock, latch ;
327 if ((params = extractInt (progName, params, &pins)) == NULL)
330 if ((pins < 8) || (pins > 32))
332 verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ;
336 if ((params = extractInt (progName, params, &data)) == NULL)
339 if ((params = extractInt (progName, params, &clock)) == NULL)
342 if ((params = extractInt (progName, params, &latch)) == NULL)
345 sr595Setup (pinBase, pins, data, clock, latch) ;
352 * doExtensionPcf8574:
353 * Digital IO (Crude!)
354 * pcf8574:base:i2cAddr
355 *********************************************************************************
358 static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
362 if ((params = extractInt (progName, params, &i2c)) == NULL)
365 if ((i2c < 0x03) || (i2c > 0x77))
367 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
371 pcf8574Setup (pinBase, i2c) ;
378 * doExtensionPcf8591:
380 * pcf8591:base:i2cAddr
381 *********************************************************************************
384 static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
388 if ((params = extractInt (progName, params, &i2c)) == NULL)
391 if ((i2c < 0x03) || (i2c > 0x77))
393 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
397 pcf8591Setup (pinBase, i2c) ;
404 * doExtensionMax31855:
406 * max31855:base:spiChan
407 *********************************************************************************
410 static int doExtensionMax31855 (char *progName, int pinBase, char *params)
414 if ((params = extractInt (progName, params, &spi)) == NULL)
417 if ((spi < 0) || (spi > 1))
419 verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
423 max31855Setup (pinBase, spi) ;
430 * doExtensionMcp3002:
432 * mcp3002:base:spiChan
433 *********************************************************************************
436 static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
440 if ((params = extractInt (progName, params, &spi)) == NULL)
443 if ((spi < 0) || (spi > 1))
445 verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
449 mcp3002Setup (pinBase, spi) ;
456 * doExtensionMcp3004:
458 * mcp3004:base:spiChan
459 *********************************************************************************
462 static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
466 if ((params = extractInt (progName, params, &spi)) == NULL)
469 if ((spi < 0) || (spi > 1))
471 verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
475 mcp3004Setup (pinBase, spi) ;
482 * doExtensionMax5322:
484 * max5322:base:spiChan
485 *********************************************************************************
488 static int doExtensionMax5322 (char *progName, int pinBase, char *params)
492 if ((params = extractInt (progName, params, &spi)) == NULL)
495 if ((spi < 0) || (spi > 1))
497 verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
501 max5322Setup (pinBase, spi) ;
508 * doExtensionMcp4802:
510 * mcp4802:base:spiChan
511 *********************************************************************************
514 static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
518 if ((params = extractInt (progName, params, &spi)) == NULL)
521 if ((spi < 0) || (spi > 1))
523 verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
527 mcp4802Setup (pinBase, spi) ;
535 * Analog Output (LED Driver)
537 *********************************************************************************
540 static int doExtensionSn3218 (char *progName, int pinBase, char *params)
542 sn3218Setup (pinBase) ;
548 * doExtensionMcp3422:
550 * mcp3422:base:i2cAddr
551 *********************************************************************************
554 static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
556 int i2c, sampleRate, gain ;
558 if ((params = extractInt (progName, params, &i2c)) == NULL)
561 if ((i2c < 0x03) || (i2c > 0x77))
563 verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
567 if ((params = extractInt (progName, params, &sampleRate)) == NULL)
570 if ((sampleRate < 0) || (sampleRate > 3))
572 verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ;
576 if ((params = extractInt (progName, params, &gain)) == NULL)
579 if ((gain < 0) || (gain > 3))
581 verbError ("%s: gain (%d) out of range", progName, gain) ;
585 mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
593 * Interface to a DRC Serial system
594 * drcs:base:pins:serialPort:baud
595 *********************************************************************************
598 static int doExtensionDrcS (char *progName, int pinBase, char *params)
603 if ((params = extractInt (progName, params, &pins)) == NULL)
606 if ((pins < 1) || (pins > 100))
608 verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ;
612 if ((params = extractStr (progName, params, &port)) == NULL)
615 if (strlen (port) == 0)
617 verbError ("%s: serial port device name required", progName) ;
621 if ((params = extractInt (progName, params, &baud)) == NULL)
624 if ((baud < 1) || (baud > 4000000))
626 verbError ("%s: baud rate (%d) out of range", progName, baud) ;
630 drcSetupSerial (pinBase, pins, port, baud) ;
639 *********************************************************************************
642 static struct extensionFunctionStruct extensionFunctions [] =
644 { "mcp23008", &doExtensionMcp23008 },
645 { "mcp23016", &doExtensionMcp23016 },
646 { "mcp23017", &doExtensionMcp23017 },
647 { "mcp23s08", &doExtensionMcp23s08 },
648 { "mcp23s17", &doExtensionMcp23s17 },
649 { "sr595", &doExtensionSr595 },
650 { "pcf8574", &doExtensionPcf8574 },
651 { "pcf8591", &doExtensionPcf8591 },
652 { "mcp3002", &doExtensionMcp3002 },
653 { "mcp3004", &doExtensionMcp3004 },
654 { "mcp4802", &doExtensionMcp4802 },
655 { "mcp3422", &doExtensionMcp3422 },
656 { "max31855", &doExtensionMax31855 },
657 { "max5322", &doExtensionMax5322 },
658 { "sn3218", &doExtensionSn3218 },
659 { "drcs", &doExtensionDrcS },
666 * Load in a wiringPi extension
667 * The extensionData always starts with the name, a colon then the pinBase
668 * number. Other parameters after that are decoded by the module in question.
669 *********************************************************************************
672 int loadWPiExtension (char *progName, char *extensionData, int printErrors)
675 char *extension = extensionData ;
676 struct extensionFunctionStruct *extensionFn ;
679 verbose = printErrors ;
681 // Get the extension name by finding the first colon
686 if (!*p) // ran out of characters
688 verbError ("%s: extension name not terminated by a colon", progName) ;
699 verbError ("%s: pinBase number expected after extension name", progName) ;
705 if (pinBase > 1000000000) // Lets be realistic here...
707 verbError ("%s: pinBase too large", progName) ;
711 pinBase = pinBase * 10 + (*p - '0') ;
717 verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ;
721 // Search for extensions:
723 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
725 if (strcmp (extensionFn->name, extension) == 0)
726 return extensionFn->function (progName, pinBase, p) ;
729 verbError ("%s: extension %s not found", progName, extension) ;