WiringPi: Bring back all of the stuffs I removed to do with peripherals

Imported from the official WiringPi repository, version 2.60.

Signed-off-by: Deokgyu Yang <secugyu@gmail.com>
Change-Id: I82dc00ab9f038f9bc4c6a9c4ca3affe5a5d33ae1
diff --git a/build b/build
index ba31b7a..d74071e 100755
--- a/build
+++ b/build
@@ -107,6 +107,21 @@
   echo
   echo "WiringPi Devices Library"
   cd ../devLib
+  $sudo $make uninstall
+  if [ x$1 = "xstatic" ]; then
+    $make static
+    check_make_ok
+    $sudo $make install-static
+  else
+    $make
+    check_make_ok
+    $sudo $make install
+  fi
+  check_make_ok
+
+  echo
+  echo "WiringPi Devices Library"
+  cd ../devLib
   if [ x$1 = "xstatic" ]; then
     $make static
     check_make_ok
@@ -135,6 +150,9 @@
   echo ""
   echo "NOTE: To compile programs with wiringPi, you need to add:"
   echo "    -lwiringPi -wiringPiDev"
+  echo "  to your compile line(s) To use the Gertboard, MaxDetect, etc."
+  echo "  code (the devLib), you need to also add:"
+  echo "    -lwiringPiDev"
   echo "  to your compile line(s)."
   echo ""
 }
@@ -159,8 +177,18 @@
   cd ../gpio
   echo -n "gpio:       "	; $make clean
   cd ../examples
-  echo -n "examples:   "	; $make clean
-  cd ..
+  echo -n "Examples:   "	; $make clean
+  cd Gertboard
+  echo -n "Gertboard:  "	; $make clean
+  cd ../PiFace
+  echo -n "PiFace:     "	; $make clean
+  cd ../q2w
+  echo -n "Quick2Wire: "	; $make clean
+  cd ../PiGlow
+  echo -n "PiGlow:     "	; $make clean
+  cd ../scrollPhat
+  echo -n "scrollPhat: "	; $make clean
+  cd ../..
 }
 
 if [ x$1 = "xclean" ]; then
diff --git a/devLib/Makefile b/devLib/Makefile
index 59a4cc8..6f1c800 100644
--- a/devLib/Makefile
+++ b/devLib/Makefile
@@ -47,11 +47,16 @@
 
 ###############################################################################
 
-SRC	=	lcd128x64.c lcd.c
+SRC	=	ds1302.c maxdetect.c  piNes.c		\
+		gertboard.c piFace.c			\
+		lcd128x64.c lcd.c			\
+		scrollPhat.c				\
+		piGlow.c
 
 OBJ	=	$(SRC:.c=.o)
 
-HEADERS	=	lcd128x64.h  lcd.h
+HEADERS	=	ds1302.h gertboard.h  lcd128x64.h  lcd.h  maxdetect.h piFace.h  piGlow.h  piNes.h\
+		scrollPhat.h
 
 all:		$(DYNAMIC)
 
@@ -117,5 +122,10 @@
 
 # DO NOT DELETE
 
+ds1302.o: ds1302.h
+maxdetect.o: maxdetect.h
+piNes.o: piNes.h
+gertboard.o: gertboard.h
+piFace.o: piFace.h
 lcd128x64.o: font.h lcd128x64.h
 lcd.o: lcd.h
