Browse Source

Aded lcd-adafruit to test/drive the Adafruit RGB LCD plate
Added the Quick 2 Wire codes, etc.
Minor typo/bug fixes.
Added more modules into gpio -x

Gordon Henderson 11 years ago
parent
commit
bfaf266ada

+ 3 - 0
People

@@ -25,3 +25,6 @@ CHARLES Thibaut:
 
 Xian Stannard
   Fixing some typos in the man page!
+
+Andre Crone
+  Suggested the __WIRING_PI.H__ round wiringPi.h

+ 13 - 6
build

@@ -15,17 +15,19 @@ check-make-ok()
 
 if [ x$1 = "xclean" ]; then
   cd wiringPi
-  echo -n "wiringPi:  "	; make clean
+  echo -n "wiringPi:   "	; make clean
   cd ../devLib
-  echo -n "DevLib:    "	; make clean
+  echo -n "DevLib:     "	; make clean
   cd ../gpio
-  echo -n "gpio:      "	; make clean
+  echo -n "gpio:       "	; make clean
   cd ../examples
-  echo -n "Examples:  "	; make clean
+  echo -n "Examples:   "	; make clean
   cd Gertboard
-  echo -n "Gertboard: "	; make clean
+  echo -n "Gertboard:  "	; make clean
   cd ../PiFace
-  echo -n "PiFace:    "	; make clean
+  echo -n "PiFace:     "	; make clean
+  cd ../q2w
+  echo -n "Quick2Wire: "	; make clean
   exit
 fi
 
@@ -78,3 +80,8 @@ fi
 
 echo
 echo All Done.
+echo ""
+echo "NOTE: This is wiringPi v2, and if you need to use the lcd, Piface,"
+echo "  Gertboard, MaxDetext, etc. routines then you must change your"
+echo "  compile scripts to add -lwiringPiDev"
+echo ""

+ 5 - 1
examples/Makefile

@@ -38,7 +38,7 @@ LDLIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
 SRC	=	blink.c blink8.c blink12.c					\
 		pwm.c								\
 		speed.c wfi.c isr.c isr-osc.c					\
-		lcd.c clock.c							\
+		lcd.c lcd-adafruit.c clock.c					\
 		nes.c								\
 		softPwm.c softTone.c 						\
 		delayTest.c serialRead.c serialTest.c okLed.c ds1302.c		\
@@ -75,6 +75,10 @@ lcd:	lcd.o
 	@echo [link]
 	@$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS)
 
+lcd-adafruit:	lcd-adafruit.o
+	@echo [link]
+	@$(CC) -o $@ lcd-adafruit.o $(LDFLAGS) $(LDLIBS)
+
 clock:	clock.o
 	@echo [link]
 	@$(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS)

+ 347 - 0
examples/lcd-adafruit.c

