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>
47 #include "extensions.h"
49 extern int wiringPiDebug ;
56 // Local structure to hold details
58 struct extensionFunctionStruct
61 int (*function)(char *progName, int pinBase, char *params) ;
67 * Check & return an integer at the given location (prefixed by a :)
68 *********************************************************************************
71 static char *extractInt (char *progName, char *p, int *num)
75 fprintf (stderr, "%s: colon expected\n", progName) ;
83 fprintf (stderr, "%s: digit expected\n", progName) ;
87 *num = strtol (p, NULL, 0) ;
97 * doExtensionMcp23008:
98 * MCP23008 - 8-bit I2C GPIO expansion chip
99 * mcp23002:base:i2cAddr
100 *********************************************************************************
103 static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
107 if ((params = extractInt (progName, params, &i2c)) == NULL)
110 if ((i2c < 0x03) || (i2c > 0x77))
112 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
116 mcp23008Setup (pinBase, i2c) ;
123 * doExtensionMcp23016:
124 * MCP230016- 16-bit I2C GPIO expansion chip
125 * mcp23016:base:i2cAddr
126 *********************************************************************************
129 static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
133 if ((params = extractInt (progName, params, &i2c)) == NULL)
136 if ((i2c < 0x03) || (i2c > 0x77))
138 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
142 mcp23016Setup (pinBase, i2c) ;
149 * doExtensionMcp23017:
150 * MCP230017- 16-bit I2C GPIO expansion chip
151 * mcp23017:base:i2cAddr
152 *********************************************************************************
155 static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
159 if ((params = extractInt (progName, params, &i2c)) == NULL)
162 if ((i2c < 0x03) || (i2c > 0x77))
164 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
168 mcp23017Setup (pinBase, i2c) ;
175 * doExtensionMcp23s08:
176 * MCP23s08 - 8-bit SPI GPIO expansion chip
177 * mcp23s08:base:spi:port
178 *********************************************************************************
181 static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
185 if ((params = extractInt (progName, params, &spi)) == NULL)
188 if ((spi < 0) || (spi > 1))
190 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
194 if ((params = extractInt (progName, params, &port)) == NULL)
197 if ((port < 0) || (port > 7))
199 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
203 mcp23s08Setup (pinBase, spi, port) ;
210 * doExtensionMcp23s17:
211 * MCP23s17 - 16-bit SPI GPIO expansion chip
212 * mcp23s17:base:spi:port
213 *********************************************************************************
216 static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
220 if ((params = extractInt (progName, params, &spi)) == NULL)
223 if ((spi < 0) || (spi > 1))
225 fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
229 if ((params = extractInt (progName, params, &port)) == NULL)
232 if ((port < 0) || (port > 7))
234 fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
238 mcp23s17Setup (pinBase, spi, port) ;
246 * Shift Register 74x595
247 * sr595:base:pins:data:clock:latch
248 *********************************************************************************
251 static int doExtensionSr595 (char *progName, int pinBase, char *params)
253 int pins, data, clock, latch ;
257 if ((params = extractInt (progName, params, &pins)) == NULL)
260 if ((pins < 8) || (pins > 32))
262 fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
266 if ((params = extractInt (progName, params, &data)) == NULL)
269 if ((params = extractInt (progName, params, &clock)) == NULL)
272 if ((params = extractInt (progName, params, &latch)) == NULL)
275 sr595Setup (pinBase, pins, data, clock, latch) ;
282 * doExtensionPcf8574:
283 * Digital IO (Crude!)
284 * pcf8574:base:i2cAddr
285 *********************************************************************************
288 static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
292 if ((params = extractInt (progName, params, &i2c)) == NULL)
295 if ((i2c < 0x03) || (i2c > 0x77))
297 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
301 pcf8574Setup (pinBase, i2c) ;
308 * doExtensionPcf8591:
310 * pcf8591:base:i2cAddr
311 *********************************************************************************
314 static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
318 if ((params = extractInt (progName, params, &i2c)) == NULL)
321 if ((i2c < 0x03) || (i2c > 0x77))
323 fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
327 pcf8591Setup (pinBase, i2c) ;
335 *********************************************************************************
338 struct extensionFunctionStruct extensionFunctions [] =
340 { "mcp23008", &doExtensionMcp23008 },
341 { "mcp23016", &doExtensionMcp23016 },
342 { "mcp23017", &doExtensionMcp23017 },
343 { "mcp23s08", &doExtensionMcp23s08 },
344 { "mcp23s17", &doExtensionMcp23s17 },
345 { "sr595", &doExtensionSr595 },
346 { "pcf8574", &doExtensionPcf8574 },
347 { "pcf8591", &doExtensionPcf8591 },
354 * Load in a wiringPi extension
355 *********************************************************************************
358 int doExtension (char *progName, char *extensionData)
361 char *extension = extensionData ;
362 struct extensionFunctionStruct *extensionFn ;
365 // Get the extension extension name by finding the first colon
370 if (!*p) // ran out of characters
372 fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
382 fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
388 if (pinBase > 1000000000)
390 fprintf (stderr, "%s: pinBase too large\n", progName) ;
394 pinBase = pinBase * 10 + (*p - '0') ;
400 fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
404 // Search for extensions:
406 for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
408 if (strcmp (extensionFn->name, extension) == 0)
409 return extensionFn->function (progName, pinBase, p) ;
412 fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;