diff --git a/devLib/ds1302.c b/devLib/ds1302.c
new file mode 100644
index 0000000..cf64de7
--- /dev/null
+++ b/devLib/ds1302.c
@@ -0,0 +1,240 @@
+/*
+ * ds1302.c:
+ *	Real Time clock
+ *
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#include <wiringPi.h>
+
+#include "ds1302.h"
+
+// Register defines
+
+#define	RTC_SECS	 0
+#define	RTC_MINS	 1
+#define	RTC_HOURS	 2
+#define	RTC_DATE	 3
+#define	RTC_MONTH	 4
+#define	RTC_DAY		 5
+#define	RTC_YEAR	 6
+#define	RTC_WP		 7
+#define	RTC_TC		 8
+#define	RTC_BM		31
+
+
+// Locals
+
+static int dPin, cPin, sPin ;
+
+/*
+ * dsShiftIn:
+ *	Shift a number in from the chip, LSB first. Note that the data is
+ *	sampled on the trailing edge of the last clock, so it's valid immediately.
+ *********************************************************************************
+ */
+
+static unsigned int dsShiftIn (void)
+{
+  uint8_t value = 0 ;
+  int i ;
+
+  pinMode (dPin, INPUT) ;	delayMicroseconds (1) ;
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    value |= (digitalRead (dPin) << i) ;
+    digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
+    digitalWrite (cPin, LOW) ;	delayMicroseconds (1) ;
+  }
+
+  return value;
+}
+
+
+/*
+ * dsShiftOut:
+ *	A normal LSB-first shift-out, just slowed down a bit - the Pi is
+ *	a bit faster than the chip can handle.
+ *********************************************************************************
+ */
+
+static void dsShiftOut (unsigned int data)
+{
+  int i ;
+
+  pinMode (dPin, OUTPUT) ;
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    digitalWrite (dPin, data & (1 << i)) ;	delayMicroseconds (1) ;
+    digitalWrite (cPin, HIGH) ;			delayMicroseconds (1) ;
+    digitalWrite (cPin, LOW) ;			delayMicroseconds (1) ;
+  }
+}
+
+
+/*
+ * ds1302regRead: ds1302regWrite:
+ *	Read/Write a value to an RTC Register or RAM location on the chip
+ *********************************************************************************
+ */
+
+static unsigned int ds1302regRead (const int reg)
+{
+  unsigned int data ;
+
+  digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+    dsShiftOut (reg) ;
+    data = dsShiftIn () ;
+  digitalWrite (sPin, LOW)  ; delayMicroseconds (1) ;
+
+  return data ;
+}
+
+static void ds1302regWrite (const int reg, const unsigned int data)
+{
+  digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+    dsShiftOut (reg) ;
+    dsShiftOut (data) ;
+  digitalWrite (sPin, LOW)  ; delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302rtcWrite: ds1302rtcRead:
+ *	Writes/Reads the data to/from the RTC register
+ *********************************************************************************
+ */
+
+unsigned int ds1302rtcRead (const int reg)
+{
+  return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ;
+}
+
+void ds1302rtcWrite (int reg, unsigned int data)
+{
+  ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ;
+}
+
+
+/*
+ * ds1302ramWrite: ds1302ramRead:
+ *	Writes/Reads the data to/from the RTC register
+ *********************************************************************************
+ */
+
+unsigned int ds1302ramRead (const int addr)
+{
+  return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ;
+}
+
+void ds1302ramWrite (const int addr, const unsigned int data)
+{
+  ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ;
+}
+
+/*
+ * ds1302clockRead:
+ *	Read all 8 bytes of the clock in a single operation
+ *********************************************************************************
+ */
+
+void ds1302clockRead (int clockData [8])
+{
+  int i ;
+  unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ;
+
+  digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+
+  dsShiftOut (regVal) ;
+  for (i = 0 ; i < 8 ; ++i)
+    clockData [i] = dsShiftIn () ;
+
+  digitalWrite (sPin, LOW) ;  delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302clockWrite:
+ *	Write all 8 bytes of the clock in a single operation
+ *********************************************************************************
+ */
+
+void ds1302clockWrite (const int clockData [8])
+{
+  int i ;
+  unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ;
+
+  digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+
+  dsShiftOut (regVal) ;
+  for (i = 0 ; i < 8 ; ++i)
+    dsShiftOut (clockData [i]) ;
+
+  digitalWrite (sPin, LOW) ;  delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302trickleCharge:
+ *	Set the bits on the trickle charger.
+ *	Probably best left alone...
+ *********************************************************************************
+ */
+
+void ds1302trickleCharge (const int diodes, const int resistors)
+{
+  if (diodes + resistors == 0)
+    ds1302rtcWrite (RTC_TC, 0x5C) ;	// Disabled
+  else
+    ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ;
+}
+
+
+
+
+/*
+ * ds1302setup:
+ *	Initialise the chip & remember the pins we're using
+ *********************************************************************************
+ */
+
+void ds1302setup (const int clockPin, const int dataPin, const int csPin)
+{
+  dPin = dataPin ;
+  cPin = clockPin ;
+  sPin = csPin ;
+
+  digitalWrite (dPin, LOW) ;
+  digitalWrite (cPin, LOW) ;
+  digitalWrite (sPin, LOW) ;
+
+  pinMode (dPin, OUTPUT) ;
+  pinMode (cPin, OUTPUT) ;
+  pinMode (sPin, OUTPUT) ;
+
+  ds1302rtcWrite (RTC_WP, 0) ;	// Remove write-protect
+}
diff --git a/devLib/ds1302.h b/devLib/ds1302.h
new file mode 100644
index 0000000..e82b3ed
--- /dev/null
+++ b/devLib/ds1302.h
@@ -0,0 +1,44 @@
+/*
+ * ds1302.h:
+ *	Real Time clock
+ *
+ * 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 unsigned int ds1302rtcRead       (const int reg) ;
+extern void         ds1302rtcWrite      (const int reg, const unsigned int data) ;
+
+extern unsigned int ds1302ramRead       (const int addr) ;
+extern void         ds1302ramWrite      (const int addr, const unsigned int data) ;
+
+extern void         ds1302clockRead     (int clockData [8]) ;
+extern void         ds1302clockWrite    (const int clockData [8]) ;
+
+extern void         ds1302trickleCharge (const int diodes, const int resistors) ;
+
+extern void         ds1302setup         (const int clockPin, const int dataPin, const int csPin) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/gertboard.c b/devLib/gertboard.c
new file mode 100644
index 0000000..6a84415
--- /dev/null
+++ b/devLib/gertboard.c
@@ -0,0 +1,164 @@
+/*
+ * gertboard.c:
+ *	Access routines for the SPI devices on the Gertboard
+ *	Copyright (c) 2012 Gordon Henderson
+ *
+ *	The Gertboard has:
+ *
+ *		An MCP3002 dual-channel A to D convertor connected
+ *		to the SPI bus, selected by chip-select A, and:
+ *
+ *		An MCP4802 dual-channel D to A convertor connected
+ *		to the SPI bus, selected via chip-select B.
+ *
+ ***********************************************************************
+ * 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 <stdint.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
+
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "gertboard.h"
+
+// The A-D convertor won't run at more than 1MHz @ 3.3v
+
+#define	SPI_ADC_SPEED	1000000
+#define	SPI_DAC_SPEED	1000000
+#define	SPI_A2D		      0
+#define	SPI_D2A		      1
+
+
+/*
+ * gertboardAnalogWrite:
+ *	Write an 8-bit data value to the MCP4802 Analog to digital
+ *	convertor on the Gertboard.
+ *********************************************************************************
+ */
+
+void gertboardAnalogWrite (const int chan, const int value)
+{
+  uint8_t spiData [2] ;
+  uint8_t chanBits, dataBits ;
+
+  if (chan == 0)
+    chanBits = 0x30 ;
+  else
+    chanBits = 0xB0 ;
+
+  chanBits |= ((value >> 4) & 0x0F) ;
+  dataBits  = ((value << 4) & 0xF0) ;
+
+  spiData [0] = chanBits ;
+  spiData [1] = dataBits ;
+
+  wiringPiSPIDataRW (SPI_D2A, spiData, 2) ;
+}
+
+
+/*
+ * gertboardAnalogRead:
+ *	Return the analog value of the given channel (0/1).
+ *	The A/D is a 10-bit device
+ *********************************************************************************
+ */
+
+int gertboardAnalogRead (const int chan)
+{
+  uint8_t spiData [2] ;
+
+  uint8_t chanBits ;
+
+  if (chan == 0)
+    chanBits = 0b11010000 ;
+  else
+    chanBits = 0b11110000 ;
+
+  spiData [0] = chanBits ;
+  spiData [1] = 0 ;
+
+  wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;
+
+  return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
+}
+
+
+/*
+ * gertboardSPISetup:
+ *	Initialise the SPI bus, etc.
+ *********************************************************************************
+ */
+
+int gertboardSPISetup (void)
+{
+  if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
+    return -1 ;
+
+  if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0)
+    return -1 ;
+
+  return 0 ;
+}
+
+
+/*
+ * New wiringPi node extension methods.
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan)
+{
+  return gertboardAnalogRead (chan - node->pinBase) ;
+}
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value)
+{
+  gertboardAnalogWrite (chan - node->pinBase, value) ;
+}
+
+
+/*
+ * gertboardAnalogSetup:
+ *	Create a new wiringPi device node for the analog devices on the
+ *	Gertboard. We create one node with 2 pins - each pin being read
+ *	and write - although the operations actually go to different
+ *	hardware devices.
+ *********************************************************************************
+ */
+
+int gertboardAnalogSetup (const int pinBase)
+{
+  struct wiringPiNodeStruct *node ;
+  int    x ;
+
+  if (( x = gertboardSPISetup ()) != 0)
+    return  x;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+  node->analogRead  = myAnalogRead ;
+  node->analogWrite = myAnalogWrite ;
+
+  return 0 ;
+}
diff --git a/devLib/gertboard.h b/devLib/gertboard.h
new file mode 100644
index 0000000..3fa1919
--- /dev/null
+++ b/devLib/gertboard.h
@@ -0,0 +1,45 @@
+/*
+ * gertboard.h:
+ *	Access routines for the SPI devices on the Gertboard
+ *	Copyright (c) 2012 Gordon Henderson
+ *
+ *	The Gertboard has an MCP4802 dual-channel D to A convertor
+ *	connected to the SPI bus, selected via chip-select B.
+ *
+ ***********************************************************************
+ * 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
+
+// Old routines
+
+extern void gertboardAnalogWrite (const int chan, const int value) ;
+extern int  gertboardAnalogRead  (const int chan) ;
+extern int  gertboardSPISetup    (void) ;
+
+// New
+
+extern int  gertboardAnalogSetup (const int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/maxdetect.c b/devLib/maxdetect.c
new file mode 100644
index 0000000..74ff70e
--- /dev/null
+++ b/devLib/maxdetect.c
@@ -0,0 +1,238 @@
+/*
+ * maxdetect.c:
+ *	Driver for the MaxDetect series sensors
+ *
+ * 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 <sys/time.h>
+#include <stdio.h>
+//#include <stdlib.h>
+//#include <unistd.h>
+
+#include <wiringPi.h>
+
+#include "maxdetect.h"
+
+#ifndef	TRUE
+#  define	TRUE	(1==1)
+#  define	FALSE	(1==2)
+#endif
+
+
+/*
+ * maxDetectLowHighWait:
+ *	Wait for a transition from low to high on the bus
+ *********************************************************************************
+ */
+
+static int maxDetectLowHighWait (const int pin)
+{
+  struct timeval now, timeOut, timeUp ;
+
+// If already high then wait for pin to go low
+
+  gettimeofday (&now, NULL) ;
+  timerclear   (&timeOut) ;
+  timeOut.tv_usec = 1000 ;
+  timeradd     (&now, &timeOut, &timeUp) ;
+
+  while (digitalRead (pin) == HIGH)
+  {
+    gettimeofday (&now, NULL) ;
+    if (timercmp (&now, &timeUp, >))
+      return FALSE ;
+  }
+
+// Wait for it to go HIGH
+
+  gettimeofday (&now, NULL) ;
+  timerclear (&timeOut) ;
+  timeOut.tv_usec = 1000 ;
+  timeradd (&now, &timeOut, &timeUp) ;
+
+  while (digitalRead (pin) == LOW)
+  {
+    gettimeofday (&now, NULL) ;
+    if (timercmp (&now, &timeUp, >))
+      return FALSE ;
+  }
+
+  return TRUE ;
+}
+
+
+/*
+ * maxDetectClockByte:
+ *	Read in a single byte from the MaxDetect bus
+ *********************************************************************************
+ */
+
+static unsigned int maxDetectClockByte (const int pin)
+{
+  unsigned int byte = 0 ;
+  int bit ;
+
+  for (bit = 0 ; bit < 8 ; ++bit)
+  {
+    if (!maxDetectLowHighWait (pin))
+      return 0 ;
+
+// bit starting now - we need to time it.
+
+    delayMicroseconds (30) ;
+    byte <<= 1 ;
+    if (digitalRead (pin) == HIGH)	// It's a 1
+      byte |= 1 ;
+  }
+
+  return byte ;
+}
+
+
+/*
+ * maxDetectRead:
+ *	Read in and return the 4 data bytes from the MaxDetect sensor.
+ *	Return TRUE/FALSE depending on the checksum validity
+ *********************************************************************************
+ */
+
+int maxDetectRead (const int pin, unsigned char buffer [4])
+{
+  int i ;
+  unsigned int checksum ;
+  unsigned char localBuf [5] ;
+  struct timeval now, then, took ;
+
+// See how long we took
+
+  gettimeofday (&then, NULL) ;
+
+// Wake up the RHT03 by pulling the data line low, then high
+//	Low for 10mS, high for 40uS.
+
+  pinMode      (pin, OUTPUT) ;
+  digitalWrite (pin, 0) ; delay             (10) ;
+  digitalWrite (pin, 1) ; delayMicroseconds (40) ;
+  pinMode      (pin, INPUT) ;
+
+// Now wait for sensor to pull pin low
+
+  if (!maxDetectLowHighWait (pin))
+    return FALSE ;
+
+// and read in 5 bytes (40 bits)
+
+  for (i = 0 ; i < 5 ; ++i)
+    localBuf [i] = maxDetectClockByte (pin) ;
+
+  checksum = 0 ;
+  for (i = 0 ; i < 4 ; ++i)
+  {
+    buffer [i] = localBuf [i] ;
+    checksum += localBuf [i] ;
+  }
+  checksum &= 0xFF ;
+
+// See how long we took
+  
+  gettimeofday (&now, NULL) ;
+  timersub (&now, &then, &took) ;
+
+// Total time to do this should be:
+//	10mS + 40µS - reset
+//	+ 80µS + 80µS - sensor doing its low -> high thing
+//	+ 40 * (50µS + 27µS (0) or 70µS (1) )
+//	= 15010µS
+// so if we take more than that, we've had a scheduling interruption and the
+// reading is probably bogus.
+
+  if ((took.tv_sec != 0) || (took.tv_usec > 16000))
+    return FALSE ;
+
+  return checksum == localBuf [4] ;
+}
+
+
+/*
+ * readRHT03:
+ *	Read the Temperature & Humidity from an RHT03 sensor
+ *	Values returned are *10, so 123 is 12.3.
+ *********************************************************************************
+ */
+
+int readRHT03 (const int pin, int *temp, int *rh)
+{
+  static struct timeval then ;	// will initialise to zero
+  static        int     lastTemp = 0 ;
+  static        int     lastRh   = 0 ;
+
+  int result ;
+  struct timeval now, timeOut ;
+  unsigned char buffer [4] ;
+
+// The data sheets say to not read more than once every 2 seconds, so you
+//	get the last good reading
+
+  gettimeofday (&now, NULL) ;
+  if (timercmp (&now, &then, <))
+  {
+    *rh   = lastRh ;
+    *temp = lastTemp ;
+    return TRUE ;
+  }
+
+// Set timeout for next read
+
+  gettimeofday (&now, NULL) ;
+  timerclear   (&timeOut) ;
+  timeOut.tv_sec = 2 ;
+  timeradd (&now, &timeOut, &then) ;
+
+// Read ...
+  
+  result = maxDetectRead (pin, buffer) ;
+
+  if (!result) // Try again, but just once
+    result = maxDetectRead (pin, buffer) ;
+
+  if (!result)
+    return FALSE ;
+
+  *rh   = (buffer [0] * 256 + buffer [1]) ;
+  *temp = (buffer [2] * 256 + buffer [3]) ;
+
+  if ((*temp & 0x8000) != 0)	// Negative
+  {
+    *temp &= 0x7FFF ;
+    *temp = -*temp ;
+  }
+
+// Discard obviously bogus readings - the checksum can't detect a 2-bit error
+//	(which does seem to happen - no realtime here)
+
+  if ((*rh > 999) || (*temp > 800) || (*temp < -400))
+    return FALSE ;
+
+  lastRh   = *rh ;
+  lastTemp = *temp ;
+
+  return TRUE ;
+}
diff --git a/devLib/maxdetect.h b/devLib/maxdetect.h
new file mode 100644
index 0000000..a1fd742
--- /dev/null
+++ b/devLib/maxdetect.h
@@ -0,0 +1,40 @@
+/*
+ * maxdetect.h:
+ *	Driver for the MaxDetect series sensors
+ *
+ * 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
+
+// Main generic function
+
+int maxDetectRead (const int pin, unsigned char buffer [4]) ;
+
+// Individual sensors
+
+int readRHT03 (const int pin, int *temp, int *rh) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/piFace.c b/devLib/piFace.c
new file mode 100644
index 0000000..4475c7f
--- /dev/null
+++ b/devLib/piFace.c
@@ -0,0 +1,112 @@
+/*
+ * piFace.:
+ *	This file to interface with the PiFace peripheral device which
+ *	has an MCP23S17 GPIO device connected via the SPI bus.
+ *
+ *	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 <stdint.h>
+
+#include <wiringPi.h>
+#include <mcp23s17.h>
+
+#include "piFace.h"
+
+
+/*
+ * myDigitalWrite:
+ *	Perform the digitalWrite function on the PiFace board
+ *********************************************************************************
+ */
+
+void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  digitalWrite (pin + 16, value) ;
+}
+
+
+/*
+ * myDigitalRead:
+ *	Perform the digitalRead function on the PiFace board
+ *	With a slight twist - if we read from base + 8, then we
+ *	read from the output latch...
+ *********************************************************************************
+ */
+
+int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  if ((pin - node->pinBase) >= 8)
+    return digitalRead (pin + 8) ;
+  else
+    return digitalRead (pin + 16 + 8) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *	Perform the pullUpDnControl function on the PiFace board
+ *********************************************************************************
+ */
+
+void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud)
+{
+  pullUpDnControl (pin + 16 + 8, pud) ;
+}
+
+
+/*
+ * piFaceSetup
+ *	We're going to create an instance of the mcp23s17 here, then
+ *	provide our own read/write routines on-top of it...
+ *	The supplied PiFace code (in Pithon) treats it as an 8-bit device
+ *	where you write the output ports and read the input port using the
+ *	same pin numbers, however I have had a request to be able to read
+ *	the output port, so reading 8..15 will read the output latch.
+ *********************************************************************************
+ */
+
+int piFaceSetup (const int pinBase)
+{
+  int    i ;
+  struct wiringPiNodeStruct *node ;
+
+// Create an mcp23s17 instance:
+
+   mcp23s17Setup (pinBase + 16, 0, 0) ;
+
+// Set the direction bits
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    pinMode (pinBase + 16 +     i, OUTPUT) ;	// Port A is the outputs
+    pinMode (pinBase + 16 + 8 + i, INPUT) ;	// Port B inputs.
+  }
+
+  node = wiringPiNewNode (pinBase, 16) ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->pullUpDnControl = myPullUpDnControl ;
+
+  return 0 ;
+}
diff --git a/devLib/piFace.h b/devLib/piFace.h
new file mode 100644
index 0000000..4965314
--- /dev/null
+++ b/devLib/piFace.h
@@ -0,0 +1,32 @@
+/*
+ * piFace.h:
+ *	Control the PiFace Interface board 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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int  piFaceSetup (const int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c
new file mode 100644
index 0000000..cadbfe8
--- /dev/null
+++ b/devLib/piFaceOld.c
@@ -0,0 +1,177 @@
+/*
+ * piFace.:
+ *	Copyright (c) 2012-2016 Gordon Henderson
+ *
+ *	This file to interface with the PiFace peripheral device which
+ *	has an MCP23S17 GPIO device connected via the SPI bus.
+ ***********************************************************************
+ * 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 <stdint.h>
+
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "../wiringPi/mcp23x0817.h"
+
+#include "piFace.h"
+
+#define	PIFACE_SPEED	4000000
+#define	PIFACE_DEVNO	0
+
+
+
+/*
+ * writeByte:
+ *	Write a byte to a register on the MCP23S17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static void writeByte (uint8_t reg, uint8_t data)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_WRITE ;
+  spiData [1] = reg ;
+  spiData [2] = data ;
+
+  wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ;
+}
+
+/*
+ * readByte:
+ *	Read a byte from a register on the MCP23S17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static uint8_t readByte (uint8_t reg)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_READ ;
+  spiData [1] = reg ;
+
+  wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ;
+
+  return spiData [2] ;
+}
+
+
+/*
+ * myDigitalWrite:
+ *	Perform the digitalWrite function on the PiFace board
+ *********************************************************************************
+ */
+
+void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  uint8_t mask, old ;
+
+  pin -= node->pinBase ;
+  mask = 1 << pin ;
+  old  = readByte (MCP23x17_GPIOA) ;
+
+  if (value == 0)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  writeByte (MCP23x17_GPIOA, old) ;
+}
+
+
+/*
+ * myDigitalRead:
+ *	Perform the digitalRead function on the PiFace board
+ *********************************************************************************
+ */
+
+int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  uint8_t mask, reg ;
+
+  mask = 1 << ((pin - node->pinBase) & 7) ;
+
+  if (pin < 8)
+    reg = MCP23x17_GPIOB ;	// Input regsiter
+  else
+    reg = MCP23x17_OLATA ;	// Output latch regsiter
+
+  if ((readByte (reg) & mask) != 0)
+    return HIGH ;
+  else
+    return LOW ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *	Perform the pullUpDnControl function on the PiFace board
+ *********************************************************************************
+ */
+
+void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud)
+{
+  uint8_t mask, old ;
+
+  mask = 1 << (pin - node->pinBase) ;
+  old  = readByte (MCP23x17_GPPUB) ;
+
+  if (pud == 0)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  writeByte (MCP23x17_GPPUB, old) ;
+}
+
+
+/*
+ * piFaceSetup
+ *	Setup the SPI interface and initialise the MCP23S17 chip
+ *	We create one node with 16 pins - each if the first 8 pins being read
+ *	and write - although the operations actually go to different
+ *	hardware ports. The top 8 let you read the state of the output register.
+ *********************************************************************************
+ */
+
+int piFaceSetup (const int pinBase)
+{
+  int    x ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0)
+    return x ;
+
+// Setup the MCP23S17
+
+  writeByte (MCP23x17_IOCON,  IOCON_INIT) ;
+  writeByte (MCP23x17_IODIRA, 0x00) ;		// Port A -> Outputs
+  writeByte (MCP23x17_IODIRB, 0xFF) ;		// Port B -> Inputs
+
+  node = wiringPiNewNode (pinBase, 16) ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->pullUpDnControl = myPullUpDnControl ;
+
+  return 0 ;
+}
diff --git a/devLib/piGlow.c b/devLib/piGlow.c
new file mode 100644
index 0000000..44e3db8
--- /dev/null
+++ b/devLib/piGlow.c
@@ -0,0 +1,118 @@
+/*
+ * piGlow.c:
+ *	Easy access to the Pimoroni PiGlow board.
+ *
+ * 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 <wiringPi.h>
+#include <sn3218.h>
+
+#include "piGlow.h"
+
+#define	PIGLOW_BASE	577
+
+static int leg0 [6] = {  6,  7,  8,  5,  4,  9 } ;
+static int leg1 [6] = { 17, 16, 15, 13, 11, 10 } ;
+static int leg2 [6] = {  0,  1,  2,  3, 14, 12 } ;
+
+
+/*
+ * piGlow1:
+ *	Light up an individual LED
+ *********************************************************************************
+ */
+
+void piGlow1 (const int leg, const int ring, const int intensity)
+{
+  int *legLeds ;
+
+  if ((leg  < 0) || (leg  > 2)) return ;
+  if ((ring < 0) || (ring > 5)) return ;
+
+  /**/ if (leg == 0)
+    legLeds = leg0 ;
+  else if (leg == 1)
+    legLeds = leg1 ;
+  else
+    legLeds = leg2 ;
+
+  analogWrite (PIGLOW_BASE + legLeds [ring], intensity) ;
+}
+
+/*
+ * piGlowLeg:
+ *	Light up all 6 LEDs on a leg
+ *********************************************************************************
+ */
+
+void piGlowLeg (const int leg, const int intensity)
+{
+  int  i ;
+  int *legLeds ;
+
+  if ((leg < 0) || (leg > 2))
+    return ;
+
+  /**/ if (leg == 0)
+    legLeds = leg0 ;
+  else if (leg == 1)
+    legLeds = leg1 ;
+  else
+    legLeds = leg2 ;
+
+  for (i = 0 ; i < 6 ; ++i)
+    analogWrite (PIGLOW_BASE + legLeds [i], intensity) ;
+}
+
+
+/*
+ * piGlowRing:
+ *	Light up 3 LEDs in a ring. Ring 0 is the outermost, 5 the innermost
+ *********************************************************************************
+ */
+
+void piGlowRing (const int ring, const int intensity)
+{
+  if ((ring < 0) || (ring > 5))
+    return ;
+
+  analogWrite (PIGLOW_BASE + leg0 [ring], intensity) ;
+  analogWrite (PIGLOW_BASE + leg1 [ring], intensity) ;
+  analogWrite (PIGLOW_BASE + leg2 [ring], intensity) ;
+}
+
+/*
+ * piGlowSetup:
+ *	Initialise the board & remember the pins we're using
+ *********************************************************************************
+ */
+
+void piGlowSetup (int clear)
+{
+  sn3218Setup (PIGLOW_BASE) ;
+
+  if (clear)
+  {
+    piGlowLeg (0, 0) ;
+    piGlowLeg (1, 0) ;
+    piGlowLeg (2, 0) ;
+  }
+}
diff --git a/devLib/piGlow.h b/devLib/piGlow.h
new file mode 100644
index 0000000..a4d89d0
--- /dev/null
+++ b/devLib/piGlow.h
@@ -0,0 +1,45 @@
+/*
+ * piglow.h:
+ *	Easy access to the Pimoroni PiGlow board.
+ *
+ * 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/>.
+ ***********************************************************************
+ */
+
+
+#define	PIGLOW_RED	0
+#define	PIGLOW_ORANGE	1
+#define	PIGLOW_YELLOW	2
+#define	PIGLOW_GREEN	3
+#define	PIGLOW_BLUE	4
+#define	PIGLOW_WHITE	5
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void piGlow1     (const int leg,  const int ring, const int intensity) ;
+extern void piGlowLeg   (const int leg,  const int intensity) ;
+extern void piGlowRing  (const int ring, const int intensity) ;
+extern void piGlowSetup (int clear) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/piNes.c b/devLib/piNes.c
new file mode 100644
index 0000000..a115050
--- /dev/null
+++ b/devLib/piNes.c
@@ -0,0 +1,113 @@
+/*
+ * piNes.c:
+ *	Driver for the NES Joystick controller on the Raspberry Pi
+ *	Copyright (c) 2012 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 <wiringPi.h>
+
+#include "piNes.h"
+
+#define	MAX_NES_JOYSTICKS	8
+
+#define	NES_RIGHT	0x01
+#define	NES_LEFT	0x02
+#define	NES_DOWN	0x04
+#define	NES_UP		0x08
+#define	NES_START	0x10
+#define	NES_SELECT	0x20
+#define	NES_B		0x40
+#define	NES_A		0x80
+
+
+#define	PULSE_TIME	25
+
+// Data to store the pins for each controller
+
+struct nesPinsStruct
+{
+  unsigned int cPin, dPin, lPin ;
+} ;
+
+static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ;
+
+static int joysticks = 0 ;
+
+
+/*
+ * setupNesJoystick:
+ *	Create a new NES joystick interface, program the pins, etc.
+ *********************************************************************************
+ */
+
+int setupNesJoystick (int dPin, int cPin, int lPin)
+{
+  if (joysticks == MAX_NES_JOYSTICKS)
+    return -1 ;
+
+  nesPins [joysticks].dPin = dPin ;
+  nesPins [joysticks].cPin = cPin ;
+  nesPins [joysticks].lPin = lPin ;
+
+  digitalWrite (lPin, LOW) ;
+  digitalWrite (cPin, LOW) ;
+
+  pinMode (lPin, OUTPUT) ;
+  pinMode (cPin, OUTPUT) ;
+  pinMode (dPin, INPUT) ;
+
+  return joysticks++ ;
+}
+
+
+/*
+ * readNesJoystick:
+ *	Do a single scan of the NES Joystick.
+ *********************************************************************************
+ */
+
+unsigned int readNesJoystick (int joystick)
+{
+  unsigned int value = 0 ;
+  int  i ;
+
+  struct nesPinsStruct *pins = &nesPins [joystick] ;
+ 
+// Toggle Latch - which presents the first bit
+
+  digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
+  digitalWrite (pins->lPin, LOW)  ; delayMicroseconds (PULSE_TIME) ;
+
+// Read first bit
+
+  value = digitalRead (pins->dPin) ;
+
+// Now get the next 7 bits with the clock
+
+  for (i = 0 ; i < 7 ; ++i)
+  {
+    digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
+    digitalWrite (pins->cPin, LOW)  ; delayMicroseconds (PULSE_TIME) ;
+    value = (value << 1) | digitalRead (pins->dPin) ;
+  }
+
+  return value ^ 0xFF ;
+}
diff --git a/devLib/piNes.h b/devLib/piNes.h
new file mode 100644
index 0000000..897f181
--- /dev/null
+++ b/devLib/piNes.h
@@ -0,0 +1,45 @@
+/*
+ * piNes.h:
+ *	Driver for the NES Joystick controller on the Raspberry Pi
+ *	Copyright (c) 2012 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/>.
+ ***********************************************************************
+ */
+
+#define	MAX_NES_JOYSTICKS	8
+
+#define	NES_RIGHT	0x01
+#define	NES_LEFT	0x02
+#define	NES_DOWN	0x04
+#define	NES_UP		0x08
+#define	NES_START	0x10
+#define	NES_SELECT	0x20
+#define	NES_B		0x40
+#define	NES_A		0x80
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int          setupNesJoystick (int dPin, int cPin, int lPin) ;
+extern unsigned int  readNesJoystick (int joystick) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/scrollPhat.c b/devLib/scrollPhat.c
new file mode 100644
index 0000000..c1a6f11
--- /dev/null
+++ b/devLib/scrollPhat.c
@@ -0,0 +1,430 @@
+/*
+ * scrollPhat.c:
+ *	Simple driver for the Pimoroni Scroll Phat device
+ *
+ * Copyright (c) 2015 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 <stdarg.h>
+#include <string.h>
+#include <time.h>
+
+#include <wiringPiI2C.h>
+
+#include "scrollPhatFont.h"
+#include "scrollPhat.h"
+
+// Size
+
+#define	SP_WIDTH	11
+#define	SP_HEIGHT	 5
+
+// I2C
+
+#define	PHAT_I2C_ADDR	0x60
+
+// Software copy of the framebuffer
+//	it's 8-bit deep although the display itself is only 1-bit deep.
+
+static unsigned char frameBuffer [SP_WIDTH * SP_HEIGHT] ;
+
+static int lastX,   lastY ;
+static int printDelayFactor  ;
+static int scrollPhatFd ;
+
+static int putcharX ;
+
+#undef	DEBUG
+
+
+/*
+ * delay:
+ *	Wait for some number of milliseconds.
+ *	This taken from wiringPi as there is no-need to include the whole of
+ *	wiringPi just for the delay function.
+ *********************************************************************************
+ */
+
+static void delay (unsigned int howLong)
+{
+  struct timespec sleeper, dummy ;
+
+  sleeper.tv_sec  = (time_t)(howLong / 1000) ;
+  sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
+
+  nanosleep (&sleeper, &dummy) ;
+}
+
+
+
+/*
+ * scrollPhatUpdate:
+ *	Copy our software version to the real display
+ *********************************************************************************
+ */
+
+void scrollPhatUpdate (void)
+{
+  register int x, y ;
+  register unsigned char data, pixel ;
+  unsigned char pixels [SP_WIDTH] ;
+
+#ifdef	DEBUG
+  printf ("+-----------+\n") ;
+  for (y = 0 ; y < SP_HEIGHT ; ++y)
+  {
+    putchar ('|') ;
+    for (x = 0 ; x < SP_WIDTH ; ++x)
+    {
+      pixel = frameBuffer [x + y * SP_WIDTH] ;
+      putchar (pixel == 0 ? ' ' : '*') ;
+    }
+    printf ("|\n") ;
+  }
+  printf ("+-----------+\n") ;
+#endif 
+
+  for (x = 0 ; x < SP_WIDTH ; ++x)
+  {
+    data = 0 ;
+    for (y = 0 ; y < SP_HEIGHT ; ++y)
+    {
+      pixel = frameBuffer [x + y * SP_WIDTH] ;
+      data = (data << 1) | ((pixel == 0) ? 0 : 1) ;
+    }
+    pixels [x] = data ;
+  }
+
+  for (x = 0 ; x < SP_WIDTH ; ++x)
+    wiringPiI2CWriteReg8 (scrollPhatFd, 1 + x, pixels [x]) ;
+
+  wiringPiI2CWriteReg8 (scrollPhatFd, 0x0C, 0) ;
+}
+
+
+/*
+ *********************************************************************************
+ * Standard Graphical Functions
+ *********************************************************************************
+ */
+
+
+/*
+ * scrollPhatPoint:
+ *	Plot a pixel. Crude clipping - speed is not the essence here.
+ *********************************************************************************
+ */
+
+void scrollPhatPoint (int x, int y, int colour)
+{
+  lastX = x ;
+  lastY = y ;
+
+  if ((x < 0) || (x >= SP_WIDTH) || (y < 0) || (y >= SP_HEIGHT))
+    return ;
+
+  frameBuffer [x + y * SP_WIDTH] = colour ;
+}
+
+
+/*
+ * scrollPhatLine: scrollPhatLineTo:
+ *	Classic Bressenham Line code - rely on the point function to do the
+ *	clipping for us here.
+ *********************************************************************************
+ */
+
+void scrollPhatLine (int x0, int y0, int x1, int y1, int colour)
+{
+  int dx, dy ;
+  int sx, sy ;
+  int err, e2 ;
+
+  lastX = x1 ;
+  lastY = y1 ;
+
+  dx = abs (x1 - x0) ;
+  dy = abs (y1 - y0) ;
+
+  sx = (x0 < x1) ? 1 : -1 ;
+  sy = (y0 < y1) ? 1 : -1 ;
+
+  err = dx - dy ;
+ 
+  for (;;)
+  {
+    scrollPhatPoint (x0, y0, colour) ;
+
+    if ((x0 == x1) && (y0 == y1))
+      break ;
+
+    e2 = 2 * err ;
+
+    if (e2 > -dy)
+    {
+      err -= dy ;
+      x0  += sx ;
+    }
+
+    if (e2 < dx)
+    {
+      err += dx ;
+      y0  += sy ;
+    }
+  }
+
+}
+
+void scrollPhatLineTo (int x, int y, int colour)
+{
+  scrollPhatLine (lastX, lastY, x, y, colour) ;
+}
+
+
+/*
+ * scrollPhatRectangle:
+ *	A rectangle is a spoilt days fishing
+ *********************************************************************************
+ */
+
+void scrollPhatRectangle (int x1, int y1, int x2, int y2, int colour, int filled)
+{
+  register int x ;
+
+  if (filled)
+  {
+    /**/ if (x1 == x2)
+      scrollPhatLine (x1, y1, x2, y2, colour) ;
+    else if (x1 < x2)
+      for (x = x1 ; x <= x2 ; ++x)
+	scrollPhatLine (x, y1, x, y2, colour) ;
+    else
+      for (x = x2 ; x <= x1 ; ++x)
+	scrollPhatLine (x, y1, x, y2, colour) ;
+  }
+  else
+  {
+    scrollPhatLine   (x1, y1, x2, y1, colour) ;
+    scrollPhatLineTo (x2, y2, colour) ;
+    scrollPhatLineTo (x1, y2, colour) ;
+    scrollPhatLineTo (x1, y1, colour) ;
+  }
+}
+
+
+/*
+ * scrollPhatPutchar:
+ *      Print a single character to the screen then advance the pointer by an
+ *	appropriate ammount (variable width font).
+ *      We rely on the clipping done by the pixel plot function to keep us
+ *      out of trouble.
+ *	Return the width + space
+ *********************************************************************************
+ */
+
+int scrollPhatPutchar (int c)
+{
+  register int x, y ;
+
+  unsigned char line ;
+  unsigned char *fontPtr ;
+  unsigned char *p2 ;
+  int lineWidth, width, mask ;
+
+// The font is printable characters, uppercase only...
+//	and somewhat varaible width...
+
+  c &= 0x7F ;
+  if (c > 0x60)
+    c -= 64 ;
+  else
+    c -= 32 ;
+
+  fontPtr = scrollPhatFont + c * fontHeight ;
+
+// Work out width of this character
+//	There probably is a more efficient way to do this, but...
+
+  p2    = fontPtr ;
+  width = 0 ;
+  for (y = 0 ; y < fontHeight ; ++y)
+  {
+    mask = 0x80 ;
+    for (lineWidth = 8 ; lineWidth > 0 ; --lineWidth)
+    {
+      if ((*p2 & mask) != 0)
+	break ;
+      mask >>= 1 ;
+    }
+    if (lineWidth > width)
+      width = lineWidth ;
+
+    ++p2 ;
+  }
+
+  if (width == 0)	// Likely to be a blank or space character
+    width = 3 ;
+
+  for (y = fontHeight - 1 ; y >= 0 ; --y)
+  {
+    x    = 0 ;
+    line = *fontPtr++ ;
+    for (mask = 1 << (width - 1) ; mask != 0 ; mask >>= 1)
+    {
+      scrollPhatPoint (putcharX + x, y, (line & mask)) ;
+      ++x ;
+    }
+  }
+
+// make a line of space
+
+  for (y = fontHeight - 1 ; y >= 0 ; --y)
+    scrollPhatPoint (putcharX + width, y, 0) ;
+
+  putcharX = putcharX + width + 1 ;
+
+  return width + 1 ;
+}
+
+
+/*
+ * scrollPhatPuts:
+ *	Send a string to the display - and scroll it across.
+ *	This is somewhat of a hack in that we print the entire string to the
+ *	display and let the point clipping take care of what's off-screen...
+ *********************************************************************************
+ */
+
+void scrollPhatPuts (const char *str)
+{
+  int i ;
+  int movingX = 0 ;
+  const char *s ;
+  int pixelLen ;
+
+// Print it once, then we know the width in pixels...
+
+  putcharX = 0 ;
+  s = str ;
+  while (*s)
+    scrollPhatPutchar (*s++) ;
+
+  pixelLen = putcharX ;
+
+// Now scroll it by printing it and moving left one pixel
+
+  movingX = 0 ;
+  for (i = 0 ; i < pixelLen ; ++i)
+  {
+    putcharX = movingX ;
+    s = str ;
+    while (*s)
+      scrollPhatPutchar (*s++) ;
+    --movingX ;
+    scrollPhatUpdate () ;
+    delay (printDelayFactor) ;
+  }
+}
+
+
+/*
+ * scrollPhatPrintf:
+ *	Does what it says
+ *********************************************************************************
+ */
+
+void scrollPhatPrintf (const char *message, ...)
+{
+  va_list argp ;
+  char buffer [1024] ;
+
+  va_start (argp, message) ;
+    vsnprintf (buffer, 1023, message, argp) ;
+  va_end (argp) ;
+
+  scrollPhatPuts (buffer) ;
+}
+
+
+/*
+ * scrollPhatPrintSpeed:
+ *	Change the print speed - mS per shift by 1 pixel
+ *********************************************************************************
+ */
+
+void scrollPhatPrintSpeed (const int pps)
+{
+  if (pps < 0)
+    printDelayFactor = 0 ;
+  else
+    printDelayFactor = pps ;
+}
+
+
+/*
+ * scrollPhatClear:
+ *	Clear the display
+ *********************************************************************************
+ */
+
+void scrollPhatClear (void)
+{
+  register int i ;
+  register unsigned char *ptr = frameBuffer ;
+
+  for (i = 0 ; i < (SP_WIDTH * SP_HEIGHT) ; ++i)
+    *ptr++ = 0 ;
+
+  scrollPhatUpdate () ;
+}
+
+
+/*
+ * scrollPhatIntensity:
+ *	Set the display brightness - percentage
+ *********************************************************************************
+ */
+
+void scrollPhatIntensity (const int percent)
+{
+  wiringPiI2CWriteReg8 (scrollPhatFd, 0x19, (127 * percent) / 100) ;
+}
+
+
+/*
+ * scrollPhatSetup:
+ *	Initialise the Scroll Phat display
+ *********************************************************************************
+ */
+
+int scrollPhatSetup (void)
+{
+  if ((scrollPhatFd = wiringPiI2CSetup (PHAT_I2C_ADDR)) < 0)
+    return scrollPhatFd ;
+
+  wiringPiI2CWriteReg8 (scrollPhatFd, 0x00, 0x03) ;	// Enable display, set to 5x11 mode
+  scrollPhatIntensity (10) ;
+  scrollPhatClear () ;
+  scrollPhatPrintSpeed (100) ;
+
+  return 0 ;
+}
diff --git a/devLib/scrollPhat.h b/devLib/scrollPhat.h
new file mode 100644
index 0000000..0e762b1
--- /dev/null
+++ b/devLib/scrollPhat.h
@@ -0,0 +1,39 @@
+/*
+ * scrollPhat.h:
+ *	Simple driver for the Pimoroni Scroll Phat device
+ *
+ * Copyright (c) 2015 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/>.
+ ***********************************************************************
+ */
+
+extern void scrollPhatPoint      (int x, int y, int colour) ;
+extern void scrollPhatLine       (int x0, int y0, int x1, int y1, int colour) ;
+extern void scrollPhatLineTo     (int x, int y, int colour) ;
+extern void scrollPhatRectangle  (int x1, int y1, int x2, int y2, int colour, int filled) ;
+extern void scrollPhatUpdate     (void) ;
+extern void scrollPhatClear      (void) ;
+
+extern int  scrollPhatPutchar    (int c) ;
+//extern void scrollPhatPutchar    (int c) ;
+extern void scrollPhatPuts       (const char *str) ;
+extern void scrollPhatPrintf     (const char *message, ...) ;
+extern void scrollPhatPrintSpeed (const int cps10) ;
+
+extern void scrollPhatIntensity  (const int percent) ;
+extern int  scrollPhatSetup      (void) ;
diff --git a/devLib/scrollPhatFont.h b/devLib/scrollPhatFont.h
new file mode 100644
index 0000000..92f623a
--- /dev/null
+++ b/devLib/scrollPhatFont.h
@@ -0,0 +1,544 @@
+/*
+ * scrollPhatFont.h:
+ *	Simple font for the Pimoroni Scroll Phat.
+ *	Note: this is a very much reduced font - 5 pixels high and
+ *	mostly 4 pixels wide - sometimes 5. Also only
+ *	printable characters from space to _ uppercase only.
+ *
+ * Copyright (c) 2015-2016 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/>.
+ ***********************************************************************
+ */
+
+static const int fontHeight = 5 ;
+
+static unsigned char scrollPhatFont [] =
+{
+
+// 0x20, Space. Handeled as a special case in the code.
+
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+
+// 0x21, !
+
+   0x1, // *
+   0x1, // *
+   0x1, // *
+   0x0, // .
+   0x1, // *
+
+// 0x22, "
+
+   0x5, // *..*
+   0x5, // *..*
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+
+// 0x23, #
+
+   0x9, // *..*
+   0xF, // ****
+   0x9, // *..*
+   0xF, // ****
+   0x9, // *..*
+
+// 0x24, $
+
+   0x1, // ..*.
+   0x7, // .***
+   0x2, // ..*.
+   0xE, // ***.
+   0x8, // ..*.
+
+// 0x25, %
+
+   0x9, // *..*
+   0x1, // ...*
+   0x6, // .**.
+   0x8, // *...
+   0x9, // *..*
+
+// 0x26, &
+
+   0x6, // .**.
+   0x8, // *...
+   0x4, // .*..
+   0xA, // *.*.
+   0x5, // .*.*
+
+// 0x27, '
+
+   0x1, // .*
+   0x2, // *.
+   0x0, // ..
+   0x0, // ..
+   0x0, // ..
+
+// 0x28, (
+
+   0x3, // ..**
+   0x4, // .*..
+   0x8, // *...
+   0x4, // .*..
+   0x3, // ..**
+
+// 0x29, )
+
+   0xC, // **..
+   0x2, // ..*.
+   0x1, // ...*
+   0x2, // ..*.
+   0xC, // **..
+
+// 0x2A, *
+
+   0x9, // *..*
+   0x6, // .**.
+   0xF, // ****
+   0x6, // .**.
+   0x9, // *..*
+
+// 0x2B, +
+
+   0x6, // .**.
+   0x6, // .**.
+   0xF, // ****
+   0x6, // .**.
+   0x6, // .**.
+
+// 0x2C, ,
+
+   0x0, // ..
+   0x0, // ..
+   0x0, // ..
+   0x1, // .*
+   0x2, // *.
+
+// 0x2D, -
+
+   0x0, // ....
+   0x0, // ....
+   0xF, // ****
+   0x0, // ....
+   0x0, // ....
+
+// 0x2E, .
+
+   0x0, // .
+   0x0, // .
+   0x0, // .
+   0x0, // .
+   0x1, // *
+
+// 0x2F, /
+
+   0x1, // ...*
+   0x3, // ..**
+   0x4, // ..*.
+   0xC, // **..
+   0x8, // *...
+
+// 0x30, 0
+
+   0x6, // .**.
+   0x9, // *..*
+   0x9, // *..*
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x31, 1
+
+   0x2, // ..*.
+   0x6, // .**.
+   0x2, // ..*.
+   0x2, // ..*.
+   0x7, // .***
+
+// 0x32, 2
+
+   0x6, // .**.
+   0x1, // ...*
+   0x6, // .**.
+   0x8, // *...
+   0xF, // ****
+
+// 0x33, 3
+
+   0xE, // ***.
+   0x1, // ...*
+   0xE, // ***.
+   0x1, // ...*
+   0xE, // ***.
+
+// 0x34, 4
+
+   0x6, // .**.
+   0xA, // *.*.
+   0xF, // ****
+   0x2, // ..*.
+   0x2, // ..*.
+
+// 0x35, 5
+
+   0xF, // ****
+   0x8, // *...
+   0xF, // ****
+   0x1, // ...*
+   0xE, // ***.
+
+// 0x36, 6
+
+   0x2, // ..*.
+   0x4, // .*..
+   0xA, // *.*.
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x37, 7
+
+   0xF, // ****
+   0x1, // ...*
+   0x2, // ..*.
+   0x4, // .*..
+   0x8, // *...
+
+// 0x38, 8
+
+   0x6, // .**.
+   0x9, // *..*
+   0x6, // .**.
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x39, 9
+
+   0x6, // .**.
+   0x9, // *..*
+   0x7, // .*.*
+   0x1, // ..*.
+   0x2, // .*..
+
+// 0x3A, :
+
+   0x0, // .
+   0x1, // *
+   0x0, // .
+   0x1, // *
+   0x0, // .
+
+// 0x3B, ;
+
+   0x0, // ..
+   0x1, // .*
+   0x0, // ..
+   0x1, // .*
+   0x2, // *.
+
+// 0x3C, <
+
+   0x2, // ..*.
+   0x4, // .*..
+   0x8, // *...
+   0x4, // .*..
+   0x2, // ..*.
+
+// 0x3D, =
+
+   0x0, // ....
+   0xF, // ****
+   0x0, // ....
+   0xF, // ****
+   0x0, // ....
+
+// 0x3E, >
+
+   0x0, // .*..
+   0x0, // ..*.
+   0x0, // ...*
+   0x0, // ..*.
+   0x0, // .*..
+
+// 0x3F, ?
+
+   0x6, // .**.
+   0x1, // ...*
+   0x2, // ..*.
+   0x0, // ....
+   0x2, // ..*.
+
+// 0x40, @
+
+   0x6, // .**.
+   0xD, // **.*
+   0x8, // *...
+   0x4, // .*..
+   0x3, // ..**
+
+// 0x41, A
+
+   0x6, // .**.
+   0x9, // *..*
+   0xF, // ****
+   0x9, // *..*
+   0x9, // *..*
+
+// 0x42, B
+
+   0xE, // ***.
+   0x9, // *..*
+   0xE, // ***.
+   0x9, // *..*
+   0xE, // ***.
+
+// 0x43, C
+
+   0x6, // .**.
+   0x9, // *..*
+   0x8, // *...
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x44, D
+
+   0xE, // ***.
+   0x9, // *..*
+   0x9, // *..*
+   0x9, // *..*
+   0xE, // ***.
+
+// 0x45, E
+
+   0xF, // ****
+   0x8, // *...
+   0xE, // ***.
+   0x8, // *...
+   0xF, // ****
+
+// 0x46, F
+
+   0xF, // ****
+   0x8, // *...
+   0xE, // ***.
+   0x8, // *...
+   0x8, // *...
+
+// 0x47, G
+
+   0x6, // .**.
+   0x9, // *..*
+   0x8, // *...
+   0xB, // *.**
+   0x6, // .**.
+
+// 0x48, H
+
+   0x9, // *..*
+   0x9, // *..*
+   0xF, // ****
+   0x9, // *..*
+   0x9, // *..*
+
+// 0x49, I
+
+   0x7, // ***
+   0x2, // .*.
+   0x2, // .*.
+   0x2, // .*.
+   0x7, // ***
+
+// 0x4A, J
+
+   0x7, // .***
+   0x2, // ..*.
+   0x2, // ..*.
+   0xA, // *.*.
+   0x4, // .*..
+
+// 0x4B, K
+
+   0x9, // *..*
+   0xA, // *.*.
+   0xC, // **..
+   0xA, // *.*.
+   0x9, // *..*
+
+// 0x4C, L
+
+   0x4, // *..
+   0x4, // *..
+   0x4, // *..
+   0x4, // *..
+   0x7, // ***
+
+// 0x4D, M
+
+   0x11, // *...*
+   0x1B, // **.**
+   0x15, // *.*.*
+   0x11, // *...*
+   0x11, // *...*
+
+// 0x4E, N
+
+   0x9, // *..*
+   0xD, // **.*
+   0xB, // *.**
+   0x9, // *..*
+   0x9, // *..*
+
+// 0x4F, O
+
+   0x6, // .**.
+   0x9, // *..*
+   0x9, // *..*
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x50, P
+
+   0xE, // ***.
+   0x9, // *..*
+   0xE, // ***.
+   0x8, // *...
+   0x8, // *...
+
+// 0x51, Q
+
+   0x6, // .**.
+   0x9, // *..*
+   0x9, // *..*
+   0xA, // *.*.
+   0x5, // .*.*
+
+// 0x52, R
+
+   0xE, // ***.
+   0x9, // *..*
+   0xF, // ***.
+   0xA, // *.*.
+   0x9, // *..*
+
+// 0x53, S
+
+   0x6, // .**.
+   0x8, // *...
+   0x6, // .**.
+   0x1, // ...*
+   0x6, // .**.
+
+// 0x54, T
+
+   0x7, // .***
+   0x2, // ..*.
+   0x2, // ..*.
+   0x2, // ..*.
+   0x2, // ..*.
+
+// 0x55, U
+
+   0x9, // *..*
+   0x9, // *..*
+   0x9, // *..*
+   0x9, // *..*
+   0x6, // .**.
+
+// 0x56, V
+
+   0x11, // *...*
+   0x11, // *...*
+   0x11, // *...*
+   0x0A, // .*.*.
+   0x04, // ..*..
+
+// 0x57, W
+
+   0x11, // *...*
+   0x11, // *...*
+   0x11, // *...*
+   0x15, // *.*.*
+   0x1B, // **.**
+
+// 0x58, X
+
+   0x9, // *..*
+   0x9, // *..*
+   0x6, // .**.
+   0x9, // *..*
+   0x9, // *..*
+
+// 0x59, Y
+
+   0x11, // *...*
+   0x0A, // .*.*.
+   0x04, // ..*..
+   0x04, // ..*..
+   0x04, // ..*..
+
+// 0x5A, Z
+
+   0xF, // ****
+   0x1, // ...*
+   0x6, // .**.
+   0x8, // *...
+   0xF, // ****
+
+// 0x5B, [
+
+   0xE, // ***.
+   0x8, // *...
+   0x8, // *...
+   0x8, // *...
+   0xE, // ***.
+
+// 0x5C, Backslash
+
+   0x8, // *...
+   0xC, // **..
+   0x6, // .**.
+   0x3, // ..**
+   0x1, // ...*
+
+// 0x5D, ]
+
+   0x7, // .***
+   0x1, // ...*
+   0x1, // ...*
+   0x1, // ...*
+   0x7, // .***
+
+// 0x5E, ^
+
+   0x6, // .**.
+   0x9, // *..*
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+
+// 0x5F, _
+
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+   0x0, // ....
+   0xF, // ****
+} ;
diff --git a/examples/Gertboard/7segments.c b/examples/Gertboard/7segments.c
new file mode 100644
index 0000000..8797e49
--- /dev/null
+++ b/examples/Gertboard/7segments.c
@@ -0,0 +1,221 @@
+/*
+ * 7segments.c:
+ *	Simple test program to see if we can drive a 7-segment LED
+ *	display using the GPIO and little else on the Raspberry Pi
+ *
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#undef	PHOTO_HACK
+
+#include <wiringPi.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+#include <string.h>
+
+/*
+ *  Segment mapping
+ *
+ *	 --a--
+ *	|     |
+ *	f     b
+ *	|     |
+ *	 --g--
+ *	|     |
+ *	e     c
+ *	|     |
+ *	 --d--  p
+ */
+
+// GPIO Pin Mapping
+
+static int digits   [6] = {  7, 11, 10, 13, 12, 14    } ;
+static int segments [7] = {  6,  5,  4,  3,  2,  1, 0 } ;
+
+
+static const int segmentDigits [] =
+{
+// a  b  c  d  e  f  g     Segments
+// 6  5  4  3  2  1  0,	// wiringPi pin No.
+
+   1, 1, 1, 1, 1, 1, 0,	// 0
+   0, 1, 1, 0, 0, 0, 0,	// 1
+   1, 1, 0, 1, 1, 0, 1,	// 2
+   1, 1, 1, 1, 0, 0, 1,	// 3
+   0, 1, 1, 0, 0, 1, 1,	// 4
+   1, 0, 1, 1, 0, 1, 1,	// 5
+   1, 0, 1, 1, 1, 1, 1,	// 6
+   1, 1, 1, 0, 0, 0, 0,	// 7
+   1, 1, 1, 1, 1, 1, 1,	// 8
+   1, 1, 1, 1, 0, 1, 1,	// 9
+   1, 1, 1, 0, 1, 1, 1,	// A
+   0, 0, 1, 1, 1, 1, 1,	// b
+   1, 0, 0, 1, 1, 1, 0,	// C
+   0, 1, 1, 1, 1, 0, 1,	// d
+   1, 0, 0, 1, 1, 1, 1,	// E
+   1, 0, 0, 0, 1, 1, 1,	// F
+   0, 0, 0, 0, 0, 0, 0,	// blank
+} ;
+ 
+
+// display:
+//	A global variable which is written to by the main program and
+//	read from by the thread that updates the display. Only the first
+//	6 characters are used.
+
+char display [8] ;
+
+
+/*
+ * displayDigits:
+ *	This is our thread that's run concurrently with the main program.
+ *	Essentially sit in a loop, parsing and displaying the data held in
+ *	the "display" global.
+ *********************************************************************************
+ */
+
+PI_THREAD (displayDigits)
+{
+  int digit, segment ;
+  int index, d, segVal ;
+
+  piHiPri (50) ;
+
+  for (;;)
+  {
+    for (digit = 0 ; digit < 6 ; ++digit)
+    {
+      for (segment = 0 ; segment < 7 ; ++segment)
+      {
+	d = toupper (display [digit]) ;
+	/**/ if ((d >= '0') && (d <= '9'))	// Digit
+	  index = d - '0' ;
+	else if ((d >= 'A') && (d <= 'F'))	// Hex
+	  index = d - 'A' + 10 ;
+	else
+	  index = 16 ;				// Blank
+
+	segVal = segmentDigits [index * 7 + segment] ;
+
+	digitalWrite (segments [segment], segVal) ;
+      }
+      digitalWrite (digits [digit], 1) ;
+      delay (2) ;
+      digitalWrite (digits [digit], 0) ;
+    }
+  }
+}
+
+
+/*
+ * setup:
+ *	Initialise the hardware and start the thread
+ *********************************************************************************
+ */
+
+void setup (void)
+{
+  int i, c ;
+
+  wiringPiSetup () ;
+
+// 7 segments
+
+  for (i = 0 ; i < 7 ; ++i)
+    { digitalWrite (segments [i], 0) ; pinMode (segments [i], OUTPUT) ; }
+
+// 6 digits
+
+  for (i = 0 ; i < 6 ; ++i)
+    { digitalWrite (digits [i], 0) ;   pinMode (digits [i],   OUTPUT) ; }
+
+  strcpy (display, "      ") ;
+  piThreadCreate (displayDigits) ;
+  delay (10) ; // Just to make sure it's started
+
+// Quick countdown LED test sort of thing
+
+  c = 999999 ;
+  for (i = 0 ; i < 10 ; ++i)
+  {
+    sprintf (display, "%06d", c) ;
+    delay (400) ;
+    c -= 111111 ;
+  }
+
+  strcpy (display, "      ") ;
+  delay (400) ;
+
+#ifdef PHOTO_HACK
+  sprintf (display, "%s", "123456") ;
+  for (;;)
+    delay (1000) ;
+#endif
+
+}
+
+
+/*
+ * teenager:
+ *	No explanation needed. (Nor one given!)
+ *********************************************************************************
+ */
+
+void teenager (void)
+{
+  char *message = "      feedbeef      babe      cafe      b00b      " ;
+  int i ;
+
+  for (i = 0 ; i < strlen (message) - 4 ; ++i)
+  {
+    strncpy (display, &message [i], 6) ;
+    delay (200) ;
+  }
+  delay (1000) ;
+  for (i = 0 ; i < 3 ; ++i)
+  {
+    strcpy (display, "    ") ;
+    delay (150) ;
+    strcpy (display, " b00b ") ;
+    delay (250) ;
+  }
+  delay (1000) ;
+  strcpy (display, "      ") ;
+  delay (1000) ;
+}
+
+
+/*
+ *********************************************************************************
+ * main:
+ *	Let the fun begin
+ *********************************************************************************
+ */
+
+int main (void)
+{
+  struct tm *t ;
+  time_t     tim ;
+
+  setup    () ;
+  teenager () ;
+
+  tim = time (NULL) ;
+  for (;;)
+  {
+    while (time (NULL) == tim)
+      delay (5) ;
+
+    tim = time (NULL) ;
+    t   = localtime (&tim) ;
+
+    sprintf (display, "%02d%02d%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
+
+    delay (500) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/Gertboard/Makefile b/examples/Gertboard/Makefile
new file mode 100644
index 0000000..1939ad6
--- /dev/null
+++ b/examples/Gertboard/Makefile
@@ -0,0 +1,78 @@
+#
+# Makefile:
+#	Gertboard - Examples using wiringPi
+#
+#	Copyright (c) 2013 Gordon Henderson
+#################################################################################
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#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
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC	=	gertboard.c				\
+		buttons.c 7segments.c			\
+		voltmeter.c temperature.c vumeter.c	\
+		record.c
+
+OBJ	=	$(SRC:.c=.o)
+
+BINS	=	$(SRC:.c=)
+
+all:	$(BINS)
+
+gertboard:	gertboard.o
+	$Q echo [link]
+	$Q $(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS)
+
+buttons:	buttons.o
+	$Q echo [link]
+	$Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS)
+
+7segments:	7segments.o
+	$Q echo [link]
+	$Q $(CC) -o $@ 7segments.o $(LDFLAGS) $(LDLIBS)
+
+voltmeter:	voltmeter.o
+	$Q echo [link]
+	$Q $(CC) -o $@ voltmeter.o $(LDFLAGS) $(LDLIBS)
+
+temperature:	temperature.o
+	$Q echo [link]
+	$Q $(CC) -o $@ temperature.o $(LDFLAGS) $(LDLIBS)
+
+vumeter:	vumeter.o
+	$Q echo [link]
+	$Q $(CC) -o $@ vumeter.o $(LDFLAGS) $(LDLIBS)
+
+record:	record.o
+	$Q echo [link]
+	$Q $(CC) -o $@ record.o $(LDFLAGS) $(LDLIBS)
+
+.c.o:
+	$Q echo [CC] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	$Q echo [Clean]
+	$Q rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/Gertboard/buttons.c b/examples/Gertboard/buttons.c
new file mode 100644
index 0000000..5f76764
--- /dev/null
+++ b/examples/Gertboard/buttons.c
@@ -0,0 +1,83 @@
+/*
+ * buttons.c:
+ *	Read the Gertboard buttons. Each one will act as an on/off
+ *	tiggle switch for 3 different LEDs
+ *
+ * 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>
+
+// Array to keep track of our LEDs
+
+int leds [] = { 0, 0, 0 } ;
+
+// scanButton:
+//	See if a button is pushed, if so, then flip that LED and
+//	wait for the button to be let-go
+
+void scanButton (int button)
+{
+  if (digitalRead (button) == HIGH)	// Low is pushed
+    return ;
+
+  leds [button] ^= 1 ; // Invert state
+  digitalWrite (4 + button, leds [button]) ;
+
+  while (digitalRead (button) == LOW)	// Wait for release
+    delay (10) ;
+}
+
+int main (void)
+{
+  int i ;
+
+  printf ("Raspberry Pi Gertboard Button Test\n") ;
+
+  wiringPiSetup () ;
+
+// Setup the outputs:
+//	Pins 3, 4, 5, 6 and 7 output:
+//	We're not using 3 or 4, but make sure they're off anyway
+//	(Using same hardware config as blink12.c)
+
+  for (i = 3 ; i < 8 ; ++i)
+  {
+    pinMode      (i, OUTPUT) ;
+    digitalWrite (i, 0) ;
+  }
+
+// Setup the inputs
+
+  for (i = 0 ; i < 3 ; ++i)
+  {
+    pinMode         (i, INPUT) ;
+    pullUpDnControl (i, PUD_UP) ;
+    leds [i] = 0 ;
+  }
+
+  for (;;)
+  {
+    for (i = 0 ; i < 3 ; ++i)
+      scanButton (i) ;
+    delay (1) ;
+  }
+}
diff --git a/examples/Gertboard/gertboard.c b/examples/Gertboard/gertboard.c
new file mode 100644
index 0000000..aefcb12
--- /dev/null
+++ b/examples/Gertboard/gertboard.c
@@ -0,0 +1,96 @@
+/*
+ * gertboard.c:
+ *	Simple test for the SPI bus on the Gertboard
+ *
+ *	Hardware setup:
+ *		D/A port 0 jumpered to A/D port 0.
+ *
+ *	We output a sine wave on D/A port 0 and sample A/D port 0. We then
+ *	plot the input value on the terminal as a sort of vertical scrolling
+ *	oscilloscipe.
+ *
+ * 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 <sys/ioctl.h>
+#include <stdlib.h>
+#include <math.h>
+
+// Gertboard D to A is an 8-bit unit.
+
+#define	B_SIZE	256
+
+#include <wiringPi.h>
+#include <gertboard.h>
+
+int main (void)
+{
+  double angle ;
+  int i, inputValue ;
+  int  buffer [B_SIZE] ;
+  int   cols ;
+  struct winsize w ;
+
+
+  printf ("Raspberry Pi Gertboard SPI test program\n") ;
+  printf ("=======================================\n") ;
+
+  ioctl (fileno (stdin), TIOCGWINSZ, &w);
+  cols = w.ws_col - 2 ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+  gertboardAnalogSetup (100) ;
+
+// Generate a Sine Wave and store in our buffer
+
+  for (i = 0 ; i < B_SIZE ; ++i)
+  {
+    angle = ((double)i / (double)B_SIZE) * M_PI * 2.0 ;
+    buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ;
+  }
+
+// Loop, output the sine wave on analog out port 0, read it into A-D port 0
+//	and display it on the screen
+
+  for (;;)
+  {
+    for (i = 0 ; i < B_SIZE ; ++i)
+    {
+      analogWrite (100, buffer [i]) ;
+
+      inputValue = analogRead (100) ;
+
+// We don't need to wory about the scale or sign - the analog hardware is
+//	a 10-bit value, so 0-1023. Just scale this to our terminal
+
+      printf ("%*s\n", (inputValue * cols) / 1023, "*") ;
+      delay (2) ;
+    }
+  }
+
+  return 0 ;
+}
diff --git a/examples/Gertboard/record.c b/examples/Gertboard/record.c
new file mode 100644
index 0000000..71d8718
--- /dev/null
+++ b/examples/Gertboard/record.c
@@ -0,0 +1,60 @@
+/*
+ * record.c:
+ *	Record some audio via the Gertboard
+ *
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <wiringPi.h>
+#include <gertboard.h>
+
+#define	B_SIZE	40000
+
+int main ()
+{
+  int i ;
+  struct timeval tStart, tEnd, tTaken ;
+  unsigned char buffer [B_SIZE] ;
+
+  printf ("\n") ;
+  printf ("Gertboard demo: Recorder\n") ;
+  printf ("========================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+  gertboardAnalogSetup (100) ;
+
+  gettimeofday (&tStart, NULL) ;
+
+  for (i = 0 ; i < B_SIZE ; ++i)
+    buffer [i] = analogRead (100) >> 2 ;
+
+  gettimeofday (&tEnd, NULL) ;
+  
+  timersub (&tEnd, &tStart, &tTaken) ;
+
+  printf ("Time taken for %d  reads: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ;
+
+  gettimeofday (&tStart, NULL) ;
+
+  for (i = 0 ; i < B_SIZE ; ++i)
+   analogWrite (100, buffer [i]) ;
+
+  gettimeofday (&tEnd, NULL) ;
+  
+  timersub (&tEnd, &tStart, &tTaken) ;
+
+  printf ("Time taken for %d writes: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ;
+
+  return 0 ;
+}
+
diff --git a/examples/Gertboard/temperature.c b/examples/Gertboard/temperature.c
new file mode 100644
index 0000000..5985a12
--- /dev/null
+++ b/examples/Gertboard/temperature.c
@@ -0,0 +1,78 @@
+/*
+ * temperature.c:
+ *	Demonstrate use of the Gertboard A to D converter to make
+ *	a simple thermometer using the LM35.
+ *
+ * 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 <gertboard.h>
+
+int main ()
+{
+  int x1, x2 ;
+  double v1, v2 ;
+
+  printf ("\n") ;
+  printf ("Gertboard demo: Simple Thermemeter\n") ;
+  printf ("==================================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+  gertboardAnalogSetup (100) ;
+
+  printf ("\n") ;
+  printf ("| Channel 0 | Channel 1 | Temperature 1 | Temperature 2 |\n") ;
+
+  for (;;)
+  {
+
+// Read the 2 channels:
+
+    x1 = analogRead (100) ;
+    x2 = analogRead (101) ;
+
+// Convert to a voltage:
+
+    v1 = (double)x1 / 1023.0 * 3.3 ;
+    v2 = (double)x2 / 1023.0 * 3.3 ;
+
+// Print
+
+    printf ("|    %6.3f |    %6.3f |", v1, v2) ;
+
+// Print Temperature of both channels by converting the LM35 reading
+//	to a temperature. Fortunately these are easy: 0.01 volts per C.
+
+    printf ("          %4.1f |          %4.1f |\r", v1 * 100.0, v2 * 100.0) ;
+    fflush (stdout) ;
+  }
+
+  return 0 ;
+}
+
diff --git a/examples/Gertboard/voltmeter.c b/examples/Gertboard/voltmeter.c
new file mode 100644
index 0000000..c4d2113
--- /dev/null
+++ b/examples/Gertboard/voltmeter.c
@@ -0,0 +1,73 @@
+/*
+ * voltmeter.c:
+ *	Demonstrate use of the Gertboard A to D converter to make
+ *	a simple voltmeter.
+ *
+ * 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 <gertboard.h>
+
+int main ()
+{
+  int x1, x2 ;
+  double v1, v2 ;
+
+  printf ("\n") ;
+  printf ("Gertboard demo: Simple Voltmeters\n") ;
+  printf ("=================================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+  gertboardAnalogSetup (100) ;
+
+  printf ("\n") ;
+  printf ("| Channel 0 | Channel 1 |\n") ;
+
+  for (;;)
+  {
+
+// Read the 2 channels:
+
+    x1 = analogRead (100) ;
+    x2 = analogRead (101) ;
+
+// Convert to a voltage:
+
+    v1 = (double)x1 / 1023.0 * 3.3 ;
+    v2 = (double)x2 / 1023.0 * 3.3 ;
+
+// Print
+
+    printf ("|    %6.3f |    %6.3f |\r", v1, v2) ;
+    fflush (stdout) ;
+  }
+
+  return 0 ;
+}
+
diff --git a/examples/Gertboard/vumeter.c b/examples/Gertboard/vumeter.c
new file mode 100644
index 0000000..9643ace
--- /dev/null
+++ b/examples/Gertboard/vumeter.c
@@ -0,0 +1,152 @@
+/*
+ * vumeter.c:
+ *	Simple VU meter
+ *
+ * Heres the theory:
+ *	We will sample at 4000 samples/sec and put the data into a
+ *	low-pass filter with a depth of 1000 samples. This will give
+ *	us 1/4 a second of lag on the signal, but I think it might
+ *	produce a more pleasing output.
+ *
+ *	The input of the microphone should be at mid-pont with no
+ *	sound input, but we might have to sample that too, to get
+ *	our reference zero...
+ *
+ *	Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <wiringPi.h>
+#include <gertboard.h>
+
+#ifndef	TRUE
+#define	TRUE	(1==1)
+#define	FALSE	(!TRUE)
+#endif
+
+#define	B_SIZE	1000
+#define	S_SIZE	 128
+
+static int buffer [B_SIZE] ;
+static int bPtr = 0 ;
+
+/*
+ * ledPercent:
+ *	Output the given value as a percentage on the LEDs
+ *********************************************************************************
+ */
+
+static void ledPercent (int percent)
+{
+  unsigned int output = 0 ;
+
+  if (percent > 11) output |= 0x01 ;
+  if (percent > 22) output |= 0x02 ;
+  if (percent > 33) output |= 0x04 ;
+  if (percent > 44) output |= 0x08 ;
+  if (percent > 55) output |= 0x10 ;
+  if (percent > 66) output |= 0x20 ;
+  if (percent > 77) output |= 0x40 ;
+  if (percent > 88) output |= 0x80 ;
+
+  digitalWriteByte (output) ;
+}
+
+static unsigned int tPeriod, tNextSampleTime ;
+
+/*
+ * sample:
+ *	Get a sample from the Gertboard. If not enough time has elapsed
+ *	since the last sample, then wait...
+ *********************************************************************************
+ */
+
+static void sample (void)
+{
+  unsigned int tFuture ;
+
+// Calculate the future sample time
+
+  tFuture = tPeriod + tNextSampleTime ;
+
+// Wait until the next sample time
+
+  while (micros () < tNextSampleTime)
+    ;
+  
+  buffer [bPtr] = gertboardAnalogRead (0) ;
+
+  tNextSampleTime = tFuture ;
+}
+
+
+int main ()
+{
+  int quietLevel, min, max ;
+  int i, sum ;
+  unsigned int tStart, tEnd ;
+
+  printf ("\n") ;
+  printf ("Gertboard demo: VU Meter\n") ;
+  printf ("========================\n") ;
+
+  wiringPiSetup     () ;
+  gertboardSPISetup () ;
+
+  ledPercent (0) ;
+  for (i = 0 ; i < 8 ; ++i)
+    pinMode (i, OUTPUT) ;
+
+  for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
+    buffer [bPtr] = 99 ;
+
+  tPeriod = 1000000 / 1000 ;
+
+  printf ("Shhhh.... ") ; fflush (stdout) ;
+  delay (1000) ;
+  printf ("Sampling quiet... ") ; fflush (stdout) ;
+
+  tStart = micros () ;
+
+  tNextSampleTime = micros () ;
+  for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
+    sample () ;
+
+  tEnd = micros () ;
+
+  quietLevel = 0 ;
+  max =    0 ;
+  min = 1024 ;
+  for (i = 0 ; i < B_SIZE ; ++i)
+  {
+    quietLevel += buffer [i] ;
+    if (buffer [i] > max) max = buffer [i] ;
+    if (buffer [i] < min) min = buffer [i] ;
+  }
+  quietLevel /= B_SIZE ;
+
+  printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ;
+
+  printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ;
+
+  for (bPtr = 0 ;;)
+  {
+    sample () ;
+    sum = 0 ;
+    for (i = 0 ; i < S_SIZE ; ++i)
+      sum += buffer [i] ;
+    sum /= S_SIZE ;
+    sum = abs (quietLevel - sum) ;
+    sum = (sum * 1000) / quietLevel ;
+    ledPercent (sum) ;
+    if (++bPtr > S_SIZE)
+      bPtr = 0 ;
+  }
+
+
+  return 0 ;
+}
diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile
new file mode 100644
index 0000000..f937c14
--- /dev/null
+++ b/examples/PiFace/Makefile
@@ -0,0 +1,88 @@
+#
+# Makefile:
+#	wiringPi - A "wiring" library for the Raspberry Pi
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	A "wiring" 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/>.
+#################################################################################
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#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
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC	=	blink.c buttons.c reaction.c ladder.c metro.c motor.c
+
+OBJ	=	$(SRC:.c=.o)
+
+BINS	=	$(SRC:.c=)
+
+all:	$(BINS)
+
+blink:	blink.o
+	$Q echo [link]
+	$Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
+
+buttons:	buttons.o
+	$Q echo [link]
+	$Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS)
+
+reaction:	reaction.o
+	$Q echo [link]
+	$Q $(CC) -o $@ reaction.o $(LDFLAGS) $(LDLIBS)
+
+ladder:	ladder.o
+	$Q echo [link]
+	$Q $(CC) -o $@ ladder.o $(LDFLAGS) $(LDLIBS)
+
+metro:	metro.o
+	$Q echo [link]
+	$Q $(CC) -o $@ metro.o $(LDFLAGS) $(LDLIBS)
+
+motor:	motor.o
+	$Q echo [link]
+	$Q $(CC) -o $@ motor.o $(LDFLAGS) $(LDLIBS)
+
+.c.o:
+	$Q echo [CC] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	$Q echo "[Clean]"
+	$Q rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/PiFace/blink.c b/examples/PiFace/blink.c
new file mode 100644
index 0000000..ffb8a2e
--- /dev/null
+++ b/examples/PiFace/blink.c
@@ -0,0 +1,59 @@
+/*
+ * blink.c:
+ *	Simple "blink" test for the PiFace 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>
+#include <piFace.h>
+
+// Use 200 as the pin-base for the PiFace board, and pick a pin
+//	for the LED that's not connected to a relay
+
+#define	PIFACE	200
+#define	LED	(PIFACE+2)
+
+int main (int argc, char *argv [])
+{
+  printf ("Raspberry Pi PiFace Blink\n") ;
+  printf ("=========================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+// Setup the PiFace board
+
+  piFaceSetup (PIFACE) ;
+
+  for (;;)
+  {
+    digitalWrite (LED, HIGH) ;	// On
+    delay (500) ;		// mS
+    digitalWrite (LED, LOW) ;	// Off
+    delay (500) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiFace/buttons.c b/examples/PiFace/buttons.c
new file mode 100644
index 0000000..147a4bd
--- /dev/null
+++ b/examples/PiFace/buttons.c
@@ -0,0 +1,103 @@
+/*
+ * buttons.c:
+ *	Simple test for the PiFace interface board.
+ *
+ *	Read the buttons and output the same to the LEDs
+ *
+ * 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 <piFace.h>
+
+int outputs [4] = { 0,0,0,0 } ;
+
+// Use 200 as the pin-base for the PiFace board
+
+#define	PIFACE_BASE	200
+
+
+/*
+ * scanButton:
+ *	Read the guiven button - if it's pressed, then flip the state
+ *	of the correspoinding output pin
+ *********************************************************************************
+ */
+
+void scanButton (int button)
+{
+  if (digitalRead (PIFACE_BASE + button) == LOW)
+  {
+    outputs [button] ^= 1 ;
+    digitalWrite (PIFACE_BASE + button, outputs [button]) ;
+    printf ("Button %d pushed - output now: %s\n",
+		button, (outputs [button] == 0) ? "Off" : "On") ;
+  }
+
+  while (digitalRead (PIFACE_BASE + button) == LOW)
+    delay (1) ;
+}
+
+
+/*
+ * start here
+ *********************************************************************************
+ */
+
+int main (void)
+{
+  int pin, button ;
+
+  printf ("Raspberry Pi wiringPi + PiFace test program\n") ;
+  printf ("===========================================\n") ;
+  printf ("\n") ;
+  printf (
+"This program reads the buttons and uses them to toggle the first 4\n"
+"outputs. Push a button once to turn an output on, and push it again to\n"
+"turn it off again.\n\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+//	(or want) to run as root
+
+  wiringPiSetupSys () ;
+
+  piFaceSetup (PIFACE_BASE) ;
+
+// Enable internal pull-ups & start with all off
+
+  for (pin = 0 ; pin < 8 ; ++pin)
+  {
+    pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ;
+    digitalWrite    (PIFACE_BASE + pin, 0) ;
+  }
+
+// Loop, scanning the buttons
+
+  for (;;)
+  {
+    for (button = 0 ; button < 4 ; ++button)
+      scanButton (button) ;
+    delay (5) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiFace/ladder.c b/examples/PiFace/ladder.c
new file mode 100644
index 0000000..4f08a6f
--- /dev/null
+++ b/examples/PiFace/ladder.c
@@ -0,0 +1,337 @@
+/*
+ * ladder.c:
+ *
+ *	Gordon Henderson, June 2012
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+#include <piFace.h>
+
+#ifndef	TRUE
+#  define	TRUE	(1==1)
+#  define	FALSE	(1==2)
+#endif
+
+#undef	DEBUG
+
+#define	NUM_LEDS	 8
+
+
+// Map the LEDs to the hardware pins
+//	using PiFace pin numbers here
+
+#define	PIFACE	200
+
+const int ledMap [NUM_LEDS] =
+{
+//  0, 1, 2, 3, 4, 5, 6, 7, 8
+    200, 201, 202, 203, 204, 205, 206, 207
+} ;
+
+
+// Some constants for our circuit simulation
+
+const double vBatt      =      9.0 ;	// Volts (ie. a PP3)
+const double capacitor  =      0.001 ;	// 1000uF
+const double rCharge    =   2200.0 ;	// ohms
+const double rDischarge =  68000.0 ;	// ohms
+const double timeInc    =      0.01 ;	// Seconds
+
+double vCharge, vCap, vCapLast ;
+
+
+
+/*
+ * setup:
+ *	Program the GPIO correctly and initialise the lamps
+ ***********************************************************************
+ */
+
+void setup (void)
+{
+  int i ;
+
+  wiringPiSetupSys () ;
+
+  if (piFaceSetup (200) == -1)
+    exit (1) ;
+
+// Enable internal pull-ups
+
+  for (i = 0 ; i < 8 ; ++i)
+    pullUpDnControl (PIFACE + i, PUD_UP) ;
+
+// Calculate the actual charging voltage - standard calculation of
+//	vCharge = r2 / (r1 + r2) * vBatt
+//
+//
+//   -----+--- vBatt
+//        |
+//        R1
+//        |
+//        +---+---- vCharge
+//        |   |
+//        R2  C
+//        |   |
+//   -----+---+-----
+
+  vCharge = rDischarge / (rCharge + rDischarge) * vBatt ;
+
+// Start with no charge
+
+  vCap    = vCapLast = 0.0 ;
+}
+
+
+/*
+ * introLeds
+ *	Put a little pattern on the LEDs to start with
+ *********************************************************************************
+ */
+
+void introLeds (void)
+{
+  int i, j ;
+
+
+  printf ("Pi Ladder\n") ;
+  printf ("=========\n\n") ;
+  printf ("       vBatt: %6.2f volts\n", vBatt) ;
+  printf ("     rCharge: %6.0f ohms\n", rCharge) ;
+  printf ("  rDischarge: %6.0f ohms\n", rDischarge) ;
+  printf ("     vCharge: %6.2f volts\n", vCharge) ;
+  printf ("   capacitor: %6.0f uF\n", capacitor * 1000.0) ;
+
+// Flash 3 times:
+
+  for (j = 0 ; j < 3 ; ++j)
+  {
+    for (i = 0 ; i < NUM_LEDS ; ++i)
+      digitalWrite (ledMap [i], 1) ;
+    delay (500) ;
+    for (i = 0 ; i < NUM_LEDS ; ++i)
+      digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+
+// All On
+
+  for (i = 0 ; i < NUM_LEDS ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+  delay (500) ;
+
+// Countdown...
+
+  for (i = NUM_LEDS - 1 ; i >= 0 ; --i)
+  {
+    digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+  delay (500) ;
+}
+
+
+/*
+ * winningLeds
+ *	Put a little pattern on the LEDs to start with
+ *********************************************************************************
+ */
+
+void winningLeds (void)
+{
+  int i, j ;
+
+// Flash 3 times:
+
+  for (j = 0 ; j < 3 ; ++j)
+  {
+    for (i = 0 ; i < NUM_LEDS ; ++i)
+      digitalWrite (ledMap [i], 1) ;
+    delay (500) ;
+    for (i = 0 ; i < NUM_LEDS ; ++i)
+      digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+
+// All On
+
+  for (i = 0 ; i < NUM_LEDS ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+  delay (500) ;
+
+// Countup...
+
+  for (i = 0 ; i < NUM_LEDS ; ++i)
+  {
+    digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+  delay (500) ;
+}
+
+
+/*
+ * chargeCapacitor: dischargeCapacitor:
+ *	Add or remove charge to the capacitor.
+ *	Standard capacitor formulae.
+ *********************************************************************************
+ */
+
+void chargeCapacitor (void)
+{
+  vCap = (vCapLast - vCharge) *
+	exp (- timeInc / (rCharge * capacitor)) + vCharge ;
+
+#ifdef	DEBUG
+  printf ("+vCap: %7.4f\n", vCap) ;
+#endif
+
+  vCapLast = vCap ;
+}
+
+void dischargeCapacitor (void)
+{
+  vCap = vCapLast *
+	exp (- timeInc / (rDischarge * capacitor)) ;
+
+#ifdef	DEBUG
+  printf ("-vCap: %7.4f\n", vCap) ;
+#endif
+
+  vCapLast = vCap ;
+}
+
+
+/*
+ * ledBargraph:
+ *	Output the supplied number as a bargraph on the LEDs
+ *********************************************************************************
+ */
+
+void ledBargraph (double value, int topLedOn)
+{
+  int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ;
+  int i ;
+
+  if (topLed > NUM_LEDS)
+    topLed = NUM_LEDS ;
+
+  if (!topLedOn)
+    --topLed ;
+
+  for (i = 0 ; i < topLed ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+
+  for (i = topLed ; i < NUM_LEDS ; ++i)
+    digitalWrite (ledMap [i], 0) ;
+}
+
+
+/*
+ * ledOnAction:
+ *	Make sure the leading LED is on and check the button
+ *********************************************************************************
+ */
+
+void ledOnAction (void)
+{
+  if (digitalRead (PIFACE) == LOW)
+  {
+    chargeCapacitor () ;
+    ledBargraph (vCap, TRUE) ;
+  }
+}
+
+
+/*
+ * ledOffAction:
+ *	Make sure the leading LED is off and check the button
+ *********************************************************************************
+ */
+
+void ledOffAction (void)
+{
+  dischargeCapacitor () ;
+
+// Are we still pushing the button?
+
+  if (digitalRead (PIFACE) == LOW)
+  {
+    vCap = vCapLast = 0.0 ;
+    ledBargraph (vCap, FALSE) ;
+
+// Wait until we release the button
+
+    while (digitalRead (PIFACE) == LOW)
+      delay (10) ;
+  }
+}
+
+
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  unsigned int then, ledOnTime, ledOffTime ;
+  unsigned int ourDelay = (int)(1000.0 * timeInc) ;
+  
+  setup     () ;
+  introLeds () ;
+
+// Setup the LED times - TODO reduce the ON time as the game progresses
+
+  ledOnTime  = 1000 ;
+  ledOffTime = 1000 ;
+
+// This is our Gate/Squarewave loop
+
+  for (;;)
+  {
+
+// LED ON:
+
+    (void)ledBargraph (vCap, TRUE) ;
+    then = millis () + ledOnTime ;
+    while (millis () < then)
+    {
+      ledOnAction () ;
+      delay       (ourDelay) ;
+    }
+
+// Have we won yet?
+//	We need vCap to be in the top NUM_LEDS of the vCharge
+
+    if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge))	// Woo hoo!
+    {
+      winningLeds () ;
+      while (digitalRead (PIFACE) == HIGH)
+	delay (10) ;
+      while (digitalRead (PIFACE) == LOW)
+	delay (10) ;
+      vCap = vCapLast = 0.0 ;
+    }
+
+// LED OFF:
+
+    (void)ledBargraph (vCap, FALSE) ;
+    then = millis () + ledOffTime ;
+    while (millis () < then)
+    {
+      ledOffAction () ;
+      delay        (ourDelay) ;
+    }
+
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiFace/metro.c b/examples/PiFace/metro.c
new file mode 100644
index 0000000..a4a8c1d
--- /dev/null
+++ b/examples/PiFace/metro.c
@@ -0,0 +1,111 @@
+/*
+ * metronome.c:
+ *	Simple test for the PiFace 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 <stdlib.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <piFace.h>
+
+#define	PIFACE	200
+
+/*
+ * middleA:
+ *	Play middle A (on the relays - yea!)
+ *********************************************************************************
+ */
+
+static void middleA (void)
+{
+  unsigned int next ;
+
+  for (;;)
+  {
+    next = micros () + 1136 ;
+    digitalWrite (PIFACE + 0, 0)  ;
+    digitalWrite (PIFACE + 1, 0)  ;
+    while (micros () < next)
+      delayMicroseconds (1) ;
+    
+    next = micros () + 1137 ;
+    digitalWrite (PIFACE + 0, 1)  ;
+    digitalWrite (PIFACE + 1, 1)  ;
+    while (micros () < next)
+      delayMicroseconds (1) ;
+    
+  }
+}
+
+
+int main (int argc, char *argv [])
+{
+  int bpm, msPerBeat, state = 0 ;
+  unsigned int end ;
+
+  printf ("Raspberry Pi PiFace Metronome\n") ;
+  printf ("=============================\n") ;
+
+  piHiPri (50) ;
+
+  wiringPiSetupSys () ;	// Needed for timing functions
+  piFaceSetup      (PIFACE) ;
+
+  if (argc != 2)
+  {
+    printf ("Usage: %s <beates per minute>\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  if (strcmp (argv [1], "a") == 0)
+    middleA () ;
+
+  bpm = atoi (argv [1]) ;
+
+  if ((bpm < 40) || (bpm > 208))
+  {
+    printf ("%s range is 40 through 208 beats per minute\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  msPerBeat = 60000 / bpm  ;
+
+// Main loop:
+//	Put some random LED pairs up for a few seconds, then blank ...
+
+  for (;;)
+  {
+    end = millis ()  + msPerBeat ;
+
+    digitalWrite (PIFACE + 0, state)  ;
+    digitalWrite (PIFACE + 1, state)  ;
+
+    while (millis () < end)
+      delayMicroseconds (500) ;
+
+    state ^= 1 ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiFace/motor.c b/examples/PiFace/motor.c
new file mode 100644
index 0000000..14f5539
--- /dev/null
+++ b/examples/PiFace/motor.c
@@ -0,0 +1,120 @@
+/*
+ * motor.c:
+ *	Use the PiFace board to demonstrate an H bridge
+ *	circuit via the 2 relays.
+ *	Then add on an external transsitor to help with PWM.
+ *
+ * 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 <wiringPi.h>
+#include <piFace.h>
+#include <softPwm.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+int outputs [2] = { 0,0 } ;
+
+#define	PIFACE_BASE	200
+#define PWM_OUT_PIN	204
+#define	PWM_UP		202
+#define	PWM_DOWN	203
+
+void scanButton (int button)
+{
+  if (digitalRead (PIFACE_BASE + button) == LOW)
+  {
+    outputs [button] ^= 1 ;
+    digitalWrite (PIFACE_BASE + button, outputs [button]) ;
+    printf ("Button %d pushed - output now: %s\n",
+		button, (outputs [button] == 0) ? "Off" : "On") ;
+  }
+
+  while (digitalRead (PIFACE_BASE + button) == LOW)
+    delay (1) ;
+}
+
+
+int main (void)
+{
+  int pin, button ;
+  int pwmValue = 0 ;
+
+  printf ("Raspberry Pi PiFace - Motor control\n") ;
+  printf ("==================================\n") ;
+  printf ("\n") ;
+  printf (
+"This program is designed to be used with a motor connected to the relays\n"
+"in an H-Bridge type configuration with optional speeed control via PWM.\n"
+"\n"
+"Use the leftmost buttons to turn each relay on and off, and the rigthmost\n"
+"buttons to increase ot decrease the PWM output on the control pin (pin\n"
+"4)\n\n") ;
+
+  wiringPiSetup () ;
+  piFaceSetup (PIFACE_BASE) ;
+  softPwmCreate (PWM_OUT_PIN, 100, 100) ;
+
+// Enable internal pull-ups & start with all off
+
+  for (pin = 0 ; pin < 8 ; ++pin)
+  {
+    pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ;
+    digitalWrite    (PIFACE_BASE + pin, 0) ;
+  }
+
+  for (;;)
+  {
+    for (button = 0 ; button < 2 ; ++button)
+      scanButton (button) ;
+
+    if (digitalRead (PWM_UP) == LOW)
+    {
+      pwmValue += 10 ;
+      if (pwmValue > 100)
+	pwmValue = 100 ;
+
+      softPwmWrite (PWM_OUT_PIN, pwmValue) ;
+      printf ("PWM -> %3d\n", pwmValue) ;
+
+      while (digitalRead (PWM_UP) == LOW)
+	delay (5) ;
+    }
+
+    if (digitalRead (PWM_DOWN) == LOW)
+    {
+      pwmValue -= 10 ;
+      if (pwmValue < 0)
+	pwmValue = 0 ;
+
+      softPwmWrite (PWM_OUT_PIN, pwmValue) ;
+      printf ("PWM -> %3d\n", pwmValue) ;
+
+      while (digitalRead (PWM_DOWN) == LOW)
+	delay (5) ;
+    }
+
+    delay (5) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiFace/reaction.c b/examples/PiFace/reaction.c
new file mode 100644
index 0000000..5084508
--- /dev/null
+++ b/examples/PiFace/reaction.c
@@ -0,0 +1,194 @@
+/*
+ * reaction.c:
+ *	Simple test for the PiFace 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 <stdlib.h>
+#include <stdint.h>
+
+#include <wiringPi.h>
+#include <piFace.h>
+
+
+int outputs [4] = { 0,0,0,0 } ;
+
+#define	PIFACE	200
+
+/*
+ * light:
+ *	Light up the given LED - actually lights up a pair
+ *********************************************************************************
+ */
+
+void light (int led, int value)
+{
+  led *= 2 ;
+  digitalWrite (PIFACE + led + 0, value) ;
+  digitalWrite (PIFACE + led + 1, value) ;
+}
+
+/*
+ * lightAll:
+ *	All On or Off
+ *********************************************************************************
+ */
+
+void lightAll (int onoff)
+{
+  light (0, onoff) ;
+  light (1, onoff) ;
+  light (2, onoff) ;
+  light (3, onoff) ;
+}
+
+
+/*
+ * waitForNoButtons:
+ *	Wait for all buttons to be released
+ *********************************************************************************
+ */
+
+void waitForNoButtons (void)
+{
+  int i, button ;
+
+  for (;;)
+  {
+    button = 0 ;
+    for (i = 0 ; i < 4 ; ++i)
+      button += digitalRead (PIFACE + i) ;
+
+    if (button == 4)
+      break ;
+  }
+}
+
+
+void scanButton (int button)
+{
+  if (digitalRead (PIFACE + button) == LOW)
+  {
+    outputs [button] ^= 1 ;
+    digitalWrite (PIFACE + button, outputs [button]) ;
+  }
+
+  while (digitalRead (PIFACE + button) == LOW)
+    delay (1) ;
+}
+
+
+int main (void)
+{
+  int i, j ;
+  int led, button ;
+  unsigned int start, stop ;
+
+  printf ("Raspberry Pi PiFace Reaction Timer\n") ;
+  printf ("==================================\n") ;
+
+  if (piFaceSetup (PIFACE) == -1)
+    exit (1) ;
+
+// Enable internal pull-ups
+
+  for (i = 0 ; i < 8 ; ++i)
+    pullUpDnControl (PIFACE + i, PUD_UP) ;
+
+
+// Main game loop:
+//	Put some random LED pairs up for a few seconds, then blank ...
+
+  for (;;)
+  {
+    printf ("Press any button to start ... \n") ; fflush (stdout) ;
+
+    for (;;)
+    {
+      led = rand () % 4 ;
+      light (led, 1) ;
+      delay (10) ;
+      light (led, 0) ;
+
+      button = 0 ;
+      for (j = 0 ; j < 4 ; ++j)
+	button += digitalRead (PIFACE + j) ;
+
+      if (button != 4)
+	break ;
+    }
+
+    waitForNoButtons () ;
+
+    printf ("Wait for it ... ") ; fflush (stdout) ;
+
+    led = rand () % 4 ;
+    delay (rand () % 500 + 1000) ;
+    light (led, 1) ;
+
+    start = millis () ;
+    for (button = -1 ; button == -1 ; )
+    {
+      for (j = 0 ; j < 4 ; ++j)
+	if (digitalRead (PIFACE + j) == 0)	// Pushed
+	{
+	  button = j ;
+	  break ;
+	}
+    }
+    stop = millis () ;
+    button = 3 - button ; // Correct for the buttons/LEDs reversed
+
+    light (led, 0) ;
+
+    waitForNoButtons () ;
+
+    light (led, 1) ;
+
+    if (button == led)
+    {
+      printf ("You got it in %3d mS\n", stop - start) ;
+    }
+    else
+    {
+      printf ("Missed: You pushed %d - LED was %d\n", button, led) ;
+      for (;;)
+      {
+	light (button, 1) ;
+	delay (100) ;
+	light (button, 0) ;
+	delay (100) ;
+	i = 0 ;
+	for (j = 0 ; j < 4 ; ++j)
+	  i += digitalRead (PIFACE + j) ;
+	if (i != 4)
+	  break ;
+      }
+
+      waitForNoButtons () ;
+    }
+    light (led, 0) ;
+    delay (4000) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiGlow/Makefile b/examples/PiGlow/Makefile
new file mode 100644
index 0000000..f182db7
--- /dev/null
+++ b/examples/PiGlow/Makefile
@@ -0,0 +1,82 @@
+#
+# Makefile:
+#	wiringPi - A "wiring" library for the Raspberry Pi
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012-2015 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	A "wiring" 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/>.
+#################################################################################
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#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
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC	=	piGlow0.c piGlow1.c piglow.c
+
+OBJ	=	$(SRC:.c=.o)
+
+BINS	=	$(SRC:.c=)
+
+all:	$(BINS)
+
+piGlow0:	piGlow0.o
+	$Q echo [link]
+	$Q $(CC) -o $@ piGlow0.o $(LDFLAGS) $(LDLIBS)
+
+piGlow1:	piGlow1.o
+	$Q echo [link]
+	$Q $(CC) -o $@ piGlow1.o $(LDFLAGS) $(LDLIBS)
+
+piglow:	piglow.o
+	$Q echo [link]
+	$Q $(CC) -o $@ piglow.o $(LDFLAGS) $(LDLIBS)
+
+.c.o:
+	$Q echo [CC] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	$Q echo "[Clean]"
+	$Q rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+install:	piglow
+	$Q echo Installing piglow into /usr/local/bin
+	$Q cp -a piglow /usr/local/bin/piglow
+	$Q chmod 755 /usr/local/bin/piglow
+	$Q echo Done. Remember to load the I2C drivers!
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/PiGlow/piGlow0.c b/examples/PiGlow/piGlow0.c
new file mode 100644
index 0000000..d3fe4b9
--- /dev/null
+++ b/examples/PiGlow/piGlow0.c
@@ -0,0 +1,51 @@
+/*
+ * piglow.c:
+ *	Very simple demonstration of the PiGlow board.
+ *	This uses the SN3218 directly - soon there will be a new PiGlow
+ *	devLib device which will handle the PiGlow board on a more easy
+ *	to use manner...
+ *
+ * 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 <wiringPi.h>
+#include <sn3218.h>
+
+#define	LED_BASE	533
+
+int main (void)
+{
+  int i, j ;
+
+  wiringPiSetupSys () ;
+
+  sn3218Setup (LED_BASE) ;
+
+  for (;;)
+  {
+    for (i = 0 ; i < 256 ; ++i)
+      for (j = 0 ; j < 18 ; ++j)
+	analogWrite (LED_BASE + j, i) ;
+
+    for (i = 255 ; i >= 0 ; --i)
+      for (j = 0 ; j < 18 ; ++j)
+	analogWrite (LED_BASE + j, i) ;
+  }
+}
diff --git a/examples/PiGlow/piGlow1.c b/examples/PiGlow/piGlow1.c
new file mode 100644
index 0000000..a00b31e
--- /dev/null
+++ b/examples/PiGlow/piGlow1.c
@@ -0,0 +1,258 @@
+/*
+ * piGlow1.c:
+ *	Very simple demonstration of the PiGlow board.
+ *	This uses the piGlow devLib.
+ *
+ * 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 <stdlib.h>
+#include <poll.h>
+
+#include <wiringPi.h>
+#include <piGlow.h>
+
+#define	PIGLOW_BASE	533
+
+#ifndef	TRUE
+#  define TRUE  (1==1)
+#  define FALSE (!TRUE)
+#endif
+
+
+/*
+ * keypressed: clearKeypressed:
+ *	Simple but effective ways to tell if the enter key has been pressed
+ *********************************************************************************
+ */
+
+static int keypressed (void)
+{
+  struct pollfd polls ;
+
+  polls.fd     = fileno (stdin) ;
+  polls.events = POLLIN ;
+
+  return poll (&polls, 1, 0) != 0 ;
+}
+
+static void clearKeypressed (void)
+{
+  while (keypressed ())
+    (void)getchar () ;
+}
+
+
+/*
+ * pulseLed:
+ *	Pulses the LED at position leg, ring from off to a max. value,
+ *	then off again
+ *********************************************************************************
+ */
+
+static void pulseLed (int leg, int ring)
+{
+  int i ;
+
+  for (i = 0 ; i < 140 ; ++i)
+  {
+    piGlow1 (leg, ring, i) ;
+    delay (1) ;
+  }
+  delay (10) ;
+  for (i = 140 ; i >= 0 ; --i)
+  {
+    piGlow1 (leg, ring, i) ;
+    delay (1) ;
+  }
+}
+
+/*
+ * pulseLeg:
+ *	Same as above, but a whole leg at a time
+ *********************************************************************************
+ */
+
+static void pulseLeg (int leg)
+{
+  int i ;
+
+  for (i = 0 ; i < 140 ; ++i)
+  {
+    piGlowLeg (leg, i) ; delay (1) ;
+  }
+  delay (10) ;
+  for (i = 140 ; i >= 0 ; --i)
+  {
+    piGlowLeg (leg, i) ; delay (1) ;
+  }
+}
+
+
+/*
+ * pulse Ring:
+ *	Same as above, but a whole ring at a time
+ *********************************************************************************
+ */
+
+static void pulseRing (int ring)
+{
+  int i ;
+
+  for (i = 0 ; i < 140 ; ++i)
+  {
+    piGlowRing (ring, i) ; delay (1) ;
+  }
+  delay (10) ;
+  for (i = 140 ; i >= 0 ; --i)
+  {
+    piGlowRing (ring, i) ; delay (1) ;
+  }
+}
+
+#define	LEG_STEPS	3
+
+static int legSequence [] =
+{
+   4, 12, 99,
+  99,  4, 12, 
+  12, 99,  4,
+} ;
+  
+
+#define	RING_STEPS	16
+
+static int ringSequence [] =
+{
+   0,  0,  0,  0,  0, 64,
+   0,  0,  0,  0, 64, 64,
+   0,  0,  0, 64, 64,  0,
+   0,  0, 64, 64,  0,  0,
+   0, 64, 64,  0,  0,  0,
+  64, 64,  0,  0,  0,  0,
+  64,  0,  0,  0,  0,  0,
+   0,  0,  0,  0,  0,  0,
+  64,  0,  0,  0,  0,  0,
+  64, 64,  0,  0,  0,  0,
+   0, 64, 64,  0,  0,  0,
+   0,  0, 64, 64,  0,  0,
+   0,  0,  0, 64, 64,  0,
+   0,  0,  0,  0, 64, 64,
+   0,  0,  0,  0,  0, 64,
+   0,  0,  0,  0,  0,  0,
+} ;
+
+/*
+ * main:
+ *	Our little demo prgoram
+ *********************************************************************************
+ */
+
+int main (void)
+{
+  int i ;
+  int step, ring, leg ;
+
+// Always initialise wiringPi:
+//	Use the Sys method if you don't need to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the piGlow devLib with our chosen pin base
+
+  piGlowSetup (1) ;
+
+// LEDs, one at a time
+
+  printf ("LEDs, one at a time\n") ;
+  for (; !keypressed () ;)
+    for (leg = 0 ; leg < 3 ; ++leg)
+    {
+      for (ring = 0 ; ring < 6 ; ++ring)
+      {
+	pulseLed (leg, ring) ;
+	if (keypressed ())
+	  break ;
+      }
+      if (keypressed ())
+	break ;
+    }
+  clearKeypressed () ;
+
+// Rings, one at a time
+
+  printf ("Rings, one at a time\n") ;
+  for (; !keypressed () ;)
+    for (ring = 0 ; ring < 6 ; ++ring)
+    {
+      pulseRing (ring) ;
+      if (keypressed ())
+	break ;
+    }
+  clearKeypressed () ;
+
+// Legs, one at a time
+
+  printf ("Legs, one at a time\n") ;
+  for (; !keypressed () ;)
+    for (leg = 0 ; leg < 3 ; ++leg)
+    {
+      pulseLeg (leg) ;
+      if (keypressed ())
+	break ;
+    }
+  clearKeypressed () ;
+
+  delay (1000) ;
+
+// Sequence - alternating rings, legs and random
+
+  printf ("Sequence now\n") ;
+  for (; !keypressed () ;)
+  {
+    for (i = 0 ; i < 20 ; ++i)
+      for (step = 0 ; step < LEG_STEPS ; ++step)
+      {
+	for (leg = 0 ; leg < 3 ; ++leg)
+	  piGlowLeg (leg, legSequence [step * 3 + leg]) ;
+	delay (80) ;
+      }
+
+    for (i = 0 ; i < 10 ; ++i)
+      for (step = 0 ; step < RING_STEPS ; ++step)
+      {
+	for (ring = 0 ; ring < 6 ; ++ring)
+	  piGlowRing (ring, ringSequence [step * 6 + ring]) ;
+	delay (80) ;
+      }
+
+    for (i = 0 ; i < 1000 ; ++i)
+    {
+      leg  = random () % 3 ;
+      ring = random () % 6 ;
+      piGlow1 (leg, ring, random () % 256) ;
+      delay (5) ; 
+      piGlow1 (leg, ring, 0) ;
+    }
+  }
+
+  return 0 ;
+}
diff --git a/examples/PiGlow/piglow.c b/examples/PiGlow/piglow.c
new file mode 100644
index 0000000..e6a2db3
--- /dev/null
+++ b/examples/PiGlow/piglow.c
@@ -0,0 +1,176 @@
+/*
+ * piglow.c:
+ *	Very simple demonstration of the PiGlow board.
+ *	This uses the piGlow devLib.
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+
+#ifndef	TRUE
+#  define TRUE  (1==1)
+#  define FALSE (!TRUE)
+#endif
+
+#include <wiringPi.h>
+#include <piGlow.h>
+
+static void failUsage (void)
+{
+  fprintf (stderr, "Usage examples:\n") ;
+  fprintf (stderr, "  piglow off         # All off\n") ;
+  fprintf (stderr, "  piglow red 50      # Light the 3 red LEDs to 50%%\n") ;
+  fprintf (stderr, "     colours are: red, yellow, orange, green, blue and white\n") ;
+  fprintf (stderr, "  piglow all 75      # Light all to 75%%\n") ;
+  fprintf (stderr, "  piglow leg 0 25    # Light leg 0 to 25%%\n") ;
+  fprintf (stderr, "  piglow ring 3 100  # Light ring 3 to 100%%\n") ;
+  fprintf (stderr, "  piglow led 2 5 100 # Light the single LED on Leg 2, ring 5 to 100%%\n") ;
+
+  exit (EXIT_FAILURE) ;
+}
+
+static int getPercent (char *typed)
+{
+  int percent ;
+
+  percent = atoi (typed) ;
+  if ((percent < 0) || (percent > 100))
+  {
+    fprintf (stderr, "piglow: percent value out of range\n") ;
+    exit (EXIT_FAILURE) ;
+  }
+  return (percent * 255) / 100 ;
+}
+
+
+/*
+ * main:
+ *	Our little demo prgoram
+ *********************************************************************************
+ */
+
+int main (int argc, char *argv [])
+{
+  int percent ;
+  int ring, leg ;
+
+// Always initialise wiringPi:
+//	Use the Sys method if you don't need to run as root
+
+  wiringPiSetupSys () ;
+
+// Initialise the piGlow devLib
+
+  piGlowSetup (FALSE) ;
+
+  if (argc == 1)
+    failUsage () ;
+
+  if ((argc == 2) && (strcasecmp (argv [1], "off") == 0))
+  {
+    for (leg = 0 ; leg < 3 ; ++leg)
+      piGlowLeg (leg, 0) ;
+    return 0 ;
+  }
+
+  if (argc == 3)
+  {
+    percent = getPercent (argv [2]) ;
+
+    /**/ if (strcasecmp (argv [1], "red") == 0)
+      piGlowRing (PIGLOW_RED, percent) ;
+    else if (strcasecmp (argv [1], "yellow") == 0)
+      piGlowRing (PIGLOW_YELLOW, percent) ;
+    else if (strcasecmp (argv [1], "orange") == 0)
+      piGlowRing (PIGLOW_ORANGE, percent) ;
+    else if (strcasecmp (argv [1], "green") == 0)
+      piGlowRing (PIGLOW_GREEN, percent) ;
+    else if (strcasecmp (argv [1], "blue") == 0)
+      piGlowRing (PIGLOW_BLUE, percent) ;
+    else if (strcasecmp (argv [1], "white") == 0)
+      piGlowRing (PIGLOW_WHITE, percent) ;
+    else if (strcasecmp (argv [1], "all") == 0)
+      for (ring = 0 ; ring < 6 ; ++ring)
+	piGlowRing (ring, percent) ;
+    else
+    {
+      fprintf (stderr, "piglow: invalid colour\n") ;
+      exit (EXIT_FAILURE) ;
+    }
+    return 0 ;
+  }
+
+  if (argc == 4)
+  {
+    /**/ if (strcasecmp (argv [1], "leg") == 0)
+    {
+      leg = atoi (argv [2]) ;
+      if ((leg < 0) || (leg > 2))
+      {
+	fprintf (stderr, "piglow: leg value out of range\n") ;
+	exit (EXIT_FAILURE) ;
+      }
+      percent = getPercent (argv [3]) ;
+      piGlowLeg (leg, percent) ;
+    }
+    else if (strcasecmp (argv [1], "ring") == 0)
+    {
+      ring = atoi (argv [2]) ;
+      if ((ring < 0) || (ring > 5))
+      {
+	fprintf (stderr, "piglow: ring value out of range\n") ;
+	exit (EXIT_FAILURE) ;
+      }
+      percent = getPercent (argv [3]) ;
+      piGlowRing (ring, percent) ;
+    }
+    return 0 ;
+  }
+
+  if (argc == 5)
+  {
+    if (strcasecmp (argv [1], "led") != 0)
+      failUsage () ;
+
+    leg = atoi (argv [2]) ;
+    if ((leg < 0) || (leg > 2))
+    {
+      fprintf (stderr, "piglow: leg value out of range\n") ;
+      exit (EXIT_FAILURE) ;
+    }
+    ring = atoi (argv [3]) ;
+    if ((ring < 0) || (ring > 5))
+    {
+      fprintf (stderr, "piglow: ring value out of range\n") ;
+      exit (EXIT_FAILURE) ;
+    }
+    percent = getPercent (argv [4]) ;
+    piGlow1 (leg, ring, percent) ;
+    return 0 ;
+  }
+
+  failUsage () ;
+  return 0 ; 
+}
+
+
diff --git a/examples/blink12drcs.c b/examples/blink12drcs.c
new file mode 100644
index 0000000..6ee11fd
--- /dev/null
+++ b/examples/blink12drcs.c
@@ -0,0 +1,125 @@
+/*
+ * blink12drcs.c:
+ *	Simple sequence over the first 12 GPIO pins - LEDs
+ *	Aimed at the Gertboard, but it's fairly generic.
+ *	This version uses DRC totalk to the ATmega on the Gertboard
+ *
+ * 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 <drcSerial.h>
+
+#define	GERT_BASE	100
+
+static int pinMap [] =
+{
+  0, 1, 2, 3,		// Pi Native
+  GERT_BASE + 2, GERT_BASE + 3, GERT_BASE + 4, GERT_BASE + 5,
+  GERT_BASE + 6, GERT_BASE + 7, GERT_BASE + 8, GERT_BASE + 9,
+} ;
+
+// Simple sequencer data
+//	Triplets of LED, On/Off and delay
+
+
+int data [] =
+{
+               0, 1, 1,
+               1, 1, 1,
+   0, 0, 0,    2, 1, 1,
+   1, 0, 0,    3, 1, 1,
+   2, 0, 0,    4, 1, 1,
+   3, 0, 0,    5, 1, 1,
+   4, 0, 0,    6, 1, 1,
+   5, 0, 0,    7, 1, 1,
+   6, 0, 0,    8, 1, 1,
+   7, 0, 0,    9, 1, 1,
+   8, 0, 0,   10, 1, 1,
+   9, 0, 0,   11, 1, 1,
+  10, 0, 1,
+  11, 0, 1,
+
+  0, 0, 1,	// Extra delay
+
+// Back again
+
+              11, 1, 1,
+              10, 1, 1,
+  11, 0, 0,    9, 1, 1,
+  10, 0, 0,    8, 1, 1,
+   9, 0, 0,    7, 1, 1,
+   8, 0, 0,    6, 1, 1,
+   7, 0, 0,    5, 1, 1,
+   6, 0, 0,    4, 1, 1,
+   5, 0, 0,    3, 1, 1,
+   4, 0, 0,    2, 1, 1,
+   3, 0, 0,    1, 1, 1,
+   2, 0, 0,    0, 1, 1,
+   1, 0, 1,
+   0, 0, 1,
+
+   0, 0, 1,	// Extra delay
+
+   0, 9, 0,	// End marker
+
+} ;
+
+
+int main (void)
+{
+  int pin ;
+  int dataPtr ;
+  int l, s, d ;
+
+  printf ("Raspberry Pi - 12-LED Sequence\n") ;
+  printf ("==============================\n") ;
+  printf ("\n") ;
+  printf ("Connect LEDs up to the first 4 Pi pins and 8 pins on the ATmega\n") ;
+  printf ("    from PD2 through PB1 in that order,\n") ;
+  printf ("  then sit back and watch the show!\n") ;
+
+  wiringPiSetup  () ;
+  drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ;
+
+  for (pin = 0 ; pin < 12 ; ++pin)
+    pinMode (pinMap [pin], OUTPUT) ;
+
+  dataPtr = 0 ;
+
+  for (;;)
+  {
+    l = data [dataPtr++] ;	// LED
+    s = data [dataPtr++] ;	// State
+    d = data [dataPtr++] ;	// Duration (10ths)
+
+    if (s == 9)			// 9 -> End Marker
+    {
+      dataPtr = 0 ;
+      continue ;
+    }
+
+    digitalWrite (pinMap [l], s) ;
+    delay        (d * analogRead (GERT_BASE) / 4) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/blink6drcs.c b/examples/blink6drcs.c
new file mode 100644
index 0000000..32f4921
--- /dev/null
+++ b/examples/blink6drcs.c
@@ -0,0 +1,115 @@
+/*
+ * blink6drcs.c:
+ *	Simple sequence over 6 pins on a remote DRC board.
+ *	Aimed at the Gertduino, but it's fairly generic.
+ *	This version uses DRC to talk to the ATmega on the Gertduino
+ *
+ * Copyright (c) 2012-2014 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 <drcSerial.h>
+
+#define	GERT_BASE	100
+
+static int pinMap [] =
+{
+  GERT_BASE + 6, GERT_BASE + 5, GERT_BASE + 3, GERT_BASE + 10, GERT_BASE + 9, GERT_BASE + 13,
+} ;
+
+// Simple sequencer data
+//	Triplets of LED, On/Off and delay
+
+
+int data [] =
+{
+               0, 1, 1,
+               1, 1, 1,
+   0, 0, 0,    2, 1, 1,
+   1, 0, 0,    3, 1, 1,
+   2, 0, 0,    4, 1, 1,
+   3, 0, 0,    5, 1, 1,
+   4, 0, 1,
+   5, 0, 1,
+
+   0, 0, 1,	// Extra delay
+
+// Back again
+
+               5, 1, 1,
+               4, 1, 1,
+   5, 0, 0,    3, 1, 1,
+   4, 0, 0,    2, 1, 1,
+   3, 0, 0,    1, 1, 1,
+   2, 0, 0,    0, 1, 1,
+   1, 0, 1,
+   0, 0, 1,
+
+   0, 0, 1,	// Extra delay
+
+   0, 9, 0,	// End marker
+
+} ;
+
+
+int main (void)
+{
+  int pin ;
+  int dataPtr ;
+  int l, s, d ;
+
+  printf ("Raspberry Pi - 6-LED Sequence\n") ;
+  printf ("=============================\n") ;
+  printf ("\n") ;
+  printf ("  Use the 2 buttons to temporarily speed up the sequence\n") ;
+
+  wiringPiSetupSys  () ;	// Not using the Pi's GPIO here
+  drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ;
+
+  for (pin = 0 ; pin < 6 ; ++pin)
+    pinMode (pinMap [pin], OUTPUT) ;
+
+  pinMode (GERT_BASE + 16, INPUT) ;	// Buttons
+  pinMode (GERT_BASE + 17, INPUT) ;
+
+  pullUpDnControl (GERT_BASE + 16, PUD_UP) ;
+  pullUpDnControl (GERT_BASE + 17, PUD_UP) ;
+
+  dataPtr = 0 ;
+
+  for (;;)
+  {
+    l = data [dataPtr++] ;	// LED
+    s = data [dataPtr++] ;	// State
+    d = data [dataPtr++] ;	// Duration (10ths)
+
+    if (s == 9)			// 9 -> End Marker
+    {
+      dataPtr = 0 ;
+      continue ;
+    }
+
+    digitalWrite (pinMap [l], s) ;
+    delay        (d * digitalRead (GERT_BASE + 16) * 15 + digitalRead (GERT_BASE + 17) * 20) ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/blink8-drcn.c b/examples/blink8-drcn.c
new file mode 100644
index 0000000..96c775b
--- /dev/null
+++ b/examples/blink8-drcn.c
@@ -0,0 +1,61 @@
+/*
+ * blink8-drcn.c:
+ *	Simple sequence over the first 8 GPIO pins - LEDs
+ *	Aimed at the Ladder board, but it's fairly generic.
+ *
+ * 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 <drcNet.h>
+
+int main (void)
+{
+  int i, led ;
+
+  printf ("Raspberry Pi - 8-LED Sequencer\n") ;
+  printf ("==============================\n") ;
+  printf ("\n") ;
+  printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ;
+
+  int pinBase = 100 ;
+
+//  wiringPiSetup () ;
+  drcSetupNet (pinBase, 100, "192.168.254.21", "6124", "123456") ;
+
+  for (i = 0 ; i < 8 ; ++i)
+    pinMode (i + pinBase, OUTPUT) ;
+
+  for (;;)
+  {
+    for (led = 0 ; led < 8 ; ++led)
+    {
+      digitalWrite (led + pinBase, 1) ;
+      delay (10) ;
+    }
+
+    for (led = 0 ; led < 8 ; ++led)
+    {
+      digitalWrite (led + pinBase, 0) ;
+      delay (10) ;
+    }
+  }
+}
diff --git a/examples/ds1302.c b/examples/ds1302.c
new file mode 100644
index 0000000..f1e9e20
--- /dev/null
+++ b/examples/ds1302.c
@@ -0,0 +1,238 @@
+/*
+ * ds1302.c:
+ *	Real Time clock
+ *
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+
+#include <wiringPi.h>
+#include <ds1302.h>
+
+// Register defines
+
+#define	RTC_SECS	 0
+#define	RTC_MINS	 1
+#define	RTC_HOURS	 2
+#define	RTC_DATE	 3
+#define	RTC_MONTH	 4
+#define	RTC_DAY		 5
+#define	RTC_YEAR	 6
+#define	RTC_WP		 7
+#define	RTC_TC		 8
+#define	RTC_BM		31
+
+
+static unsigned int masks [] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF } ;
+
+
+/*
+ * bcdToD: dToBCD:
+ *	BCD decode/encode
+ *********************************************************************************
+ */
+
+static int bcdToD (unsigned int byte, unsigned int mask)
+{
+  unsigned int b1, b2 ;
+  byte &= mask ;
+  b1 = byte & 0x0F ;
+  b2 = ((byte >> 4) & 0x0F) * 10 ;
+  return b1 + b2 ;
+}
+
+static unsigned int dToBcd (unsigned int byte)
+{
+  return ((byte / 10) << 4) + (byte % 10) ;
+}
+
+
+/*
+ * ramTest:
+ *	Simple test of the 31 bytes of RAM inside the DS1302 chip
+ *********************************************************************************
+ */
+
+static int ramTestValues [] =
+  { 0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0xF0, 0x0F, -1 } ;
+
+static int ramTest (void)
+{
+  int addr ;
+  int got ;
+  int i = 0 ;
+  int errors = 0 ;
+  int testVal ;
+
+  printf ("DS1302 RAM TEST\n") ;
+
+  testVal = ramTestValues [i] ;
+
+  while (testVal != -1)
+  {
+    for (addr = 0 ; addr < 31 ; ++addr)
+      ds1302ramWrite (addr, testVal) ;
+
+    for (addr = 0 ; addr < 31 ; ++addr)
+      if ((got = ds1302ramRead (addr)) != testVal)
+      {
+	printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n",
+		addr, testVal, got) ;
+	++errors ;
+      }
+    testVal = ramTestValues [++i] ;
+  }
+
+  for (addr = 0 ; addr < 31 ; ++addr)
+    ds1302ramWrite (addr, addr) ;
+
+  for (addr = 0 ; addr < 31 ; ++addr)
+    if ((got = ds1302ramRead (addr)) != addr)
+    {
+      printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n",
+	      addr, addr, got) ;
+      ++errors ;
+    }
+
+  if (errors == 0)
+    printf ("-- DS1302 RAM TEST: OK\n") ;
+  else
+    printf ("-- DS1302 RAM TEST FAILURE. %d errors.\n", errors) ;
+
+  return 0 ;
+}
+
+/*
+ * setLinuxClock:
+ *	Set the Linux clock from the hardware
+ *********************************************************************************
+ */
+
+static int setLinuxClock (void)
+{
+  char dateTime [20] ;
+  char command [64] ;
+  int  clock [8] ;
+
+
+  printf ("Setting the Linux Clock from the DS1302... ") ; fflush (stdout) ;
+
+  ds1302clockRead (clock) ;
+
+// [MMDDhhmm[[CC]YY][.ss]]
+
+  sprintf (dateTime, "%02d%02d%02d%02d%02d%02d.%02d",
+	bcdToD (clock [RTC_MONTH], masks [RTC_MONTH]),
+	bcdToD (clock [RTC_DATE],  masks [RTC_DATE]),
+	bcdToD (clock [RTC_HOURS], masks [RTC_HOURS]),
+	bcdToD (clock [RTC_MINS],  masks [RTC_MINS]),
+	20,
+	bcdToD (clock [RTC_YEAR],  masks [RTC_YEAR]),
+	bcdToD (clock [RTC_SECS],  masks [RTC_SECS])) ;
+
+  sprintf (command, "/bin/date %s", dateTime) ;
+  system (command) ;
+
+  return 0 ;
+}
+
+
+/*
+ * setDSclock:
+ *	Set the DS1302 block from Linux time
+ *********************************************************************************
+ */
+
+static int setDSclock (void)
+{
+  struct tm t ;
+  time_t now ;
+  int clock [8] ;
+
+  printf ("Setting the clock in the DS1302 from Linux time... ") ;
+
+  now = time (NULL) ;
+  gmtime_r (&now, &t) ;
+
+  clock [ 0] = dToBcd (t.tm_sec) ;	// seconds
+  clock [ 1] = dToBcd (t.tm_min) ;	// mins
+  clock [ 2] = dToBcd (t.tm_hour) ;	// hours
+  clock [ 3] = dToBcd (t.tm_mday) ;	// date
+  clock [ 4] = dToBcd (t.tm_mon + 1) ;	// months 0-11 --> 1-12
+  clock [ 5] = dToBcd (t.tm_wday + 1) ;	// weekdays (sun 0)
+  clock [ 6] = dToBcd (t.tm_year - 100) ;       // years
+  clock [ 7] = 0 ;			// W-Protect off
+
+  ds1302clockWrite (clock) ;
+
+  printf ("OK\n") ;
+
+  return 0 ;
+}
+
+
+
+
+int main (int argc, char *argv [])
+{
+  int i ;
+  int clock [8] ;
+
+  wiringPiSetup () ;
+  ds1302setup   (0, 1, 2) ;
+
+  if (argc == 2)
+  {
+    /**/ if (strcmp (argv [1], "-slc") == 0)
+      return setLinuxClock () ;
+    else if (strcmp (argv [1], "-sdsc") == 0)
+      return setDSclock () ;
+    else if (strcmp (argv [1], "-rtest") == 0)
+      return ramTest () ;
+    else
+    {
+      printf ("Usage: ds1302 [-slc | -sdsc | -rtest]\n") ;
+      return EXIT_FAILURE ;
+    }
+  }
+
+  for (i = 0 ;; ++i)
+  {
+    printf ("%5d:  ", i) ;
+
+    ds1302clockRead (clock) ;
+    printf (" %2d:%02d:%02d",
+	bcdToD (clock [2], masks [2]), bcdToD (clock [1], masks [1]), bcdToD (clock [0], masks [0])) ;
+
+    printf (" %2d/%02d/%04d",
+	bcdToD (clock [3], masks [3]), bcdToD (clock [4], masks [4]), bcdToD (clock [6], masks [6]) + 2000) ;
+      
+    printf ("\n") ;
+
+    delay (200) ;
+  }
+ 
+  return 0 ;
+}
diff --git a/examples/lcd-adafruit.c b/examples/lcd-adafruit.c
new file mode 100644
index 0000000..47c9b9b
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/max31855.c b/examples/max31855.c
new file mode 100644
index 0000000..36b3cf6
--- /dev/null
+++ b/examples/max31855.c
@@ -0,0 +1,60 @@
+/*
+ * max31855.c:
+ *	SPI Thermocouple interface chip
+ *
+ * Copyright (c) 2015 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 <stdint.h>
+#include <string.h>
+#include <time.h>
+
+#include <wiringPi.h>
+#include <max31855.h>
+
+int main (int argc, char *argv [])
+{
+  int i = 0 ;
+
+  wiringPiSetup () ;
+  max31855Setup (200, 0) ;
+  max31855Setup (400, 1) ;
+
+  for (;;)
+  {
+    if (i == 0)
+    {
+      printf ("+------+------+------+------++------+------+------+------+\n") ;
+      printf ("| Raw  | Err  |  C   |   F  || Raw  | Err  |  C   |  F   |\n") ;
+      printf ("+------+------+------+------++------+------+------+------+\n") ;
+    }
+
+    printf ("| %4d | %4d | %4d | %4d |",   analogRead (200), analogRead (201), analogRead (202), analogRead (203)) ;
+    printf ("| %4d | %4d | %4d | %4d |\n", analogRead (400), analogRead (401), analogRead (402), analogRead (403)) ;
+    delay (500) ;
+
+    if (++i == 10)
+      i = 0 ;
+
+  }
+
+}
diff --git a/examples/nes.c b/examples/nes.c
new file mode 100644
index 0000000..31908e8
--- /dev/null
+++ b/examples/nes.c
@@ -0,0 +1,67 @@
+/*
+ * nes.c:
+ *	Test program for an old NES controller connected to the Pi.
+ *
+ * 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 <errno.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <piNes.h>
+
+#define	BLANK	"|      "
+
+int main ()
+{
+  int joystick ;
+  unsigned int buttons ;
+
+  if (wiringPiSetup () == -1)
+  {
+    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
+    return 1 ;
+  }
+
+  if ((joystick = setupNesJoystick (2, 1, 0)) == -1)
+  {
+    fprintf (stdout, "Unable to setup joystick\n") ;
+    return 1 ;
+  }
+
+  for (;;)
+  {
+    buttons = readNesJoystick (joystick) ;
+
+    if ((buttons & NES_UP)     != 0) printf ("|  UP  " ) ; else printf (BLANK) ;
+    if ((buttons & NES_DOWN)   != 0) printf ("| DOWN " ) ; else printf (BLANK) ;
+    if ((buttons & NES_LEFT)   != 0) printf ("| LEFT " ) ; else printf (BLANK) ;
+    if ((buttons & NES_RIGHT)  != 0) printf ("|RIGHT " ) ; else printf (BLANK) ;
+    if ((buttons & NES_SELECT) != 0) printf ("|SELECT" ) ; else printf (BLANK) ;
+    if ((buttons & NES_START)  != 0) printf ("|START " ) ; else printf (BLANK) ;
+    if ((buttons & NES_A)      != 0) printf ("|  A   " ) ; else printf (BLANK) ;
+    if ((buttons & NES_B)      != 0) printf ("|  B   " ) ; else printf (BLANK) ;
+    printf ("|\n") ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/q2w/Makefile b/examples/q2w/Makefile
new file mode 100644
index 0000000..8f773bf
--- /dev/null
+++ b/examples/q2w/Makefile
@@ -0,0 +1,84 @@
+#
+# Makefile:
+#	wiringPi - A "wiring" library for the Raspberry Pi
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012-2013 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	A "wiring" 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/>.
+#################################################################################
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#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
+	$Q echo [link]
+	$Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
+
+blink-io:	blink-io.o
+	$Q echo [link]
+	$Q $(CC) -o $@ blink-io.o $(LDFLAGS) $(LDLIBS)
+
+button:	button.o
+	$Q echo [link]
+	$Q $(CC) -o $@ button.o $(LDFLAGS) $(LDLIBS)
+
+volts:	volts.o
+	$Q echo [link]
+	$Q $(CC) -o $@ volts.o $(LDFLAGS) $(LDLIBS)
+
+bright:	bright.o
+	$Q echo [link]
+	$Q $(CC) -o $@ bright.o $(LDFLAGS) $(LDLIBS)
+
+
+.c.o:
+	$Q echo [CC] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	$Q echo "[Clean]"
+	$Q rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/q2w/binary.c b/examples/q2w/binary.c
new file mode 100644
index 0000000..3c987c6
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/q2w/blink-io.c b/examples/q2w/blink-io.c
new file mode 100644
index 0000000..4dd4276
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/q2w/blink.c b/examples/q2w/blink.c
new file mode 100644
index 0000000..62b694a
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/q2w/blink.sh b/examples/q2w/blink.sh
new file mode 100644
index 0000000..bb6107a
--- /dev/null
+++ b/examples/q2w/blink.sh
@@ -0,0 +1,37 @@
+#!/bin/sh -e
+#
+# 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
diff --git a/examples/q2w/bright.c b/examples/q2w/bright.c
new file mode 100644
index 0000000..2318834
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/q2w/button.c b/examples/q2w/button.c
new file mode 100644
index 0000000..1781f02
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/q2w/volts.c b/examples/q2w/volts.c
new file mode 100644
index 0000000..e091093
--- /dev/null
+++ b/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 ;
+}
diff --git a/examples/rht03.c b/examples/rht03.c
new file mode 100644
index 0000000..854f837
--- /dev/null
+++ b/examples/rht03.c
@@ -0,0 +1,86 @@
+/*
+ * rht03.c:
+ *	Driver for the MaxDetect series sensors
+ *
+ * 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 <maxdetect.h>
+
+#define	RHT03_PIN	7
+
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  int result, temp, rh ;
+  int minT, maxT, minRH, maxRH ;
+
+  int numGood, numBad ;
+
+  wiringPiSetup () ;
+  piHiPri       (55) ;
+
+  minT =  1000 ;
+  maxT = -1000 ;
+
+  minRH =  1000 ;
+  maxRH = -1000 ;
+
+  numGood = numBad = 0 ;
+
+  for (;;)
+  {
+    delay (100) ;
+
+    result = readRHT03 (RHT03_PIN, &temp, &rh) ;
+
+    if (!result)
+    {
+      printf (".") ;
+      fflush (stdout) ;
+      ++numBad ;
+      continue ;
+    }
+
+    ++numGood ;
+
+    if (temp < minT) minT = temp ;
+    if (temp > maxT) maxT = temp ;
+    if (rh  < minRH) minRH = rh ;
+    if (rh  > maxRH) maxRH = rh ;
+
+    printf ("\r%6d, %6d: ", numGood, numBad) ;
+    printf ("Temp: %5.1f, RH: %5.1f%%", temp / 10.0, rh / 10.0) ;
+    printf ("  Max/Min Temp: %5.1f:%5.1f", maxT / 10.0, minT / 10.0) ;
+    printf ("  Max/Min RH: %5.1f:%5.1f", maxRH / 10.0, minRH / 10.0) ;
+
+    printf ("\n") ;
+  }
+
+  return 0 ;
+}
diff --git a/examples/scrollPhat/Makefile b/examples/scrollPhat/Makefile
new file mode 100644
index 0000000..2471f69
--- /dev/null
+++ b/examples/scrollPhat/Makefile
@@ -0,0 +1,79 @@
+#
+# Makefile:
+#	wiringPi - A "wiring" library for the Raspberry Pi
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012-2015 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	A "wiring" 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/>.
+#################################################################################
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#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
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC	=	scphat.c test.c
+
+OBJ	=	$(SRC:.c=.o)
+
+BINS	=	$(SRC:.c=)
+
+all:	$(BINS)
+
+test:	test.o
+	$Q echo [link]
+	$Q $(CC) -o $@ test.o $(LDFLAGS) $(LDLIBS)
+
+scphat:	scphat.o
+	$Q echo [link]
+	$Q $(CC) -o $@ scphat.o $(LDFLAGS) $(LDLIBS)
+
+
+.c.o:
+	$Q echo [CC] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+	$Q echo "[Clean]"
+	$Q rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+install:	scphat
+	$Q echo Installing scphat into /usr/local/bin
+	$Q cp -a scphat /usr/local/bin/scphat
+	$Q chmod 755 /usr/local/bin/scphat
+	$Q echo Done. Remember to load the I2C drivers if needed.
+
+depend:
+	makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/scrollPhat/scphat.c b/examples/scrollPhat/scphat.c
new file mode 100644
index 0000000..8f90bad
--- /dev/null
+++ b/examples/scrollPhat/scphat.c
@@ -0,0 +1,230 @@
+/*
+ * scphat.c:
+ *	Little program to allow use of the Pimoroni Sctoll Phat
+ *	from the command-line.
+ *
+ * Copyright (c) 2015-2016 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 <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <scrollPhat.h>
+
+static char *progName ;
+
+
+/*
+ * checkArgs:
+ *	Count the arguments for each little function
+ *********************************************************************************
+ */
+
+static void checkArgs (char *command, int num, int arg, int argc)
+{
+  if ((arg + num) < argc)
+    return ;
+
+  fprintf (stderr, "%s: Not enough data for %s command.\n", progName, command) ;
+  exit (EXIT_FAILURE) ;
+}
+
+
+/*
+ * doClear:
+ *	Clear the display
+ *********************************************************************************
+ */
+
+static int doClear (void)
+{
+  scrollPhatClear () ;
+  return 1 ;
+}
+
+
+/*
+ * doBright
+ *********************************************************************************
+ */
+
+static int doBright (int arg, int argc, char *argv [])
+{
+  checkArgs ("bright", 1, arg, argc) ;
+  scrollPhatIntensity (atoi (argv [arg+1])) ;
+  return 2 ;
+}
+
+
+
+/*
+ * doPlot
+ *********************************************************************************
+ */
+
+static int doPlot (int arg, int argc, char *argv [])
+{
+  checkArgs ("plot", 2, arg, argc) ;
+  scrollPhatPoint (atoi (argv [arg+1]), atoi (argv [arg+2]), 1) ;
+  scrollPhatUpdate () ;
+  return 3 ;
+}
+
+
+/*
+ * doLine
+ *********************************************************************************
+ */
+
+static int doLine (int arg, int argc, char *argv [])
+{
+  checkArgs ("line", 4, arg, argc) ;
+  scrollPhatLine (atoi (argv [arg+1]), atoi (argv [arg+2]),
+  			atoi (argv [arg+3]), atoi (argv [arg+4]), 1) ;
+  scrollPhatUpdate () ;
+  return 5 ;
+}
+
+
+/*
+ * doLineTo
+ *********************************************************************************
+ */
+
+static int doLineTo (int arg, int argc, char *argv [])
+{
+  checkArgs ("lineto", 2, arg, argc) ;
+  scrollPhatLineTo (atoi (argv [arg+1]), atoi (argv [arg+2]), 1) ;
+  scrollPhatUpdate () ;
+  return 3 ;
+}
+
+
+/*
+ * doWait
+ *********************************************************************************
+ */
+
+static int doWait (int arg, int argc, char *argv [])
+{
+  checkArgs ("wait", 1, arg, argc) ;
+  delay (atoi (argv [arg+1]) * 100) ;
+  scrollPhatUpdate () ;
+  return 2 ;
+}
+
+
+/*
+ * doSpeed
+ *********************************************************************************
+ */
+
+static int doSpeed (int arg, int argc, char *argv [])
+{
+  checkArgs ("speed", 1, arg, argc) ;
+  scrollPhatPrintSpeed (atoi (argv [arg+1])) ;
+  return 2 ;
+}
+
+
+/*
+ * doScroll
+ *********************************************************************************
+ */
+
+static int doScroll (int arg, int argc, char *argv [])
+{
+  checkArgs ("scroll", 1, arg, argc) ;
+  scrollPhatPuts (argv [arg+1]) ;
+  return 2 ;
+}
+
+
+static void failUsage (void)
+{
+  fprintf (stderr, "Usage: %s command [paremters] ...\n", progName) ;
+  fprintf (stderr, "  commands:\n") ;
+  fprintf (stderr, "    clear/cls        - Clear the display\n") ;
+  fprintf (stderr, "    bright N         - Set display brightness; 1-100\n") ;
+  fprintf (stderr, "    plot X Y         - Set a single pixel at location X Y; 0-10, 0-4\n") ;
+  fprintf (stderr, "    line X1 Y1 X2 Y2 - Draw a line from the 2 points\n") ;
+  fprintf (stderr, "    lineto X2 Y2     - Draw a line from the last point to the new one\n") ;
+  fprintf (stderr, "    wait/delay N     - Wait for N 10ths seconds\n") ;
+  fprintf (stderr, "    speed N          - Set scrolling speed (cps)\n") ;
+  fprintf (stderr, "    scroll S         - Scroll the given string\n") ;
+  fprintf (stderr, "\n") ;
+  fprintf (stderr, "  Example: %s plot 0 0 wait 50 scroll \"  Hello  \"\n", progName) ;
+  exit (EXIT_FAILURE) ;
+}
+
+
+/*
+ * the works
+ *********************************************************************************
+ */
+
+int main (int argc, char *argv [])
+{
+  int arg = 1 ;
+  char *command ;
+
+  progName = argv [0] ;
+
+  wiringPiSetupSys () ;
+
+  if (scrollPhatSetup () != 0)
+  {
+    fprintf (stderr, "%s: Unable to initialise the scrollPhat: %s\n", progName, strerror (errno)) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  progName = argv [0] ;
+
+  if (argc < 2)
+  {
+    fprintf (stderr, "%s: Nothing to do...\n", argv [0]) ;
+    failUsage () ;
+  }
+
+  while (arg != argc)
+  {
+    command = argv [arg] ;
+    /**/ if (strcasecmp (command, "clear")  == 0) arg += doClear  () ;
+    else if (strcasecmp (command, "cls")    == 0) arg += doClear  () ;
+    else if (strcasecmp (command, "bright") == 0) arg += doBright (arg, argc, argv) ;
+    else if (strcasecmp (command, "plot")   == 0) arg += doPlot   (arg, argc, argv) ;
+    else if (strcasecmp (command, "line")   == 0) arg += doLine   (arg, argc, argv) ;
+    else if (strcasecmp (command, "lineto") == 0) arg += doLineTo (arg, argc, argv) ;
+    else if (strcasecmp (command, "wait")   == 0) arg += doWait   (arg, argc, argv) ;
+    else if (strcasecmp (command, "delay")  == 0) arg += doWait   (arg, argc, argv) ;
+    else if (strcasecmp (command, "speed")  == 0) arg += doSpeed  (arg, argc, argv) ;
+    else if (strcasecmp (command, "scroll") == 0) arg += doScroll (arg, argc, argv) ;
+    else
+    {
+      fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [arg]) ;
+      failUsage () ;
+    }
+  }
+
+  return 0 ;
+}
diff --git a/examples/scrollPhat/test.c b/examples/scrollPhat/test.c
new file mode 100644
index 0000000..e4d8021
--- /dev/null
+++ b/examples/scrollPhat/test.c
@@ -0,0 +1,115 @@
+/*
+ * test.c:
+ *	Little test program forthe Pimoroni Scroll Phat.
+ *
+ * Copyright (c) 2015-2016 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 <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <scrollPhat.h>
+
+
+/*
+ * prompt:
+ *	Simple prompt & wait
+ *********************************************************************************
+ */
+
+static void prompt (const char *p)
+{
+  printf ("    %s. Press ENTER: ", p) ;
+  (void)getchar () ;
+}
+
+
+/*
+ * the works
+ *********************************************************************************
+ */
+
+int main (void)
+{
+  int x, y ;
+
+  printf ("\n") ;
+  printf ("Scroll Phat Test program\n") ;
+  printf ("========================\n") ;
+
+  if (scrollPhatSetup () != 0)
+  {
+    printf ("Unable to initialise the scrollPhat: %s\n", strerror (errno)) ;
+    exit (1) ;
+  }
+
+  printf ("-> Scroll Phat initialised OK\n") ;
+  printf ("... Basic display tests.\n\n") ;
+
+  prompt ("Display ought to be blank") ;
+
+// Light all pixels using one point at a time
+
+  for (y = 0 ; y < 5 ; ++y)
+    for (x = 0 ; x < 12 ; ++x)
+      scrollPhatPoint (x, y, 1) ;
+  scrollPhatUpdate () ;
+
+  prompt ("Display ought to be all lit-up") ;
+
+// Big rectangle
+  
+  scrollPhatClear () ;
+  scrollPhatRectangle (0,0, 10, 4, 1, 0) ;
+  scrollPhatUpdate () ;
+
+  prompt ("There should now be a rectangle round the outside") ;
+
+  scrollPhatLine (0,0, 10,4, 1) ;
+  scrollPhatLine (0,4, 10,0, 1) ;
+  scrollPhatUpdate () ;
+
+  prompt ("Diagonal lines") ;
+
+  scrollPhatIntensity (1) ;
+
+  prompt ("Minimum brightness") ;
+  
+  scrollPhatIntensity (100) ;
+
+  prompt ("Maximum brightness") ;
+  
+  scrollPhatIntensity (10) ;
+
+  prompt ("Default brightness") ;
+  
+  scrollPhatClear () ;
+  
+  printf ("    Message Test...Press Ctrl-C to exit: ") ;
+  fflush (stdout) ;
+
+  scrollPhatPrintSpeed (75) ;
+  for (;;)
+    scrollPhatPuts ("  Welcome to the scroll phat from Pimoroni  ") ;
+  
+  return 0 ;
+}
diff --git a/gpio/readall.c b/gpio/readall.c
index 1279f01..462a22f 100644
--- a/gpio/readall.c
+++ b/gpio/readall.c
@@ -43,6 +43,28 @@
 #endif
 
 /*----------------------------------------------------------------------------*/
+/*
+ * doReadallExternal:
+ *	A relatively crude way to read the pins on an external device.
+ *	We don't know the input/output mode of pins, but we can tell
+ *	if it's an analog pin or a digital one...
+ */
+/*----------------------------------------------------------------------------*/
+static void doReadallExternal (void)
+{
+	int pin ;
+
+	printf ("+------+---------+--------+\n") ;
+	printf ("|  Pin | Digital | Analog |\n") ;
+	printf ("+------+---------+--------+\n") ;
+
+	for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin)
+		printf ("| %4d |  %4d   |  %4d  |\n", pin, digitalRead (pin), analogRead (pin)) ;
+
+	printf ("+------+---------+--------+\n") ;
+}
+
+/*----------------------------------------------------------------------------*/
 static const char *alts [] =
 {
 	"IN", "OUT", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "ALT7"
@@ -694,6 +716,12 @@
 	int model, rev, mem, maker, overVolted, isAll;
 	char *headerName, *physNames;
 
+	// External readall
+	if (wiringPiNodes != NULL) {
+		doReadallExternal();
+		return;
+	}
+
 	if (argc <= 2) {
 		isAll = FALSE;
 	} else if (argc == 3 && (strcasecmp(argv[2], "-a") == 0 || strcasecmp(argv[2], "--all") == 0)) {
diff --git a/wiringPi/Makefile b/wiringPi/Makefile
index dae51cf..2598a4c 100644
--- a/wiringPi/Makefile
+++ b/wiringPi/Makefile
@@ -41,7 +41,7 @@
 CC	= gcc
 INCLUDE	= -I.
 DEFS	= -D_GNU_SOURCE
-CFLAGS	= $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC
+CFLAGS	= $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline -Wno-format-truncation $(INCLUDE) -pipe -fPIC
 
 LIBS    = -lm -lpthread -lrt -lcrypt
 
@@ -52,6 +52,17 @@
 		wiringPiSPI.c wiringPiI2C.c				\
 		piHiPri.c piThread.c					\
 		softPwm.c softTone.c softServo.c			\
+		mcp23008.c mcp23016.c mcp23017.c			\
+		mcp23s08.c mcp23s17.c					\
+		sr595.c							\
+		pcf8574.c pcf8591.c					\
+		mcp3002.c mcp3004.c mcp4802.c mcp3422.c			\
+		max31855.c max5322.c ads1115.c				\
+		sn3218.c						\
+		bmp180.c htu21d.c ds18b20.c rht03.c			\
+		drcSerial.c drcNet.c					\
+		pseudoPins.c						\
+		wpiExtensions.c					\
 		odroidc1.c						\
 		odroidc2.c						\
 		odroidxu3.c						\
@@ -137,6 +148,32 @@
 softPwm.o: wiringPi.h softPwm.h
 softTone.o: wiringPi.h softTone.h
 softServo.o: wiringPi.h softServo.h
+mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.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
+mcp3004.o: wiringPi.h wiringPiSPI.h mcp3004.h
+mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
+mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h
+max31855.o: wiringPi.h wiringPiSPI.h max31855.h
+max5322.o: wiringPi.h wiringPiSPI.h max5322.h
+ads1115.o: wiringPi.h wiringPiI2C.h ads1115.h
+sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h
+bmp180.o: wiringPi.h wiringPiI2C.h bmp180.h
+htu21d.o: wiringPi.h wiringPiI2C.h htu21d.h
+ds18b20.o: wiringPi.h ds18b20.h
+drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h
+pseudoPins.o: wiringPi.h pseudoPins.h
+wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h
+wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h
+wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h ads1115.h sn3218.h
+wpiExtensions.o: drcSerial.h pseudoPins.h bmp180.h htu21d.h ds18b20.h
+wpiExtensions.o: wpiExtensions.h
 
 # ODROID Boards
 odroidc1.o  : wiringPi.h odroidc1.h
diff --git a/wiringPi/ads1115.c b/wiringPi/ads1115.c
new file mode 100644
index 0000000..648e612
--- /dev/null
+++ b/wiringPi/ads1115.c
@@ -0,0 +1,293 @@
+/*
+ * ads1115.c:
+ *	Extend wiringPi with the ADS1115 I2C 16-bit ADC
+ *	Copyright (c) 2016 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/>.
+ ***********************************************************************
+ */
+
+/*
+ *********************************************************************************
+ * We're going to work in a hybrid mode to fit in with the wiringPi way of
+ * doing things, so there will be 4 analog pin which read the 4 single-ended
+ * channels as usual, also some fake digitalOutputs - these are the control
+ * registers that allow the user to put it into single/diff mode, set the
+ * gain and data rates.
+ *********************************************************************************
+ */
+
+#include <byteswap.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <wiringPi.h>
+#include <wiringPiI2C.h>
+
+#include "ads1115.h"
+
+// Bits in the config register (it's a 16-bit register)
+
+#define	CONFIG_OS_MASK		(0x8000)	// Operational Status Register
+#define	CONFIG_OS_SINGLE	(0x8000)	// Write - Starts a single-conversion
+						// Read    1 = Conversion complete
+
+// The multiplexor
+
+#define	CONFIG_MUX_MASK		(0x7000)
+
+// Differential modes
+
+#define	CONFIG_MUX_DIFF_0_1	(0x0000)	// Pos = AIN0, Neg = AIN1 (default)
+#define	CONFIG_MUX_DIFF_0_3	(0x1000)	// Pos = AIN0, Neg = AIN3
+#define	CONFIG_MUX_DIFF_1_3	(0x2000)	// Pos = AIN1, Neg = AIN3
+#define	CONFIG_MUX_DIFF_2_3	(0x3000)	// Pos = AIN2, Neg = AIN3 (2nd differential channel)
+
+// Single-ended modes
+
+#define	CONFIG_MUX_SINGLE_0	(0x4000)	// AIN0
+#define	CONFIG_MUX_SINGLE_1	(0x5000)	// AIN1
+#define	CONFIG_MUX_SINGLE_2	(0x6000)	// AIN2
+#define	CONFIG_MUX_SINGLE_3	(0x7000)	// AIN3
+
+// Programmable Gain Amplifier
+
+#define	CONFIG_PGA_MASK		(0x0E00)
+#define	CONFIG_PGA_6_144V	(0x0000)	// +/-6.144V range = Gain 2/3
+#define	CONFIG_PGA_4_096V	(0x0200)	// +/-4.096V range = Gain 1
+#define	CONFIG_PGA_2_048V	(0x0400)	// +/-2.048V range = Gain 2 (default)
+#define	CONFIG_PGA_1_024V	(0x0600)	// +/-1.024V range = Gain 4
+#define	CONFIG_PGA_0_512V	(0x0800)	// +/-0.512V range = Gain 8
+#define	CONFIG_PGA_0_256V	(0x0A00)	// +/-0.256V range = Gain 16
+
+#define	CONFIG_MODE		(0x0100)	// 0 is continuous, 1 is single-shot (default)
+
+// Data Rate
+
+#define	CONFIG_DR_MASK		(0x00E0)
+#define	CONFIG_DR_8SPS		(0x0000)	//   8 samples per second
+#define	CONFIG_DR_16SPS		(0x0020)	//  16 samples per second
+#define	CONFIG_DR_32SPS		(0x0040)	//  32 samples per second
+#define	CONFIG_DR_64SPS		(0x0060)	//  64 samples per second
+#define	CONFIG_DR_128SPS	(0x0080)	// 128 samples per second (default)
+#define	CONFIG_DR_475SPS	(0x00A0)	// 475 samples per second
+#define	CONFIG_DR_860SPS	(0x00C0)	// 860 samples per second
+
+// Comparator mode
+
+#define	CONFIG_CMODE_MASK	(0x0010)
+#define	CONFIG_CMODE_TRAD	(0x0000)	// Traditional comparator with hysteresis (default)
+#define	CONFIG_CMODE_WINDOW	(0x0010)	// Window comparator
+
+// Comparator polarity - the polarity of the output alert/rdy pin
+
+#define	CONFIG_CPOL_MASK	(0x0008)
+#define	CONFIG_CPOL_ACTVLOW	(0x0000)	// Active low (default)
+#define	CONFIG_CPOL_ACTVHI	(0x0008)	// Active high
+
+// Latching comparator - does the alert/rdy pin latch
+
+#define	CONFIG_CLAT_MASK	(0x0004)
+#define	CONFIG_CLAT_NONLAT	(0x0000)	// Non-latching comparator (default)
+#define	CONFIG_CLAT_LATCH	(0x0004)	// Latching comparator
+
+// Comparitor queue
+
+#define	CONFIG_CQUE_MASK	(0x0003)
+#define	CONFIG_CQUE_1CONV	(0x0000)	// Assert after one conversions
+#define	CONFIG_CQUE_2CONV	(0x0001)	// Assert after two conversions
+#define	CONFIG_CQUE_4CONV	(0x0002)	// Assert after four conversions
+#define	CONFIG_CQUE_NONE	(0x0003)	// Disable the comparator (default)
+
+#define	CONFIG_DEFAULT		(0x8583)	// From the datasheet
+
+
+static const uint16_t dataRates [8] =
+{
+  CONFIG_DR_8SPS, CONFIG_DR_16SPS, CONFIG_DR_32SPS, CONFIG_DR_64SPS, CONFIG_DR_128SPS, CONFIG_DR_475SPS, CONFIG_DR_860SPS
+} ;
+
+static const uint16_t gains [6] =
+{
+  CONFIG_PGA_6_144V, CONFIG_PGA_4_096V, CONFIG_PGA_2_048V, CONFIG_PGA_1_024V, CONFIG_PGA_0_512V, CONFIG_PGA_0_256V
+} ;
+
+
+/*
+ * analogRead:
+ *	Pin is the channel to sample on the device.
+ *	Channels 0-3 are single ended inputs,
+ *	channels 4-7 are the various differential combinations.
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int chan = pin - node->pinBase ;
+  int16_t  result ;
+  uint16_t config = CONFIG_DEFAULT ;
+
+  chan &= 7 ;
+
+// Setup the configuration register
+
+//	Set PGA/voltage range
+
+  config &= ~CONFIG_PGA_MASK ;
+  config |= node->data0 ;
+
+//	Set sample speed
+
+  config &= ~CONFIG_DR_MASK ;
+  config |= node->data1 ;
+
+//	Set single-ended channel or differential mode
+
+  config &= ~CONFIG_MUX_MASK ;
+
+  switch (chan)
+  {
+    case 0: config |= CONFIG_MUX_SINGLE_0 ; break ;
+    case 1: config |= CONFIG_MUX_SINGLE_1 ; break ;
+    case 2: config |= CONFIG_MUX_SINGLE_2 ; break ;
+    case 3: config |= CONFIG_MUX_SINGLE_3 ; break ;
+
+    case 4: config |= CONFIG_MUX_DIFF_0_1 ; break ;
+    case 5: config |= CONFIG_MUX_DIFF_2_3 ; break ;
+    case 6: config |= CONFIG_MUX_DIFF_0_3 ; break ;
+    case 7: config |= CONFIG_MUX_DIFF_1_3 ; break ;
+  }
+
+//	Start a single conversion
+
+  config |= CONFIG_OS_SINGLE ;
+  config = __bswap_16 (config) ;
+  wiringPiI2CWriteReg16 (node->fd, 1, config) ;
+
+// Wait for the conversion to complete
+
+  for (;;)
+  {
+    result =  wiringPiI2CReadReg16 (node->fd, 1) ;
+    result = __bswap_16 (result) ;
+    if ((result & CONFIG_OS_MASK) != 0)
+      break ;
+    delayMicroseconds (100) ;
+  }
+
+  result =  wiringPiI2CReadReg16 (node->fd, 0) ;
+  result = __bswap_16 (result) ;
+
+// Sometimes with a 0v input on a single-ended channel the internal 0v reference
+//	can be higher than the input, so you get a negative result...
+
+  if ( (chan < 4) && (result < 0) ) 
+    return 0 ;
+  else
+    return (int)result ;
+}
+
+
+/*
+ * digitalWrite:
+ *	It may seem odd to have a digital write here, but it's the best way
+ *	to pass paramters into the chip in the wiringPi way of things.
+ *	We have 2 digital registers:
+ *		0 is the gain control
+ *		1 is the data rate control
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data)
+{
+  int chan = pin - node->pinBase ;
+  chan &= 3 ;
+
+  if (chan == 0)	// Gain Control
+  {
+    if ( (data < 0) || (data > 6) )	// Use default if out of range
+      data = 2 ;
+    node->data0 = gains [data] ;
+  }
+  else			// Data rate control
+  {
+    if ( (data < 0) || (data > 7) )	// Use default if out of range
+      data = 4 ;
+    node->data1 = dataRates [data] ;	// Bugfix 0-1 by "Eric de jong (gm)" <ericdejong@gmx.net> - Thanks.
+  }
+  
+}
+
+
+/*
+ * analogWrite:
+ *	We're using this to write to the 2 comparitor threshold registers.
+ *	We could use a digitalWrite here but as it's an analog comparison
+ *	then it feels better to do it this way.
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int data)
+{
+  int chan = pin - node->pinBase ;
+  int reg ;
+  int16_t ndata ;
+
+  chan &= 3 ;
+
+  reg = chan + 2 ;
+
+  /**/ if (data < -32767)
+    ndata = -32767 ;
+  else if (data > 32767)
+    ndata = 32767 ;
+  else
+    ndata = (int16_t)data ;
+
+  ndata = __bswap_16 (ndata) ;
+  wiringPiI2CWriteReg16 (node->fd, reg, data) ;
+}
+
+
+
+/*
+ * ads1115Setup:
+ *	Create a new wiringPi device node for an ads1115 on the Pi's
+ *	I2C interface.
+ *********************************************************************************
+ */
+
+int ads1115Setup (const int pinBase, int i2cAddr)
+{
+  struct wiringPiNodeStruct *node ;
+  int fd ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddr)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->fd           = fd ;
+  node->data0        = CONFIG_PGA_4_096V ;	// Gain in data0
+  node->data1        = CONFIG_DR_128SPS ;	// Samples/sec in data1
+  node->analogRead   = myAnalogRead ;
+  node->analogWrite  = myAnalogWrite ;
+  node->digitalWrite = myDigitalWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/ads1115.h b/wiringPi/ads1115.h
new file mode 100644
index 0000000..5c91735
--- /dev/null
+++ b/wiringPi/ads1115.h
@@ -0,0 +1,55 @@
+/*
+ * ads1115.c:
+ *	Extend wiringPi with the ADS1115 I2C 16-bit ADC
+ *	Copyright (c) 2016 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/>.
+ ***********************************************************************
+ */
+
+// Constants for some of the internal functions
+
+//	Gain
+
+#define	ADS1115_GAIN_6		0
+#define	ADS1115_GAIN_4		1
+#define	ADS1115_GAIN_2		2
+#define	ADS1115_GAIN_1		3
+#define	ADS1115_GAIN_HALF	4
+#define	ADS1115_GAIN_QUARTER	5
+
+//	Data rate
+
+#define	ADS1115_DR_8		0
+#define	ADS1115_DR_16		1
+#define	ADS1115_DR_32		2
+#define	ADS1115_DR_64		3
+#define	ADS1115_DR_128		4
+#define	ADS1115_DR_250		5
+#define	ADS1115_DR_475		6
+#define	ADS1115_DR_860		7
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ads1115Setup (int pinBase, int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/bmp180.c b/wiringPi/bmp180.c
new file mode 100644
index 0000000..bad4bb3
--- /dev/null
+++ b/wiringPi/bmp180.c
@@ -0,0 +1,237 @@
+/*
+ * bmp180.c:
+ *	Extend wiringPi with the BMP180 I2C Pressure and Temperature
+ *	sensor. This is used in the Pi Weather Station
+ *	Copyright (c) 2016 Gordon Henderson
+ *
+ *	Information from the document held at:
+ *		http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf
+ *	was very useful when building this code.
+ *
+ ***********************************************************************
+ * 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 <stdint.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "wiringPi.h"
+#include "wiringPiI2C.h"
+
+#include "bmp180.h"
+
+#undef	DEBUG
+
+#define	I2C_ADDRESS	0x77
+#define	BMP180_OSS	   0
+
+
+// Static calibration data
+//	The down-side of this is that there can only be one BMP180 in
+//	a system - which is practice isn't an issue as it's I2C
+//	address is fixed.
+
+static  int16_t AC1, AC2, AC3 ;
+static uint16_t AC4, AC5, AC6 ;
+static  int16_t VB1, VB2 ;
+static  int16_t  MB,  MC, MD ;
+
+static double c5, c6, mc, md, x0, x1, x2, yy0, yy1, yy2, p0, p1, p2 ;
+
+// Pressure & Temp variables
+
+uint32_t cPress, cTemp ;
+
+static int altitude ;
+
+/*
+ * read16:
+ *	Quick hack to read the 16-bit data with the correct endian
+ *********************************************************************************
+ */
+
+uint16_t read16 (int fd, int reg)
+{
+  return (wiringPiI2CReadReg8 (fd, reg) <<  8) | wiringPiI2CReadReg8 (fd, reg + 1) ;
+
+}
+
+
+/*
+ * bmp180ReadTempPress:
+ *	Does the hard work of reading the sensor
+ *********************************************************************************
+ */
+
+static void bmp180ReadTempPress (int fd)
+{
+  double fTemp, fPress ;
+  double tu, a ;
+  double pu, s, x, y, z ;
+
+  uint8_t data [4] ;
+
+// Start a temperature sensor reading
+
+  wiringPiI2CWriteReg8 (fd, 0xF4, 0x2E) ;
+  delay (5) ;
+
+// Read the raw data
+
+  data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ;
+  data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ;
+
+// And calculate...
+
+  tu = (data [0] * 256.0) + data [1] ;
+
+  a = c5 * (tu - c6) ;
+  fTemp = a + (mc / (a + md)) ;
+  cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;
+
+#ifdef	DEBUG
+  printf ("fTemp: %f, cTemp: %6d\n", fTemp, cTemp) ;
+#endif
+
+// Start a pressure snsor reading
+
+  wiringPiI2CWriteReg8 (fd, 0xF4, 0x34 | (BMP180_OSS << 6)) ;
+  delay (5) ;
+
+// Read the raw data
+
+  data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ;
+  data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ;
+  data [2] = wiringPiI2CReadReg8 (fd, 0xF8) ;
+
+// And calculate...
+
+  pu = ((double)data [0] * 256.0) + (double)data [1] + ((double)data [2] / 256.0) ;
+  s = fTemp - 25.0 ;
+  x = (x2 * pow (s, 2.0)) + (x1 * s) + x0 ;
+  y = (yy2 * pow (s, 2.0)) + (yy1 * s) + yy0 ;
+  z = (pu - x) / y ;
+  fPress = (p2 * pow (z, 2.0)) + (p1 * z) + p0 ;
+  cPress = (int)rint (((100.0 * fPress) + 0.5) / 10.0) ;
+
+#ifdef	DEBUG
+  printf ("fPress: %f, cPress: %6d\n", fPress, cPress) ;
+#endif
+}
+
+
+/*
+ * myAnalogWrite:
+ *	Write to a fake register to represent the height above sea level
+ *	so that the peudo millibar register can read the pressure in mB
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int chan = pin - node->pinBase ;
+
+  if (chan == 0)
+    altitude = value ;
+}
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int chan = pin - node->pinBase ;
+
+  bmp180ReadTempPress (node->fd) ;
+
+  /**/ if (chan == 0)	// Read Temperature
+    return cTemp ;
+  else if (chan == 1)	// Pressure
+    return cPress ;
+  else if (chan == 2)	// Pressure in mB
+    return cPress / pow (1 - ((double)altitude / 44330.0), 5.255) ;
+  else
+    return -9999 ;
+
+}
+
+
+/*
+ * bmp180Setup:
+ *	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 bmp180Setup (const int pinBase)
+{
+  double c3, c4, b1 ;
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 4) ;
+
+  node->fd          = fd ;
+  node->analogRead  = myAnalogRead ;
+  node->analogWrite = myAnalogWrite ;
+
+// Read calibration data
+
+  AC1 = read16 (fd, 0xAA) ;
+  AC2 = read16 (fd, 0xAC) ;
+  AC3 = read16 (fd, 0xAE) ;
+  AC4 = read16 (fd, 0xB0) ;
+  AC5 = read16 (fd, 0xB2) ;
+  AC6 = read16 (fd, 0xB4) ;
+  VB1 = read16 (fd, 0xB6) ;
+  VB2 = read16 (fd, 0xB8) ;
+   MB = read16 (fd, 0xBA) ;
+   MC = read16 (fd, 0xBC) ;
+   MD = read16 (fd, 0xBE) ;
+
+// Calculate coefficients
+
+  c3 = 160.0 * pow (2.0, -15.0) * AC3 ;
+  c4 = pow (10.0, -3.0) * pow(2.0,-15.0) * AC4 ;
+  b1 = pow (160.0, 2.0) * pow(2.0,-30.0) * VB1 ;
+  c5 = (pow (2.0, -15.0) / 160.0) * AC5 ;
+  c6 = AC6 ;
+  mc = (pow (2.0, 11.0) / pow(160.0,2.0)) * MC ;
+  md = MD / 160.0 ;
+  x0 = AC1 ;
+  x1 = 160.0 * pow (2.0, -13.0) * AC2 ;
+  x2 = pow (160.0, 2.0) * pow(2.0,-25.0) * VB2 ;
+  yy0 = c4 * pow (2.0, 15.0) ;
+  yy1 = c4 * c3 ;
+  yy2 = c4 * b1 ;
+  p0 = (3791.0 - 8.0) / 1600.0 ;
+  p1 = 1.0 - 7357.0 * pow (2.0, -20.0) ;
+  p2 = 3038.0 * 100.0 * pow (2.0,  -36.0) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/bmp180.h b/wiringPi/bmp180.h
new file mode 100644
index 0000000..4a6d13a
--- /dev/null
+++ b/wiringPi/bmp180.h
@@ -0,0 +1,34 @@
+/*
+ * bmp180.h:
+ *	Extend wiringPi with the BMP180 I2C Pressure and Temperature
+ *	sensor.
+ *	Copyright (c) 2016 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 bmp180Setup (const int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/drcNet.c b/wiringPi/drcNet.c
new file mode 100644
index 0000000..7799e52
--- /dev/null
+++ b/wiringPi/drcNet.c
@@ -0,0 +1,405 @@
+/*
+ * drcNet.h:
+ *	Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
+ *	Copyright (c) 2016-2017 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 <stdint.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include <errno.h>
+#include <crypt.h>
+
+
+#include "wiringPi.h"
+#include "drcNet.h"
+#include "../wiringPiD/drcNetCmd.h"
+
+
+/*
+ * remoteReadline:
+ *	Read in a line of data from the remote server, ending with a newline
+ *	character which is not stored. Returns the length or < 0 on
+ *	any sort of failure.
+ *********************************************************************************
+ */
+
+static int remoteReadline (int fd, char *buf, int max)
+{
+  int  len = 0 ;
+  char c ;
+
+  for (;;)
+  {
+    if (read (fd, &c, 1) < 1)
+      return -1 ;
+
+    if (c == '\n')
+      return len ;
+
+    *buf++ = c ;
+    if (++len == max)
+      return len ;
+  }
+}
+
+
+/*
+ * getChallenge:
+ *	Read in lines from the remote site until we get one identified
+ *	as the challenge. This line contains the password salt.
+ *********************************************************************************
+ */
+
+static char *getChallenge (int fd)
+{
+  static char buf [1024] ;
+  int num ;
+
+  for (;;)
+  {
+    if ((num = remoteReadline (fd, buf, 1023)) < 0)
+      return NULL ;
+    buf [num] = 0 ;
+
+    if (strncmp (buf, "Challenge ", 10) == 0)
+      return &buf [10] ;
+  }
+}
+
+
+/*
+ * authenticate:
+ *	Read in the challenge from the server, use it to encrypt our password
+ *	and send it back to the server. Wait for a reply back from the server
+ *	to say that we're good to go.
+ *	The server will simply disconnect on a bad response. No 3 chances here.
+ *********************************************************************************
+ */
+
+static int authenticate (int fd, const char *pass)
+{
+  char *challenge ;
+  char *encrypted ;
+  char salted [1024] ;
+
+  if ((challenge = getChallenge (fd)) == NULL)
+    return -1 ;
+
+  snprintf (salted, 1024, "$6$%s$", challenge) ;
+  encrypted = crypt (pass, salted) ;
+
+// This is an assertion, or sanity check on my part...
+//	The '20' comes from the $6$ then the 16 characters of the salt,
+//	then the terminating $.
+
+  if (strncmp (encrypted, salted, 20) != 0)
+  {
+    errno = EBADE ;
+    return -1 ;
+  }
+
+// 86 characters is the length of the SHA-256 hash
+
+  if (write (fd, encrypted + 20, 86) == 86)
+    return 0 ;
+  else
+    return -1 ;
+}
+
+
+/*
+ * _drcSetupNet:
+ *	Do the hard work of establishing a network connection and authenticating
+ *	the password.
+ *********************************************************************************
+ */
+
+int _drcSetupNet (const char *ipAddress, const char *port, const char *password)
+{
+  struct addrinfo hints;
+  struct addrinfo *result, *rp ;
+  struct in6_addr serveraddr ;
+  int remoteFd ;
+
+// Start by seeing if we've been given a (textual) numeric IP address
+//	which will save lookups in getaddrinfo()
+
+  memset (&hints, 0, sizeof (hints)) ;
+  hints.ai_flags    = AI_NUMERICSERV ;
+  hints.ai_family   = AF_UNSPEC ;
+  hints.ai_socktype = SOCK_STREAM ;
+  hints.ai_protocol = 0 ;
+
+  if (inet_pton (AF_INET, ipAddress, &serveraddr) == 1)		// Valid IPv4
+  {
+    hints.ai_family = AF_INET ;
+    hints.ai_flags |= AI_NUMERICHOST ;
+  }
+  else
+  {
+    if (inet_pton (AF_INET6, ipAddress, &serveraddr) == 1)	// Valid IPv6
+    {
+      hints.ai_family = AF_INET6 ;
+      hints.ai_flags |= AI_NUMERICHOST ;
+    }
+  }
+
+// Now use getaddrinfo() with the newly supplied hints
+
+  if (getaddrinfo (ipAddress, port, &hints, &result) != 0)
+    return -1 ;
+
+// Now try each address in-turn until we get one that connects...
+
+  for (rp = result; rp != NULL; rp = rp->ai_next)
+  {
+    if ((remoteFd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
+      continue ;
+
+    if (connect (remoteFd, rp->ai_addr, rp->ai_addrlen) < 0)
+      continue ;
+
+    if (authenticate (remoteFd, password) < 0)
+    {
+      close (remoteFd) ;
+      errno = EACCES ;		// Permission denied
+      return -1 ;
+    }
+    else
+      return remoteFd ;
+  }
+
+  errno = EHOSTUNREACH ;	// Host unreachable - may not be right, but good enough
+  return -1 ; // Nothing connected
+}
+
+
+/*
+ * myPinMode:
+ *	Change the pin mode on the remote DRC device
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_PIN_MODE ;
+  cmd.data = mode ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_PULL_UP_DN ;
+  cmd.data = mode ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_DIGITAL_WRITE ;
+  cmd.data = value ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+
+
+/*
+ * myDigitalWrite8:
+ *********************************************************************************
+
+static void myDigitalWrite8 (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_DIGITAL_WRITE8 ;
+  cmd.data = value ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+ */
+
+
+/*
+ * myAnalogWrite:
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_ANALOG_WRITE ;
+  cmd.data = value ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+
+
+/*
+ * myPwmWrite:
+ *********************************************************************************
+ */
+
+static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_PWM_WRITE ;
+  cmd.data = value ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+}
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_ANALOG_READ ;
+  cmd.data = 0 ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+
+  return cmd.data ;
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_DIGITAL_READ ;
+  cmd.data = 0 ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+
+  return cmd.data ;
+}
+
+
+/*
+ * myDigitalRead8:
+ *********************************************************************************
+
+static unsigned int myDigitalRead8 (struct wiringPiNodeStruct *node, int pin)
+{
+  struct drcNetComStruct cmd ;
+
+  cmd.pin  = pin - node->pinBase ;
+  cmd.cmd  = DRCN_DIGITAL_READ8 ;
+  cmd.data = 0 ;
+
+  (void)send (node->fd, &cmd, sizeof (cmd), 0) ;
+  (void)recv (node->fd, &cmd, sizeof (cmd), 0) ;
+
+  return cmd.data ;
+}
+ */
+
+
+/*
+ * drcNet:
+ *	Create a new instance of an DRC GPIO interface.
+ *	Could be a variable nunber of pins here - we might not know in advance.
+ *********************************************************************************
+ */
+
+int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password)
+{
+  int fd, len ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = _drcSetupNet (ipAddress, port, password)) < 0)
+    return FALSE ;
+
+  len = sizeof (struct drcNetComStruct) ;
+
+  if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, numPins) ;
+
+  node->fd               = fd ;
+  node->pinMode          = myPinMode ;
+  node->pullUpDnControl  = myPullUpDnControl ;
+  node->analogRead       = myAnalogRead ;
+  node->analogRead       = myAnalogRead ;
+  node->analogWrite      = myAnalogWrite ;
+  node->digitalRead      = myDigitalRead ;
+  node->digitalWrite     = myDigitalWrite ;
+//node->digitalRead8     = myDigitalRead8 ;
+//node->digitalWrite8    = myDigitalWrite8 ;
+  node->pwmWrite         = myPwmWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/drcNet.h b/wiringPi/drcNet.h
new file mode 100644
index 0000000..00f9b05
--- /dev/null
+++ b/wiringPi/drcNet.h
@@ -0,0 +1,42 @@
+/*
+ * drcNet.h:
+ *	Extend wiringPi with the DRC Network protocol (e.g. to another Pi)
+ *	Copyright (c) 2016-2017 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/>.
+ ***********************************************************************
+ */
+
+/*********
+struct drcNetStruct
+{
+  uint32_t pin ;
+  uint32_t cmd ;
+  uint32_t data ;
+} ;
+**************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c
new file mode 100644
index 0000000..db7cc09
--- /dev/null
+++ b/wiringPi/drcSerial.c
@@ -0,0 +1,196 @@
+/*
+ * drcSerial.c:
+ *	Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
+ *	Copyright (c) 2013-2016 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 <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include "wiringPi.h"
+#include "wiringSerial.h"
+
+#include "drcSerial.h"
+
+
+/*
+ * myPinMode:
+ *	Change the pin mode on the remote DRC device
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  /**/ if (mode == OUTPUT)
+    serialPutchar (node->fd, 'o') ;       // Input
+  else if (mode == PWM_OUTPUT)
+    serialPutchar (node->fd, 'p') ;       // PWM
+  else
+    serialPutchar (node->fd, 'i') ;       // Default to input
+
+  serialPutchar (node->fd, pin - node->pinBase) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *	ATmegas only have pull-up's on of off. No pull-downs.
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+
+// Force pin into input mode
+
+  serialPutchar (node->fd, 'i' ) ;
+  serialPutchar (node->fd, pin - node->pinBase) ;
+
+  /**/ if (mode == PUD_UP)
+  {
+    serialPutchar (node->fd, '1') ;
+    serialPutchar (node->fd, pin - node->pinBase) ;
+  }
+  else if (mode == PUD_OFF)
+  {
+    serialPutchar (node->fd, '0') ;
+    serialPutchar (node->fd, pin - node->pinBase) ;
+  }
+}
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  serialPutchar (node->fd, value == 0 ? '0' : '1') ;
+  serialPutchar (node->fd, pin - node->pinBase) ;
+}
+
+
+/*
+ * myPwmWrite:
+ *********************************************************************************
+ */
+
+static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  serialPutchar (node->fd, 'v') ;
+  serialPutchar (node->fd, pin - node->pinBase) ;
+  serialPutchar (node->fd, value & 0xFF) ;
+}
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int vHi, vLo ;
+
+  serialPutchar (node->fd, 'a') ;
+  serialPutchar (node->fd, pin - node->pinBase) ;
+  vHi = serialGetchar (node->fd) ;
+  vLo = serialGetchar (node->fd) ;
+
+  return (vHi << 8) | vLo ;
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  serialPutchar (node->fd, 'r') ; // Send read command
+  serialPutchar (node->fd, pin - node->pinBase) ;
+  return (serialGetchar (node->fd) == '0') ? 0 : 1 ;
+}
+
+
+/*
+ * drcSetup:
+ *	Create a new instance of an DRC GPIO interface.
+ *	Could be a variable nunber of pins here - we might not know in advance
+ *	if it's an ATmega with 14 pins, or something with less or more!
+ *********************************************************************************
+ */
+
+int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud)
+{
+  int fd ;
+  int ok, tries ;
+  time_t then ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = serialOpen (device, baud)) < 0)
+    return FALSE ;
+
+  delay (10) ;	// May need longer if it's an Uno that reboots on the open...
+
+// Flush any pending input
+
+  while (serialDataAvail (fd))
+    (void)serialGetchar (fd) ;
+
+  ok = FALSE ;
+  for (tries = 1 ; (tries < 5) && (!ok) ; ++tries)
+  {
+    serialPutchar (fd, '@') ;		// Ping
+    then = time (NULL) + 2 ;
+    while (time (NULL) < then)
+      if (serialDataAvail (fd))
+      {
+        if (serialGetchar (fd) == '@')
+        {
+          ok = TRUE ;
+          break ;
+        }
+      }
+  }
+
+  if (!ok)
+  {
+    serialClose (fd) ;
+    return FALSE ;
+  }
+
+  node = wiringPiNewNode (pinBase, numPins) ;
+
+  node->fd              = fd ;
+  node->pinMode         = myPinMode ;
+  node->pullUpDnControl = myPullUpDnControl ;
+  node->analogRead      = myAnalogRead ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->pwmWrite        = myPwmWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/drcSerial.h b/wiringPi/drcSerial.h
new file mode 100644
index 0000000..29e988e
--- /dev/null
+++ b/wiringPi/drcSerial.h
@@ -0,0 +1,33 @@
+/*
+ * drcSerial.h:
+ *	Extend wiringPi with the DRC Serial protocol (e.g. to Arduino)
+ *	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 drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/ds18b20.c b/wiringPi/ds18b20.c
new file mode 100644
index 0000000..533398e
--- /dev/null
+++ b/wiringPi/ds18b20.c
@@ -0,0 +1,146 @@
+/*
+ * ds18b20.c:
+ *	Extend wiringPi with the DS18B20 1-Wire temperature sensor.
+ *	This is used in the Pi Weather Station and many other places.
+ *	Copyright (c) 2016 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <ctype.h>
+
+#include "wiringPi.h"
+
+#include "ds18b20.h"
+
+#define	W1_PREFIX	"/sys/bus/w1/devices/28-"
+#define	W1_POSTFIX	"/w1_slave"
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int  chan = pin - node->pinBase ;
+  int  fd = node->fd ;
+  char buffer [4096] ;
+  char *p ;
+  int  temp, sign ;
+
+  if (chan != 0)
+    return -9999 ;
+
+// Rewind the file - we're keeping it open to keep things going
+//	smoothly
+
+  lseek (fd, 0, SEEK_SET) ;
+
+// Read the file - we know it's only a couple of lines, so this ought to be
+//	more than enough
+
+  if (read (fd, buffer, 4096) <= 0)	// Read nothing, or it failed in some odd way
+    return -9998 ;
+
+// Look for YES, then t=
+
+  if (strstr (buffer, "YES") == NULL)
+    return -9997 ;
+
+  if ((p = strstr (buffer, "t=")) == NULL)
+    return -9996 ;
+
+// p points to the 't', so we skip over it...
+
+  p += 2 ;
+
+// and extract the number
+//	(without caring about overflow)
+
+
+  if (*p == '-')	// Negative number?
+  {
+    sign = -1 ;
+    ++p ;
+  }
+  else
+    sign = 1 ;
+
+  temp = 0 ;
+  while (isdigit (*p))
+  {
+    temp = temp * 10 + (*p - '0') ;
+    ++p ;
+  }
+
+// We know it returns temp * 1000, but we only really want temp * 10, so
+//	do a bit of rounding...
+
+  temp = (temp + 50) / 100 ;
+  return temp * sign ;
+}
+
+
+/*
+ * ds18b20Setup:
+ *	Create a new instance of a DS18B20 temperature sensor.
+ *********************************************************************************
+ */
+
+int ds18b20Setup (const int pinBase, const char *deviceId)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+  char *fileName ;
+
+// Allocate space for the filename
+
+  if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL)
+    return FALSE ;
+
+  sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ;
+
+  fd = open (fileName, O_RDONLY) ;
+
+  free (fileName) ;
+
+  if (fd < 0)
+    return FALSE ;
+
+// We'll keep the file open, to make access a little faster
+//	although it's very slow reading these things anyway )-:
+
+  node = wiringPiNewNode (pinBase, 1) ;
+
+  node->fd         = fd ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/ds18b20.h b/wiringPi/ds18b20.h
new file mode 100644
index 0000000..a9ea291
--- /dev/null
+++ b/wiringPi/ds18b20.h
@@ -0,0 +1,34 @@
+/*
+ * bmp180.h:
+ *	Extend wiringPi with the BMP180 I2C Pressure and Temperature
+ *	sensor.
+ *	Copyright (c) 2016 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 ds18b20Setup (const int pinBase, const char *serialNum) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/htu21d.c b/wiringPi/htu21d.c
new file mode 100644
index 0000000..46c0fcb
--- /dev/null
+++ b/wiringPi/htu21d.c
@@ -0,0 +1,150 @@
+/*
+ * htu21d.c:
+ *	Extend wiringPi with the HTU21D I2C humidity and Temperature
+ *	sensor. This is used in the Pi Weather station.
+ *	Copyright (c) 2016 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 <stdint.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "wiringPi.h"
+#include "wiringPiI2C.h"
+
+#include "htu21d.h"
+
+#define	DEBUG
+#undef	FAKE_SENSOR
+
+#define	I2C_ADDRESS	0x40
+
+int checksum (UNU uint8_t data [4])
+{
+  return TRUE ;
+}
+
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int chan = pin - node->pinBase ;
+  int fd   = node->fd ;
+  uint8_t data [4] ;
+  uint32_t sTemp, sHumid ;
+  double   fTemp, fHumid ;
+  int      cTemp, cHumid ;
+
+  /**/ if (chan == 0)	// Read Temperature
+  {
+
+// Send read temperature command:
+
+    data [0] = 0xF3 ;
+    if (write (fd, data, 1) != 1)
+      return -9999 ;
+
+// Wait then read the data
+
+    delay (50) ;
+    if (read (fd, data, 3) != 3)
+      return -9998 ;
+
+    if (!checksum (data))
+      return -9997 ;
+
+// Do the calculation
+
+    sTemp = (data [0] << 8) | data [1] ;
+    fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ;
+    cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ;
+    return cTemp ;
+  }
+  else if (chan == 1)	// humidity
+  {
+// Send read humidity command:
+
+    data [0] = 0xF5 ;
+    if (write (fd, data, 1) != 1)
+      return -9999 ;
+
+// Wait then read the data
+
+    delay (50) ;
+    if (read (fd, data, 3) != 3)
+      return -9998 ;
+
+    if (!checksum (data))
+      return -9997 ;
+
+    sHumid = (data [0] << 8) | data [1] ;
+    fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ;
+    cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ;
+    return cHumid ;
+  }
+  else
+    return -9999 ;
+}
+
+
+/*
+ * htu21dSetup:
+ *	Create a new instance of a HTU21D I2C GPIO interface.
+ *	This chip has a fixed I2C address, so we are not providing any
+ *	allowance to change this.
+ *********************************************************************************
+ */
+
+int htu21dSetup (const int pinBase)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+  uint8_t data ;
+  int status ;
+
+  if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd         = fd ;
+  node->analogRead = myAnalogRead ;
+
+// Send a reset code to it:
+
+  data = 0xFE ;
+  if (write (fd, &data, 1) != 1)
+    return FALSE ;
+
+  delay (15) ;
+
+// Read the status register to check it's really there
+
+  status = wiringPiI2CReadReg8 (fd, 0xE7) ;
+
+  return (status == 0x02) ? TRUE : FALSE ;
+}
diff --git a/wiringPi/htu21d.h b/wiringPi/htu21d.h
new file mode 100644
index 0000000..3965c54
--- /dev/null
+++ b/wiringPi/htu21d.h
@@ -0,0 +1,34 @@
+/*
+ * htu21d.h:
+ *	Extend wiringPi with the HTU21D I2C Humidity and Temperature
+ *	sensor.
+ *	Copyright (c) 2016 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 htu21dSetup (const int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/max31855.c b/wiringPi/max31855.c
new file mode 100644
index 0000000..d86cabd
--- /dev/null
+++ b/wiringPi/max31855.c
@@ -0,0 +1,99 @@
+/*
+ * max31855.c:
+ *	Extend wiringPi with the max31855 SPI Analog to Digital convertor
+ *	Copyright (c) 2012-2015 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 <byteswap.h>
+#include <stdint.h>
+
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "max31855.h"
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  uint32_t spiData ;
+  int temp ;
+  int chan = pin - node->pinBase ;
+
+  wiringPiSPIDataRW (node->fd, (unsigned char *)&spiData, 4) ;
+
+  spiData = __bswap_32(spiData) ;
+
+  switch (chan)
+  {
+    case 0:				// Existing read - return raw value * 4
+      spiData >>= 18 ;
+      temp = spiData & 0x1FFF ;		// Bottom 13 bits
+      if ((spiData & 0x2000) != 0)	// Negative
+        temp = -temp ;
+
+      return temp ;
+
+    case 1:				// Return error bits
+      return spiData & 0x7 ;
+
+    case 2:				// Return temp in C * 10
+      spiData >>= 18 ;
+      temp = spiData & 0x1FFF ;		// Bottom 13 bits
+      if ((spiData & 0x2000) != 0)	// Negative
+        temp = -temp ;
+
+      return (int)((((double)temp * 25) + 0.5) / 10.0) ;
+
+    case 3:				// Return temp in F * 10
+      spiData >>= 18 ;
+      temp = spiData & 0x1FFF ;		// Bottom 13 bits
+      if ((spiData & 0x2000) != 0)	// Negative
+        temp = -temp ;
+
+      return (int)((((((double)temp * 0.25 * 9.0 / 5.0) + 32.0) * 100.0) + 0.5) / 10.0) ;
+
+    default:				// Who knows...
+      return 0 ;
+
+  }
+}
+
+
+/*
+ * max31855Setup:
+ *	Create a new wiringPi device node for an max31855 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int max31855Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiChannel, 5000000) < 0)	// 5MHz - prob 4 on the Pi
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 4) ;
+
+  node->fd         = spiChannel ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/max31855.h b/wiringPi/max31855.h
new file mode 100644
index 0000000..385c4bd
--- /dev/null
+++ b/wiringPi/max31855.h
@@ -0,0 +1,33 @@
+/*
+ * max31855.c:
+ *	Extend wiringPi with the MAX31855 SPI Thermocouple driver
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int max31855Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/max5322.c b/wiringPi/max5322.c
new file mode 100644
index 0000000..e56b085
--- /dev/null
+++ b/wiringPi/max5322.c
@@ -0,0 +1,84 @@
+/*
+ * max5322.c:
+ *	Extend wiringPi with the MAX5322 SPI Digital to Analog convertor
+ *	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 <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "max5322.h"
+
+/*
+ * myAnalogWrite:
+ *	Write analog value on the given pin
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  unsigned char spiData [2] ;
+  unsigned char chanBits, dataBits ;
+  int chan = pin - node->pinBase ;
+
+  if (chan == 0)
+    chanBits = 0b01000000 ;
+  else
+    chanBits = 0b01010000 ;
+
+  chanBits |= ((value >> 12) & 0x0F) ;
+  dataBits  = ((value      ) & 0xFF) ;
+
+  spiData [0] = chanBits ;
+  spiData [1] = dataBits ;
+
+  wiringPiSPIDataRW (node->fd, spiData, 2) ;
+}
+
+/*
+ * max5322Setup:
+ *	Create a new wiringPi device node for an max5322 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int max5322Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+  unsigned char spiData [2] ;
+
+  if (wiringPiSPISetup (spiChannel, 8000000) < 0)	// 10MHz Max
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd          = spiChannel ;
+  node->analogWrite = myAnalogWrite ;
+
+// Enable both DACs
+
+  spiData [0] = 0b11100000 ;
+  spiData [1] = 0 ;
+  
+  wiringPiSPIDataRW (node->fd, spiData, 2) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/max5322.h b/wiringPi/max5322.h
new file mode 100644
index 0000000..a217cf8
--- /dev/null
+++ b/wiringPi/max5322.h
@@ -0,0 +1,33 @@
+/*
+ * max5322.h:
+ *	Extend wiringPi with the MAX5322 SPI Digital to Analog convertor
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int max5322Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c
new file mode 100644
index 0000000..71757a8
--- /dev/null
+++ b/wiringPi/mcp23008.c
@@ -0,0 +1,149 @@
+/*
+ * mcp23008.c:
+ *	Extend wiringPi with the MCP 23008 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 "mcp23x0817.h"
+
+#include "mcp23008.h"
+
+
+/*
+ * myPinMode:
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  reg  = MCP23x08_IODIR ;
+  mask = 1 << (pin - node->pinBase) ;
+  old  = wiringPiI2CReadReg8 (node->fd, reg) ;
+
+  if (mode == OUTPUT)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  wiringPiI2CWriteReg8 (node->fd, reg, old) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  reg  = MCP23x08_GPPU ;
+  mask = 1 << (pin - node->pinBase) ;
+
+  old  = wiringPiI2CReadReg8 (node->fd, reg) ;
+
+  if (mode == PUD_UP)
+    old |=   mask ;
+  else
+    old &= (~mask) ;
+
+  wiringPiI2CWriteReg8 (node->fd, reg, old) ;
+}
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int bit, old ;
+
+  bit  = 1 << ((pin - node->pinBase) & 7) ;
+
+  old = node->data2 ;
+  if (value == LOW)
+    old &= (~bit) ;
+  else
+    old |=   bit ;
+
+  wiringPiI2CWriteReg8 (node->fd, MCP23x08_GPIO, old) ;
+  node->data2 = old ;
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int mask, value ;
+
+  mask  = 1 << ((pin - node->pinBase) & 7) ;
+  value = wiringPiI2CReadReg8 (node->fd, MCP23x08_GPIO) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * mcp23008Setup:
+ *	Create a new instance of an MCP23008 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.
+ *********************************************************************************
+ */
+
+int mcp23008Setup (const int pinBase, const int i2cAddress)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return FALSE ;
+
+  wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->fd              = fd ;
+  node->pinMode         = myPinMode ;
+  node->pullUpDnControl = myPullUpDnControl ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp23008.h b/wiringPi/mcp23008.h
new file mode 100644
index 0000000..e9299a8
--- /dev/null
+++ b/wiringPi/mcp23008.h
@@ -0,0 +1,33 @@
+/*
+ * 23008.h:
+ *	Extend wiringPi with the MCP 23008 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 mcp23008Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23016.c b/wiringPi/mcp23016.c
new file mode 100644
index 0000000..928d9e5
--- /dev/null
+++ b/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 FALSE ;
+
+  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 TRUE ;
+}
diff --git a/wiringPi/mcp23016.h b/wiringPi/mcp23016.h
new file mode 100644
index 0000000..f9b5cc5
--- /dev/null
+++ b/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
diff --git a/wiringPi/mcp23016reg.h b/wiringPi/mcp23016reg.h
new file mode 100644
index 0000000..9aea92d
--- /dev/null
+++ b/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
diff --git a/wiringPi/mcp23017.c b/wiringPi/mcp23017.c
new file mode 100644
index 0000000..4c3952d
--- /dev/null
+++ b/wiringPi/mcp23017.c
@@ -0,0 +1,195 @@
+/*
+ * mcp23017.c:
+ *	Extend wiringPi with the MCP 23017 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 "mcp23x0817.h"
+
+#include "mcp23017.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  = MCP23x17_IODIRA ;
+  else
+  {
+    reg  = MCP23x17_IODIRB ;
+    pin &= 0x07 ;
+  }
+
+  mask = 1 << pin ;
+  old  = wiringPiI2CReadReg8 (node->fd, reg) ;
+
+  if (mode == OUTPUT)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  wiringPiI2CWriteReg8 (node->fd, reg, old) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  pin -= node->pinBase ;
+
+  if (pin < 8)		// Bank A
+    reg  = MCP23x17_GPPUA ;
+  else
+  {
+    reg  = MCP23x17_GPPUB ;
+    pin &= 0x07 ;
+  }
+
+  mask = 1 << pin ;
+  old  = wiringPiI2CReadReg8 (node->fd, reg) ;
+
+  if (mode == PUD_UP)
+    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, MCP23x17_GPIOA, old) ;
+    node->data2 = old ;
+  }
+  else				// Bank B
+  {
+    old = node->data3 ;
+
+    if (value == LOW)
+      old &= (~bit) ;
+    else
+      old |=   bit ;
+
+    wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, 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  = MCP23x17_GPIOA ;
+  else
+  {
+    gpio  = MCP23x17_GPIOB ;
+    pin  &= 0x07 ;
+  }
+
+  mask  = 1 << pin ;
+  value = wiringPiI2CReadReg8 (node->fd, gpio) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * mcp23017Setup:
+ *	Create a new instance of an MCP23017 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 mcp23017Setup (const int pinBase, const int i2cAddress)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return FALSE ;
+
+  wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
+
+  node = wiringPiNewNode (pinBase, 16) ;
+
+  node->fd              = fd ;
+  node->pinMode         = myPinMode ;
+  node->pullUpDnControl = myPullUpDnControl ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ;
+  node->data3           = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp23017.h b/wiringPi/mcp23017.h
new file mode 100644
index 0000000..79b4d7b
--- /dev/null
+++ b/wiringPi/mcp23017.h
@@ -0,0 +1,33 @@
+/*
+ * 23017.h:
+ *	Extend wiringPi with the MCP 23017 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 mcp23017Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23s08.c b/wiringPi/mcp23s08.c
new file mode 100644
index 0000000..f293f3a
--- /dev/null
+++ b/wiringPi/mcp23s08.c
@@ -0,0 +1,188 @@
+/*
+ * mcp23s08.c:
+ *	Extend wiringPi with the MCP 23s08 SPI 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 <stdint.h>
+
+#include "wiringPi.h"
+#include "wiringPiSPI.h"
+#include "mcp23x0817.h"
+
+#include "mcp23s08.h"
+
+#define	MCP_SPEED	4000000
+
+
+
+/*
+ * writeByte:
+ *	Write a byte to a register on the MCP23s08 on the SPI bus.
+ *********************************************************************************
+ */
+
+static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_WRITE | ((devId & 7) << 1) ;
+  spiData [1] = reg ;
+  spiData [2] = data ;
+
+  wiringPiSPIDataRW (spiPort, spiData, 3) ;
+}
+
+/*
+ * readByte:
+ *	Read a byte from a register on the MCP23s08 on the SPI bus.
+ *********************************************************************************
+ */
+
+static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_READ | ((devId & 7) << 1) ;
+  spiData [1] = reg ;
+
+  wiringPiSPIDataRW (spiPort, spiData, 3) ;
+
+  return spiData [2] ;
+}
+
+
+/*
+ * myPinMode:
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  reg  = MCP23x08_IODIR ;
+  mask = 1 << (pin - node->pinBase) ;
+  old  = readByte (node->data0, node->data1, reg) ;
+
+  if (mode == OUTPUT)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  writeByte (node->data0, node->data1, reg, old) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  reg  = MCP23x08_GPPU ;
+  mask = 1 << (pin - node->pinBase) ;
+
+  old  = readByte (node->data0, node->data1, reg) ;
+
+  if (mode == PUD_UP)
+    old |=   mask ;
+  else
+    old &= (~mask) ;
+
+  writeByte (node->data0, node->data1, reg, old) ;
+}
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int bit, old ;
+
+  bit  = 1 << ((pin - node->pinBase) & 7) ;
+
+  old = node->data2 ;
+  if (value == LOW)
+    old &= (~bit) ;
+  else
+    old |=   bit ;
+
+  writeByte (node->data0, node->data1, MCP23x08_GPIO, old) ;
+  node->data2 = old ;
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int mask, value ;
+
+  mask  = 1 << ((pin - node->pinBase) & 7) ;
+  value = readByte (node->data0, node->data1, MCP23x08_GPIO) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * mcp23s08Setup:
+ *	Create a new instance of an MCP23s08 SPI GPIO interface. We know it
+ *	has 8 pins, so all we need to know here is the SPI address and the
+ *	user-defined pin base.
+ *********************************************************************************
+ */
+
+int mcp23s08Setup (const int pinBase, const int spiPort, const int devId)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0)
+    return FALSE ;
+
+  writeByte (spiPort, devId, MCP23x08_IOCON, IOCON_INIT) ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->data0           = spiPort ;
+  node->data1           = devId ;
+  node->pinMode         = myPinMode ;
+  node->pullUpDnControl = myPullUpDnControl ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = readByte (spiPort, devId, MCP23x08_OLAT) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp23s08.h b/wiringPi/mcp23s08.h
new file mode 100644
index 0000000..ebf93d1
--- /dev/null
+++ b/wiringPi/mcp23s08.h
@@ -0,0 +1,33 @@
+/*
+ * 23s08.h:
+ *	Extend wiringPi with the MCP 23s08 SPI 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 mcp23s08Setup (const int pinBase, const int spiPort, const int devId) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23s17.c b/wiringPi/mcp23s17.c
new file mode 100644
index 0000000..42b0358
--- /dev/null
+++ b/wiringPi/mcp23s17.c
@@ -0,0 +1,235 @@
+/*
+ * mcp23s17.c:
+ *	Extend wiringPi with the MCP 23s17 SPI 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 <stdint.h>
+
+#include "wiringPi.h"
+#include "wiringPiSPI.h"
+#include "mcp23x0817.h"
+
+#include "mcp23s17.h"
+
+#define	MCP_SPEED	4000000
+
+
+
+/*
+ * writeByte:
+ *	Write a byte to a register on the MCP23s17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_WRITE | ((devId & 7) << 1) ;
+  spiData [1] = reg ;
+  spiData [2] = data ;
+
+  wiringPiSPIDataRW (spiPort, spiData, 3) ;
+}
+
+/*
+ * readByte:
+ *	Read a byte from a register on the MCP23s17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg)
+{
+  uint8_t spiData [4] ;
+
+  spiData [0] = CMD_READ | ((devId & 7) << 1) ;
+  spiData [1] = reg ;
+
+  wiringPiSPIDataRW (spiPort, spiData, 3) ;
+
+  return spiData [2] ;
+}
+
+
+/*
+ * myPinMode:
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  pin -= node->pinBase ;
+
+  if (pin < 8)		// Bank A
+    reg  = MCP23x17_IODIRA ;
+  else
+  {
+    reg  = MCP23x17_IODIRB ;
+    pin &= 0x07 ;
+  }
+
+  mask = 1 << pin ;
+  old  = readByte (node->data0, node->data1, reg) ;
+
+  if (mode == OUTPUT)
+    old &= (~mask) ;
+  else
+    old |=   mask ;
+
+  writeByte (node->data0, node->data1, reg, old) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ *********************************************************************************
+ */
+
+static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int mask, old, reg ;
+
+  pin -= node->pinBase ;
+
+  if (pin < 8)		// Bank A
+    reg  = MCP23x17_GPPUA ;
+  else
+  {
+    reg  = MCP23x17_GPPUB ;
+    pin &= 0x07 ;
+  }
+
+  mask = 1 << pin ;
+  old  = readByte (node->data0, node->data1, reg) ;
+
+  if (mode == PUD_UP)
+    old |=   mask ;
+  else
+    old &= (~mask) ;
+
+  writeByte (node->data0, node->data1, 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 ;
+
+    writeByte (node->data0, node->data1, MCP23x17_GPIOA, old) ;
+    node->data2 = old ;
+  }
+  else				// Bank B
+  {
+    old = node->data3 ;
+
+    if (value == LOW)
+      old &= (~bit) ;
+    else
+      old |=   bit ;
+
+    writeByte (node->data0, node->data1, MCP23x17_GPIOB, 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  = MCP23x17_GPIOA ;
+  else
+  {
+    gpio  = MCP23x17_GPIOB ;
+    pin  &= 0x07 ;
+  }
+
+  mask  = 1 << pin ;
+  value = readByte (node->data0, node->data1, gpio) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * mcp23s17Setup:
+ *	Create a new instance of an MCP23s17 SPI GPIO interface. We know it
+ *	has 16 pins, so all we need to know here is the SPI address and the
+ *	user-defined pin base.
+ *********************************************************************************
+ */
+
+int mcp23s17Setup (const int pinBase, const int spiPort, const int devId)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0)
+    return FALSE ;
+
+  writeByte (spiPort, devId, MCP23x17_IOCON,  IOCON_INIT | IOCON_HAEN) ;
+  writeByte (spiPort, devId, MCP23x17_IOCONB, IOCON_INIT | IOCON_HAEN) ;
+
+  node = wiringPiNewNode (pinBase, 16) ;
+
+  node->data0           = spiPort ;
+  node->data1           = devId ;
+  node->pinMode         = myPinMode ;
+  node->pullUpDnControl = myPullUpDnControl ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = readByte (spiPort, devId, MCP23x17_OLATA) ;
+  node->data3           = readByte (spiPort, devId, MCP23x17_OLATB) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp23s17.h b/wiringPi/mcp23s17.h
new file mode 100644
index 0000000..3b2a808
--- /dev/null
+++ b/wiringPi/mcp23s17.h
@@ -0,0 +1,33 @@
+/*
+ * 23s17.h:
+ *	Extend wiringPi with the MCP 23s17 SPI 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 mcp23s17Setup (int pinBase, int spiPort, int devId) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23x08.h b/wiringPi/mcp23x08.h
new file mode 100644
index 0000000..c4e6b27
--- /dev/null
+++ b/wiringPi/mcp23x08.h
@@ -0,0 +1,73 @@
+/*
+ * mcp23x17:
+ *	Copyright (c) 2012-2013 Gordon Henderson
+ *
+ *	Header file for code using the MCP23x17 GPIO expander chip.
+ *	This comes in 2 flavours: MCP23017 which has an I2C interface,
+ *	an the MXP23S17 which has an SPI interface.
+ ***********************************************************************
+ * 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/>.
+ ***********************************************************************
+ */
+
+
+// MCP23x17 Registers
+
+#define	IODIRA		0x00
+#define	IPOLA		0x02
+#define	GPINTENA	0x04
+#define	DEFVALA		0x06
+#define	INTCONA		0x08
+#define	IOCON		0x0A
+#define	GPPUA		0x0C
+#define	INTFA		0x0E
+#define	INTCAPA		0x10
+#define	GPIOA		0x12
+#define	OLATA		0x14
+
+#define	IODIRB		0x01
+#define	IPOLB		0x03
+#define	GPINTENB	0x05
+#define	DEFVALB		0x07
+#define	INTCONB		0x09
+#define	IOCONB		0x0B
+#define	GPPUB		0x0D
+#define	INTFB		0x0F
+#define	INTCAPB		0x11
+#define	GPIOB		0x13
+#define	OLATB		0x15
+
+// Bits in the IOCON register
+
+#define	IOCON_UNUSED	0x01
+#define	IOCON_INTPOL	0x02
+#define	IOCON_ODR	0x04
+#define	IOCON_HAEN	0x08
+#define	IOCON_DISSLW	0x10
+#define	IOCON_SEQOP	0x20
+#define	IOCON_MIRROR	0x40
+#define	IOCON_BANK_MODE	0x80
+
+// Default initialisation mode
+
+#define	IOCON_INIT	(IOCON_SEQOP)
+
+// SPI Command codes
+
+#define	CMD_WRITE	0x40
+#define CMD_READ	0x41
diff --git a/wiringPi/mcp23x0817.h b/wiringPi/mcp23x0817.h
new file mode 100644
index 0000000..58bc038
--- /dev/null
+++ b/wiringPi/mcp23x0817.h
@@ -0,0 +1,87 @@
+/*
+ * mcp23xxx:
+ *	Copyright (c) 2012-2013 Gordon Henderson
+ *
+ *	Header file for code using the MCP23x08 and 17 GPIO expander
+ *	chips.
+ *	This comes in 2 flavours: MCP230xx (08/17) which has an I2C
+ *	interface, and the MXP23Sxx (08/17) which has an SPI interface.
+ ***********************************************************************
+ * 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/>.
+ ***********************************************************************
+ */
+
+// MCP23x08 Registers
+	
+#define	MCP23x08_IODIR		0x00
+#define	MCP23x08_IPOL		0x01
+#define	MCP23x08_GPINTEN	0x02
+#define	MCP23x08_DEFVAL		0x03
+#define	MCP23x08_INTCON		0x04
+#define	MCP23x08_IOCON		0x05
+#define	MCP23x08_GPPU		0x06
+#define	MCP23x08_INTF		0x07
+#define	MCP23x08_INTCAP		0x08
+#define	MCP23x08_GPIO		0x09
+#define	MCP23x08_OLAT		0x0A
+
+// MCP23x17 Registers
+
+#define	MCP23x17_IODIRA		0x00
+#define	MCP23x17_IPOLA		0x02
+#define	MCP23x17_GPINTENA	0x04
+#define	MCP23x17_DEFVALA	0x06
+#define	MCP23x17_INTCONA	0x08
+#define	MCP23x17_IOCON		0x0A
+#define	MCP23x17_GPPUA		0x0C
+#define	MCP23x17_INTFA		0x0E
+#define	MCP23x17_INTCAPA	0x10
+#define	MCP23x17_GPIOA		0x12
+#define	MCP23x17_OLATA		0x14
+
+#define	MCP23x17_IODIRB		0x01
+#define	MCP23x17_IPOLB		0x03
+#define	MCP23x17_GPINTENB	0x05
+#define	MCP23x17_DEFVALB	0x07
+#define	MCP23x17_INTCONB	0x09
+#define	MCP23x17_IOCONB		0x0B
+#define	MCP23x17_GPPUB		0x0D
+#define	MCP23x17_INTFB		0x0F
+#define	MCP23x17_INTCAPB	0x11
+#define	MCP23x17_GPIOB		0x13
+#define	MCP23x17_OLATB		0x15
+
+// Bits in the IOCON register
+
+#define	IOCON_UNUSED	0x01
+#define	IOCON_INTPOL	0x02
+#define	IOCON_ODR	0x04
+#define	IOCON_HAEN	0x08
+#define	IOCON_DISSLW	0x10
+#define	IOCON_SEQOP	0x20
+#define	IOCON_MIRROR	0x40
+#define	IOCON_BANK_MODE	0x80
+
+// Default initialisation mode
+
+#define	IOCON_INIT	(IOCON_SEQOP)
+
+// SPI Command codes
+
+#define	CMD_WRITE	0x40
+#define CMD_READ	0x41
diff --git a/wiringPi/mcp3002.c b/wiringPi/mcp3002.c
new file mode 100644
index 0000000..9ebf3e4
--- /dev/null
+++ b/wiringPi/mcp3002.c
@@ -0,0 +1,76 @@
+/*
+ * mcp3002.c:
+ *	Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
+ *	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 <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "mcp3002.h"
+
+/*
+ * myAnalogRead:
+ *	Return the analog value of the given pin
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  unsigned char spiData [2] ;
+  unsigned char chanBits ;
+  int chan = pin - node->pinBase ;
+
+  if (chan == 0)
+    chanBits = 0b11010000 ;
+  else
+    chanBits = 0b11110000 ;
+
+  spiData [0] = chanBits ;
+  spiData [1] = 0 ;
+
+  wiringPiSPIDataRW (node->fd, spiData, 2) ;
+
+  return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
+}
+
+
+/*
+ * mcp3002Setup:
+ *	Create a new wiringPi device node for an mcp3002 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int mcp3002Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiChannel, 1000000) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd         = spiChannel ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp3002.h b/wiringPi/mcp3002.h
new file mode 100644
index 0000000..0cd727f
--- /dev/null
+++ b/wiringPi/mcp3002.h
@@ -0,0 +1,33 @@
+/*
+ * mcp3002.c:
+ *	Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp3002Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp3004.c b/wiringPi/mcp3004.c
new file mode 100644
index 0000000..be8383e
--- /dev/null
+++ b/wiringPi/mcp3004.c
@@ -0,0 +1,76 @@
+/*
+ * mcp3004.c:
+ *	Extend wiringPi with the MCP3004 SPI Analog to Digital convertor
+ *	Copyright (c) 2012-2013 Gordon Henderson
+ *
+ *	Thanks also to "ShorTie" on IRC for some remote debugging help!
+ ***********************************************************************
+ * 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 <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "mcp3004.h"
+
+/*
+ * myAnalogRead:
+ *	Return the analog value of the given pin
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  unsigned char spiData [3] ;
+  unsigned char chanBits ;
+  int chan = pin - node->pinBase ;
+
+  chanBits = 0b10000000 | (chan << 4) ;
+
+  spiData [0] = 1 ;		// Start bit
+  spiData [1] = chanBits ;
+  spiData [2] = 0 ;
+
+  wiringPiSPIDataRW (node->fd, spiData, 3) ;
+
+  return ((spiData [1] << 8) | spiData [2]) & 0x3FF ;
+}
+
+
+/*
+ * mcp3004Setup:
+ *	Create a new wiringPi device node for an mcp3004 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int mcp3004Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiChannel, 1000000) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->fd         = spiChannel ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp3004.h b/wiringPi/mcp3004.h
new file mode 100644
index 0000000..a07c0bf
--- /dev/null
+++ b/wiringPi/mcp3004.h
@@ -0,0 +1,33 @@
+/*
+ * mcp3004.c:
+ *	Extend wiringPi with the MCP3004 SPI Analog to Digital convertor
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp3004Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp3422.c b/wiringPi/mcp3422.c
new file mode 100644
index 0000000..3999181
--- /dev/null
+++ b/wiringPi/mcp3422.c
@@ -0,0 +1,129 @@
+/*
+ * mcp3422.c:
+ *	Extend wiringPi with the MCP3422/3/4 I2C ADC chip
+ *	This code assumes single-ended mode only.
+ *	Tested on actual hardware: 20th Feb 2016.
+ *	Copyright (c) 2013-2016 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 <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <errno.h>
+
+#include <wiringPi.h>
+#include <wiringPiI2C.h>
+
+#include "mcp3422.h"
+
+
+/*
+ * waitForConversion:
+ *	Common code to wait for the ADC to finish conversion
+ *********************************************************************************
+ */
+
+void waitForConversion (int fd, unsigned char *buffer, int n)
+{
+  for (;;)
+  {
+    if (read(fd, buffer, n) < 0) {
+      fprintf(stderr, "Unable to read from the file descriptor: %s \n", strerror(errno));
+    }
+    if ((buffer [n-1] & 0x80) == 0)
+      break ;
+    delay (1) ;
+  }
+}
+
+/*
+ * myAnalogRead:
+ *	Read a channel from the device
+ *********************************************************************************
+ */
+
+int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
+{
+  unsigned char config ;
+  unsigned char buffer [4] ;
+  int value = 0 ;
+  int realChan = (chan & 3) - node->pinBase ;
+
+// One-shot mode, trigger plus the other configs.
+
+  config = 0x80 | (realChan << 5) | (node->data0 << 2) | (node->data1) ;
+
+  wiringPiI2CWrite (node->fd, config) ;
+
+  switch (node->data0)	// Sample rate
+  {
+    case MCP3422_SR_3_75:			// 18 bits
+      waitForConversion (node->fd, &buffer [0], 4) ;
+      value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [2] ;
+      break ;
+
+    case MCP3422_SR_15:				// 16 bits
+      waitForConversion (node->fd, buffer, 3) ;
+      value = (buffer [0] << 8) | buffer [1] ;
+      break ;
+
+    case MCP3422_SR_60:				// 14 bits
+      waitForConversion (node->fd, buffer, 3) ;
+      value = ((buffer [0] & 0x3F) << 8) | buffer [1] ;
+      break ;
+
+    case MCP3422_SR_240:			// 12 bits - default
+      waitForConversion (node->fd, buffer, 3) ;
+      value = ((buffer [0] & 0x0F) << 8) | buffer [1] ;
+      break ;
+  }
+
+  return value ;
+}
+
+
+/*
+ * mcp3422Setup:
+ *	Create a new wiringPi device node for the mcp3422
+ *********************************************************************************
+ */
+
+int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 4) ;
+
+  node->fd         = fd ;
+  node->data0      = sampleRate ;
+  node->data1      = gain ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp3422.h b/wiringPi/mcp3422.h
new file mode 100644
index 0000000..72647d4
--- /dev/null
+++ b/wiringPi/mcp3422.h
@@ -0,0 +1,43 @@
+/*
+ * mcp3422.h:
+ *	Extend wiringPi with the MCP3422/3/4 I2C ADC 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/>.
+ ***********************************************************************
+ */
+
+#define	MCP3422_SR_240	0
+#define	MCP3422_SR_60	1
+#define	MCP3422_SR_15	2
+#define	MCP3422_SR_3_75	3
+
+#define	MCP3422_GAIN_1	0
+#define	MCP3422_GAIN_2	1
+#define	MCP3422_GAIN_4	2
+#define	MCP3422_GAIN_8	3
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp4802.c b/wiringPi/mcp4802.c
new file mode 100644
index 0000000..ef104ed
--- /dev/null
+++ b/wiringPi/mcp4802.c
@@ -0,0 +1,76 @@
+/*
+ * mcp4802.c:
+ *	Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
+ *	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 <wiringPi.h>
+#include <wiringPiSPI.h>
+
+#include "mcp4802.h"
+
+/*
+ * myAnalogWrite:
+ *	Write analog value on the given pin
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  unsigned char spiData [2] ;
+  unsigned char chanBits, dataBits ;
+  int chan = pin - node->pinBase ;
+
+  if (chan == 0)
+    chanBits = 0x30 ;
+  else
+    chanBits = 0xB0 ;
+
+  chanBits |= ((value >> 4) & 0x0F) ;
+  dataBits  = ((value << 4) & 0xF0) ;
+
+  spiData [0] = chanBits ;
+  spiData [1] = dataBits ;
+
+  wiringPiSPIDataRW (node->fd, spiData, 2) ;
+}
+
+/*
+ * mcp4802Setup:
+ *	Create a new wiringPi device node for an mcp4802 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int mcp4802Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiChannel, 1000000) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd          = spiChannel ;
+  node->analogWrite = myAnalogWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/mcp4802.h b/wiringPi/mcp4802.h
new file mode 100644
index 0000000..effa024
--- /dev/null
+++ b/wiringPi/mcp4802.h
@@ -0,0 +1,33 @@
+/*
+ * mcp4802.c:
+ *	Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp4802Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/pcf8574.c b/wiringPi/pcf8574.c
new file mode 100644
index 0000000..e0b686a
--- /dev/null
+++ b/wiringPi/pcf8574.c
@@ -0,0 +1,126 @@
+/*
+ * pcf8574.c:
+ *	Extend wiringPi with the PCF8574 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 "pcf8574.h"
+
+
+/*
+ * myPinMode:
+ *	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...
+ *********************************************************************************
+ */
+
+static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
+{
+  int bit, old ;
+
+  bit  = 1 << ((pin - node->pinBase) & 7) ;
+
+  old = node->data2 ;
+  if (mode == OUTPUT)
+    old &= (~bit) ;	// Write bit to 0
+  else
+    old |=   bit ;	// Write bit to 1
+
+  wiringPiI2CWrite (node->fd, old) ;
+  node->data2 = old ;
+}
+
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int bit, old ;
+
+  bit  = 1 << ((pin - node->pinBase) & 7) ;
+
+  old = node->data2 ;
+  if (value == LOW)
+    old &= (~bit) ;
+  else
+    old |=   bit ;
+
+  wiringPiI2CWrite (node->fd, old) ;
+  node->data2 = old ;
+}
+
+
+/*
+ * myDigitalRead:
+ *********************************************************************************
+ */
+
+static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int mask, value ;
+
+  mask  = 1 << ((pin - node->pinBase) & 7) ;
+  value = wiringPiI2CRead (node->fd) ;
+
+  if ((value & mask) == 0)
+    return LOW ;
+  else 
+    return HIGH ;
+}
+
+
+/*
+ * pcf8574Setup:
+ *	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.
+ *********************************************************************************
+ */
+
+int pcf8574Setup (const int pinBase, const int i2cAddress)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return FALSE ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->fd           = fd ;
+  node->pinMode      = myPinMode ;
+  node->digitalRead  = myDigitalRead ;
+  node->digitalWrite = myDigitalWrite ;
+  node->data2        = wiringPiI2CRead (fd) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/pcf8574.h b/wiringPi/pcf8574.h
new file mode 100644
index 0000000..8e2d818
--- /dev/null
+++ b/wiringPi/pcf8574.h
@@ -0,0 +1,33 @@
+/*
+ * pcf8574.h:
+ *	Extend wiringPi with the PCF8574 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 pcf8574Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/pcf8591.c b/wiringPi/pcf8591.c
new file mode 100644
index 0000000..cfb094a
--- /dev/null
+++ b/wiringPi/pcf8591.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <string.h>
+#include <errno.h>
+
+#include "wiringPi.h"
+#include "wiringPiI2C.h"
+
+#include "pcf8591.h"
+
+
+/*
+ * myAnalogWrite:
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, UNU int pin, int value)
+{
+  unsigned char b [2] ;
+  b [0] = 0x40 ;
+  b [1] = value & 0xFF ;
+  if (write(node->fd, b, 2) < 0) {
+    fprintf(stderr, "Unable to write to the file descriptor: %s \n", strerror(errno));
+  }
+}
+
+
+/*
+ * 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 FALSE ;
+
+  node = wiringPiNewNode (pinBase, 4) ;
+
+  node->fd          = fd ;
+  node->analogRead  = myAnalogRead ;
+  node->analogWrite = myAnalogWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/pcf8591.h b/wiringPi/pcf8591.h
new file mode 100644
index 0000000..6b44ccf
--- /dev/null
+++ b/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
diff --git a/wiringPi/pseudoPins.c b/wiringPi/pseudoPins.c
new file mode 100644
index 0000000..350b723
--- /dev/null
+++ b/wiringPi/pseudoPins.c
@@ -0,0 +1,95 @@
+/*
+ * pseudoPins.c:
+ *	Extend wiringPi with a number of pseudo pins which can be
+ *	digitally or analog written/read.
+ *
+ *	Note:
+ *		Just one set of pseudo pins can exist per Raspberry Pi.
+ *		These pins are shared between all programs running on
+ *		that Raspberry Pi. The values are also persistant as
+ *		they live in shared RAM. This gives you a means for
+ *		temporary variable storing/sharing between programs,
+ *		or for other cunning things I've not thought of yet..
+ *
+ *	Copyright (c) 2012-2016 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/>.
+ ***********************************************************************
+ */
+
+#define	SHARED_NAME	"wiringPiPseudoPins"
+#define	PSEUDO_PINS	64
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <wiringPi.h>
+
+#include "pseudoPins.h"
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int *ptr   = (int *)(uintptr_t) node->data0 ;
+  int  myPin = pin - node->pinBase ;
+
+  return *(ptr + myPin) ;
+}
+
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int *ptr   = (int *)(uintptr_t) node->data0 ;
+  int  myPin = pin - node->pinBase ;
+
+  *(ptr + myPin) = value ;
+}
+
+
+/*
+ * pseudoPinsSetup:
+ *	Create a new wiringPi device node for the pseudoPins driver
+ *********************************************************************************
+ */
+
+int pseudoPinsSetup (const int pinBase)
+{
+  struct wiringPiNodeStruct *node ;
+  void *ptr ;
+
+  node = wiringPiNewNode (pinBase, PSEUDO_PINS) ;
+
+  node->fd = shm_open (SHARED_NAME, O_CREAT | O_RDWR, 0666) ;
+
+  if (node->fd < 0)
+    return FALSE ;
+
+  if (ftruncate (node->fd, PSEUDO_PINS * sizeof (int)) < 0)
+    return FALSE ;
+
+  ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ;
+
+  node->data0 = (unsigned int)(uintptr_t) ptr ;
+
+  node->analogRead  = myAnalogRead ;
+  node->analogWrite = myAnalogWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/pseudoPins.h b/wiringPi/pseudoPins.h
new file mode 100644
index 0000000..bef4660
--- /dev/null
+++ b/wiringPi/pseudoPins.h
@@ -0,0 +1,26 @@
+/*
+ * pseudoPins.h:
+ *	Extend wiringPi with a number of pseudo pins which can be
+ *	digitally or analog written/read.
+ *	Copyright (c) 2012-2016 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/>.
+ ***********************************************************************
+ */
+
+extern int pseudoPinsSetup (const int pinBase) ;
diff --git a/wiringPi/rht03.c b/wiringPi/rht03.c
new file mode 100644
index 0000000..1129cfd
--- /dev/null
+++ b/wiringPi/rht03.c
@@ -0,0 +1,252 @@
+/*
+ * rht03.c:
+ *	Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
+ *	Copyright (c) 2016-2017 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 <sys/time.h>
+#include <stdio.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "wiringPi.h"
+#include "rht03.h"
+
+/*
+ * maxDetectLowHighWait:
+ *	Wait for a transition from low to high on the bus
+ *********************************************************************************
+ */
+
+static int maxDetectLowHighWait (const int pin)
+{
+  struct timeval now, timeOut, timeUp ;
+
+// If already high then wait for pin to go low
+
+  gettimeofday (&now, NULL) ;
+  timerclear   (&timeOut) ;
+  timeOut.tv_usec = 1000 ;
+  timeradd     (&now, &timeOut, &timeUp) ;
+
+  while (digitalRead (pin) == HIGH)
+  {
+    gettimeofday (&now, NULL) ;
+    if (timercmp (&now, &timeUp, >))
+      return FALSE ;
+  }
+
+// Wait for it to go HIGH
+
+  gettimeofday (&now, NULL) ;
+  timerclear (&timeOut) ;
+  timeOut.tv_usec = 1000 ;
+  timeradd (&now, &timeOut, &timeUp) ;
+
+  while (digitalRead (pin) == LOW)
+  {
+    gettimeofday (&now, NULL) ;
+    if (timercmp (&now, &timeUp, >))
+      return FALSE ;
+  }
+
+  return TRUE ;
+}
+
+
+/*
+ * maxDetectClockByte:
+ *	Read in a single byte from the MaxDetect bus
+ *********************************************************************************
+ */
+
+static unsigned int maxDetectClockByte (const int pin)
+{
+  unsigned int byte = 0 ;
+  int bit ;
+
+  for (bit = 0 ; bit < 8 ; ++bit)
+  {
+    if (!maxDetectLowHighWait (pin))
+      return 0 ;
+
+// bit starting now - we need to time it.
+
+    delayMicroseconds (30) ;
+    byte <<= 1 ;
+    if (digitalRead (pin) == HIGH)	// It's a 1
+      byte |= 1 ;
+  }
+
+  return byte ;
+}
+
+
+/*
+ * maxDetectRead:
+ *	Read in and return the 4 data bytes from the MaxDetect sensor.
+ *	Return TRUE/FALSE depending on the checksum validity
+ *********************************************************************************
+ */
+
+static int maxDetectRead (const int pin, unsigned char buffer [4])
+{
+  int i ;
+  unsigned int checksum ;
+  unsigned char localBuf [5] ;
+  struct timeval now, then, took ;
+
+// See how long we took
+
+  gettimeofday (&then, NULL) ;
+
+// Wake up the RHT03 by pulling the data line low, then high
+//	Low for 10mS, high for 40uS.
+
+  pinMode      (pin, OUTPUT) ;
+  digitalWrite (pin, 0) ; delay             (10) ;
+  digitalWrite (pin, 1) ; delayMicroseconds (40) ;
+  pinMode      (pin, INPUT) ;
+
+// Now wait for sensor to pull pin low
+
+  if (!maxDetectLowHighWait (pin))
+    return FALSE ;
+
+// and read in 5 bytes (40 bits)
+
+  for (i = 0 ; i < 5 ; ++i)
+    localBuf [i] = maxDetectClockByte (pin) ;
+
+  checksum = 0 ;
+  for (i = 0 ; i < 4 ; ++i)
+  {
+    buffer [i] = localBuf [i] ;
+    checksum += localBuf [i] ;
+  }
+  checksum &= 0xFF ;
+
+// See how long we took
+  
+  gettimeofday (&now, NULL) ;
+  timersub (&now, &then, &took) ;
+
+// Total time to do this should be:
+//	10mS + 40µS - reset
+//	+ 80µS + 80µS - sensor doing its low -> high thing
+//	+ 40 * (50µS + 27µS (0) or 70µS (1) )
+//	= 15010µS
+// so if we take more than that, we've had a scheduling interruption and the
+// reading is probably bogus.
+
+  if ((took.tv_sec != 0) || (took.tv_usec > 16000))
+    return FALSE ;
+
+  return checksum == localBuf [4] ;
+}
+
+
+/*
+ * myReadRHT03:
+ *	Read the Temperature & Humidity from an RHT03 sensor
+ *	Values returned are *10, so 123 is 12.3.
+ *********************************************************************************
+ */
+
+static int myReadRHT03 (const int pin, int *temp, int *rh)
+{
+  int result ;
+  unsigned char buffer [4] ;
+
+// Read ...
+  
+  result = maxDetectRead (pin, buffer) ;
+
+  if (!result)
+    return FALSE ;
+
+  *rh   = (buffer [0] * 256 + buffer [1]) ;
+  *temp = (buffer [2] * 256 + buffer [3]) ;
+
+  if ((*temp & 0x8000) != 0)	// Negative
+  {
+    *temp &= 0x7FFF ;
+    *temp = -*temp ;
+  }
+
+// Discard obviously bogus readings - the checksum can't detect a 2-bit error
+//	(which does seem to happen - no realtime here)
+
+  if ((*rh > 999) || (*temp > 800) || (*temp < -400))
+    return FALSE ;
+
+  return TRUE ;
+}
+
+
+/*
+ * myAnalogRead:
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, int pin)
+{
+  int piPin = node->fd ;
+  int chan  = pin - node->pinBase ;
+  int temp  = -9997 ;
+  int rh    = -9997 ;
+  int try ;
+
+  if (chan > 1)
+    return -9999 ;	// Bad parameters
+
+  for (try = 0 ; try < 10 ; ++try)
+  {
+    if (myReadRHT03 (piPin, &temp, &rh))
+      return chan == 0 ? temp : rh ;
+  }
+
+  return -9998 ;
+}
+
+
+/*
+ * rht03Setup:
+ *	Create a new instance of an RHT03 temperature sensor.
+ *********************************************************************************
+ */
+
+int rht03Setup (const int pinBase, const int piPin)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if ((piPin & PI_GPIO_MASK) != 0)	// Must be an on-board pin
+    return FALSE ;
+  
+// 2 pins - temperature and humidity
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd         = piPin ;
+  node->analogRead = myAnalogRead ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/rht03.h b/wiringPi/rht03.h
new file mode 100644
index 0000000..9523fbf
--- /dev/null
+++ b/wiringPi/rht03.h
@@ -0,0 +1,25 @@
+/*
+ * rht03.h:
+ *	Extend wiringPi with the rht03 Maxdetect 1-Wire sensor.
+ *	Copyright (c) 2016-2017 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/>.
+ ***********************************************************************
+ */
+
+extern int rht03Setup (const int pinBase, const int devicePin) ;
diff --git a/wiringPi/sn3218.c b/wiringPi/sn3218.c
new file mode 100644
index 0000000..d9b9113
--- /dev/null
+++ b/wiringPi/sn3218.c
@@ -0,0 +1,75 @@
+/*
+ * sn3218.c:
+ *	Extend wiringPi with the SN3218 I2C LEd Driver
+ *	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 <wiringPi.h>
+#include <wiringPiI2C.h>
+
+#include "sn3218.h"
+
+/*
+ * myAnalogWrite:
+ *	Write analog value on the given pin
+ *********************************************************************************
+ */
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  int fd   = node->fd ;
+  int chan = 0x01 + (pin - node->pinBase) ;
+  
+  wiringPiI2CWriteReg8 (fd, chan, value & 0xFF) ;	// Value
+  wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ;		// Update
+}
+
+/*
+ * sn3218Setup:
+ *	Create a new wiringPi device node for an sn3218 on the Pi's
+ *	SPI interface.
+ *********************************************************************************
+ */
+
+int sn3218Setup (const int pinBase)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (0x54)) < 0)
+    return FALSE ;
+
+// Setup the chip - initialise all 18 LEDs to off
+
+//wiringPiI2CWriteReg8 (fd, 0x17, 0) ;		// Reset
+  wiringPiI2CWriteReg8 (fd, 0x00, 1) ;		// Not Shutdown
+  wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ;	// Enable LEDs  0- 5
+  wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ;	// Enable LEDs  6-11
+  wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ;	// Enable LEDs 12-17
+  wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ;	// Update
+  
+  node = wiringPiNewNode (pinBase, 18) ;
+
+  node->fd          = fd ;
+  node->analogWrite = myAnalogWrite ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/sn3218.h b/wiringPi/sn3218.h
new file mode 100644
index 0000000..580d5f9
--- /dev/null
+++ b/wiringPi/sn3218.h
@@ -0,0 +1,33 @@
+/*
+ * sn3218.c:
+ *	Extend wiringPi with the SN3218 I2C LED driver board.
+ *	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/>.
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int sn3218Setup (int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c
new file mode 100644
index 0000000..8280618
--- /dev/null
+++ b/wiringPi/sr595.c
@@ -0,0 +1,109 @@
+/*
+ * sr595.c:
+ *	Extend wiringPi with the 74x595 shift register as a GPIO
+ *	expander chip.
+ *	Note that the code can cope with a number of 595's
+ *	daisy-chained together - up to 4 for now as we're storing
+ *	the output "register" in a single unsigned int.
+ *
+ *	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 <stdint.h>
+
+#include "wiringPi.h"
+
+#include "sr595.h"
+
+
+/*
+ * myDigitalWrite:
+ *********************************************************************************
+ */
+
+static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+  unsigned int mask ;
+  int  dataPin, clockPin, latchPin ;
+  int  bit, bits, output ;
+
+  pin     -= node->pinBase ;				// Normalise pin number
+  bits     = node->pinMax - node->pinBase + 1 ;		// ie. number of clock pulses
+  dataPin  = node->data0 ;
+  clockPin = node->data1 ;
+  latchPin = node->data2 ;
+  output   = node->data3 ;
+
+  mask = 1 << pin ;
+
+  if (value == LOW)
+    output &= (~mask) ;
+  else
+    output |=   mask ;
+
+  node->data3 = output ;
+
+// A low -> high latch transition copies the latch to the output pins
+
+  digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ;
+    for (bit = bits - 1 ; bit >= 0 ; --bit)
+    {
+      digitalWrite (dataPin, output & (1 << bit)) ;
+
+      digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ;
+      digitalWrite (clockPin, LOW) ;  delayMicroseconds (1) ;
+    }
+  digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ;
+}
+
+
+/*
+ * sr595Setup:
+ *	Create a new instance of a 74x595 shift register GPIO expander.
+ *********************************************************************************
+ */
+
+int sr595Setup (const int pinBase, const int numPins,
+	const int dataPin, const int clockPin, const int latchPin) 
+{
+  struct wiringPiNodeStruct *node ;
+
+  node = wiringPiNewNode (pinBase, numPins) ;
+
+  node->data0           = dataPin ;
+  node->data1           = clockPin ;
+  node->data2           = latchPin ;
+  node->data3           = 0 ;		// Output register
+  node->digitalWrite    = myDigitalWrite ;
+
+// Initialise the underlying hardware
+
+  digitalWrite (dataPin,  LOW) ;
+  digitalWrite (clockPin, LOW) ;
+  digitalWrite (latchPin, HIGH) ;
+
+  pinMode (dataPin,  OUTPUT) ;
+  pinMode (clockPin, OUTPUT) ;
+  pinMode (latchPin, OUTPUT) ;
+
+  return TRUE ;
+}
diff --git a/wiringPi/sr595.h b/wiringPi/sr595.h
new file mode 100644
index 0000000..4a26dc7
--- /dev/null
+++ b/wiringPi/sr595.h
@@ -0,0 +1,34 @@
+/*
+ * sr595.h:
+ *	Extend wiringPi with the 74x595 shift registers.
+ *	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 sr595Setup (const int pinBase, const int numPins,
+	const int dataPin, const int clockPin, const int latchPin) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c
index 4c7f65a..9fde661 100644
--- a/wiringPi/wiringPi.c
+++ b/wiringPi/wiringPi.c
@@ -964,6 +964,74 @@
 }
 
 /*----------------------------------------------------------------------------*/