@@ -0,0 +1,347 @@
+/*
+ * lcd-adafruit.c:
+ *	Text-based LCD driver test code
+ *	This is designed to drive the Adafruit RGB LCD Plate
+ *	with the additional 5 buttons for the Raspberry Pi
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+
+#include <wiringPi.h>
+#include <mcp23017.h>
+#include <lcd.h>
+
+#ifndef	TRUE
+#  define	TRUE	(1==1)
+#  define	FALSE	(1==2)
+#endif
+
+
+// Defines for the Adafruit Pi LCD interface board
+
+#define	AF_BASE		100
+#define	AF_RED		(AF_BASE + 6)
+#define	AF_GREEN	(AF_BASE + 7)
+#define	AF_BLUE		(AF_BASE + 8)
+
+#define	AF_E		(AF_BASE + 13)
+#define	AF_RW		(AF_BASE + 14)
+#define	AF_RS		(AF_BASE + 15)
+
+#define	AF_DB4		(AF_BASE + 12)
+#define	AF_DB5		(AF_BASE + 11)
+#define	AF_DB6		(AF_BASE + 10)
+#define	AF_DB7		(AF_BASE +  9)
+
+#define	AF_SELECT	(AF_BASE +  0)
+#define	AF_RIGHT	(AF_BASE +  1)
+#define	AF_DOWN		(AF_BASE +  2)
+#define	AF_UP		(AF_BASE +  3)
+#define	AF_LEFT		(AF_BASE +  4)
+
+
+// User-Defined character test
+
+static unsigned char newChar [8] = 
+{
+  0b00100,
+  0b00100,
+  0b00000,
+  0b00100,
+  0b01110,
+  0b11011,
+  0b11011,
+  0b10001,
+} ;
+
+// Global lcd handle:
+
+static int lcdHandle ;
+
+/*
+ * usage:
+ *********************************************************************************
+ */
+
+int usage (const char *progName)
+{
+  fprintf (stderr, "Usage: %s colour\n", progName) ;
+  return EXIT_FAILURE ;
+}
+
+
+/*
+ * scrollMessage:
+ *********************************************************************************
+ */
+
+static const char *message =
+  "                    "
+  "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
+  "                    " ;
+
+void scrollMessage (int line, int width)
+{
+  char buf [32] ;
+  static int position = 0 ;
+  static int timer = 0 ;
+
+  if (millis () < timer)
+    return ;
+
+  timer = millis () + 200 ;
+
+  strncpy (buf, &message [position], width) ;
+  buf [width] = 0 ;
+  lcdPosition (lcdHandle, 0, line) ;
+  lcdPuts (lcdHandle, buf) ;
+
+  if (++position == (strlen (message) - width))
+    position = 0 ;
+}
+
+
+/*
+ * setBacklightColour:
+ *	The colour outputs are inverted.
+ *********************************************************************************
+ */
+
+static void setBacklightColour (int colour)
+{
+  colour &= 7 ;
+
+  digitalWrite (AF_RED,   !(colour & 1)) ;
+  digitalWrite (AF_GREEN, !(colour & 2)) ;
+  digitalWrite (AF_BLUE,  !(colour & 4)) ;
+}
+
+
+/*
+ * adafruitLCDSetup:
+ *	Setup the Adafruit board by making sure the additional pins are
+ *	set to the correct modes, etc.
+ *********************************************************************************
+ */
+
+static void adafruitLCDSetup (int colour)
+{
+  int i ;
+
+//	Backlight LEDs
+
+  pinMode (AF_RED,   OUTPUT) ;
+  pinMode (AF_GREEN, OUTPUT) ;
+  pinMode (AF_BLUE,  OUTPUT) ;
+  setBacklightColour (colour) ;
+
+//	Input buttons
+
+  for (i = 0 ; i <= 4 ; ++i)
+  {
+    pinMode (AF_BASE + i, INPUT) ;
+    pullUpDnControl (AF_BASE + i, PUD_UP) ;	// Enable pull-ups, switches close to 0v
+  }
+
+// Control signals
+
+  pinMode (AF_RW, OUTPUT) ; digitalWrite (AF_RW, LOW) ;	// Not used with wiringPi - always in write mode
+
+// The other control pins are initialised with lcdInit ()
+
+  lcdHandle = lcdInit (2, 16, 4, AF_RS, AF_E, AF_DB4,AF_DB5,AF_DB6,AF_DB7, 0,0,0,0) ;
+
+  if (lcdHandle < 0)
+  {
+    fprintf (stderr, "lcdInit failed\n") ;
+    exit (EXIT_FAILURE) ;
+  }
+}
+
+
+/*
+ * waitForEnter:
+ *	On the Adafruit display, wait for the select button
+ *********************************************************************************
+ */
+
+static void waitForEnter (void)
+{
+  printf ("Press SELECT to continue: ") ; fflush (stdout) ;
+
+  while (digitalRead (AF_SELECT) == HIGH)	// Wait for push
+    delay (1) ;
+
+  while (digitalRead (AF_SELECT) == LOW)	// Wait for release
+    delay (1) ;
+
+  printf ("OK\n") ;
+}
+
+
+/*
+ * speedTest:
+ *	Test the update speed of the display
+ *********************************************************************************
+ */
+
+static void speedTest (void)
+{
+  unsigned int start, end, taken ;
+  int times ;
+
+  lcdClear (lcdHandle) ;
+  start = millis () ;
+  for (times = 0 ; times < 10 ; ++times)
+  {
+    lcdPuts (lcdHandle, "0123456789ABCDEF") ;
+    lcdPuts (lcdHandle, "0123456789ABCDEF") ;
+  }
+  end   = millis () ;
+  taken = (end - start) / 10;
+
+  lcdClear (lcdHandle) ;
+  lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Speed: %dmS", taken) ;
+  lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "For full update") ;
+
+  waitForEnter () ;
+
+  lcdClear (lcdHandle) ;
+  lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Time: %dmS", taken / 32) ;
+  lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "Per character") ;
+
+  waitForEnter () ;
+
+  lcdClear (lcdHandle) ;
+  lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "%d cps...", 32000 / taken) ;
+
+  waitForEnter () ;
+}
+
+
+/*
+ * The works
+ *********************************************************************************
+ */
+
+int main (int argc, char *argv[])
+{
+  int colour ;
+  int cols = 16 ;
+  int waitForRelease = FALSE ;
+
+  struct tm *t ;
+  time_t tim ;
+
+  char buf [32] ;
+
+  if (argc != 2)
+    return usage (argv [0]) ;
+
+  printf ("Raspberry Pi Adafruit LCD test\n") ;
+  printf ("==============================\n") ;
+
+  colour = atoi (argv [1]) ;
+
+  wiringPiSetupSys () ;
+  mcp23017Setup (AF_BASE, 0x20) ;
+
+  adafruitLCDSetup (colour) ;
+
+  lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ;
+  lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "  wiringpi.com  ") ;
+
+  waitForEnter () ;
+
+  lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "Adafruit RGB LCD") ;
+
+  waitForEnter () ;
+
+  lcdCharDef  (lcdHandle, 2, newChar) ;
+
+  lcdClear    (lcdHandle) ;
+  lcdPosition (lcdHandle, 0, 0) ;
+  lcdPuts     (lcdHandle, "User Char: ") ;
+  lcdPutchar  (lcdHandle, 2) ;
+
+  lcdCursor      (lcdHandle, TRUE) ;
+  lcdCursorBlink (lcdHandle, TRUE) ;
+
+  waitForEnter () ;
+
+  lcdCursor      (lcdHandle, FALSE) ;
+  lcdCursorBlink (lcdHandle, FALSE) ;
+
+  speedTest () ;
+
+  lcdClear (lcdHandle) ;
+
+  for (;;)
+  {
+    scrollMessage (0, cols) ;
+    
+    tim = time (NULL) ;
+    t = localtime (&tim) ;
+
+    sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
+
+    lcdPosition (lcdHandle, (cols - 8) / 2, 1) ;
+    lcdPuts     (lcdHandle, buf) ;
+
+// Check buttons to cycle colour
+
+// If Up or Down are still pushed, then skip
+
+    if (waitForRelease)
+    {
+      if ((digitalRead (AF_UP) == LOW) || (digitalRead (AF_DOWN) == LOW))
+	continue ;
+      else
+	waitForRelease = FALSE ;
+    }
+
+    if (digitalRead (AF_UP) == LOW)	// Pushed
+    {
+      colour = colour + 1 ;
+      if (colour == 8)
+	colour = 0 ;
+      setBacklightColour (colour) ;
+      waitForRelease = TRUE ;
+    }
+
+    if (digitalRead (AF_DOWN) == LOW)	// Pushed
+    {
+      colour = colour - 1 ;
+      if (colour == -1)
+	colour = 7 ;
+      setBacklightColour (colour) ;
+      waitForRelease = TRUE ;
+    }
+
+  }
+
+  return 0 ;
+}

