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>
52 #include "extensions.h"
54 extern int wiringPiDebug ;
61 // Local structure to hold details
63 struct extensionFunctionStruct
66 int (*function)(char *progName, int pinBase, char *params) ;
72 * Check & return an integer at the given location (prefixed by a :)
73 *********************************************************************************
76 static char *extractInt (char *progName, char *p, int *num)
80 fprintf (stderr, "%s: colon expected\n", progName) ;
88 fprintf (stderr, "%s: digit expected\n", progName) ;
92 *num = strtol (p, NULL, 0) ;
102 * doExtensionMcp23008:
103 * MCP23008 - 8-bit I2C GPIO expansion chip
104 * mcp23002:base:i2cAddr
105 *********************************************************************************
108 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
112 if ((params = extractInt (progName, params, &i2c)) == NULL)
115 if ((i2c < 0x03) || (i2c > 0x77))
117 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
121 mcp23008Setup (pinBase, i2c) ;
128 * doExtensionMcp23016:
129 * MCP230016- 16-bit I2C GPIO expansion chip
130 * mcp23016:base:i2cAddr
131 *********************************************************************************
134 static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
138 if ((params = extractInt (progName, params, &i2c)) == NULL)
141 if ((i2c < 0x03) || (i2c > 0x77))
143 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
147 mcp23016Setup (pinBase, i2c) ;
154 * doExtensionMcp23017:
155 * MCP230017- 16-bit I2C GPIO expansion chip
156 * mcp23017:base:i2cAddr
157 *********************************************************************************
160 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
164 if ((params = extractInt (progName, params, &i2c)) == NULL)
167 if ((i2c < 0x03) || (i2c > 0x77))
169 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
173 mcp23017Setup (pinBase, i2c) ;
180 * doExtensionMcp23s08:
181 * MCP23s08 - 8-bit SPI GPIO expansion chip
182 * mcp23s08:base:spi:port
183 *********************************************************************************
186 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
190 if ((params = extractInt (progName, params, &spi)) == NULL)
193 if ((spi < 0) || (spi > 1))
195 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
199 if ((params = extractInt (progName, params, &port)) == NULL)
202 if ((port < 0) || (port > 7))
204 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
208 mcp23s08Setup (pinBase, spi, port) ;
215 * doExtensionMcp23s17:
216 * MCP23s17 - 16-bit SPI GPIO expansion chip
217 * mcp23s17:base:spi:port
218 *********************************************************************************
221 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
225 if ((params = extractInt (progName, params, &spi)) == NULL)
228 if ((spi < 0) || (spi > 1))
230 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
234 if ((params = extractInt (progName, params, &port)) == NULL)
237 if ((port < 0) || (port > 7))
239 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
243 mcp23s17Setup (pinBase, spi, port) ;
251 * Shift Register 74x595
252 * sr595:base:pins:data:clock:latch
253 *********************************************************************************
256 static int doExtensionSr595 (char *progName, int pinBase, char *params)
258 int pins, data, clock, latch ;
262 if ((params = extractInt (progName, params, &pins)) == NULL)
265 if ((pins < 8) || (pins > 32))
267 fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
271 if ((params = extractInt (progName, params, &data)) == NULL)
274 if ((params = extractInt (progName, params, &clock)) == NULL)
277 if ((params = extractInt (progName, params, &latch)) == NULL)
280 sr595Setup (pinBase, pins, data, clock, latch) ;
287 * doExtensionPcf8574:
288 * Digital IO (Crude!)
289 * pcf8574:base:i2cAddr
290 *********************************************************************************
293 static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
297 if ((params = extractInt (progName, params, &i2c)) == NULL)
300 if ((i2c < 0x03) || (i2c > 0x77))
302 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
306 pcf8574Setup (pinBase, i2c) ;
313 * doExtensionPcf8591:
315 * pcf8591:base:i2cAddr
316 *********************************************************************************
319 static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
323 if ((params = extractInt (progName, params, &i2c)) == NULL)
326 if ((i2c < 0x03) || (i2c > 0x77))
328 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
332 pcf8591Setup (pinBase, i2c) ;
339 * doExtensionMax31855:
341 * max31855:base:spiChan
342 *********************************************************************************
345 static int doExtensionMax31855 (char *progName, int pinBase, char *params)
349 if ((params = extractInt (progName, params, &spi)) == NULL)
352 if ((spi < 0) || (spi > 1))
354 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
358 max31855Setup (pinBase, spi) ;
365 * doExtensionMcp3002:
367 * mcp3002:base:spiChan
368 *********************************************************************************
371 static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
375 if ((params = extractInt (progName, params, &spi)) == NULL)
378 if ((spi < 0) || (spi > 1))
380 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
384 mcp3002Setup (pinBase, spi) ;
391 * doExtensionMcp3004:
393 * mcp3004:base:spiChan
394 *********************************************************************************
397 static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
401 if ((params = extractInt (progName, params, &spi)) == NULL)
404 if ((spi < 0) || (spi > 1))
406 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
410 mcp3004Setup (pinBase, spi) ;
417 * doExtensionMcp4802:
419 * mcp4802:base:spiChan
420 *********************************************************************************
423 static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
427 if ((params = extractInt (progName, params, &spi)) == NULL)
430 if ((spi < 0) || (spi > 1))
432 fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
436 mcp4802Setup (pinBase, spi) ;
443 * doExtensionMcp3422:
445 * mcp3422:base:i2cAddr
446 *********************************************************************************
449 static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
451 int i2c, sampleRate, gain ;
453 if ((params = extractInt (progName, params, &i2c)) == NULL)
456 if ((i2c < 0x03) || (i2c > 0x77))
458 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
462 if ((params = extractInt (progName, params, &sampleRate)) == NULL)
465 if ((sampleRate < 0) || (sampleRate > 3))
467 fprintf (stderr, "%s: sample rate (%d) out of range\n", progName, sampleRate) ;
471 if ((params = extractInt (progName, params, &gain)) == NULL)
474 if ((gain < 0) || (gain > 3))
476 fprintf (stderr, "%s: gain (%d) out of range\n", progName, gain) ;
480 mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
488 *********************************************************************************
491 struct extensionFunctionStruct extensionFunctions [] =
493 { "mcp23008", &doExtensionMcp23008 },
494 { "mcp23016", &doExtensionMcp23016 },
495 { "mcp23017", &doExtensionMcp23017 },
496 { "mcp23s08", &doExtensionMcp23s08 },
497 { "mcp23s17", &doExtensionMcp23s17 },
498 { "sr595", &doExtensionSr595 },
499 { "pcf8574", &doExtensionPcf8574 },
500 { "pcf8591", &doExtensionPcf8591 },
501 { "mcp3002", &doExtensionMcp3002 },
502 { "mcp3004", &doExtensionMcp3004 },
503 { "mcp4802", &doExtensionMcp4802 },
504 { "mcp3422", &doExtensionMcp3422 },
505 { "max31855", &doExtensionMax31855 },
512 * Load in a wiringPi extension
513 *********************************************************************************
516 int doExtension (char *progName, char *extensionData)
519 char *extension = extensionData ;
520 struct extensionFunctionStruct *extensionFn ;
523 // Get the extension extension name by finding the first colon
528 if (!*p) // ran out of characters
530 fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
540 fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
546 if (pinBase > 1000000000)
548 fprintf (stderr, "%s: pinBase too large\n", progName) ;
552 pinBase = pinBase * 10 + (*p - '0') ;
558 fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
562 // Search for extensions:
564 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
566 if (strcmp (extensionFn->name, extension) == 0)
567 return extensionFn->function (progName, pinBase, p) ;
570 fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;