+//
+// Unsupport Function list on ODROIDs
+//
+/*----------------------------------------------------------------------------*/
+static 	void UNU piGpioLayoutOops	(const char UNU *why)	{ warn_msg(__func__); return; }
+	void gpioClockSet	(int UNU pin, int UNU freq)	{ warn_msg(__func__); return; }
+
+	/* core unsupport function */
+	void pinModeAlt		(int UNU pin, int UNU mode)	{ warn_msg(__func__); return; }
+	void analogWrite	(int UNU pin, int UNU value)	{ warn_msg(__func__); return; }
+	void pwmToneWrite	(int UNU pin, int UNU freq)	{ warn_msg(__func__); return; }
+	void digitalWriteByte2	(const int UNU value)	{ warn_msg(__func__); return; }
+	unsigned int digitalReadByte2 (void)		{ warn_msg(__func__); return -1; }
+
+/*----------------------------------------------------------------------------*/
+// Extend wiringPi with other pin-based devices and keep track of
+//	them in this structure
+/*----------------------------------------------------------------------------*/
+struct wiringPiNodeStruct *wiringPiNodes = NULL ;
+
+struct wiringPiNodeStruct *wiringPiFindNode (int UNU pin) {	return NULL; }
+
+static		void pinModeDummy		(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode)  { return ; }
+static		void pullUpDnControlDummy	(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud)   { return ; }
+static	unsigned int UNU digitalRead8Dummy		(UNU struct wiringPiNodeStruct *node, UNU int UNU pin)            { return 0 ; }
+static		void UNU digitalWrite8Dummy		(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
+static		int  digitalReadDummy		(UNU struct wiringPiNodeStruct *node, UNU int UNU pin)            { return LOW ; }
+static		void digitalWriteDummy		(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
+static		void pwmWriteDummy		(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
+static		int  analogReadDummy		(UNU struct wiringPiNodeStruct *node, UNU int pin)            { return 0 ; }
+static		void analogWriteDummy		(UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; }
+
+struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
+{
+	int	pin ;
+	struct wiringPiNodeStruct *node ;
+
+	// Minimum pin base is 64
+	if (pinBase < 64)
+		(void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ;
+
+	// Check all pins in-case there is overlap:
+	for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin)
+		if (wiringPiFindNode (pin) != NULL)
+			(void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ;
+
+	node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ;	// calloc zeros
+	if (node == NULL)
+		(void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ;
+
+	node->pinBase		= pinBase ;
+	node->pinMax		= pinBase + numPins - 1 ;
+	node->pinMode		= pinModeDummy ;
+	node->pullUpDnControl	= pullUpDnControlDummy ;
+	node->digitalRead	= digitalReadDummy ;
+	//node->digitalRead8	= digitalRead8Dummy ;
+	node->digitalWrite	= digitalWriteDummy ;
+	//node->digitalWrite8	= digitalWrite8Dummy ;
+	node->pwmWrite		= pwmWriteDummy ;
+	node->analogRead	= analogReadDummy ;
+	node->analogWrite	= analogWriteDummy ;
+	node->next		= wiringPiNodes ;
+	wiringPiNodes		= node ;
+
+	return node ;
+}
+
+/*----------------------------------------------------------------------------*/
 void wiringPiVersion (int *major, char **minor)
 {
 	*major = VERSION_MAJOR ;
diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h
index 473cfa2..893b692 100644
--- a/wiringPi/wiringPi.h
+++ b/wiringPi/wiringPi.h
@@ -98,6 +98,11 @@
 #define	WPI_FATAL		(1==1)
 #define	WPI_ALMOST		(1==2)
 
+// Legacy compatibility
+// Mask for the bottom 64 pins which belong to the Raspberry Pi
+//	The others are available for the other devices
+#define	PI_GPIO_MASK		(0xFFFFFFC0)
+
 extern const char *piModelNames    [16];
 extern const char *piRevisionNames [16];
 extern const char *piMakerNames    [16];
@@ -197,6 +202,41 @@
 };
 
 /*----------------------------------------------------------------------------*/
+// wiringPiNodeStruct:
+//	This describes additional device nodes in the extended wiringPi
+//	2.0 scheme of things.
+//	It's a simple linked list for now, but will hopefully migrate to
+//	a binary tree for efficiency reasons - but then again, the chances
+//	of more than 1 or 2 devices being added are fairly slim, so who
+//	knows....
+/*----------------------------------------------------------------------------*/
+struct wiringPiNodeStruct
+{
+	int	pinBase;
+	int	pinMax;
+
+	int	fd;		// Node specific
+	unsigned int data0;	//  ditto
+	unsigned int data1;	//  ditto
+	unsigned int data2;	//  ditto
+	unsigned int data3;	//  ditto
+
+	void		(*pinMode)		(struct wiringPiNodeStruct *node, int pin, int mode);
+	void		(*pullUpDnControl)	(struct wiringPiNodeStruct *node, int pin, int mode);
+	int		(*digitalRead)		(struct wiringPiNodeStruct *node, int pin);
+	// unsigned int	(*digitalRead8)		(struct wiringPiNodeStruct *node, int pin);
+	void		(*digitalWrite)		(struct wiringPiNodeStruct *node, int pin, int value);
+	// void		(*digitalWrite8)	(struct wiringPiNodeStruct *node, int pin, int value);
+	void		(*pwmWrite)		(struct wiringPiNodeStruct *node, int pin, int value);
+	int		(*analogRead)		(struct wiringPiNodeStruct *node, int pin);
+	void		(*analogWrite)		(struct wiringPiNodeStruct *node, int pin, int value);
+
+	struct wiringPiNodeStruct *next;
+};
+
+extern struct wiringPiNodeStruct *wiringPiNodes;
+
+/*----------------------------------------------------------------------------*/
 // Function prototypes
 //	c++ wrappers thanks to a comment by Nick Lott
 //	(and others on the Raspberry Pi forums)
@@ -205,6 +245,10 @@
 extern "C" {
 #endif
 
+// Node supports for external boards
+extern struct wiringPiNodeStruct *wiringPiFindNode (int pin);
+extern struct wiringPiNodeStruct *wiringPiNewNode  (int pinBase, int numPins);
+
 // Internal WiringPi functions
 extern		int  wiringPiFailure	(int fatal, const char *message, ...);
 extern		int  msg		(int type, const char *message, ...);
@@ -261,6 +305,16 @@
 extern unsigned int  millis		(void);
 extern unsigned int  micros		(void);
 
+// Unsupoorted
+extern		void pinModeAlt		(int pin, int mode) UNU;
+extern		void analogWrite	(int pin, int value) UNU;
+extern		void pwmToneWrite	(int pin, int freq) UNU;
+extern		void gpioClockSet	(int pin, int freq) UNU;
+extern unsigned int  digitalReadByte	(void) UNU;
+extern unsigned int  digitalReadByte2	(void) UNU;
+extern		void digitalWriteByte	(int value) UNU;
+extern		void digitalWriteByte2	(int value) UNU;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c
new file mode 100644
index 0000000..bef126f
--- /dev/null
+++ b/wiringPi/wpiExtensions.c
@@ -0,0 +1,928 @@
+/*
+ * extensions.c:
+ *	Originally part of the GPIO program to test, peek, poke and otherwise
+ *	noodle with the GPIO hardware on the Raspberry Pi.
+ *	Now used as a general purpose library to allow systems to dynamically
+ *	add in new devices into wiringPi at program run-time.
+ *	Copyright (c) 2012-2015 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 <stdint.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <wiringPi.h>
+
+#include "mcp23008.h"
+#include "mcp23016.h"
+#include "mcp23017.h"
+#include "mcp23s08.h"
+#include "mcp23s17.h"
+#include "sr595.h"
+#include "pcf8574.h"
+#include "pcf8591.h"
+#include "mcp3002.h"
+#include "mcp3004.h"
+#include "mcp4802.h"
+#include "mcp3422.h"
+#include "max31855.h"
+#include "max5322.h"
+#include "ads1115.h"
+#include "sn3218.h"
+#include "drcSerial.h"
+#include "drcNet.h"
+#include "../wiringPiD/drcNetCmd.h"
+#include "pseudoPins.h"
+#include "bmp180.h"
+#include "htu21d.h"
+#include "ds18b20.h"
+#include "rht03.h"
+
+#include "wpiExtensions.h"
+
+extern int wiringPiDebug ;
+
+static int verbose ;
+static char errorMessage [1024] ;
+
+
+// Local structure to hold details
+
+struct extensionFunctionStruct
+{
+  const char *name ;
+  int	(*function)(char *progName, int pinBase, char *params) ;
+} ;
+
+
+/*
+ * verbError:
+ *	Convenient error handling
+ *********************************************************************************
+ */
+
+static void verbError (const char *message, ...)
+{
+  va_list argp ;
+  va_start (argp, message) ;
+    vsnprintf (errorMessage, 1023, message, argp) ;
+  va_end (argp) ;
+
+  if (verbose)
+    fprintf (stderr, "%s\n", errorMessage) ;
+}
+
+
+/*
+ * extractInt:
+ *	Check & return an integer at the given location (prefixed by a :)
+ *********************************************************************************
+ */
+
+static char *extractInt (char *progName, char *p, int *num)
+{
+  if (*p != ':')
+  {
+    verbError ("%s: colon expected", progName) ;
+    return NULL ;
+  }
+
+  ++p ;
+
+  if (!isdigit (*p))
+  {
+    verbError ("%s: digit expected", progName) ;
+    return NULL ;
+  }
+
+  *num = strtol (p, NULL, 0) ;
+
+// Increment p, but we need to check for hex 0x
+
+  if ((*p == '0') && (*(p + 1) == 'x'))
+    p +=2 ;
+
+  while (isxdigit (*p))
+    ++p ;
+
+  return p ;
+}
+
+
+/*
+ * extractStr:
+ *	Check & return a string at the given location (prefixed by a :)
+ *	Note: The string can be enclosed in []'s to escape colons. This is
+ *	so we can handle IPv6 addresses which contain colons and the []'s is
+ *	a common way to prepresent them.
+ *********************************************************************************
+ */
+
+static char *extractStr (char *progName, char *p, char **str)
+{
+  char *q, *r ;
+  int quoted = FALSE ;
+
+  if (*p != ':')
+  {
+    verbError ("%s: colon expected", progName) ;
+    return NULL ;
+  }
+
+  ++p ;
+
+  if (*p == '[')
+  {
+    quoted = TRUE ;
+    ++p ;
+  }
+
+  if (!isprint (*p))	// Is this needed?
+  {
+    verbError ("%s: character expected", progName) ;
+    return NULL ;
+  }
+
+  q = p ;
+  if (quoted)
+  {
+    while ((*q != 0) && (*q != ']'))
+      ++q ;
+  }
+  else
+  {
+    while ((*q != 0) && (*q != ':'))
+      ++q ;
+  }
+
+  *str = r = calloc (q - p + 2, 1) ;	// Zeros it
+
+  while (p != q)
+    *r++ = *p++ ;
+
+  if (quoted)				// Skip over the ] to the :
+    ++p ;
+
+  return p ;
+}
+
+
+
+/*
+ * doExtensionMcp23008:
+ *	MCP23008 - 8-bit I2C GPIO expansion chip
+ *	mcp23002:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x01) || (i2c > 0x77))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  mcp23008Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * 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))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  mcp23016Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp23017:
+ *	MCP230017- 16-bit I2C GPIO expansion chip
+ *	mcp23017:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  mcp23017Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp23s08:
+ *	MCP23s08 - 8-bit SPI GPIO expansion chip
+ *	mcp23s08:base:spi:port
+ *********************************************************************************
+ */
+
+static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
+{
+  int spi, port ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI address (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if ((port < 0) || (port > 7))
+  {
+    verbError ("%s: port address (%d) out of range", progName, port) ;
+    return FALSE ;
+  }
+
+  mcp23s08Setup (pinBase, spi, port) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp23s17:
+ *	MCP23s17 - 16-bit SPI GPIO expansion chip
+ *	mcp23s17:base:spi:port
+ *********************************************************************************
+ */
+
+static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
+{
+  int spi, port ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI address (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if ((port < 0) || (port > 7))
+  {
+    verbError ("%s: port address (%d) out of range", progName, port) ;
+    return FALSE ;
+  }
+
+  mcp23s17Setup (pinBase, spi, port) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionSr595:
+ *	Shift Register 74x595
+ *	sr595:base:pins:data:clock:latch
+ *********************************************************************************
+ */
+
+static int doExtensionSr595 (char *progName, int pinBase, char *params)
+{
+  int pins, data, clock, latch ;
+
+// Extract pins
+
+  if ((params = extractInt (progName, params, &pins)) == NULL)
+    return FALSE ;
+
+  if ((pins < 8) || (pins > 32))
+  {
+    verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &data)) == NULL)
+    return FALSE ;
+
+  if ((params = extractInt (progName, params, &clock)) == NULL)
+    return FALSE ;
+
+  if ((params = extractInt (progName, params, &latch)) == NULL)
+    return FALSE ;
+
+  sr595Setup (pinBase, pins, data, clock, latch) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * 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))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  pcf8574Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionAds1115:
+ *	Analog Input
+ *	ads1115:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionAds1115 (char *progName, int pinBase, char *params)
+{
+  int i2c ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  ads1115Setup (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))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  pcf8591Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionPseudoPins:
+ *	64 Memory resident pseudo pins
+ *	pseudoPins:base
+ *********************************************************************************
+ */
+
+static int doExtensionPseudoPins (UNU char *progName, int pinBase, UNU char *params)
+{
+  pseudoPinsSetup (pinBase) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionBmp180:
+ *	Analog Temp + Pressure
+ *	bmp180:base
+ *********************************************************************************
+ */
+
+static int doExtensionBmp180 (UNU char *progName, int pinBase, UNU char *params)
+{
+  bmp180Setup (pinBase) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionHtu21d:
+ *	Analog humidity + Pressure
+ *	htu21d:base
+ *********************************************************************************
+ */
+
+static int doExtensionHtu21d (UNU char *progName, int pinBase, UNU char *params)
+{
+  htu21dSetup (pinBase) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionDs18b20:
+ *	1-Wire Temperature
+ *	htu21d:base:serialNum
+ *********************************************************************************
+ */
+
+static int doExtensionDs18b20 (char *progName, int pinBase, char *params)
+{
+  char *serialNum ;
+
+  if ((params = extractStr (progName, params, &serialNum)) == NULL)
+    return FALSE ;
+
+  return ds18b20Setup (pinBase, serialNum) ;
+}
+
+
+/*
+ * doExtensionRht03:
+ *	Maxdetect 1-Wire Temperature & Humidity
+ *	rht03:base:piPin
+ *********************************************************************************
+ */
+
+static int doExtensionRht03 (char *progName, int pinBase, char *params)
+{
+  int piPin ;
+
+  if ((params = extractInt (progName, params, &piPin)) == NULL)
+    return FALSE ;
+
+  return rht03Setup (pinBase, piPin) ;
+}
+
+
+/*
+ * doExtensionMax31855:
+ *	Analog IO
+ *	max31855:base:spiChan
+ *********************************************************************************
+ */
+
+static int doExtensionMax31855 (char *progName, int pinBase, char *params)
+{
+  int spi ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  max31855Setup (pinBase, spi) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp3002:
+ *	Analog IO
+ *	mcp3002:base:spiChan
+ *********************************************************************************
+ */
+
+static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
+{
+  int spi ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  mcp3002Setup (pinBase, spi) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp3004:
+ *	Analog IO
+ *	mcp3004:base:spiChan
+ *********************************************************************************
+ */
+
+static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
+{
+  int spi ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  mcp3004Setup (pinBase, spi) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMax5322:
+ *	Analog O
+ *	max5322:base:spiChan
+ *********************************************************************************
+ */
+
+static int doExtensionMax5322 (char *progName, int pinBase, char *params)
+{
+  int spi ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  max5322Setup (pinBase, spi) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp4802:
+ *	Analog IO
+ *	mcp4802:base:spiChan
+ *********************************************************************************
+ */
+
+static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
+{
+  int spi ;
+
+  if ((params = extractInt (progName, params, &spi)) == NULL)
+    return FALSE ;
+
+  if ((spi < 0) || (spi > 1))
+  {
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
+    return FALSE ;
+  }
+
+  mcp4802Setup (pinBase, spi) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionSn3218:
+ *	Analog Output (LED Driver)
+ *	sn3218:base
+ *********************************************************************************
+ */
+
+static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params)
+{
+  sn3218Setup (pinBase) ;
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp3422:
+ *	Analog IO
+ *	mcp3422:base:i2cAddr
+ *********************************************************************************
+ */
+
+static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
+{
+  int i2c, sampleRate, gain ;
+
+  if ((params = extractInt (progName, params, &i2c)) == NULL)
+    return FALSE ;
+
+  if ((i2c < 0x03) || (i2c > 0x77))
+  {
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &sampleRate)) == NULL)
+    return FALSE ;
+
+  if ((sampleRate < 0) || (sampleRate > 3))
+  {
+    verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &gain)) == NULL)
+    return FALSE ;
+
+  if ((gain < 0) || (gain > 3))
+  {
+    verbError ("%s: gain (%d) out of range", progName, gain) ;
+    return FALSE ;
+  }
+
+  mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionDrcS:
+ *	Interface to a DRC Serial system
+ *	drcs:base:pins:serialPort:baud
+ *********************************************************************************
+ */
+
+static int doExtensionDrcS (char *progName, int pinBase, char *params)
+{
+  char *port ;
+  int pins, baud ;
+
+  if ((params = extractInt (progName, params, &pins)) == NULL)
+    return FALSE ;
+
+  if ((pins < 1) || (pins > 1000))
+  {
+    verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
+    return FALSE ;
+  }
+  
+  if ((params = extractStr (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if (strlen (port) == 0)
+  {
+    verbError ("%s: serial port device name required", progName) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &baud)) == NULL)
+    return FALSE ;
+
+  if ((baud < 1) || (baud > 4000000))
+  {
+    verbError ("%s: baud rate (%d) out of range", progName, baud) ;
+    return FALSE ;
+  }
+
+  drcSetupSerial (pinBase, pins, port, baud) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionDrcNet:
+ *	Interface to a DRC Network system
+ *	drcn:base:pins:ipAddress:port:password
+ *********************************************************************************
+ */
+
+static int doExtensionDrcNet (char *progName, int pinBase, char *params)
+{
+  int pins ;
+  char *ipAddress, *port, *password ;
+  char pPort [1024] ;
+
+  if ((params = extractInt (progName, params, &pins)) == NULL)
+    return FALSE ;
+
+  if ((pins < 1) || (pins > 1000))
+  {
+    verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
+    return FALSE ;
+  }
+  
+  if ((params = extractStr (progName, params, &ipAddress)) == NULL)
+    return FALSE ;
+
+  if (strlen (ipAddress) == 0)
+  {
+    verbError ("%s: ipAddress required", progName) ;
+    return FALSE ;
+  }
+
+  if ((params = extractStr (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if (strlen (port) == 0)
+  {
+    sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ;
+    port = pPort ;
+  }
+
+  if ((params = extractStr (progName, params, &password)) == NULL)
+    return FALSE ;
+
+  if (strlen (password) == 0)
+  {
+    verbError ("%s: password required", progName) ;
+    return FALSE ;
+  }
+
+  return drcSetupNet (pinBase, pins, ipAddress, port, password) ;
+}
+
+
+
+/*
+ * Function list
+ *********************************************************************************
+ */
+
+static struct extensionFunctionStruct extensionFunctions [] = 
+{
+  { "mcp23008",		&doExtensionMcp23008 	},
+  { "mcp23016",		&doExtensionMcp23016 	},
+  { "mcp23017",		&doExtensionMcp23017 	},
+  { "mcp23s08",		&doExtensionMcp23s08 	},
+  { "mcp23s17",		&doExtensionMcp23s17 	},
+  { "sr595",		&doExtensionSr595	},
+  { "pcf8574",		&doExtensionPcf8574	},
+  { "pcf8591",		&doExtensionPcf8591	},
+  { "bmp180",		&doExtensionBmp180	},
+  { "pseudoPins",	&doExtensionPseudoPins	},
+  { "htu21d",		&doExtensionHtu21d	},
+  { "ds18b20",		&doExtensionDs18b20	},
+  { "rht03",		&doExtensionRht03	},
+  { "mcp3002",		&doExtensionMcp3002	},
+  { "mcp3004",		&doExtensionMcp3004	},
+  { "mcp4802",		&doExtensionMcp4802	},
+  { "mcp3422",		&doExtensionMcp3422	},
+  { "max31855",		&doExtensionMax31855	},
+  { "ads1115",		&doExtensionAds1115	},
+  { "max5322",		&doExtensionMax5322	},
+  { "sn3218",		&doExtensionSn3218	},
+  { "drcs",		&doExtensionDrcS	},
+  { "drcn",		&doExtensionDrcNet	},
+  { NULL,		NULL		 	},
+} ;
+
+
+/*
+ * loadWPiExtension:
+ *	Load in a wiringPi extension
+ *	The extensionData always starts with the name, a colon then the pinBase
+ *	number. Other parameters after that are decoded by the module in question.
+ *********************************************************************************
+ */
+
+int loadWPiExtension (char *progName, char *extensionData, int printErrors)
+{
+  char *p ;
+  char *extension = extensionData ;
+  struct extensionFunctionStruct *extensionFn ;
+  int pinBase = 0 ;
+
+  verbose = printErrors ;
+
+// Get the extension name by finding the first colon
+
+  p = extension ;
+  while (*p != ':')
+  {
+    if (!*p)	// ran out of characters
+    {
+      verbError ("%s: extension name not terminated by a colon", progName) ;
+      return FALSE ;
+    }
+    ++p ;
+  }
+  *p++ = 0 ;
+
+// Simple ATOI code
+
+  if (!isdigit (*p))
+  {
+    verbError ("%s: decimal pinBase number expected after extension name", progName) ;
+    return FALSE ;
+  }
+
+  while (isdigit (*p))
+  {
+    if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here...
+    {
+      verbError ("%s: pinBase too large", progName) ;
+      return FALSE ;
+    }
+
+    pinBase = pinBase * 10 + (*p - '0') ;
+    ++p ;
+  }
+
+  if (pinBase < 64)
+  {
+    verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ;
+    return FALSE ;
+  }
+
+// Search for extensions:
+
+  for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
+  {
+    if (strcmp (extensionFn->name, extension) == 0)
+      return extensionFn->function (progName, pinBase, p) ;
+  }
+
+  fprintf (stderr, "%s: extension %s not found", progName, extension) ;
+  return FALSE ;
+}
diff --git a/wiringPi/wpiExtensions.h b/wiringPi/wpiExtensions.h
new file mode 100644
index 0000000..fcaec96
--- /dev/null
+++ b/wiringPi/wpiExtensions.h
@@ -0,0 +1,26 @@
+/*
+ * extensions.h:
+ *	Part of the GPIO program to test, peek, poke and otherwise
+ *	noodle with the GPIO hardware on the Raspberry Pi.
+ *	Copyright (c) 2012-2015 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/>.
+ ***********************************************************************
+ */
+
+
+extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ;
diff --git a/wiringPiD/Makefile b/wiringPiD/Makefile
new file mode 100644
index 0000000..6b2cc9e
--- /dev/null
+++ b/wiringPiD/Makefile
@@ -0,0 +1,100 @@
+#
+# Makefile:
+#	The wiringPiD utility:
+#	https://projects.drogon.net/wiring-pi
+#
+#	Copyright (c) 2012-2017 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	A "wiring" 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/>.
+#################################################################################
+
+DESTDIR?=/usr
+PREFIX?=/local
+
+ifneq ($V,1)
+Q ?= @
+endif
+
+#DEBUG	= -g -O0
+DEBUG	= -O2
+CC	= gcc
+INCLUDE	= -I$(DESTDIR)$(PREFIX)/include
+CFLAGS	= $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe
+
+LDFLAGS	= -L$(DESTDIR)$(PREFIX)/lib
+LIBS    = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt
+
+# May not need to  alter anything below this line
+###############################################################################
+
+SRC	=	wiringpid.c network.c runRemote.c daemonise.c
+
+OBJ	=	$(SRC:.c=.o)
+
+all:		wiringpid
+
+wiringpid:	$(OBJ)
+	$Q echo [Link]
+	$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
+
+.c.o:
+	$Q echo [Compile] $<
+	$Q $(CC) -c $(CFLAGS) $< -o $@
+
+.PHONY:	clean
+clean:
+	$Q echo "[Clean]"
+	$Q rm -f $(OBJ) wiringpid *~ core tags *.bak
+
+.PHONY:	tags
+tags:	$(SRC)
+	$Q echo [ctags]
+	$Q ctags $(SRC)
+
+.PHONY:	install
+install: wiringpid
+	$Q echo "[Install]"
+	$Q mkdir -p		$(DESTDIR)$(PREFIX)/sbin
+	$Q cp wiringpid		$(DESTDIR)$(PREFIX)/sbin
+	$Q chown root.root	$(DESTDIR)$(PREFIX)/sbin/wiringpid
+
+#	$Q mkdir -p		$(DESTDIR)$(PREFIX)/man/man8
+#	$Q cp gpio.1		$(DESTDIR)$(PREFIX)/man/man8
+
+.PHONY:	install-deb
+install-deb:	gpio
+	$Q echo "[Install: deb]"
+	$Q install -m 0755 -d							~/wiringPi/debian-template/wiringPi/usr/bin
+	$Q install -m 0755 gpio							~/wiringPi/debian-template/wiringPi/usr/bin
+	$Q install -m 0755 -d							~/wiringPi/debian-template/wiringPi/man/man1
+	$Q install -m 0644 gpio.1						~/wiringPi/debian-template/wiringPi/man/man1
+
+.PHONY:	uninstall
+uninstall:
+	$Q echo "[UnInstall]"
+	$Q rm -f $(DESTDIR)$(PREFIX)/sbin/wiringpid
+	$Q rm -f $(DESTDIR)$(PREFIX)/man/man8/wiringpid.8
+
+.PHONY:	depend
+depend:
+	makedepend -Y $(SRC)
+# DO NOT DELETE
+
+wiringpid.o: drcNetCmd.h network.h runRemote.h daemonise.h
+network.o: network.h
+runRemote.o: drcNetCmd.h network.h runRemote.h
+daemonise.o: daemonise.h
diff --git a/wiringPiD/daemonise.c b/wiringPiD/daemonise.c
new file mode 100644
index 0000000..134a6bb
--- /dev/null
+++ b/wiringPiD/daemonise.c
@@ -0,0 +1,82 @@
+/*
+ * daemonise.c:
+ *	Fairly generic "Turn the current process into a daemon" code.
+ *
+ *	Copyright (c) 2016-2017 Gordon Henderson.
+ *********************************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "daemonise.h"
+
+void daemonise (const char *pidFile)
+{
+  pid_t pid ;
+  int i ;
+  FILE *fd ;
+
+  syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ;
+
+// Fork from the parent
+
+  if ((pid = fork ()) < 0)
+  {
+    syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  if (pid > 0)			// Parent - terminate
+    exit (EXIT_SUCCESS) ;
+
+// Now running on the child - become session leader
+
+  if (setsid() < 0)
+  {
+    syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ;
+    exit (EXIT_FAILURE) ;
+  }
+
+// Ignore a few signals
+
+  signal (SIGCHLD, SIG_IGN) ;
+  signal (SIGHUP,  SIG_IGN) ;
+
+// Fork again
+
+  if ((pid = fork ()) < 0)
+  {
+    syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  if (pid > 0)			// parent - terminate
+    exit (EXIT_SUCCESS) ;
+
+// Tidying up - reset umask, change to / and close all files
+
+  umask (0) ;
+  chdir ("/") ;
+
+  for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i)
+    close (i) ;
+
+// Write PID into /var/run
+
+  if (pidFile != NULL)
+  {
+    if ((fd = fopen (pidFile, "w")) == NULL)
+    {
+      syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ;
+      exit (EXIT_FAILURE) ;
+    }
+
+    fprintf (fd, "%d\n", getpid ()) ;
+    fclose (fd) ;
+  }
+}
diff --git a/wiringPiD/daemonise.h b/wiringPiD/daemonise.h
new file mode 100644
index 0000000..8d13319
--- /dev/null
+++ b/wiringPiD/daemonise.h
@@ -0,0 +1,9 @@
+/*
+ * daemonise.h:
+ *	Fairly generic "Turn the current process into a daemon" code.
+ *
+ *	Copyright (c) 2016-2017 Gordon Henderson.
+ *********************************************************************************
+ */
+
+extern void daemonise (const char *pidFile) ;
diff --git a/wiringPiD/drcNetCmd.h b/wiringPiD/drcNetCmd.h
new file mode 100644
index 0000000..23f7dc1
--- /dev/null
+++ b/wiringPiD/drcNetCmd.h
@@ -0,0 +1,44 @@
+/*
+ * drcNetCmd.c:
+ *	Copyright (c) 2012-2017 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/>.
+ ***********************************************************************
+ */
+
+#define	DEFAULT_SERVER_PORT	6124
+
+#define	DRCN_PIN_MODE		1
+#define	DRCN_PULL_UP_DN		2
+
+#define	DRCN_DIGITAL_WRITE	3
+#define	DRCN_DIGITAL_WRITE8	4
+#define	DRCN_ANALOG_WRITE	5
+#define	DRCN_PWM_WRITE		6
+
+#define	DRCN_DIGITAL_READ	7
+#define	DRCN_DIGITAL_READ8	8
+#define	DRCN_ANALOG_READ	9
+
+
+struct drcNetComStruct
+{
+  uint32_t pin ;
+  uint32_t cmd ;
+  uint32_t data ;
+} comDat ;
+
diff --git a/wiringPiD/network.c b/wiringPiD/network.c
new file mode 100644
index 0000000..9f6bb88
--- /dev/null
+++ b/wiringPiD/network.c
@@ -0,0 +1,330 @@
+/*
+ * network.c:
+ *	Part of wiringPiD
+ *	Copyright (c) 2012-2017 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 <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <malloc.h>
+
+#include <fcntl.h>
+#include <crypt.h>
+
+#include "network.h"
+
+#define	TRUE	(1==1)
+#define	FALSE	(!TRUE)
+
+// Local data
+
+#define	SALT_LEN	16
+
+static char salt [SALT_LEN + 1] ;
+static char *returnedHash = NULL ;
+static int serverFd = -1 ;
+
+// Union for the server Socket Address
+
+static union
+{
+  struct sockaddr_in  sin ;
+  struct sockaddr_in6 sin6 ;
+} serverSockAddr ; 
+
+// and client address
+
+static union
+{
+  struct sockaddr_in  sin ;
+  struct sockaddr_in6 sin6 ;
+} clientSockAddr ;
+
+
+/*
+ * getClientIP:
+ *	Returns a pointer to a static string containing the clients IP address
+ *********************************************************************************
+ */
+
+char *getClientIP (void)
+{
+  char buf [INET6_ADDRSTRLEN] ;
+  static char ipAddress [1024] ;
+
+  if (clientSockAddr.sin.sin_family == AF_INET)	// IPv4
+  {
+    if (snprintf (ipAddress, 1024, "IPv4: %s", 
+	inet_ntop (clientSockAddr.sin.sin_family, (void *)&clientSockAddr.sin.sin_addr, buf, sizeof (buf))) == 1024)
+      strcpy (ipAddress, "Too long") ;
+  }
+  else						// IPv6
+  {
+    if (clientSockAddr.sin.sin_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&clientSockAddr.sin6.sin6_addr))
+    {
+      if (snprintf (ipAddress, 1024, "IPv4in6: %s", 
+	inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
+      strcpy (ipAddress, "Too long") ;
+    }
+    else
+    {
+      if (snprintf (ipAddress, 1024, "IPv6: %s", 
+	inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024)
+      strcpy (ipAddress, "Too long") ;
+    }
+  }
+
+  return ipAddress ;
+}
+
+
+
+/*
+ * clientPstr: clientPrintf:
+ *	Print over a network socket
+ *********************************************************************************
+ */
+
+static int clientPstr (int fd, char *s)
+{
+  int len = strlen (s) ;
+  return (write (fd, s, len) == len) ? 0 : -1 ;
+}
+
+static int clientPrintf (const int fd, const char *message, ...)
+{
+  va_list argp ;
+  char buffer [1024] ;
+
+  va_start (argp, message) ;
+    vsnprintf (buffer, 1023, message, argp) ;
+  va_end (argp) ;
+
+  return clientPstr (fd, buffer) ;
+}
+
+
+/*
+ * sendGreeting:
+ *	Send some text to the client device
+ *********************************************************************************
+ */
+
+int sendGreeting (int clientFd)
+{
+  if (clientPrintf (clientFd, "200 Welcome to wiringPiD - http://wiringpi.com/\n") < 0)
+    return -1 ;
+
+  return clientPrintf (clientFd, "200 Connecting from: %s\n", getClientIP ()) ;
+}
+
+
+/*
+ * getSalt:
+ *	Create a random 'salt' value for the password encryption process
+ *********************************************************************************
+ */
+
+static int getSalt (char drySalt [])
+{
+  static const char *seaDog =	"abcdefghijklmnopqrstuvwxyz"
+				"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+				"0123456789/." ;
+
+  unsigned char wetSalt [SALT_LEN] ;
+  int i, fd ;
+
+  if ((fd = open ("/dev/urandom", O_RDONLY)) < 0)
+    return fd ;
+
+  if (read (fd, wetSalt, SALT_LEN) != SALT_LEN)
+    return -1 ;
+
+  close (fd) ;
+
+  for (i = 0 ; i < SALT_LEN ; ++i)
+    drySalt [i] = seaDog [wetSalt [i] & 63] ;
+    
+  drySalt [SALT_LEN] = 0 ;
+
+  return 0 ;
+}
+
+
+/*
+ * sendChallenge:
+ *	Create and send our salt (aka nonce) to the remote device
+ *********************************************************************************
+ */
+
+int sendChallenge (int clientFd)
+{
+  if (getSalt (salt) < 0)
+    return -1 ;
+
+  return clientPrintf (clientFd, "Challenge %s\n", salt) ;
+}
+
+
+/*
+ * getResponse:
+ *	Read the encrypted password from the remote device.
+ *********************************************************************************
+ */
+
+
+int getResponse (int clientFd)
+{
+  char reply [1024] ;
+  int len ;
+
+// Being sort of lazy about this. I'm expecting an SHA-512 hash back and these
+//	are exactly 86 characters long, so no reason not to, I guess...
+
+  len = 86 ;
+
+  if (setsockopt (clientFd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
+    return -1 ;
+
+  len = recv (clientFd, reply, 86, 0) ;
+  if (len != 86)
+    return -1 ;
+
+  reply [len] = 0 ;
+
+  if ((returnedHash = malloc (len + 1)) == NULL)
+    return -1 ;
+
+  strcpy (returnedHash, reply) ;
+
+  return 0 ;
+}
+
+
+/*
+ * passwordMatch:
+ *	See if there's a match. If not, we simply dump them.
+ *********************************************************************************
+ */
+
+int passwordMatch (const char *password)
+{
+  char *encrypted ;
+  char salted [1024] ;
+
+  sprintf (salted, "$6$%s$", salt) ;
+
+  encrypted = crypt (password, salted) ;
+
+// 20: $6$ then 16 characters of salt, then $
+// 86 is the length of an SHA-512 hash
+
+  return strncmp (encrypted + 20, returnedHash, 86) == 0 ;
+}
+
+
+/* 
+ * setupServer:
+ *	Do what's needed to create a local server socket instance that can listen
+ *	on both IPv4 and IPv6 interfaces.
+ *********************************************************************************
+ */
+
+int setupServer (int serverPort)
+{
+  socklen_t clientSockAddrSize = sizeof (clientSockAddr) ;
+
+  int on = 1 ;
+  int family ;
+  socklen_t serverSockAddrSize ;
+  int clientFd ;
+
+// Try to create an IPv6 socket
+
+  serverFd = socket (PF_INET6, SOCK_STREAM, 0) ;
+
+// If it didn't work, then fall-back to IPv4.
+
+  if (serverFd < 0)
+  {
+    if ((serverFd = socket (PF_INET, SOCK_STREAM, 0)) < 0)
+      return -1 ;
+
+    family             = AF_INET ;
+    serverSockAddrSize = sizeof (struct sockaddr_in) ;
+  }
+  else		// We got an IPv6 socket
+  {
+    family             = AF_INET6 ;
+    serverSockAddrSize = sizeof (struct sockaddr_in6) ;
+  }
+
+  if (setsockopt (serverFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+    return -1 ;
+
+// Setup the servers socket address - cope with IPv4 and v6.
+
+  memset (&serverSockAddr, 0, sizeof (serverSockAddr)) ;
+  switch (family)
+  {
+    case AF_INET:
+      serverSockAddr.sin.sin_family      = AF_INET ;
+      serverSockAddr.sin.sin_addr.s_addr = htonl (INADDR_ANY) ;
+      serverSockAddr.sin.sin_port        = htons (serverPort) ;
+      break;
+
+    case AF_INET6:
+      serverSockAddr.sin6.sin6_family = AF_INET6 ;
+      serverSockAddr.sin6.sin6_addr   = in6addr_any ;
+      serverSockAddr.sin6.sin6_port   = htons (serverPort) ;
+  }
+
+// Bind, listen and accept
+
+  if (bind (serverFd, (struct sockaddr *)&serverSockAddr, serverSockAddrSize) < 0)
+    return -1 ;
+
+  if (listen (serverFd, 4) < 0)	// Really only going to talk to one client at a time...
+    return -1 ;
+
+  if ((clientFd = accept (serverFd, (struct sockaddr *)&clientSockAddr, &clientSockAddrSize)) < 0)
+    return -1 ;
+
+  return clientFd ;
+}
+
+
+/*
+ * closeServer:
+ *********************************************************************************
+ */
+
+void closeServer (int clientFd)
+{
+  if (serverFd != -1) close (serverFd) ;
+  if (clientFd != -1) close (clientFd) ;
+  serverFd = clientFd = -1 ;
+}
diff --git a/wiringPiD/network.h b/wiringPiD/network.h
new file mode 100644
index 0000000..94c3380
--- /dev/null
+++ b/wiringPiD/network.h
@@ -0,0 +1,31 @@
+/*
+ * network.h:
+ *	Part of wiringPiD
+ *	Copyright (c) 2012-2017 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/>.
+ ***********************************************************************
+ */
+
+extern char *getClientIP   (void) ;
+extern int   getResponce   (int clientFd) ;
+extern int   setupServer   (int serverPort) ;
+extern int   sendGreeting  (int clientFd) ;
+extern int   sendChallenge (int clientFd) ;
+extern int   getResponse   (int clientFd) ;
+extern int   passwordMatch (const char *password) ;
+extern void  closeServer   (int clientFd) ;
diff --git a/wiringPiD/runRemote.c b/wiringPiD/runRemote.c
new file mode 100644
index 0000000..cd7432b
--- /dev/null
+++ b/wiringPiD/runRemote.c
@@ -0,0 +1,126 @@
+/*
+ * runRemote.c:
+ *	Run the remote commands passed over the network link.
+ *
+ *	Copyright (c) 2012-2017 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 <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+//#include <stdarg.h>
+
+#include <wiringPi.h>
+#include <wpiExtensions.h>
+
+#include "drcNetCmd.h"
+#include "network.h"
+#include "runRemote.h"
+
+
+
+int noLocalPins = FALSE ;
+
+
+void runRemoteCommands (int fd)
+{
+  register uint32_t pin ;
+  int len ;
+  struct drcNetComStruct cmd ;
+
+  len = sizeof (struct drcNetComStruct) ;
+
+  if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0)
+    return ;
+
+  for (;;)
+  {
+    if (recv (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))	// Probably remote hangup
+      return ;
+
+    pin = cmd.pin ;
+    if (noLocalPins && ((pin & PI_GPIO_MASK) == 0))
+    {
+      if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	return ;
+      continue ;
+    }
+
+    switch (cmd.cmd)
+    {
+      case DRCN_PIN_MODE:
+	pinMode (pin, cmd.data) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_PULL_UP_DN:
+	pullUpDnControl (pin, cmd.data) ;
+	break ;
+
+      case DRCN_PWM_WRITE:
+	pwmWrite (pin, cmd.data) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_DIGITAL_WRITE:
+	digitalWrite (pin, cmd.data) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_DIGITAL_WRITE8:
+	//digitalWrite8 (pin, cmd.data) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_DIGITAL_READ:
+	cmd.data = digitalRead (pin) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_DIGITAL_READ8:
+	//cmd.data = digitalRead8 (pin) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_ANALOG_WRITE:
+	analogWrite (pin, cmd.data) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+
+      case DRCN_ANALOG_READ:
+	cmd.data = analogRead (pin) ;
+	if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd))
+	  return ;
+	break ;
+    }
+  }
+
+}
diff --git a/wiringPiD/runRemote.h b/wiringPiD/runRemote.h
new file mode 100644
index 0000000..57d5018
--- /dev/null
+++ b/wiringPiD/runRemote.h
@@ -0,0 +1,29 @@
+/*
+ * runRemote.h:
+ *	Run the remote commands passed over the network link.
+ *
+ *	Copyright (c) 2012-2017 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/>.
+ ***********************************************************************
+ */
+
+// Globals
+
+extern int noLocalPins ;
+
+extern void runRemoteCommands (int fd) ;
diff --git a/wiringPiD/wiringpid.c b/wiringPiD/wiringpid.c
new file mode 100644
index 0000000..8dde1cd
--- /dev/null
+++ b/wiringPiD/wiringpid.c
@@ -0,0 +1,382 @@
+/*
+ * wiringPiD.c:
+ *	Copyright (c) 2012-2017 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 <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <wiringPi.h>
+#include <wpiExtensions.h>
+
+#include "drcNetCmd.h"
+#include "network.h"
+#include "runRemote.h"
+#include "daemonise.h"
+
+
+#define	PIDFILE	"/var/run/wiringPiD.pid"
+
+
+// Globals
+
+static const char *usage = "[-h] [-d] [-g | -1 | -z] [[-x extension:pin:params] ...] password" ;
+static int doDaemon = FALSE ;
+
+//
+
+static void logMsg (const char *message, ...)
+{
+  va_list argp ;
+  char buffer [1024] ;
+
+  va_start (argp, message) ;
+    vsnprintf (buffer, 1023, message, argp) ;
+  va_end (argp) ;
+
+  if (doDaemon)
+    syslog (LOG_DAEMON | LOG_INFO, "%s", buffer) ;
+  else
+    printf ("%s\n", buffer) ;
+}
+
+
+/*
+ * sigHandler:
+ * setupSigHandler:
+ *      Somehing has happened that would normally terminate the program so try
+ *	to close down nicely.
+ *********************************************************************************
+ */
+
+void sigHandler (int sig)
+{
+  logMsg ("Exiting on signal %d: %s", sig, strsignal (sig)) ;
+  (void)unlink (PIDFILE) ;
+  exit (EXIT_FAILURE) ;
+}
+
+void setupSigHandler (void)
+{
+  struct sigaction action ;
+
+  sigemptyset (&action.sa_mask) ;
+  action.sa_flags = 0 ;
+
+// Ignore what we can
+
+  action.sa_handler = SIG_IGN ;
+
+  sigaction (SIGHUP,  &action, NULL) ;
+  sigaction (SIGTTIN, &action, NULL) ;
+  sigaction (SIGTTOU, &action, NULL) ;
+
+// Trap what we can to exit gracefully
+
+  action.sa_handler = sigHandler ;
+
+  sigaction (SIGINT,  &action, NULL) ;
+  sigaction (SIGQUIT, &action, NULL) ;
+  sigaction (SIGILL,  &action, NULL) ;
+  sigaction (SIGABRT, &action, NULL) ;
+  sigaction (SIGFPE,  &action, NULL) ;
+  sigaction (SIGSEGV, &action, NULL) ;
+  sigaction (SIGPIPE, &action, NULL) ;
+  sigaction (SIGALRM, &action, NULL) ;
+  sigaction (SIGTERM, &action, NULL) ;
+  sigaction (SIGUSR1, &action, NULL) ;
+  sigaction (SIGUSR2, &action, NULL) ;
+  sigaction (SIGCHLD, &action, NULL) ;
+  sigaction (SIGTSTP, &action, NULL) ;
+  sigaction (SIGBUS,  &action, NULL) ;
+}
+
+
+/*
+ * The works...
+ *********************************************************************************
+ */
+
+int main (int argc, char *argv [])
+{
+  int clientFd ;
+  char *p, *password ;
+  int i ;
+  int port = DEFAULT_SERVER_PORT ;
+  int wpiSetup = 0 ;
+
+  if (argc < 2)
+  {
+    fprintf (stderr, "Usage: %s %s\n", argv [0], usage) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+// Help?
+
+  if (strcasecmp (argv [1], "-h") == 0)
+  {
+    printf ("Usage: %s %s\n", argv [0], usage) ;
+    return 0 ;
+  }
+
+// Daemonize?
+//	Must come before the other args as e.g. some extensions
+//	open files which get closed on daemonise...
+
+  if (strcasecmp (argv [1], "-d") == 0)
+  {
+    if (geteuid () != 0)
+    {
+      fprintf (stderr, "%s: Must be root to run as a daemon.\n", argv [0]) ;
+      exit (EXIT_FAILURE) ;
+    }
+
+    doDaemon = TRUE ;
+    daemonise (PIDFILE) ;
+
+    for (i = 2 ; i < argc ; ++i)
+      argv [i - 1] = argv [i] ;
+    --argc ;
+  }
+
+// Scan all other arguments
+
+  while (*argv [1] == '-')
+  {
+
+// Look for wiringPi setup arguments:
+//	Same as the gpio command and rtb.
+
+//	-g - bcm_gpio
+
+    if (strcasecmp (argv [1], "-g") == 0)
+    {
+      if (wpiSetup == 0)
+      {
+	logMsg ("BCM_GPIO mode selected") ;
+	wiringPiSetupGpio () ;
+      }
+
+      for (i = 2 ; i < argc ; ++i)
+	argv [i - 1] = argv [i] ;
+      --argc ;
+      ++wpiSetup ;
+      continue ;
+    }
+
+//	-1 - physical pins
+
+    if (strcasecmp (argv [1], "-1") == 0)
+    {
+      if (wpiSetup == 0)
+      {
+	logMsg ("GPIO-PHYS mode selected") ;
+	wiringPiSetupPhys () ;
+      }
+
+      for (i = 2 ; i < argc ; ++i)
+	argv [i - 1] = argv [i] ;
+      --argc ;
+      ++wpiSetup ;
+      continue ;
+    }
+
+//	-z  - no wiringPi - blocks remotes accessing local pins
+
+    if (strcasecmp (argv [1], "-z") == 0)
+    {
+      if (wpiSetup == 0)
+	logMsg ("No GPIO mode selected") ;
+
+      for (i = 2 ; i < argc ; ++i)
+	argv [i - 1] = argv [i] ;
+      --argc ;
+      noLocalPins = TRUE ;
+      ++wpiSetup ;
+      continue ;
+    }
+
+// -p to select the port
+
+    if (strcasecmp (argv [1], "-p") == 0)
+    {
+      if (argc < 3)
+      {
+	logMsg ("-p missing extension port") ;
+	exit (EXIT_FAILURE) ;
+      }
+
+      logMsg ("Setting port to: %s", argv [2]) ;
+
+      port = atoi (argv [2]) ;
+      if ((port < 1) || (port > 65535))
+      {
+	logMsg ("Invalid server port: %d", port) ;
+	exit (EXIT_FAILURE) ;
+      }
+
+// Shift args down by 2
+
+      for (i = 3 ; i < argc ; ++i)
+	argv [i - 2] = argv [i] ;
+      argc -= 2 ;
+
+      continue ;
+    }
+
+// Check for -x argument to load in a new extension
+//	-x extension:base:args
+//	Can load many modules to extend the daemon.
+
+    if (strcasecmp (argv [1], "-x") == 0)
+    {
+      if (argc < 3)
+      {
+	logMsg ("-x missing extension name:data:etc.") ;
+	exit (EXIT_FAILURE) ;
+      }
+
+      logMsg ("Loading extension: %s", argv [2]) ;
+
+      if (!loadWPiExtension (argv [0], argv [2], TRUE))
+      {
+	logMsg ("Extension load failed: %s", strerror (errno)) ;
+	exit (EXIT_FAILURE) ;
+      }
+
+// Shift args down by 2
+
+      for (i = 3 ; i < argc ; ++i)
+	argv [i - 2] = argv [i] ;
+      argc -= 2 ;
+
+      continue ;
+    }
+
+    logMsg ("Invalid parameter: %s", argv [1]) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+// Default to wiringPi mode
+
+  if (wpiSetup == 0)
+  {
+    logMsg ("WiringPi GPIO mode selected") ;
+    wiringPiSetup () ;
+  }
+
+// Finally, should just be one arg left - the password...
+
+  if (argc != 2)
+  {
+    logMsg ("No password supplied") ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  if (strlen (argv [1]) < 6)
+  {
+    logMsg ("Password too short - at least 6 chars, not %d", strlen (argv [1])) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  if ((password = malloc (strlen (argv [1]) + 1)) == NULL)
+  {
+    logMsg ("Out of memory") ;
+    exit (EXIT_FAILURE) ;
+  }
+  strcpy (password, argv [1]) ;
+
+// Wipe out the password on the command-line in a vague attempt to try to
+//	hide it from snoopers
+
+  for (p = argv [1] ; *p ; ++p)
+    *p = ' ' ;
+
+  setupSigHandler () ;
+ 
+// Enter our big loop
+
+  for (;;)
+  {
+
+    if (!doDaemon)
+      printf ("-=-\nWaiting for a new connection...\n") ;
+
+    if ((clientFd = setupServer (port)) < 0)
+    {
+      logMsg ("Unable to setup server: %s", strerror (errno)) ;
+      exit (EXIT_FAILURE) ;
+    }
+
+    logMsg ("New connection from: %s.", getClientIP ()) ;
+
+    if (!doDaemon)
+      printf ("Sending Greeting.\n") ;
+
+    if (sendGreeting (clientFd) < 0)
+    {
+      logMsg ("Unable to send greeting message: %s", strerror (errno)) ;
+      closeServer (clientFd) ;
+      continue ;
+    }
+
+    if (!doDaemon)
+      printf ("Sending Challenge.\n") ;
+
+    if (sendChallenge (clientFd) < 0)
+    {
+      logMsg ("Unable to send challenge message: %s", strerror (errno)) ;
+      closeServer (clientFd) ;
+      continue ;
+    }
+
+    if (!doDaemon)
+      printf ("Waiting for response.\n") ;
+
+    if (getResponse (clientFd) < 0)
+    {
+      logMsg ("Connection closed waiting for response: %s", strerror (errno)) ;
+      closeServer (clientFd) ;
+      continue ;
+    }
+
+    if (!passwordMatch (password))
+    {
+      logMsg ("Password failure") ;
+      closeServer (clientFd) ;
+      continue ;
+    }
+
+    logMsg ("Password OK - Starting") ;
+
+    runRemoteCommands (clientFd) ;
+    closeServer       (clientFd) ;
+  }
+
+  return 0 ;
+}