+ 76 - 45
examples/lcd.c

@@ -65,31 +65,59 @@ static unsigned char newChar [8] =
 } ;
 
 
+// Global lcd handle:
+
+static int lcdHandle ;
+
+/*
+ * usage:
+ *********************************************************************************
+ */
+
 int usage (const char *progName)
 {
   fprintf (stderr, "Usage: %s bits cols rows\n", progName) ;
   return EXIT_FAILURE ;
 }
 
+
+/*
+ * scrollMessage:
+ *********************************************************************************
+ */
+
 static const char *message =
   "                    "
   "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
   "                    " ;
 
-void scrollMessage (int lcd, int line, int width)
+void scrollMessage (int line, int width)
 {
   char buf [32] ;
   static int position = 0 ;
+  static int timer = 0 ;
+
+  if (millis () < timer)
+    return ;
+
+  timer = millis () + 200 ;
 
   strncpy (buf, &message [position], width) ;
   buf [width] = 0 ;
-  lcdPosition (lcd, 0, line) ;
-  lcdPuts (lcd, buf) ;
+  lcdPosition (lcdHandle, 0, line) ;
+  lcdPuts     (lcdHandle, buf) ;
 
   if (++position == (strlen (message) - width))
     position = 0 ;
 }
 
+
+/*
+ * pingPong:
+ *	Bounce a character - only on 4-line displays
+ *********************************************************************************
+ */
+
 static void pingPong (int lcd, int cols)
 {
   static int position = 0 ;
@@ -98,13 +126,13 @@ static void pingPong (int lcd, int cols)
   if (dir == 0)		// Setup
   {
     dir = 1 ;
-    lcdPosition (lcd, 0, 3) ;
-    lcdPutchar (lcd, '*') ;
+    lcdPosition (lcdHandle, 0, 3) ;
+    lcdPutchar  (lcdHandle, '*') ;
     return ;
   }
 
-  lcdPosition (lcd, position, 3) ;
-  lcdPutchar (lcd, ' ') ;
+  lcdPosition (lcdHandle, position, 3) ;
+  lcdPutchar (lcdHandle, ' ') ;
   position += dir ;
 
   if (position == cols)
@@ -119,11 +147,15 @@ static void pingPong (int lcd, int cols)
     ++position ;
   }
 
-  lcdPosition (lcd, position, 3) ;
-  lcdPutchar (lcd, '#') ;
+  lcdPosition (lcdHandle, position, 3) ;
+  lcdPutchar  (lcdHandle, '#') ;
 }
 
 
+/*
+ * waitForEnter:
+ *********************************************************************************
+ */
 
 static void waitForEnter (void)
 {
@@ -131,6 +163,12 @@ static void waitForEnter (void)
   (void)fgetc (stdin) ;
 }
 
+
+/*
+ * The works
+ *********************************************************************************
+ */
+
 int main (int argc, char *argv[])
 {
   int i ;
@@ -167,67 +205,60 @@ int main (int argc, char *argv[])
   wiringPiSetup () ;
 
   if (bits == 4)
-    lcd = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ;
+    lcdHandle = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ;
   else
-    lcd = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ;
+    lcdHandle = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ;
 
-  if (lcd < 0)
+  if (lcdHandle < 0)
   {
     fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ;
     return -1 ;
   }
 
-  lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "Gordon Henderson") ;
+  lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ;
+  lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "  wiringpi.com  ") ;
+
+  waitForEnter () ;
 
   if (rows > 1)
   {
-    lcdPosition (lcd, 0, 1) ;
-    for (i = 0 ; i < (cols - 1) ; ++i)
-      lcdPutchar (lcd, '*') ;
-    lcdPutchar (lcd, '2') ;
+    lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "  wiringpi.com  ") ;
 
     if (rows == 4)
     {
-      lcdPosition (lcd, 0, 2) ;
+      lcdPosition (lcdHandle, 0, 2) ;
       for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
-        lcdPuts (lcd, "=-") ;
-      lcdPuts (lcd, "=3") ;
+        lcdPuts (lcdHandle, "=-") ;
+      lcdPuts (lcdHandle, "=3") ;
 
-      lcdPosition (lcd, 0, 3) ;
+      lcdPosition (lcdHandle, 0, 3) ;
       for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
-        lcdPuts (lcd, "-=") ;
-      lcdPuts (lcd, "-4") ;
+        lcdPuts (lcdHandle, "-=") ;
+      lcdPuts (lcdHandle, "-4") ;
     }
   }
 
