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>
44 #include "extensions.h"
46 extern int wiringPiDebug ;
53 // Local structure to hold details
55 struct extensionFunctionStruct
58 int (*function)(char *progName, int pinBase, char *params) ;
64 * Check & return an integer at the given location (prefixed by a :)
65 *********************************************************************************
68 static char *extractInt (char *progName, char *p, int *num)
72 fprintf (stderr, "%s: colon expected\n", progName) ;
80 fprintf (stderr, "%s: digit expected\n", progName) ;
84 *num = strtol (p, NULL, 0) ;
94 * doExtensionMcp23008:
95 * MCP23008 - 8-bit I2C GPIO expansion chip
96 * mcp23002:base:i2cAddr
97 *********************************************************************************
100 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
104 if ((params = extractInt (progName, params, &i2c)) == NULL)
107 if ((i2c < 0x03) || (i2c > 0x77))
109 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
113 mcp23008Setup (pinBase, i2c) ;
120 * doExtensionMcp23017:
121 * MCP23008 - 16-bit I2C GPIO expansion chip
122 * mcp23002:base:i2cAddr
123 *********************************************************************************
126 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
130 if ((params = extractInt (progName, params, &i2c)) == NULL)
133 if ((i2c < 0x03) || (i2c > 0x77))
135 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
139 mcp23017Setup (pinBase, i2c) ;
146 * doExtensionMcp23s08:
147 * MCP23s08 - 8-bit SPI GPIO expansion chip
148 * mcp23s08:base:spi:port
149 *********************************************************************************
152 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
156 if ((params = extractInt (progName, params, &spi)) == NULL)
159 if ((spi < 0) || (spi > 1))
161 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
165 if ((params = extractInt (progName, params, &port)) == NULL)
168 if ((port < 0) || (port > 7))
170 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
174 mcp23s08Setup (pinBase, spi, port) ;
181 * doExtensionMcp23s17:
182 * MCP23s17 - 16-bit SPI GPIO expansion chip
183 * mcp23s17:base:spi:port
184 *********************************************************************************
187 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
191 if ((params = extractInt (progName, params, &spi)) == NULL)
194 if ((spi < 0) || (spi > 1))
196 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
200 if ((params = extractInt (progName, params, &port)) == NULL)
203 if ((port < 0) || (port > 7))
205 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
209 mcp23s17Setup (pinBase, spi, port) ;
216 * Shift Register 74x595
217 * sr595:base:pins:data:clock:latch
218 *********************************************************************************
221 static int doExtensionSr595 (char *progName, int pinBase, char *params)
223 int pins, data, clock, latch ;
227 if ((params = extractInt (progName, params, &pins)) == NULL)
230 if ((pins < 8) || (pins > 32))
232 fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
236 if ((params = extractInt (progName, params, &data)) == NULL)
239 if ((params = extractInt (progName, params, &clock)) == NULL)
242 if ((params = extractInt (progName, params, &latch)) == NULL)
245 sr595Setup (pinBase, pins, data, clock, latch) ;
253 *********************************************************************************
256 struct extensionFunctionStruct extensionFunctions [] =
258 { "mcp23008", &doExtensionMcp23008 },
259 { "mcp23017", &doExtensionMcp23017 },
260 { "mcp23s08", &doExtensionMcp23s08 },
261 { "mcp23s17", &doExtensionMcp23s17 },
262 { "sr595", &doExtensionSr595 },
269 * Load in a wiringPi extension
270 *********************************************************************************
273 int doExtension (char *progName, char *extensionData)
276 char *extension = extensionData ;
277 struct extensionFunctionStruct *extensionFn ;
280 // Get the extension extension name by finding the first colon
285 if (!*p) // ran out of characters
287 fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
297 fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
303 if (pinBase > 1000000000)
305 fprintf (stderr, "%s: pinBase too large\n", progName) ;
309 pinBase = pinBase * 10 + (*p - '0') ;
315 fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
319 // Search for extensions:
321 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
323 if (strcmp (extensionFn->name, extension) == 0)
324 return extensionFn->function (progName, pinBase, p) ;
327 fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;