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>
51 #include "extensions.h"
53 extern int wiringPiDebug ;
60 // Local structure to hold details
62 struct extensionFunctionStruct
65 int (*function)(char *progName, int pinBase, char *params) ;
71 * Check & return an integer at the given location (prefixed by a :)
72 *********************************************************************************
75 static char *extractInt (char *progName, char *p, int *num)
79 fprintf (stderr, "%s: colon expected\n", progName) ;
87 fprintf (stderr, "%s: digit expected\n", progName) ;
91 *num = strtol (p, NULL, 0) ;
101 * doExtensionMcp23008:
102 * MCP23008 - 8-bit I2C GPIO expansion chip
103 * mcp23002:base:i2cAddr
104 *********************************************************************************
107 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
111 if ((params = extractInt (progName, params, &i2c)) == NULL)
114 if ((i2c < 0x03) || (i2c > 0x77))
116 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
120 mcp23008Setup (pinBase, i2c) ;
127 * doExtensionMcp23016:
128 * MCP230016- 16-bit I2C GPIO expansion chip
129 * mcp23016:base:i2cAddr
130 *********************************************************************************
133 static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
137 if ((params = extractInt (progName, params, &i2c)) == NULL)
140 if ((i2c < 0x03) || (i2c > 0x77))
142 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
146 mcp23016Setup (pinBase, i2c) ;
153 * doExtensionMcp23017:
154 * MCP230017- 16-bit I2C GPIO expansion chip
155 * mcp23017:base:i2cAddr
156 *********************************************************************************
159 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
163 if ((params = extractInt (progName, params, &i2c)) == NULL)
166 if ((i2c < 0x03) || (i2c > 0x77))
168 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
172 mcp23017Setup (pinBase, i2c) ;
179 * doExtensionMcp23s08:
180 * MCP23s08 - 8-bit SPI GPIO expansion chip
181 * mcp23s08:base:spi:port
182 *********************************************************************************
185 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
189 if ((params = extractInt (progName, params, &spi)) == NULL)
192 if ((spi < 0) || (spi > 1))
194 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
198 if ((params = extractInt (progName, params, &port)) == NULL)
201 if ((port < 0) || (port > 7))
203 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
207 mcp23s08Setup (pinBase, spi, port) ;
214 * doExtensionMcp23s17:
215 * MCP23s17 - 16-bit SPI GPIO expansion chip
216 * mcp23s17:base:spi:port
217 *********************************************************************************
220 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
224 if ((params = extractInt (progName, params, &spi)) == NULL)
227 if ((spi < 0) || (spi > 1))
229 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
233 if ((params = extractInt (progName, params, &port)) == NULL)
236 if ((port < 0) || (port > 7))
238 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
242 mcp23s17Setup (pinBase, spi, port) ;
250 * Shift Register 74x595
251 * sr595:base:pins:data:clock:latch
252 *********************************************************************************
255 static int doExtensionSr595 (char *progName, int pinBase, char *params)
257 int pins, data, clock, latch ;
261 if ((params = extractInt (progName, params, &pins)) == NULL)
264 if ((pins < 8) || (pins > 32))
266 fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
270 if ((params = extractInt (progName, params, &data)) == NULL)
273 if ((params = extractInt (progName, params, &clock)) == NULL)
276 if ((params = extractInt (progName, params, &latch)) == NULL)
279 sr595Setup (pinBase, pins, data, clock, latch) ;
286 * doExtensionPcf8574:
287 * Digital IO (Crude!)
288 * pcf8574:base:i2cAddr
289 *********************************************************************************
292 static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
296 if ((params = extractInt (progName, params, &i2c)) == NULL)
299 if ((i2c < 0x03) || (i2c > 0x77))
301 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
305 pcf8574Setup (pinBase, i2c) ;
312 * doExtensionPcf8591:
314 * pcf8591:base:i2cAddr
315 *********************************************************************************
318 static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
322 if ((params = extractInt (progName, params, &i2c)) == NULL)
325 if ((i2c < 0x03) || (i2c > 0x77))
327 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
331 pcf8591Setup (pinBase, i2c) ;
338 * doExtensionMcp3002:
340 * mcp3002:base:spiChan
341 *********************************************************************************
344 static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
348 if ((params = extractInt (progName, params, &spi)) == NULL)
351 if ((spi < 0) || (spi > 1))
353 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
357 mcp3002Setup (pinBase, spi) ;
364 * doExtensionMcp3004:
366 * mcp3004:base:spiChan
367 *********************************************************************************
370 static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
374 if ((params = extractInt (progName, params, &spi)) == NULL)
377 if ((spi < 0) || (spi > 1))
379 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
383 mcp3004Setup (pinBase, spi) ;
390 * doExtensionMcp4802:
392 * mcp4802:base:spiChan
393 *********************************************************************************
396 static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
400 if ((params = extractInt (progName, params, &spi)) == NULL)
403 if ((spi < 0) || (spi > 1))
405 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
409 mcp4802Setup (pinBase, spi) ;
416 * doExtensionMcp3422:
418 * mcp3422:base:i2cAddr
419 *********************************************************************************
422 static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
424 int i2c, sampleRate, gain ;
426 if ((params = extractInt (progName, params, &i2c)) == NULL)
429 if ((i2c < 0x03) || (i2c > 0x77))
431 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
435 if ((params = extractInt (progName, params, &sampleRate)) == NULL)
438 if ((sampleRate < 0) || (sampleRate > 3))
440 fprintf (stderr, "%s: sample rate (%d) out of range\n", progName, sampleRate) ;
444 if ((params = extractInt (progName, params, &gain)) == NULL)
447 if ((gain < 0) || (gain > 3))
449 fprintf (stderr, "%s: gain (%d) out of range\n", progName, gain) ;
453 mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
461 *********************************************************************************
464 struct extensionFunctionStruct extensionFunctions [] =
466 { "mcp23008", &doExtensionMcp23008 },
467 { "mcp23016", &doExtensionMcp23016 },
468 { "mcp23017", &doExtensionMcp23017 },
469 { "mcp23s08", &doExtensionMcp23s08 },
470 { "mcp23s17", &doExtensionMcp23s17 },
471 { "sr595", &doExtensionSr595 },
472 { "pcf8574", &doExtensionPcf8574 },
473 { "pcf8591", &doExtensionPcf8591 },
474 { "mcp3002", &doExtensionMcp3002 },
475 { "mcp3004", &doExtensionMcp3004 },
476 { "mcp4802", &doExtensionMcp4802 },
477 { "mcp3422", &doExtensionMcp3422 },
484 * Load in a wiringPi extension
485 *********************************************************************************
488 int doExtension (char *progName, char *extensionData)
491 char *extension = extensionData ;
492 struct extensionFunctionStruct *extensionFn ;
495 // Get the extension extension name by finding the first colon
500 if (!*p) // ran out of characters
502 fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
512 fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
518 if (pinBase > 1000000000)
520 fprintf (stderr, "%s: pinBase too large\n", progName) ;
524 pinBase = pinBase * 10 + (*p - '0') ;
530 fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
534 // Search for extensions:
536 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
538 if (strcmp (extensionFn->name, extension) == 0)
539 return extensionFn->function (progName, pinBase, p) ;
542 fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;