-  sleep (2) ;
-
-  lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "  wiringpi.com  ") ;
-
-
   waitForEnter () ;
 
-  lcdCharDef  (lcd, 2, newChar) ;
+  lcdCharDef  (lcdHandle, 2, newChar) ;
 
-  lcdClear    (lcd) ;
-  lcdPosition (lcd, 0, 0) ;
-  lcdPuts     (lcd, "User Char: ") ;
-  lcdPutchar  (lcd, 2) ;
+  lcdClear    (lcdHandle) ;
+  lcdPosition (lcdHandle, 0, 0) ;
+  lcdPuts     (lcdHandle, "User Char: ") ;
+  lcdPutchar  (lcdHandle, 2) ;
 
-  lcdCursor      (lcd, TRUE) ;
-  lcdCursorBlink (lcd, TRUE) ;
+  lcdCursor      (lcdHandle, TRUE) ;
+  lcdCursorBlink (lcdHandle, TRUE) ;
 
   waitForEnter () ;
 
-  lcdCursor      (lcd, FALSE) ;
-  lcdCursorBlink (lcd, FALSE) ;
-
+  lcdCursor      (lcdHandle, FALSE) ;
+  lcdCursorBlink (lcdHandle, FALSE) ;
+  lcdClear       (lcdHandle) ;
 
   for (;;)
   {
-    delay (250) ;
-
-    scrollMessage (lcd, 0, cols) ;
+    scrollMessage (0, cols) ;
     
     if (rows == 1)
       continue ;
@@ -237,16 +268,16 @@ int main (int argc, char *argv[])
 
     sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
 
-    lcdPosition (lcd, (cols - 8) / 2, 1) ;
-    lcdPuts     (lcd, buf) ;
+    lcdPosition (lcdHandle, (cols - 8) / 2, 1) ;
+    lcdPuts     (lcdHandle, buf) ;
 
     if (rows == 2)
       continue ;
 
     sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
 
-    lcdPosition (lcd, (cols - 10) / 2, 2) ;
-    lcdPuts     (lcd, buf) ;
+    lcdPosition (lcdHandle, (cols - 10) / 2, 2) ;
+    lcdPuts     (lcdHandle, buf) ;
 
     pingPong (lcd, cols) ;
   }

+ 81 - 0
examples/q2w/Makefile

@@ -0,0 +1,81 @@
+#
+# Makefile:
+#	wiringPi - Wiring Compatable library for the Raspberry Pi
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012-2013 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Lesser General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+#DEBUG	= -g -O0
+DEBUG	= -O3
+CC	= gcc
+INCLUDE	= -I/usr/local/include
+CFLAGS	= $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LDFLAGS	= -L/usr/local/lib
+LDLIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
+
+###############################################################################
+
+SRC	=	blink.c button.c blink-io.c volts.c bright.c
+
+OBJ	=	$(SRC:.c=.o)
+
+BINS	=	$(SRC:.c=)
+
+all:	$(BINS)
+
+blink:	blink.o
+	@echo [link]
+	@$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
+
+blink-io:	blink-io.o
+	@echo [link]
+	@$(CC) -o $@ blink-io.o $(LDFLAGS) $(LDLIBS)
+
+button:	button.o
+	@echo [link]
+	@$(CC) -o $@ button.o $(LDFLAGS) $(LDLIBS)
+
+volts:	volts.o
+	@echo [link]
+	@$(CC) -o $@ volts.o $(LDFLAGS) $(LDLIBS)
+
+bright:	bright.o
+	@echo [link]
+	@$(CC) -o $@ bright.o $(LDFLAGS) $(LDLIBS)
+
+
+.c.o:
+	@echo [CC] $<
+	@$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	@echo "[Clean]"
+	@rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	@echo [ctags]
+	@ctags $(SRC)
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE

+ 79 - 0
examples/q2w/binary.c

