3 * Part of the GPIO program to test, peek, poke and otherwise
4 * noodle with the GPIO hardware on the Raspberry Pi.
5 * Copyright (c) 2012-2013 Gordon Henderson
6 ***********************************************************************
7 * This file is part of wiringPi:
8 * https://projects.drogon.net/raspberry-pi/wiringpi/
10 * wiringPi is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * wiringPi is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22 ***********************************************************************
33 #include <sys/types.h>
53 #include <drcSerial.h>
55 #include "extensions.h"
57 extern int wiringPiDebug ;
64 // Local structure to hold details
66 struct extensionFunctionStruct
69 int (*function)(char *progName, int pinBase, char *params) ;
75 * Check & return an integer at the given location (prefixed by a :)
76 *********************************************************************************
79 static char *extractInt (char *progName, char *p, int *num)
83 fprintf (stderr, "%s: colon expected\n", progName) ;
91 fprintf (stderr, "%s: digit expected\n", progName) ;
95 *num = strtol (p, NULL, 0) ;
105 * Check & return a string at the given location (prefixed by a :)
106 *********************************************************************************
109 static char *extractStr (char *progName, char *p, char **str)
115 fprintf (stderr, "%s: colon expected\n", progName) ;
123 fprintf (stderr, "%s: character expected\n", progName) ;
128 while ((*q != 0) && (*q != ':'))
131 *str = r = calloc (q - p + 2, 1) ; // Zeros it
142 * doExtensionMcp23008:
143 * MCP23008 - 8-bit I2C GPIO expansion chip
144 * mcp23002:base:i2cAddr
145 *********************************************************************************
148 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
152 if ((params = extractInt (progName, params, &i2c)) == NULL)
155 if ((i2c < 0x03) || (i2c > 0x77))
157 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
161 mcp23008Setup (pinBase, i2c) ;
168 * doExtensionMcp23016:
169 * MCP230016- 16-bit I2C GPIO expansion chip
170 * mcp23016:base:i2cAddr
171 *********************************************************************************
174 static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
178 if ((params = extractInt (progName, params, &i2c)) == NULL)
181 if ((i2c < 0x03) || (i2c > 0x77))
183 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
187 mcp23016Setup (pinBase, i2c) ;
194 * doExtensionMcp23017:
195 * MCP230017- 16-bit I2C GPIO expansion chip
196 * mcp23017:base:i2cAddr
197 *********************************************************************************
200 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
204 if ((params = extractInt (progName, params, &i2c)) == NULL)
207 if ((i2c < 0x03) || (i2c > 0x77))
209 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
213 mcp23017Setup (pinBase, i2c) ;
220 * doExtensionMcp23s08:
221 * MCP23s08 - 8-bit SPI GPIO expansion chip
222 * mcp23s08:base:spi:port
223 *********************************************************************************
226 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
230 if ((params = extractInt (progName, params, &spi)) == NULL)
233 if ((spi < 0) || (spi > 1))
235 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
239 if ((params = extractInt (progName, params, &port)) == NULL)
242 if ((port < 0) || (port > 7))
244 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
248 mcp23s08Setup (pinBase, spi, port) ;
255 * doExtensionMcp23s17:
256 * MCP23s17 - 16-bit SPI GPIO expansion chip
257 * mcp23s17:base:spi:port
258 *********************************************************************************
261 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
265 if ((params = extractInt (progName, params, &spi)) == NULL)
268 if ((spi < 0) || (spi > 1))
270 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
274 if ((params = extractInt (progName, params, &port)) == NULL)
277 if ((port < 0) || (port > 7))
279 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
283 mcp23s17Setup (pinBase, spi, port) ;
291 * Shift Register 74x595
292 * sr595:base:pins:data:clock:latch
293 *********************************************************************************
296 static int doExtensionSr595 (char *progName, int pinBase, char *params)
298 int pins, data, clock, latch ;
302 if ((params = extractInt (progName, params, &pins)) == NULL)
305 if ((pins < 8) || (pins > 32))
307 fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
311 if ((params = extractInt (progName, params, &data)) == NULL)
314 if ((params = extractInt (progName, params, &clock)) == NULL)
317 if ((params = extractInt (progName, params, &latch)) == NULL)
320 sr595Setup (pinBase, pins, data, clock, latch) ;
327 * doExtensionPcf8574:
328 * Digital IO (Crude!)
329 * pcf8574:base:i2cAddr
330 *********************************************************************************
333 static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
337 if ((params = extractInt (progName, params, &i2c)) == NULL)
340 if ((i2c < 0x03) || (i2c > 0x77))
342 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
346 pcf8574Setup (pinBase, i2c) ;
353 * doExtensionPcf8591:
355 * pcf8591:base:i2cAddr
356 *********************************************************************************
359 static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
363 if ((params = extractInt (progName, params, &i2c)) == NULL)
366 if ((i2c < 0x03) || (i2c > 0x77))
368 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
372 pcf8591Setup (pinBase, i2c) ;
379 * doExtensionMax31855:
381 * max31855:base:spiChan
382 *********************************************************************************
385 static int doExtensionMax31855 (char *progName, int pinBase, char *params)
389 if ((params = extractInt (progName, params, &spi)) == NULL)
392 if ((spi < 0) || (spi > 1))
394 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
398 max31855Setup (pinBase, spi) ;
405 * doExtensionMcp3002:
407 * mcp3002:base:spiChan
408 *********************************************************************************
411 static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
415 if ((params = extractInt (progName, params, &spi)) == NULL)
418 if ((spi < 0) || (spi > 1))
420 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
424 mcp3002Setup (pinBase, spi) ;
431 * doExtensionMcp3004:
433 * mcp3004:base:spiChan
434 *********************************************************************************
437 static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
441 if ((params = extractInt (progName, params, &spi)) == NULL)
444 if ((spi < 0) || (spi > 1))
446 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
450 mcp3004Setup (pinBase, spi) ;
457 * doExtensionMax5322:
459 * max5322:base:spiChan
460 *********************************************************************************
463 static int doExtensionMax5322 (char *progName, int pinBase, char *params)
467 if ((params = extractInt (progName, params, &spi)) == NULL)
470 if ((spi < 0) || (spi > 1))
472 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
476 max5322Setup (pinBase, spi) ;
483 * doExtensionMcp4802:
485 * mcp4802:base:spiChan
486 *********************************************************************************
489 static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
493 if ((params = extractInt (progName, params, &spi)) == NULL)
496 if ((spi < 0) || (spi > 1))
498 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
502 mcp4802Setup (pinBase, spi) ;
510 * Analog Output (LED Driver)
512 *********************************************************************************
515 static int doExtensionSn3218 (char *progName, int pinBase, char *params)
517 sn3218Setup (pinBase) ;
523 * doExtensionMcp3422:
525 * mcp3422:base:i2cAddr
526 *********************************************************************************
529 static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
531 int i2c, sampleRate, gain ;
533 if ((params = extractInt (progName, params, &i2c)) == NULL)
536 if ((i2c < 0x03) || (i2c > 0x77))
538 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
542 if ((params = extractInt (progName, params, &sampleRate)) == NULL)
545 if ((sampleRate < 0) || (sampleRate > 3))
547 fprintf (stderr, "%s: sample rate (%d) out of range\n", progName, sampleRate) ;
551 if ((params = extractInt (progName, params, &gain)) == NULL)
554 if ((gain < 0) || (gain > 3))
556 fprintf (stderr, "%s: gain (%d) out of range\n", progName, gain) ;
560 mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
567 * Interface to a DRC Serial system
568 * drcs:base:pins:serialPort:baud
569 *********************************************************************************
572 static int doExtensionDrcS (char *progName, int pinBase, char *params)
577 if ((params = extractInt (progName, params, &pins)) == NULL)
580 if ((pins < 1) || (pins > 100))
582 fprintf (stderr, "%s: pins (%d) out of range (2-100)\n", progName, pins) ;
586 if ((params = extractStr (progName, params, &port)) == NULL)
589 if (strlen (port) == 0)
591 fprintf (stderr, "%s: serial port device name required\n", progName) ;
595 if ((params = extractInt (progName, params, &baud)) == NULL)
598 if ((baud < 1) || (baud > 4000000))
600 fprintf (stderr, "%s: baud rate (%d) out of range\n", progName, baud) ;
604 drcSetupSerial (pinBase, pins, port, baud) ;
613 *********************************************************************************
616 struct extensionFunctionStruct extensionFunctions [] =
618 { "mcp23008", &doExtensionMcp23008 },
619 { "mcp23016", &doExtensionMcp23016 },
620 { "mcp23017", &doExtensionMcp23017 },
621 { "mcp23s08", &doExtensionMcp23s08 },
622 { "mcp23s17", &doExtensionMcp23s17 },
623 { "sr595", &doExtensionSr595 },
624 { "pcf8574", &doExtensionPcf8574 },
625 { "pcf8591", &doExtensionPcf8591 },
626 { "mcp3002", &doExtensionMcp3002 },
627 { "mcp3004", &doExtensionMcp3004 },
628 { "mcp4802", &doExtensionMcp4802 },
629 { "mcp3422", &doExtensionMcp3422 },
630 { "max31855", &doExtensionMax31855 },
631 { "max5322", &doExtensionMax5322 },
632 { "sn3218", &doExtensionSn3218 },
633 { "drcs", &doExtensionDrcS },
640 * Load in a wiringPi extension
641 *********************************************************************************
644 int doExtension (char *progName, char *extensionData)
647 char *extension = extensionData ;
648 struct extensionFunctionStruct *extensionFn ;
651 // Get the extension extension name by finding the first colon
656 if (!*p) // ran out of characters
658 fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
668 fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
674 if (pinBase > 1000000000)
676 fprintf (stderr, "%s: pinBase too large\n", progName) ;
680 pinBase = pinBase * 10 + (*p - '0') ;
686 fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
690 // Search for extensions:
692 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
694 if (strcmp (extensionFn->name, extension) == 0)
695 return extensionFn->function (progName, pinBase, p) ;
698 fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;