@@ -0,0 +1,79 @@
+/*
+ * binary.c:
+ *      Using the Quick 2 wire 16-bit GPIO expansion board to output
+ *	a binary counter.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+#include <mcp23017.h>
+
+#define	Q2W_BASE	100
+
+int main (void)
+{
+  int i, bit ;
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+// Add in the mcp23017 on the q2w board
+
+  mcp23017Setup (Q2W_BASE, 0x20) ;
+
+  printf ("Raspberry Pi - quite2Wire MCP23017 Test\n") ;
+
+// On-board button Input:
+
+  pinMode (0, INPUT) ;
+
+// First 10 pins on q2w board as outputs:
+
+  for (i = 0 ; i < 10 ; ++i)
+    pinMode (Q2W_BASE + i, OUTPUT) ;
+
+// Last pin as an input with the internal pull-up enabled
+
+  pinMode         (Q2W_BASE + 15, INPUT) ;
+  pullUpDnControl (Q2W_BASE + 15, PUD_UP) ;
+
+// Loop, outputting a binary number,
+//	Go faster with the button, or stop if the
+//	on-board button is pushed
+
+  for (;;)
+  {
+    for (i = 0 ; i < 1024 ; ++i)
+    {
+      for (bit = 0 ; bit < 10 ; ++bit)
+        digitalWrite (Q2W_BASE + bit, i & (1 << bit)) ;
+
+      while (digitalRead (0) == HIGH)		// While pushed
+	delay (1) ;
+
+      if (digitalRead (Q2W_BASE + 15) == HIGH)	// Not Pushed
+	delay (100) ;
+    }
+  }
+  return 0 ;
+}

+ 61 - 0
examples/q2w/blink-io.c

@@ -0,0 +1,61 @@
+/*
+ * blink-io.c:
+ *	Simple "blink" test for the Quick2Wire 16-pin IO board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+#include <mcp23017.h>
+
+#define	LED		1
+#define	Q2W_BASE	100
+
+int main (void)
+{
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+// Add in the mcp23017 on the q2w board
+
+  mcp23017Setup (Q2W_BASE, 0x20) ;
+
+  printf ("Raspberry Pi - Quick2Wire MCP23017 Blink Test\n") ;
+
+// Blink the on-board LED as well as one on the mcp23017
+
+  pinMode (LED, OUTPUT) ;
+  pinMode (Q2W_BASE + 0, OUTPUT) ;
+
+  for (;;)
+  {
+    digitalWrite (LED,          HIGH) ;
+    digitalWrite (Q2W_BASE + 0, HIGH) ;
+    delay (500) ;
+    digitalWrite (LED,          LOW) ;
+    digitalWrite (Q2W_BASE + 0, LOW) ;
+    delay (500) ;
+  }
+
+  return 0 ;
+}

+ 50 - 0
examples/q2w/blink.c

@@ -0,0 +1,50 @@
+/*
+ * blink.c:
+ *	Simple "blink" test for the Quick2Wire interface board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+
+#define	LED	1
+
+int main (void)
+{
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+  printf ("Raspberry Pi - Quick2Wire Mainboard LED Blink Test\n") ;
+
+  pinMode (LED, OUTPUT) ;
+
+  for (;;)
+  {
+    digitalWrite (LED, HIGH) ;
+    delay (500) ;
+    digitalWrite (LED, LOW) ;
+    delay (500) ;
+  }
+
+  return 0 ;
+}

+ 37 - 0
examples/q2w/blink.sh

@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# blink.sh:
+#	Standard "blink" program in wiringPi. Blinks an LED connected
+#	to the LED on the Quick2Wire board
+#
+# Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+#######################################################################
+# This file is part of wiringPi:
+#	https://projects.drogon.net/raspberry-pi/wiringpi/
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Lesser General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#######################################################################
+
+# LED Pin - wiringPi pin 1 is BCM_GPIO 18.
+
+LED=1
+
+gpio mode $LED out
+
+while true; do
+  gpio write $LED 1
+  sleep 0.5
+  gpio write $LED 0
+  sleep 0.5
+done

+ 59 - 0
examples/q2w/bright.c

@@ -0,0 +1,59 @@
+/*
+ * bright.c:
+ *	Vary the Q2W LED brightness with the analog card
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+#include <pcf8591.h>
+
+#define	LED		  1
+#define Q2W_ABASE       120
+
+int main (void)
+{
+  int value ;
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+// Add in the pcf8591 on the q2w board
+
+  pcf8591Setup (Q2W_ABASE, 0x48) ;
+
+  printf ("Raspberry Pi - Quick2Wire Analog Test\n") ;
+
+// Setup the LED
+
+  pinMode  (LED, PWM_OUTPUT) ;
+  pwmWrite (LED, 0) ;
+
+  for (;;)
+  {
+    value = analogRead  (Q2W_ABASE + 0) ;
+    pwmWrite (LED, value * 4) ;
+    delay (10) ;
+  }
+
+  return 0 ;
+}

+ 63 - 0
examples/q2w/button.c

@@ -0,0 +1,63 @@
+/*
+ * button.c:
+ *	Simple button test for the Quick2Wire interface board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+
+#define	BUTTON	0
+#define	LED1	1
+#define	LED2	7
+
+int main (void)
+{
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+  printf ("Raspberry Pi - Quick2Wire Mainboard Button & LED Test\n") ;
+
+  pinMode (BUTTON, INPUT) ;
+  pinMode (LED1, OUTPUT) ;
+  pinMode (LED2, OUTPUT) ;
+
+  digitalWrite (LED1, HIGH) ;		// On-board LED on
+  digitalWrite (LED2, LOW) ;		// 2nd LED off
+
+  for (;;)
+  {
+    if (digitalRead (BUTTON) == HIGH)	// Swap LED states
+    {
+      digitalWrite (LED1, LOW) ;
+      digitalWrite (LED2, HIGH) ;
+      while (digitalRead (BUTTON) == HIGH)
+	delay (1) ;
+      digitalWrite (LED1, HIGH) ;
+      digitalWrite (LED2, LOW) ;
+    }
+    delay (1) ;
+  }
+
+  return 0 ;
+}

+ 62 - 0
examples/q2w/volts.c

@@ -0,0 +1,62 @@
+/*
+ * volts.c:
+ *	Read in all 4 analogs on the Q2W analog board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <wiringPi.h>
+#include <pcf8591.h>
+
+#define	LED		1
+#define Q2W_ABASE       120
+
+int main (void)
+{
+  int value, pin ;
+
+// Enable the on-goard GPIO
+
+  wiringPiSetup () ;
+
+  pinMode (LED, OUTPUT) ;	// On-board LED
+
+// Add in the pcf8591 on the q2w board
+
+  pcf8591Setup (Q2W_ABASE, 0x48) ;
+
+  printf ("Raspberry Pi - Quick2Wire Voltmeter\n") ;
+
+  for (;;)
+  {
+    for (pin = 0 ; pin < 4 ; ++pin)
+    {
+      value = analogRead  (Q2W_ABASE + pin) ;
+      printf ("  %5.2f", (double)value * 3.3 / 255.0) ;
+    }
+    printf ("\r") ; fflush (stdout) ;
+
+    delay (100) ;
+    digitalWrite (LED, !digitalRead (LED)) ;	// Flicker the LED
+  }
+
+  return 0 ;
+}

+ 0 - 0
examples/rht03.c


+ 88 - 3
gpio/extensions.c

@@ -36,10 +36,13 @@
 #include <wiringPi.h>
 
 #include <mcp23008.h>
+#include <mcp23016.h>
 #include <mcp23017.h>
 #include <mcp23s08.h>
 #include <mcp23s17.h>
 #include <sr595.h>
+#include <pcf8591.h>
+#include <pcf8574.h>
 
 #include "extensions.h"
 
@@ -116,10 +119,36 @@ static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
 }
 
 
+/*
+ * doExtensionMcp23016:
+ *	MCP230016- 16-bit I2C GPIO expansion chip
+ *	mcp23016:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    return FALSE ;
+  }
+
+  mcp23016Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
 /*
  * doExtensionMcp23017:
- *	MCP23008 - 16-bit I2C GPIO expansion chip
- *	mcp23002:base:i2cAddr
+ *	MCP230017- 16-bit I2C GPIO expansion chip
+ *	mcp23017:base:i2cAddr
  *********************************************************************************
  */
 
@@ -211,6 +240,7 @@ static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
   return TRUE ;
 }
 
+
 /*
  * doExtensionSr595:
  *	Shift Register 74x595
@@ -248,6 +278,58 @@ static int doExtensionSr595 (char *progName, int pinBase, char *params)
 }
 
 
+/*
+ * doExtensionPcf8574:
+ *	Digital IO (Crude!)
+ *	pcf8574:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    return FALSE ;
+  }
+
+  pcf8574Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionPcf8591:
+ *	Analog IO
+ *	pcf8591:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    return FALSE ;
+  }
+
+  pcf8591Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
 /*
  * Function list
  *********************************************************************************
@@ -256,10 +338,13 @@ static int doExtensionSr595 (char *progName, int pinBase, char *params)
 struct extensionFunctionStruct extensionFunctions [] = 
 {
   { "mcp23008",		&doExtensionMcp23008 	},
+  { "mcp23016",		&doExtensionMcp23016 	},
   { "mcp23017",		&doExtensionMcp23017 	},
   { "mcp23s08",		&doExtensionMcp23s08 	},
   { "mcp23s17",		&doExtensionMcp23s17 	},
-  { "sr595",		&doExtensionSr595	 },
+  { "sr595",		&doExtensionSr595	},
+  { "pcf8574",		&doExtensionPcf8574	},
+  { "pcf8591",		&doExtensionPcf8591	},
   { NULL,		NULL		 	},
 } ;
 

+ 1 - 7
gpio/gpio.c

@@ -895,19 +895,13 @@ void doRead (int argc, char *argv [])
 
 void doAread (int argc, char *argv []) 
 {
-  int pin, val ;
-
   if (argc != 3)
   {
     fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
     exit (1) ;
   }
 
-  pin = atoi (argv [2]) ;
-
-  val = analogRead (pin) ;
-
-  printf ("%s\n", val == 0 ? "0" : "1") ;
+  printf ("%d\n", analogRead (atoi (argv [2]))) ;
 }
 
 

+ 12 - 4
wiringPi/Makefile

@@ -47,8 +47,10 @@ SRC	=	wiringPi.c						\
 		piHiPri.c piThread.c					\
 		wiringPiSPI.c wiringPiI2C.c				\
 		softPwm.c softTone.c					\
-		mcp23s08.c mcp23008.c					\
-		mcp23s17.c mcp23017.c sr595.c pcf8574.c			\
+		mcp23008.c mcp23016.c mcp23017.c			\
+		mcp23s08.c mcp23s17.c					\
+		sr595.c							\
+		pcf8574.c pcf8591.c					\
 		mcp3002.c mcp4802.c mcp3422.c				\
 		drc.c
 
@@ -95,6 +97,7 @@ install-headers:
 	@install -m 0644 wiringPiSPI.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 wiringPiI2C.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 mcp23008.h		$(DESTDIR)$(PREFIX)/include
+	@install -m 0644 mcp23016.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 mcp23017.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 mcp23s08.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 mcp23s17.h		$(DESTDIR)$(PREFIX)/include
@@ -103,6 +106,7 @@ install-headers:
 	@install -m 0644 mcp3422.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 sr595.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 pcf8574.h		$(DESTDIR)$(PREFIX)/include
+	@install -m 0644 pcf8591.h		$(DESTDIR)$(PREFIX)/include
 
 .PHONEY:	install
 install:	$(DYNAMIC) install-headers
@@ -129,6 +133,7 @@ uninstall:
 	@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/mcp23008.h
+	@rm -f $(DESTDIR)$(PREFIX)/include/mcp23016.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/mcp23017.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/mcp23s08.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/mcp23s17.h
@@ -137,6 +142,7 @@ uninstall:
 	@rm -f $(DESTDIR)$(PREFIX)/include/mcp3422.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/sr595.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/pcf8574.h
+	@rm -f $(DESTDIR)$(PREFIX)/include/pcf8591.h
 	@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
 	@ldconfig
 
@@ -156,12 +162,14 @@ wiringPiSPI.o: wiringPi.h wiringPiSPI.h
 wiringPiI2C.o: wiringPi.h wiringPiI2C.h
 softPwm.o: wiringPi.h softPwm.h
 softTone.o: wiringPi.h softTone.h
-mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
 mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h
-mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
+mcp23016.o: wiringPi.h wiringPiI2C.h mcp23016.h mcp23016reg.h
 mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h
+mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
+mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
 sr595.o: wiringPi.h sr595.h
 pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h
+pcf8591.o: wiringPi.h wiringPiI2C.h pcf8591.h
 mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h
 mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
 mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h

+ 164 - 0
wiringPi/mcp23016.c

@@ -0,0 +1,164 @@
+/*
+ * mcp23016.c:
+ *	Extend wiringPi with the MCP 23016 I2C GPIO expander chip
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as
+ *    published by the Free Software Foundation, either version 3 of the
+ *    License, or (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with wiringPi.
+ *    If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <pthread.h>
+
+#include "wiringPi.h"
+#include "wiringPiI2C.h"
+#include "mcp23016.h"
+
+#include "mcp23016reg.h"
+
+
+/*
+ * myPinMode:
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  pin -= node->pinBase ;
+
+  if (pin < 8)		// Bank A
+    reg  = MCP23016_IODIR0 ;
+  else
+  {
+    reg  = MCP23016_IODIR1 ;
+    pin &= 0x07 ;
+  }
+
+  mask = 1 << pin ;
+  old  = wiringPiI2CReadReg8 (node->fd, reg) ;
+
+  if (mode == OUTPUT)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  wiringPiI2CWriteReg8 (node->fd, reg, old) ;
+}
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int bit, old ;
+
+  pin -= node->pinBase ;	// Pin now 0-15
+
+  bit = 1 << (pin & 7) ;
+
+  if (pin < 8)			// Bank A
+  {
+    old = node->data2 ;
+
+    if (value == LOW)
+      old &= (~bit) ;
+    else
+      old |=   bit ;
+
+    wiringPiI2CWriteReg8 (node->fd, MCP23016_GP0, old) ;
+    node->data2 = old ;
+  }
+  else				// Bank B
+  {
+    old = node->data3 ;
+
+    if (value == LOW)
+      old &= (~bit) ;
+    else
+      old |=   bit ;
+
+    wiringPiI2CWriteReg8 (node->fd, MCP23016_GP1, old) ;
+    node->data3 = old ;
+  }
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int mask, value, gpio ;
+
+  pin -= node->pinBase ;
+
+  if (pin < 8)		// Bank A
+    gpio  = MCP23016_GP0 ;
+  else
+  {
+    gpio  = MCP23016_GP1 ;
+    pin  &= 0x07 ;
+  }
+
+  mask  = 1 << pin ;
+  value = wiringPiI2CReadReg8 (node->fd, gpio) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * mcp23016Setup:
+ *	Create a new instance of an MCP23016 I2C GPIO interface. We know it
+ *	has 16 pins, so all we need to know here is the I2C address and the
+ *	user-defined pin base.
+ *********************************************************************************
+ */
+
+int mcp23016Setup (const int pinBase, const int i2cAddress)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return fd ;
+
+  wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ;
+  wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ;
+
+  node = wiringPiNewNode (pinBase, 16) ;
+
+  node->fd              = fd ;
+  node->pinMode         = myPinMode ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ;
+  node->data3           = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ;
+
+  return 0 ;
+}

+ 33 - 0
wiringPi/mcp23016.h

@@ -0,0 +1,33 @@
+/*
+ * mcp23016.h:
+ *	Extend wiringPi with the MCP 23016 I2C GPIO expander chip
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as
+ *    published by the Free Software Foundation, either version 3 of the
+ *    License, or (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with wiringPi.
+ *    If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp23016Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif

+ 48 - 0
wiringPi/mcp23016reg.h

@@ -0,0 +1,48 @@
+/*
+ * mcp23016:
+ *	Copyright (c) 2012-2013 Gordon Henderson
+ *
+ *	Header file for code using the MCP23016 GPIO expander
+ *	chip.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as
+ *    published by the Free Software Foundation, either version 3 of the
+ *    License, or (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with wiringPi.
+ *    If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+// MCP23016 Registers
+
+#define	MCP23016_GP0		0x00
+#define	MCP23016_GP1		0x01
+#define	MCP23016_OLAT0		0x02
+#define	MCP23016_OLAT1		0x03
+#define	MCP23016_IPOL0		0x04
+#define	MCP23016_IPOL1		0x05
+#define	MCP23016_IODIR0		0x06
+#define	MCP23016_IODIR1		0x07
+#define	MCP23016_INTCAP0	0x08
+#define	MCP23016_INTCAP1	0x09
+#define	MCP23016_IOCON0		0x0A
+#define	MCP23016_IOCON1		0x0B
+
+// Bits in the IOCON register
+
+#define	IOCON_IARES	0x01
+
+// Default initialisation mode
+
+#define	IOCON_INIT	0

+ 8 - 8
wiringPi/pcf8574.c

@@ -1,6 +1,6 @@
 /*
  * pcf8574.c:
- *	Extend wiringPi with the PFC8574 I2C GPIO expander chip
+ *	Extend wiringPi with the PCF8574 I2C GPIO expander chip
  *	Copyright (c) 2013 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
@@ -33,7 +33,7 @@
 
 /*
  * myPinMode:
- *	The PFC8574 is an odd chip - the pins are effectively bi-directional,
+ *	The PCF8574 is an odd chip - the pins are effectively bi-directional,
  *	however the pins should be drven high when used as an input pin...
  *	So, we're effectively copying digitalWrite...
  *********************************************************************************
@@ -100,7 +100,7 @@ static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
 
 /*
  * pcf8574Setup:
- *	Create a new instance of a PFC8574 I2C GPIO interface. We know it
+ *	Create a new instance of a PCF8574 I2C GPIO interface. We know it
  *	has 8 pins, so all we need to know here is the I2C address and the
  *	user-defined pin base.
  *********************************************************************************
@@ -116,11 +116,11 @@ int pcf8574Setup (const int pinBase, const int i2cAddress)
 
   node = wiringPiNewNode (pinBase, 8) ;
 
-  node->fd              = fd ;
-  node->pinMode         = myPinMode ;
-  node->digitalRead     = myDigitalRead ;
-  node->digitalWrite    = myDigitalWrite ;
-  node->data2           = wiringPiI2CRead (fd) ;
+  node->fd           = fd ;
+  node->pinMode      = myPinMode ;
+  node->digitalRead  = myDigitalRead ;
+  node->digitalWrite = myDigitalWrite ;
+  node->data2        = wiringPiI2CRead (fd) ;
 
   return 0 ;
 }

+ 3 - 3
wiringPi/pcf8574.h

@@ -1,6 +1,6 @@
 /*
- * pfc8574.h:
- *	Extend wiringPi with the PFC8574 I2C GPIO expander chip
+ * pcf8574.h:
+ *	Extend wiringPi with the PCF8574 I2C GPIO expander chip
  *	Copyright (c) 2013 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
@@ -26,7 +26,7 @@
 extern "C" {
 #endif
 
-extern int pfc8574Setup (const int pinBase, const int i2cAddress) ;
+extern int pcf8574Setup (const int pinBase, const int i2cAddress) ;
 
 #ifdef __cplusplus
 }

+ 90 - 0
wiringPi/pcf8591.c

@@ -0,0 +1,90 @@
+/*
+ * pcf8591.c:
+ *	Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip
+ *	The chip has 1 8-bit DAC and 4 x 8-bit ADCs
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as
+ *    published by the Free Software Foundation, either version 3 of the
+ *    License, or (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with wiringPi.
+ *    If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <unistd.h>
+
+#include "wiringPi.h"
+#include "wiringPiI2C.h"
+
+#include "pcf8591.h"
+
+
+/*
+ * myAnalogWrite:
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  unsigned char b [2] ;
+  b [0] = 0x40 ;
+  b [1] = value & 0xFF ;
+  write (node->fd, b, 2) ;
+}
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int x ;
+
+  wiringPiI2CWrite (node->fd, 0x40 | ((pin - node->pinBase) & 3)) ;
+
+  x = wiringPiI2CRead (node->fd) ;	// Throw away the first read
+  x = wiringPiI2CRead (node->fd) ;
+
+  return x ;
+}
+
+
+/*
+ * pcf8591Setup:
+ *	Create a new instance of a PCF8591 I2C GPIO interface. We know it
+ *	has 4 pins, (4 analog inputs and 1 analog output which we'll shadow
+ *	input 0) so all we need to know here is the I2C address and the
+ *	user-defined pin base.
+ *********************************************************************************
+ */
+
+int pcf8591Setup (const int pinBase, const int i2cAddress)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return fd ;
+
+  node = wiringPiNewNode (pinBase, 4) ;
+
+  node->fd          = fd ;
+  node->analogRead  = myAnalogRead ;
+  node->analogWrite = myAnalogWrite ;
+
+  return 0 ;
+}

+ 33 - 0
wiringPi/pcf8591.h

@@ -0,0 +1,33 @@
+/*
+ * pcf8591.h:
+ *	Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *	https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as
+ *    published by the Free Software Foundation, either version 3 of the
+ *    License, or (at your option) any later version.
+ *
+ *    wiringPi is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public
+ *    License along with wiringPi.
+ *    If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int pcf8591Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif

+ 5 - 0
wiringPi/wiringPi.h

@@ -21,6 +21,9 @@
  ***********************************************************************
  */
 
+#ifndef	__WIRING_PI_H__
+#define	__WIRING_PI_H__
+
 // Handy defines
 
 // Deprecated
@@ -176,3 +179,5 @@ extern unsigned int micros            (void) ;
 #ifdef __cplusplus
 }
 #endif
+
+#endif

+ 1 - 1
wiringPi/wiringPiI2C.c

@@ -150,7 +150,7 @@ int wiringPiI2CReadReg16 (int fd, int reg)
   if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data))
     return -1 ;
   else
-    return data.byte & 0xFF ;
+    return data.byte & 0xFFFF ;
 }