chiark / gitweb /
wiringPi Version 2 - First commit (of v2)
authorGordon Henderson <projects@drogon.net>
Mon, 13 May 2013 18:43:26 +0000 (19:43 +0100)
committerGordon Henderson <projects@drogon.net>
Mon, 13 May 2013 18:43:26 +0000 (19:43 +0100)
97 files changed:
INSTALL
README.TXT
build
devLib/Makefile [new file with mode: 0644]
devLib/ds1302.c [new file with mode: 0644]
devLib/ds1302.h [moved from wiringPi/lcd.h with 58% similarity]
devLib/font.h [new file with mode: 0644]
devLib/gertboard.c [moved from wiringPi/gertboard.c with 68% similarity]
devLib/gertboard.h [moved from wiringPi/gertboard.h with 86% similarity]
devLib/lcd.c [moved from wiringPi/lcd.c with 64% similarity]
devLib/lcd.h [new file with mode: 0644]
devLib/lcd128x64.c [new file with mode: 0644]
devLib/lcd128x64.h [new file with mode: 0644]
devLib/maxdetect.c [new file with mode: 0755]
devLib/maxdetect.h [new file with mode: 0755]
devLib/piFace.c [new file with mode: 0644]
devLib/piFace.h [new file with mode: 0644]
devLib/piFaceOld.c [new file with mode: 0644]
devLib/piNes.c [moved from wiringPi/piNes.c with 100% similarity]
devLib/piNes.h [moved from wiringPi/piNes.h with 100% similarity]
examples/Gertboard/7segments.c [new file with mode: 0644]
examples/Gertboard/Makefile [new file with mode: 0644]
examples/Gertboard/buttons.c [new file with mode: 0644]
examples/Gertboard/gertboard.c [moved from examples/gertboard.c with 61% similarity]
examples/Gertboard/record.c [new file with mode: 0644]
examples/Gertboard/temperature.c [new file with mode: 0644]
examples/Gertboard/voltmeter.c [new file with mode: 0644]
examples/Gertboard/vumeter.c [new file with mode: 0644]
examples/Makefile
examples/PiFace/Makefile [new file with mode: 0644]
examples/PiFace/blink.c [new file with mode: 0644]
examples/PiFace/buttons.c [new file with mode: 0644]
examples/PiFace/ladder.c [new file with mode: 0755]
examples/PiFace/metro.c [new file with mode: 0644]
examples/PiFace/motor.c [new file with mode: 0644]
examples/PiFace/reaction.c [new file with mode: 0644]
examples/blink.c
examples/blink12.c [moved from examples/test1.c with 70% similarity]
examples/blink8.c [moved from examples/test2.c with 66% similarity]
examples/clock.c [new file with mode: 0644]
examples/ds1302.c [new file with mode: 0644]
examples/gertboard.png [deleted file]
examples/isr.c
examples/lcd.c
examples/okLed.c
examples/pwm.c
examples/rht03.c [moved from examples/piface.c with 60% similarity, mode: 0755]
examples/softPwm.c [new file with mode: 0644]
examples/softTone.c [moved from examples/tone.c with 92% similarity]
examples/speed.c
gpio/Makefile
gpio/extensions.c [new file with mode: 0644]
gpio/extensions.h [new file with mode: 0644]
gpio/gpio.1
gpio/gpio.c
gpio/pintest [new file with mode: 0755]
pins/Makefile [new file with mode: 0644]
pins/pins.pdf [new file with mode: 0644]
pins/pins.tex [new file with mode: 0644]
wiringPi/Makefile
wiringPi/README [deleted file]
wiringPi/drc.c [new file with mode: 0644]
wiringPi/drc.h [new file with mode: 0644]
wiringPi/mcp23008.c [new file with mode: 0644]
wiringPi/mcp23008.h [new file with mode: 0644]
wiringPi/mcp23017.c [new file with mode: 0644]
wiringPi/mcp23017.h [new file with mode: 0644]
wiringPi/mcp23s08.c [new file with mode: 0644]
wiringPi/mcp23s08.h [new file with mode: 0644]
wiringPi/mcp23s17.c [new file with mode: 0644]
wiringPi/mcp23s17.h [new file with mode: 0644]
wiringPi/mcp23x08.h [new file with mode: 0644]
wiringPi/mcp23x0817.h [new file with mode: 0644]
wiringPi/mcp3002.c [new file with mode: 0644]
wiringPi/mcp3002.h [new file with mode: 0644]
wiringPi/mcp3422.c [new file with mode: 0644]
wiringPi/mcp3422.h [new file with mode: 0644]
wiringPi/mcp4802.c [new file with mode: 0644]
wiringPi/mcp4802.h [new file with mode: 0644]
wiringPi/pcf8574.c [new file with mode: 0644]
wiringPi/pcf8574.h [new file with mode: 0644]
wiringPi/piHiPri.c
wiringPi/softPwm.c
wiringPi/softTone.c
wiringPi/softTone.h
wiringPi/sr595.c [new file with mode: 0644]
wiringPi/sr595.h [new file with mode: 0644]
wiringPi/wiringPi.c
wiringPi/wiringPi.h
wiringPi/wiringPiFace.c [deleted file]
wiringPi/wiringPiI2C.c
wiringPi/wiringPiI2C.h
wiringPi/wiringPiSPI.c
wiringPi/wiringSerial.c
wiringPi/wiringSerial.h
wiringPi/wiringShift.c
wiringPi/wiringShift.h

diff --git a/INSTALL b/INSTALL
index 8a6d38e4e1cc7ad3717db37feb3151d4c5369abe..8e0c43cf3994eab0b51fe83854ca624058331215 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -30,18 +30,6 @@ To un-install wiringPi:
 
   ./build uninstall
 
-
-I2C:
-
-If your system has the correct i2c-dev libraries and headers installed,
-then the I2C helpers will be compiled into wiringPi. If you want to
-use the I2C helpers and don't have them installed, then under Raspbian,
-issue the command:
-
-  sudo apt-get install libi2c-dev
-
-Consult the documentation for your system if you are not running Raspbian.
-
 Gordon Henderson
 
 projects@drogon.net
index 0fce86a5ec3925878b2d8ee330e72f1de01568a6..7789b2eba205801581acb565686f402ff62a0479 100644 (file)
@@ -16,7 +16,7 @@ accepted to Github....
 
 Please see
 
-  https://projects.drogon.net/raspberry-pi/wiringpi/
+  http://wiringpi.com/
 
 for the official documentation, etc. and the best way to submit bug reports, etc.
 is by sending an email to projects@drogon.net
diff --git a/build b/build
index cbb1a4fd31cb6e2d344d239cd7512cbbc41ec447..048ebb39d690309bd6e71643affe63692bac70ec 100755 (executable)
--- a/build
+++ b/build
@@ -14,28 +14,28 @@ check-make-ok()
 }
 
 if [ x$1 = "xclean" ]; then
-  echo Cleaning
-  echo
   cd wiringPi
-  make clean
+  echo -n "wiringPi:  "        ; make clean
+  cd ../devLib
+  echo -n "DevLib:    "        ; make clean
   cd ../gpio
-  make clean
+  echo -n "gpio:      "        ; make clean
   cd ../examples
-  make clean
+  echo -n "Examples:  "        ; make clean
+  cd Gertboard
+  echo -n "Gertboard: "        ; make clean
+  cd ../PiFace
+  echo -n "PiFace:    "        ; make clean
   exit
 fi
 
 if [ x$1 = "xuninstall" ]; then
-  echo Uninstalling
-  echo
-  echo "WiringPi library"
   cd wiringPi
-  sudo make uninstall
-  echo
-  echo "GPIO Utility"
+  echo -n "wiringPi: " ; sudo make uninstall
+  cd ../devLib
+  echo -n "DevLib:   " ; sudo make uninstall
   cd ../gpio
-  sudo make uninstall
-  cd ..
+  echo -n "gpio:     " ; sudo make uninstall
   exit
 fi
 
@@ -44,25 +44,20 @@ fi
   echo "====================="
   echo
 
-# Check for I2C being installed...
-#      ... and if-so, then automatically make the I2C helpers
-
-  if [ -f /usr/include/linux/i2c-dev.h ]; then
-    grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h
-    if [ $? = 0 ]; then
-      target=i2c
-      echo "Building wiringPi with the I2C helper libraries."
-    else
-      target=all
-      echo "The wiringPi I2C helper libraries will not be built."
-    fi
-  fi
-
   echo
-  echo "WiringPi library"
+  echo "WiringPi Library"
   cd wiringPi
   sudo make uninstall
-  make $target
+  make
+  check-make-ok
+  sudo make install
+  check-make-ok
+
+  echo
+  echo "WiringPi Devices Library"
+  cd ../devLib
+  sudo make uninstall
+  make
   check-make-ok
   sudo make install
   check-make-ok
diff --git a/devLib/Makefile b/devLib/Makefile
new file mode 100644 (file)
index 0000000..a106d93
--- /dev/null
@@ -0,0 +1,130 @@
+# Makefile:
+#      wiringPi device - Wiring Compatable library 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/>.
+#################################################################################
+
+DYN_VERS_MAJ=2
+DYN_VERS_MIN=0
+
+VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
+DESTDIR=/usr
+PREFIX=/local
+
+STATIC=libwiringPiDev.a
+DYNAMIC=libwiringPiDev.so.$(VERSION)
+
+#DEBUG = -g -O0
+DEBUG  = -O2
+CC     = gcc
+INCLUDE        = -I.
+CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC
+
+LIBS    =
+
+###############################################################################
+
+SRC    =       ds1302.c maxdetect.c  piNes.c           \
+               gertboard.c piFace.c                    \
+               lcd128x64.c lcd.c
+
+OBJ    =       $(SRC:.c=.o)
+
+all:           $(DYNAMIC)
+
+static:                $(STATIC)
+
+$(STATIC):     $(OBJ)
+       @echo "[Link (Static)]"
+       @ar rcs $(STATIC) $(OBJ)
+       @ranlib $(STATIC)
+#      @size   $(STATIC)
+
+$(DYNAMIC):    $(OBJ)
+       @echo "[Link (Dynamic)]"
+       @$(CC) -shared -Wl,-soname,libwiringPiDev.so -o libwiringPiDev.so.$(VERSION) -lpthread $(OBJ)
+
+.c.o:
+       @echo [Compile] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+.PHONEY:       clean
+clean:
+       @echo "[Clean]"
+       @rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPiDev.*
+
+.PHONEY:       tags
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+
+.PHONEY:       install-headers
+install-headers:
+       @echo "[Install Headers]"
+       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 ds1302.h               $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 maxdetect.h            $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 piNes.h                $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 gertboard.h            $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 piFace.h               $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 lcd128x64.h            $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 lcd.h                  $(DESTDIR)$(PREFIX)/include
+
+.PHONEY:       install
+install:       $(DYNAMIC) install-headers
+       @echo "[Install Dynamic Lib]"
+       @install -m 0755 -d                                             $(DESTDIR)$(PREFIX)/lib
+       @install -m 0755 libwiringPiDev.so.$(VERSION)                   $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION)
+       @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION)    $(DESTDIR)/lib/libwiringPiDev.so
+       @ldconfig
+
+.PHONEY:       install-static
+install-static:        $(STATIC) install-headers
+       @echo "[Install Static Lib]"
+       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/lib
+       @install -m 0755 libwiringPiDev.a       $(DESTDIR)$(PREFIX)/lib
+
+.PHONEY:       uninstall
+uninstall:
+       @echo "[UnInstall]"
+       @rm -f $(DESTDIR)$(PREFIX)/include/ds1302.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/maxdetect.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/piFace.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/lcd128x64.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
+       @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.*
+       @ldconfig
+
+
+.PHONEY:       depend
+depend:
+       makedepend -Y $(SRC)
+
+# 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 (file)
index 0000000..cf64de7
--- /dev/null
@@ -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
+}
similarity index 58%
rename from wiringPi/lcd.h
rename to devLib/ds1302.h
index beebb7545fe91d4ac83956a9afa168effb4fba6b..e82b3ed092b2dca77841cc7d03c0e01ecf2d35c5 100644 (file)
@@ -1,10 +1,8 @@
 /*
- * lcd.h:
- *     Text-based LCD driver.
- *     This is designed to drive the parallel interface LCD drivers
- *     based in the Hitachi HD44780U controller and compatables.
+ * ds1302.h:
+ *     Real Time clock
  *
- * Copyright (c) 2012 Gordon Henderson.
+ * Copyright (c) 2013 Gordon Henderson.
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
  ***********************************************************************
  */
 
-#define        MAX_LCDS        8
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern void lcdHome        (int fd) ;
-extern void lcdClear       (int fd) ;
-extern void lcdSendCommand (int fd, uint8_t command) ;
-extern void lcdPosition    (int fd, int x, int y) ;
-extern void lcdPutchar     (int fd, uint8_t data) ;
-extern void lcdPuts        (int fd, char *string) ;
-extern void lcdPrintf      (int fd, char *message, ...) ;
+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 int  lcdInit (int rows, int cols, int bits, int rs, int strb,
-       int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
+extern void         ds1302setup         (const int clockPin, const int dataPin, const int csPin) ;
 
 #ifdef __cplusplus
 }
diff --git a/devLib/font.h b/devLib/font.h
new file mode 100644 (file)
index 0000000..ce99e16
--- /dev/null
@@ -0,0 +1,2577 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*       ------------------------------       */
+/*       Combined with the alpha-numeric      */
+/*       portion of Greg Harp's old PEARL     */
+/*       font (from earlier versions of       */
+/*       linux-m86k) by John Shifflett        */
+/*                                            */
+/**********************************************/
+
+static const int fontHeight = 8 ;
+static const int fontWidth  = 8 ;
+
+static unsigned char font [] =
+{
+   /* 0 0x00 '^@' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 1 0x01 '^A' */
+   0x7e, /* 01111110 */
+   0x81, /* 10000001 */
+   0xa5, /* 10100101 */
+   0x81, /* 10000001 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0x81, /* 10000001 */
+   0x7e, /* 01111110 */
+
+   /* 2 0x02 '^B' */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xdb, /* 11011011 */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+
+   /* 3 0x03 '^C' */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 4 0x04 '^D' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0x10, /* 00010000 */
+   0x00, /* 00000000 */
+
+   /* 5 0x05 '^E' */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0x38, /* 00111000 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 6 0x06 '^F' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x7c, /* 01111100 */
+   0xfe, /* 11111110 */
+   0xfe, /* 11111110 */
+   0x7c, /* 01111100 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+
+   /* 7 0x07 '^G' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 8 0x08 '^H' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xe7, /* 11100111 */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0xe7, /* 11100111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 9 0x09 '^I' */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x42, /* 01000010 */
+   0x42, /* 01000010 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 10 0x0a '^J' */
+   0xff, /* 11111111 */
+   0xc3, /* 11000011 */
+   0x99, /* 10011001 */
+   0xbd, /* 10111101 */
+   0xbd, /* 10111101 */
+   0x99, /* 10011001 */
+   0xc3, /* 11000011 */
+   0xff, /* 11111111 */
+
+   /* 11 0x0b '^K' */
+   0x0f, /* 00001111 */
+   0x07, /* 00000111 */
+   0x0f, /* 00001111 */
+   0x7d, /* 01111101 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x78, /* 01111000 */
+
+   /* 12 0x0c '^L' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+
+   /* 13 0x0d '^M' */
+   0x3f, /* 00111111 */
+   0x33, /* 00110011 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x70, /* 01110000 */
+   0xf0, /* 11110000 */
+   0xe0, /* 11100000 */
+
+   /* 14 0x0e '^N' */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x7f, /* 01111111 */
+   0x63, /* 01100011 */
+   0x63, /* 01100011 */
+   0x67, /* 01100111 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+
+   /* 15 0x0f '^O' */
+   0x18, /* 00011000 */
+   0xdb, /* 11011011 */
+   0x3c, /* 00111100 */
+   0xe7, /* 11100111 */
+   0xe7, /* 11100111 */
+   0x3c, /* 00111100 */
+   0xdb, /* 11011011 */
+   0x18, /* 00011000 */
+
+   /* 16 0x10 '^P' */
+   0x80, /* 10000000 */
+   0xe0, /* 11100000 */
+   0xf8, /* 11111000 */
+   0xfe, /* 11111110 */
+   0xf8, /* 11111000 */
+   0xe0, /* 11100000 */
+   0x80, /* 10000000 */
+   0x00, /* 00000000 */
+
+   /* 17 0x11 '^Q' */
+   0x02, /* 00000010 */
+   0x0e, /* 00001110 */
+   0x3e, /* 00111110 */
+   0xfe, /* 11111110 */
+   0x3e, /* 00111110 */
+   0x0e, /* 00001110 */
+   0x02, /* 00000010 */
+   0x00, /* 00000000 */
+
+   /* 18 0x12 '^R' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+
+   /* 19 0x13 '^S' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 20 0x14 '^T' */
+   0x7f, /* 01111111 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7b, /* 01111011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x00, /* 00000000 */
+
+   /* 21 0x15 '^U' */
+   0x3e, /* 00111110 */
+   0x61, /* 01100001 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x86, /* 10000110 */
+   0x7c, /* 01111100 */
+
+   /* 22 0x16 '^V' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 23 0x17 '^W' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+
+   /* 24 0x18 '^X' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 25 0x19 '^Y' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 26 0x1a '^Z' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 27 0x1b '^[' */
+   0x00, /* 00000000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 28 0x1c '^\' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 29 0x1d '^]' */
+   0x00, /* 00000000 */
+   0x24, /* 00100100 */
+   0x66, /* 01100110 */
+   0xff, /* 11111111 */
+   0x66, /* 01100110 */
+   0x24, /* 00100100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 30 0x1e '^^' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 31 0x1f '^_' */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x7e, /* 01111110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 32 0x20 ' ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 33 0x21 '!' */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 34 0x22 '"' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 35 0x23 '#' */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 36 0x24 '$' */
+   0x18, /* 00011000 */
+   0x3e, /* 00111110 */
+   0x60, /* 01100000 */
+   0x3c, /* 00111100 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 37 0x25 '%' */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x66, /* 01100110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 38 0x26 '&' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x68, /* 01101000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 39 0x27 ''' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 40 0x28 '(' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 41 0x29 ')' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 42 0x2a '*' */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0xff, /* 11111111 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 43 0x2b '+' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 44 0x2c ',' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 45 0x2d '-' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 46 0x2e '.' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 47 0x2f '/' */
+   0x03, /* 00000011 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 48 0x30 '0' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xfe, /* 11111110 */
+   0xf6, /* 11110110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 49 0x31 '1' */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 50 0x32 '2' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 51 0x33 '3' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x06, /* 00000110 */
+   0x1c, /* 00011100 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 52 0x34 '4' */
+   0x1c, /* 00011100 */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 53 0x35 '5' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 54 0x36 '6' */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 55 0x37 '7' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 56 0x38 '8' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 57 0x39 '9' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 58 0x3a ':' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 59 0x3b ';' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+
+   /* 60 0x3c '<' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+
+   /* 61 0x3d '=' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 62 0x3e '>' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+
+   /* 63 0x3f '?' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 64 0x40 '@' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xde, /* 11011110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 65 0x41 'A' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 66 0x42 'B' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 67 0x43 'C' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 68 0x44 'D' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 69 0x45 'E' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 70 0x46 'F' */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 71 0x47 'G' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 72 0x48 'H' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 73 0x49 'I' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 74 0x4a 'J' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 75 0x4b 'K' */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 76 0x4c 'L' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 77 0x4d 'M' */
+   0x82, /* 10000010 */
+   0xc6, /* 11000110 */
+   0xee, /* 11101110 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 78 0x4e 'N' */
+   0xc6, /* 11000110 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 79 0x4f 'O' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 80 0x50 'P' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 81 0x51 'Q' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+
+   /* 82 0x52 'R' */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 83 0x53 'S' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x38, /* 00111000 */
+   0x0c, /* 00001100 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 84 0x54 'T' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 85 0x55 'U' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 86 0x56 'V' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 87 0x57 'W' */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0xee, /* 11101110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 88 0x58 'X' */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0xc3, /* 11000011 */
+   0x00, /* 00000000 */
+
+   /* 89 0x59 'Y' */
+   0xc3, /* 11000011 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 90 0x5a 'Z' */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 91 0x5b '[' */
+   0x3c, /* 00111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 92 0x5c '\' */
+   0xc0, /* 11000000 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x06, /* 00000110 */
+   0x03, /* 00000011 */
+   0x00, /* 00000000 */
+
+   /* 93 0x5d ']' */
+   0x3c, /* 00111100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 94 0x5e '^' */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 95 0x5f '_' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+
+   /* 96 0x60 '`' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 97 0x61 'a' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 98 0x62 'b' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 99 0x63 'c' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 100 0x64 'd' */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 101 0x65 'e' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 102 0x66 'f' */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x60, /* 01100000 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x60, /* 01100000 */
+   0x00, /* 00000000 */
+
+   /* 103 0x67 'g' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x7c, /* 01111100 */
+
+   /* 104 0x68 'h' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 105 0x69 'i' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 106 0x6a 'j' */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+
+   /* 107 0x6b 'k' */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xf0, /* 11110000 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 108 0x6c 'l' */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 109 0x6d 'm' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xec, /* 11101100 */
+   0xfe, /* 11111110 */
+   0xd6, /* 11010110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 110 0x6e 'n' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 111 0x6f 'o' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 112 0x70 'p' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfc, /* 11111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfc, /* 11111100 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+
+   /* 113 0x71 'q' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+
+   /* 114 0x72 'r' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0xe6, /* 11100110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 115 0x73 's' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 116 0x74 't' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x36, /* 00110110 */
+   0x1c, /* 00011100 */
+   0x00, /* 00000000 */
+
+   /* 117 0x75 'u' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 118 0x76 'v' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 119 0x77 'w' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xd6, /* 11010110 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 120 0x78 'x' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 121 0x79 'y' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xc3, /* 11000011 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+
+   /* 122 0x7a 'z' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+   0x60, /* 01100000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 123 0x7b '{' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x00, /* 00000000 */
+
+   /* 124 0x7c '|' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 125 0x7d '}' */
+   0x70, /* 01110000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 126 0x7e '~' */
+   0x72, /* 01110010 */
+   0x9c, /* 10011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 127 0x7f '\7f' */
+   0x00, /* 00000000 */
+   0x10, /* 00010000 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 128 0x80 '\80' */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x0c, /* 00001100 */
+   0x78, /* 01111000 */
+
+   /* 129 0x81 '\81' */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 130 0x82 '\82' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 131 0x83 '\83' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 132 0x84 '\84' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 133 0x85 '\85' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 134 0x86 '\86' */
+   0x30, /* 00110000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 135 0x87 '\87' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x0c, /* 00001100 */
+   0x38, /* 00111000 */
+
+   /* 136 0x88 '\88' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 137 0x89 '\89' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 138 0x8a '\8a' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 139 0x8b '\8b' */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 140 0x8c '\8c' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 141 0x8d '\8d' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 142 0x8e '\8e' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 143 0x8f '\8f' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 144 0x90 '\90' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xf8, /* 11111000 */
+   0xc0, /* 11000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 145 0x91 '\91' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 146 0x92 '\92' */
+   0x3e, /* 00111110 */
+   0x6c, /* 01101100 */
+   0xcc, /* 11001100 */
+   0xfe, /* 11111110 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 147 0x93 '\93' */
+   0x7c, /* 01111100 */
+   0x82, /* 10000010 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 148 0x94 '\94' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 149 0x95 '\95' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 150 0x96 '\96' */
+   0x78, /* 01111000 */
+   0x84, /* 10000100 */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 151 0x97 '\97' */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 152 0x98 '\98' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7e, /* 01111110 */
+   0x06, /* 00000110 */
+   0xfc, /* 11111100 */
+
+   /* 153 0x99 '\99' */
+   0xc6, /* 11000110 */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 154 0x9a '\9a' */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 155 0x9b '\9b' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 156 0x9c '\9c' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x64, /* 01100100 */
+   0xf0, /* 11110000 */
+   0x60, /* 01100000 */
+   0x66, /* 01100110 */
+   0xfc, /* 11111100 */
+   0x00, /* 00000000 */
+
+   /* 157 0x9d '\9d' */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 158 0x9e '\9e' */
+   0xf8, /* 11111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xfa, /* 11111010 */
+   0xc6, /* 11000110 */
+   0xcf, /* 11001111 */
+   0xc6, /* 11000110 */
+   0xc7, /* 11000111 */
+
+   /* 159 0x9f '\9f' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 160 0xa0 ' ' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x7c, /* 01111100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 161 0xa1 '¡' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x38, /* 00111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 162 0xa2 '¢' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+
+   /* 163 0xa3 '£' */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 164 0xa4 '¤' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xdc, /* 11011100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x00, /* 00000000 */
+
+   /* 165 0xa5 '¥' */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0xe6, /* 11100110 */
+   0xf6, /* 11110110 */
+   0xde, /* 11011110 */
+   0xce, /* 11001110 */
+   0x00, /* 00000000 */
+
+   /* 166 0xa6 '¦' */
+   0x3c, /* 00111100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 167 0xa7 '§' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 168 0xa8 '¨' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x63, /* 01100011 */
+   0x3e, /* 00111110 */
+   0x00, /* 00000000 */
+
+   /* 169 0xa9 '©' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 170 0xaa 'ª' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0x06, /* 00000110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 171 0xab '«' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7e, /* 01111110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x0f, /* 00001111 */
+
+   /* 172 0xac '¬' */
+   0x63, /* 01100011 */
+   0xe6, /* 11100110 */
+   0x6c, /* 01101100 */
+   0x7a, /* 01111010 */
+   0x36, /* 00110110 */
+   0x6a, /* 01101010 */
+   0xdf, /* 11011111 */
+   0x06, /* 00000110 */
+
+   /* 173 0xad '­' */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 174 0xae '®' */
+   0x00, /* 00000000 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 175 0xaf '¯' */
+   0x00, /* 00000000 */
+   0xcc, /* 11001100 */
+   0x66, /* 01100110 */
+   0x33, /* 00110011 */
+   0x66, /* 01100110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 176 0xb0 '°' */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+   0x22, /* 00100010 */
+   0x88, /* 10001000 */
+
+   /* 177 0xb1 '±' */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+   0x55, /* 01010101 */
+   0xaa, /* 10101010 */
+
+   /* 178 0xb2 '²' */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+   0x77, /* 01110111 */
+   0xdd, /* 11011101 */
+
+   /* 179 0xb3 '³' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 180 0xb4 '´' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 181 0xb5 'µ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 182 0xb6 '¶' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 183 0xb7 '·' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 184 0xb8 '¸' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 185 0xb9 '¹' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 186 0xba 'º' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 187 0xbb '»' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x06, /* 00000110 */
+   0xf6, /* 11110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 188 0xbc '¼' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf6, /* 11110110 */
+   0x06, /* 00000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 189 0xbd '½' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 190 0xbe '¾' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 191 0xbf '¿' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xf8, /* 11111000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 192 0xc0 'À' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 193 0xc1 'Á' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 194 0xc2 'Â' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 195 0xc3 'Ã' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 196 0xc4 'Ä' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 197 0xc5 'Å' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 198 0xc6 'Æ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 199 0xc7 'Ç' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 200 0xc8 'È' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 201 0xc9 'É' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 202 0xca 'Ê' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 203 0xcb 'Ë' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 204 0xcc 'Ì' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x37, /* 00110111 */
+   0x30, /* 00110000 */
+   0x37, /* 00110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 205 0xcd 'Í' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 206 0xce 'Î' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xf7, /* 11110111 */
+   0x00, /* 00000000 */
+   0xf7, /* 11110111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 207 0xcf 'Ï' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 208 0xd0 'Ð' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 209 0xd1 'Ñ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 210 0xd2 'Ò' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 211 0xd3 'Ó' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x3f, /* 00111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 212 0xd4 'Ô' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 213 0xd5 'Õ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 214 0xd6 'Ö' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3f, /* 00111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 215 0xd7 '×' */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0xff, /* 11111111 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+
+   /* 216 0xd8 'Ø' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0xff, /* 11111111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 217 0xd9 'Ù' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xf8, /* 11111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 218 0xda 'Ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x1f, /* 00011111 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 219 0xdb 'Û' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 220 0xdc 'Ü' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+
+   /* 221 0xdd 'Ý' */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+   0xf0, /* 11110000 */
+
+   /* 222 0xde 'Þ' */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+   0x0f, /* 00001111 */
+
+   /* 223 0xdf 'ß' */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0xff, /* 11111111 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 224 0xe0 'à' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0xc8, /* 11001000 */
+   0xdc, /* 11011100 */
+   0x76, /* 01110110 */
+   0x00, /* 00000000 */
+
+   /* 225 0xe1 'á' */
+   0x78, /* 01111000 */
+   0xcc, /* 11001100 */
+   0xcc, /* 11001100 */
+   0xd8, /* 11011000 */
+   0xcc, /* 11001100 */
+   0xc6, /* 11000110 */
+   0xcc, /* 11001100 */
+   0x00, /* 00000000 */
+
+   /* 226 0xe2 'â' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0xc0, /* 11000000 */
+   0x00, /* 00000000 */
+
+   /* 227 0xe3 'ã' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x00, /* 00000000 */
+
+   /* 228 0xe4 'ä' */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+
+   /* 229 0xe5 'å' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+   0x00, /* 00000000 */
+
+   /* 230 0xe6 'æ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x7c, /* 01111100 */
+   0xc0, /* 11000000 */
+
+   /* 231 0xe7 'ç' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+
+   /* 232 0xe8 'è' */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x3c, /* 00111100 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+
+   /* 233 0xe9 'é' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xfe, /* 11111110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+
+   /* 234 0xea 'ê' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0xee, /* 11101110 */
+   0x00, /* 00000000 */
+
+   /* 235 0xeb 'ë' */
+   0x0e, /* 00001110 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x3e, /* 00111110 */
+   0x66, /* 01100110 */
+   0x66, /* 01100110 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+
+   /* 236 0xec 'ì' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 237 0xed 'í' */
+   0x06, /* 00000110 */
+   0x0c, /* 00001100 */
+   0x7e, /* 01111110 */
+   0xdb, /* 11011011 */
+   0xdb, /* 11011011 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0xc0, /* 11000000 */
+
+   /* 238 0xee 'î' */
+   0x1e, /* 00011110 */
+   0x30, /* 00110000 */
+   0x60, /* 01100000 */
+   0x7e, /* 01111110 */
+   0x60, /* 01100000 */
+   0x30, /* 00110000 */
+   0x1e, /* 00011110 */
+   0x00, /* 00000000 */
+
+   /* 239 0xef 'ï' */
+   0x00, /* 00000000 */
+   0x7c, /* 01111100 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0xc6, /* 11000110 */
+   0x00, /* 00000000 */
+
+   /* 240 0xf0 'ð' */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0xfe, /* 11111110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 241 0xf1 'ñ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x7e, /* 01111110 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 242 0xf2 'ò' */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 243 0xf3 'ó' */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x18, /* 00011000 */
+   0x0c, /* 00001100 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+
+   /* 244 0xf4 'ô' */
+   0x0e, /* 00001110 */
+   0x1b, /* 00011011 */
+   0x1b, /* 00011011 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+
+   /* 245 0xf5 'õ' */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0xd8, /* 11011000 */
+   0xd8, /* 11011000 */
+   0x70, /* 01110000 */
+
+   /* 246 0xf6 'ö' */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x7e, /* 01111110 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 247 0xf7 '÷' */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x76, /* 01110110 */
+   0xdc, /* 11011100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 248 0xf8 'ø' */
+   0x38, /* 00111000 */
+   0x6c, /* 01101100 */
+   0x6c, /* 01101100 */
+   0x38, /* 00111000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 249 0xf9 'ù' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 250 0xfa 'ú' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x18, /* 00011000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 251 0xfb 'û' */
+   0x0f, /* 00001111 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0x0c, /* 00001100 */
+   0xec, /* 11101100 */
+   0x6c, /* 01101100 */
+   0x3c, /* 00111100 */
+   0x1c, /* 00011100 */
+
+   /* 252 0xfc 'ü' */
+   0x6c, /* 01101100 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x36, /* 00110110 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 253 0xfd 'ý' */
+   0x78, /* 01111000 */
+   0x0c, /* 00001100 */
+   0x18, /* 00011000 */
+   0x30, /* 00110000 */
+   0x7c, /* 01111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 254 0xfe 'þ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x3c, /* 00111100 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+   /* 255 0xff 'ÿ' */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+   0x00, /* 00000000 */
+
+};
similarity index 68%
rename from wiringPi/gertboard.c
rename to devLib/gertboard.c
index a8795d32a9ea510a4eea9722a0f9d613b14e9575..5aeaef7c637ceb95a148a4e4e368a7883d7c814a 100644 (file)
 #include <sys/ioctl.h>
 #include <linux/spi/spidev.h>
 
-#include "wiringPiSPI.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
+#define        SPI_ADC_SPEED   1000000
+#define        SPI_DAC_SPEED   1000000
+#define        SPI_A2D               0
+#define        SPI_D2A               1
 
 
 /*
@@ -57,7 +58,7 @@
  *********************************************************************************
  */
 
-void gertboardAnalogWrite (int chan, int value)
+void gertboardAnalogWrite (const int chan, const int value)
 {
   uint8_t spiData [2] ;
   uint8_t chanBits, dataBits ;
@@ -84,7 +85,7 @@ void gertboardAnalogWrite (int chan, int value)
  *********************************************************************************
  */
 
-int gertboardAnalogRead (int chan)
+int gertboardAnalogRead (const int chan)
 {
   uint8_t spiData [2] ;
 
@@ -120,3 +121,44 @@ int gertboardSPISetup (void)
 
   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 ;
+}
similarity index 86%
rename from wiringPi/gertboard.h
rename to devLib/gertboard.h
index 98fd1e799b49dab67a3932f4900e191a75ab4614..3fa19197426db87df3c4dfe062b86ee2d08dcdf8 100644 (file)
 extern "C" {
 #endif
 
-extern void gertboardAnalogWrite (int chan, int value) ;
-extern int  gertboardAnalogRead  (int chan) ;
+// 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
similarity index 64%
rename from wiringPi/lcd.c
rename to devLib/lcd.c
index f123db28af813c6ebedf947b72c3ab14aaf04004..6c0e474948fded0be758e0cb8cb227afdf120189 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <stdarg.h>
 
-#include "wiringPi.h"
+#include <wiringPi.h>
+
 #include "lcd.h"
 
-// Commands
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+// HD44780U Commands
 
 #define        LCD_CLEAR       0x01
 #define        LCD_HOME        0x02
 #define        LCD_ENTRY       0x04
-#define        LCD_ON_OFF      0x08
+#define        LCD_CTRL        0x08
 #define        LCD_CDSHIFT     0x10
 #define        LCD_FUNC        0x20
 #define        LCD_CGRAM       0x40
 #define        LCD_DGRAM       0x80
 
-#define        LCD_ENTRY_SH    0x01
-#define        LCD_ENTRY_ID    0x02
+// Bits in the entry register
+
+#define        LCD_ENTRY_SH            0x01
+#define        LCD_ENTRY_ID            0x02
+
+// Bits in the control register
 
-#define        LCD_ON_OFF_B    0x01
-#define        LCD_ON_OFF_C    0x02
-#define        LCD_ON_OFF_D    0x04
+#define        LCD_BLINK_CTRL          0x01
+#define        LCD_CURSOR_CTRL         0x02
+#define        LCD_DISPLAY_CTRL        0x04
+
+// Bits in the function register
 
 #define        LCD_FUNC_F      0x04
 #define        LCD_FUNC_N      0x08
 
 struct lcdDataStruct
 {
-  uint8_t bits, rows, cols ;
-  uint8_t rsPin, strbPin ;
-  uint8_t dataPins [8] ;
+  int bits, rows, cols ;
+  int rsPin, strbPin ;
+  int dataPins [8] ;
+  int cx, cy ;
 } ;
 
 struct lcdDataStruct *lcds [MAX_LCDS] ;
 
+static int lcdControl ;
+
+// Row offsets
+
+static const int rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
+
 
 /*
  * strobe:
@@ -73,7 +91,7 @@ struct lcdDataStruct *lcds [MAX_LCDS] ;
  *********************************************************************************
  */
 
-static void strobe (struct lcdDataStruct *lcd)
+static void strobe (const struct lcdDataStruct *lcd)
 {
 
 // Note timing changes for new version of delayMicroseconds ()
@@ -89,13 +107,14 @@ static void strobe (struct lcdDataStruct *lcd)
  *********************************************************************************
  */
 
-static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
+static void sendDataCmd (const struct lcdDataStruct *lcd, unsigned char data)
 {
-  uint8_t i, d4 ;
+  register unsigned char myData = data ;
+  unsigned char          i, d4 ;
 
   if (lcd->bits == 4)
   {
-    d4 = (data >> 4) & 0x0F;
+    d4 = (myData >> 4) & 0x0F;
     for (i = 0 ; i < 4 ; ++i)
     {
       digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
@@ -103,7 +122,7 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
     }
     strobe (lcd) ;
 
-    d4 = data & 0x0F ;
+    d4 = myData & 0x0F ;
     for (i = 0 ; i < 4 ; ++i)
     {
       digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
@@ -114,8 +133,8 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
   {
     for (i = 0 ; i < 8 ; ++i)
     {
-      digitalWrite (lcd->dataPins [i], (data & 1)) ;
-      data >>= 1 ;
+      digitalWrite (lcd->dataPins [i], (myData & 1)) ;
+      myData >>= 1 ;
     }
   }
   strobe (lcd) ;
@@ -128,22 +147,24 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
  *********************************************************************************
  */
 
-static void putCommand (struct lcdDataStruct *lcd, uint8_t command)
+static void putCommand (const struct lcdDataStruct *lcd, unsigned char command)
 {
   digitalWrite (lcd->rsPin,   0) ;
   sendDataCmd  (lcd, command) ;
+  delay (2) ;
 }
 
-static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
+static void put4Command (const struct lcdDataStruct *lcd, unsigned char command)
 {
-  uint8_t i ;
+  register unsigned char myCommand = command ;
+  register unsigned char i ;
 
   digitalWrite (lcd->rsPin,   0) ;
 
   for (i = 0 ; i < 4 ; ++i)
   {
-    digitalWrite (lcd->dataPins [i], (command & 1)) ;
-    command >>= 1 ;
+    digitalWrite (lcd->dataPins [i], (myCommand & 1)) ;
+    myCommand >>= 1 ;
   }
   strobe (lcd) ;
 }
@@ -151,7 +172,7 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
 
 /*
  *********************************************************************************
- * User Code below here
+ * User Callable code below here
  *********************************************************************************
  */
 
@@ -161,16 +182,66 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
  *********************************************************************************
  */
 
-void lcdHome (int fd)
+void lcdHome (const int fd)
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
+
   putCommand (lcd, LCD_HOME) ;
+  lcd->cx = lcd->cy = 0 ;
+  delay (5) ;
 }
 
-void lcdClear (int fd)
+void lcdClear (const int fd)
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
+
   putCommand (lcd, LCD_CLEAR) ;
+  putCommand (lcd, LCD_HOME) ;
+  lcd->cx = lcd->cy = 0 ;
+  delay (5) ;
+}
+
+
+/*
+ * lcdDisplay: lcdCursor: lcdCursorBlink:
+ *     Turn the display, cursor, cursor blinking on/off
+ *********************************************************************************
+ */
+
+void lcdDisplay (const int fd, int state)
+{
+  struct lcdDataStruct *lcd = lcds [fd] ;
+
+  if (state)
+    lcdControl |=  LCD_DISPLAY_CTRL ;
+  else
+    lcdControl &= ~LCD_DISPLAY_CTRL ;
+
+  putCommand (lcd, LCD_CTRL | lcdControl) ; 
+}
+
+void lcdCursor (const int fd, int state)
+{
+  struct lcdDataStruct *lcd = lcds [fd] ;
+
+  if (state)
+    lcdControl |=  LCD_CURSOR_CTRL ;
+  else
+    lcdControl &= ~LCD_CURSOR_CTRL ;
+
+  putCommand (lcd, LCD_CTRL | lcdControl) ; 
+}
+
+void lcdCursorBlink (const int fd, int state)
+{
+  struct lcdDataStruct *lcd = lcds [fd] ;
+
+  if (state)
+    lcdControl |=  LCD_BLINK_CTRL ;
+  else
+    lcdControl &= ~LCD_BLINK_CTRL ;
+
+  putCommand (lcd, LCD_CTRL | lcdControl) ; 
 }
 
 
@@ -180,40 +251,77 @@ void lcdClear (int fd)
  *********************************************************************************
  */
 
-void lcdSendCommand (int fd, uint8_t command)
+void lcdSendCommand (const int fd, unsigned char command)
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
   putCommand (lcd, command) ;
 }
 
+
 /*
  * lcdPosition:
- *     Update the position of the cursor on the display
+ *     Update the position of the cursor on the display.
+ *     Ignore invalid locations.
  *********************************************************************************
  */
 
-
-void lcdPosition (int fd, int x, int y)
+void lcdPosition (const int fd, int x, int y)
 {
-  static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
   struct lcdDataStruct *lcd = lcds [fd] ;
 
+  if ((x > lcd->cols) || (x < 0))
+    return ;
+  if ((y > lcd->rows) || (y < 0))
+    return ;
+
   putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ;
+
+  lcd->cx = x ;
+  lcd->cy = y ;
+}
+
+
+/*
+ * lcdCharDef:
+ *     Defines a new character in the CGRAM
+ *********************************************************************************
+ */
+
+void lcdCharDef (const int fd, int index, unsigned char data [8])
+{
+  struct lcdDataStruct *lcd = lcds [fd] ;
+  int i ;
+
+  putCommand (lcd, LCD_CGRAM | ((index & 7) << 3)) ;
+
+  digitalWrite (lcd->rsPin, 1) ;
+  for (i = 0 ; i < 8 ; ++i)
+    sendDataCmd (lcd, data [i]) ;
 }
 
 
 /*
  * lcdPutchar:
- *     Send a data byte to be displayed on the display
+ *     Send a data byte to be displayed on the display. We implement a very
+ *     simple terminal here - with line wrapping, but no scrolling. Yet.
  *********************************************************************************
  */
 
-void lcdPutchar (int fd, uint8_t data)
+void lcdPutchar (const int fd, unsigned char data)
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
 
   digitalWrite (lcd->rsPin, 1) ;
-  sendDataCmd (lcd, data) ;
+  sendDataCmd  (lcd, data) ;
+
+  if (++lcd->cx == lcd->cols)
+  {
+    lcd->cx = 0 ;
+    if (++lcd->cy == lcd->rows)
+      lcd->cy = 0 ;
+    
+    putCommand (lcd, lcd->cx + (LCD_DGRAM | rowOff [lcd->cy])) ;
+  }
 }
 
 
@@ -223,7 +331,7 @@ void lcdPutchar (int fd, uint8_t data)
  *********************************************************************************
  */
 
-void lcdPuts (int fd, char *string)
+void lcdPuts (const int fd, const char *string)
 {
   while (*string)
     lcdPutchar (fd, *string++) ;
@@ -236,7 +344,7 @@ void lcdPuts (int fd, char *string)
  *********************************************************************************
  */
 
-void lcdPrintf (int fd, char *message, ...)
+void lcdPrintf (const int fd, const char *message, ...)
 {
   va_list argp ;
   char buffer [1024] ;
@@ -256,12 +364,14 @@ void lcdPrintf (int fd, char *message, ...)
  *********************************************************************************
  */
 
-int lcdInit (int rows, int cols, int bits, int rs, int strb,
-       int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)
+int lcdInit (const int rows, const int cols, const int bits,
+       const int rs, const int strb,
+       const int d0, const int d1, const int d2, const int d3, const int d4,
+       const int d5, const int d6, const int d7)
 {
   static int initialised = 0 ;
 
-  uint8_t func ;
+  unsigned char func ;
   int i ;
   int lcdFd = -1 ;
   struct lcdDataStruct *lcd ;
@@ -298,7 +408,7 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
   if (lcdFd == -1)
     return -1 ;
 
-  lcd = malloc (sizeof (struct lcdDataStruct)) ;
+  lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ;
   if (lcd == NULL)
     return -1 ;
 
@@ -307,6 +417,8 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
   lcd->bits    = 8 ;           // For now - we'll set it properly later.
   lcd->rows    = rows ;
   lcd->cols    = cols ;
+  lcd->cx      = 0 ;
+  lcd->cy      = 0 ;
 
   lcd->dataPins [0] = d0 ;
   lcd->dataPins [1] = d1 ;
@@ -371,10 +483,13 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
 
 // Rest of the initialisation sequence
 
-  putCommand (lcd, LCD_ON_OFF  | LCD_ON_OFF_D) ;   delay (2) ;
-  putCommand (lcd, LCD_ENTRY   | LCD_ENTRY_ID) ;   delay (2) ;
-  putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ;
-  putCommand (lcd, LCD_CLEAR) ;                    delay (5) ;
+  lcdDisplay     (lcdFd, TRUE) ;
+  lcdCursor      (lcdFd, FALSE) ;
+  lcdCursorBlink (lcdFd, FALSE) ;
+  lcdClear       (lcdFd) ;
+
+  putCommand (lcd, LCD_ENTRY   | LCD_ENTRY_ID) ;
+  putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ;
 
   return lcdFd ;
 }
diff --git a/devLib/lcd.h b/devLib/lcd.h
new file mode 100644 (file)
index 0000000..0a0e598
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * lcd.h:
+ *     Text-based LCD driver.
+ *     This is designed to drive the parallel interface LCD drivers
+ *     based in the Hitachi HD44780U controller and compatables.
+ *
+ * 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_LCDS        8
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void lcdHome        (const int fd) ;
+extern void lcdClear       (const int fd) ;
+extern void lcdDisplay     (const int fd, int state) ;
+extern void lcdCursor      (const int fd, int state) ;
+extern void lcdCursorBlink (const int fd, int state) ;
+extern void lcdSendCommand (const int fd, unsigned char command) ;
+extern void lcdPosition    (const int fd, int x, int y) ;
+extern void lcdCharDef     (const int fd, int index, unsigned char data [8]) ;
+extern void lcdPutchar     (const int fd, unsigned char data) ;
+extern void lcdPuts        (const int fd, const char *string) ;
+extern void lcdPrintf      (const int fd, const char *message, ...) ;
+
+extern int  lcdInit (const int rows, const int cols, const int bits,
+       const int rs, const int strb,
+       const int d0, const int d1, const int d2, const int d3, const int d4,
+       const int d5, const int d6, const int d7) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/lcd128x64.c b/devLib/lcd128x64.c
new file mode 100644 (file)
index 0000000..accd5c3
--- /dev/null
@@ -0,0 +1,673 @@
+/*
+ * lcd128x64.c:
+ *     Graphics-based LCD driver.
+ *     This is designed to drive the parallel interface LCD drivers
+ *     based on the generic 12864H chips
+ *
+ *     There are many variations on these chips, however they all mostly
+ *     seem to be similar.
+ *     This implementation has the Pins from the Pi hard-wired into it,
+ *     in particular wiringPi pins 0-7 so that we can use
+ *     digitalWriteByete() to speed things up somewhat.
+ *
+ * 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 <wiringPi.h>
+
+#include "font.h"
+#include "lcd128x64.h"
+
+// Size
+
+#define        LCD_WIDTH       128
+#define        LCD_HEIGHT       64
+
+// Hardware Pins
+//     Note pins 0-7 are the 8-bit data port
+
+#define        CS1             10
+#define        CS2             11
+#define        STROBE          12
+#define        RS              13
+
+// Software copy of the framebuffer
+//     it's 8-bit deep although the display itself is only 1-bit deep.
+
+static unsigned char frameBuffer [LCD_WIDTH * LCD_HEIGHT] ;
+
+static int maxX,    maxY ;
+static int lastX,   lastY ;
+static int xOrigin, yOrigin ;
+static int lcdOrientation = 0 ;
+
+/*
+ * strobe:
+ *     Toggle the strobe (Really the "E") pin to the device.
+ *     According to the docs, data is latched on the falling edge.
+ *********************************************************************************
+ */
+
+static void strobe (void)
+{
+  digitalWrite (STROBE, 1) ; delayMicroseconds (1) ;
+  digitalWrite (STROBE, 0) ; delayMicroseconds (5) ;
+}
+
+
+/*
+ * sentData:
+ *     Send an data or command byte to the display.
+ *********************************************************************************
+ */
+
+static void sendData (const int data, const int chip)
+{
+  digitalWrite     (chip, 0) ;
+  digitalWriteByte (data) ;
+  strobe           () ;
+  digitalWrite     (chip, 1) ;
+}
+
+
+/*
+ * sendCommand:
+ *     Send a command byte to the display
+ *********************************************************************************
+ */
+
+static void sendCommand (const int command, const int chip)
+{
+  digitalWrite (RS, 0) ;
+  sendData     (command, chip) ;
+  digitalWrite (RS, 1) ;
+}
+
+
+/*
+ * setCol: SetLine:
+ *     Set the column and line addresses
+ *********************************************************************************
+ */
+
+static void setCol  (int col, const int chip)
+  { sendCommand (0x40 | (col  & 0x3F), chip) ; }
+
+static void setLine (int line, const int chip)
+  { sendCommand (0xB8 | (line & 0x07), chip) ; }
+
+
+/*
+ * lcd128x64update:
+ *     Copy our software version to the real display
+ *********************************************************************************
+ */
+
+void lcd128x64update (void)
+{
+  int line, x, y, fbLoc ;
+  unsigned char byte ;
+
+// Left side 
+
+  for (line = 0 ; line < 8 ; ++line)
+  {
+    setCol  (0,    CS1) ;
+    setLine (line, CS1) ;
+
+    for (x = 63 ; x >= 0 ; --x)
+    {
+      byte = 0 ;
+      for (y = 0 ; y < 8 ; ++y)
+      {
+       fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ;
+       if (frameBuffer [fbLoc] != 0)
+         byte |= (1 << y) ;
+      }
+      sendData (byte, CS1) ;
+    }
+  }
+
+// Right side 
+
+  for (line = 0 ; line < 8 ; ++line)
+  {
+    setCol  (0,    CS2) ;
+    setLine (line, CS2) ;
+
+    for (x = 127 ; x >= 64 ; --x)
+    {
+      byte = 0 ;
+      for (y = 0 ; y < 8 ; ++y)
+      {
+       fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ;
+       if (frameBuffer [fbLoc] != 0)
+         byte |= (1 << y) ;
+      }
+      sendData (byte, CS2) ;
+    }
+  }
+}
+
+
+/*
+ * lcd128x64setOrigin:
+ *     Set the display offset origin
+ *********************************************************************************
+ */
+
+void lcd128x64setOrigin (int x, int y)
+{
+  xOrigin = x ;
+  yOrigin = y ;
+}
+
+
+/*
+ * lcd128x64setOrientation:
+ *     Set the display orientation:
+ *     0: Normal, the display is portrait mode, 0,0 is top left
+ *     1: Landscape
+ *     2: Portrait, flipped
+ *     3: Landscape, flipped
+ *********************************************************************************
+ */
+
+void lcd128x64setOrientation (int orientation)
+{
+  lcdOrientation = orientation & 3 ;
+
+  lcd128x64setOrigin (0,0) ;
+
+  switch (lcdOrientation)
+  {
+    case 0:
+      maxX = LCD_WIDTH ;
+      maxY = LCD_HEIGHT ;
+      break ;
+
+    case 1:
+      maxX = LCD_HEIGHT ;
+      maxY = LCD_WIDTH ;
+      break ;
+
+    case 2:
+      maxX = LCD_WIDTH ;
+      maxY = LCD_HEIGHT ;
+      break ;
+
+    case 3:
+      maxX = LCD_HEIGHT ;
+      maxY = LCD_WIDTH ;
+      break ;
+  }
+}
+
+
+/*
+ * lcd128x64orientCoordinates:
+ *     Adjust the coordinates given to the display orientation
+ *********************************************************************************
+ */
+
+void lcd128x64orientCoordinates (int *x, int *y)
+{
+  register int tmp ;
+
+  *x += xOrigin ;
+  *y += yOrigin ;
+  *y  = maxY - *y - 1 ;
+
+  switch (lcdOrientation)
+  {
+    case 0:
+      break;
+
+    case 1:
+      tmp = maxY - *y - 1 ;
+      *y = *x ;
+      *x = tmp ;
+      break;
+
+    case 2:
+      *x = maxX - *x - 1 ;
+      *y = maxY - *y - 1 ;
+      break;
+
+    case 3:
+      *x = maxX - *x - 1 ;
+      tmp = *y ;
+      *y = *x ;
+      *x = tmp ;
+      break ;
+  }
+}
+
+
+/*
+ * lcd128x64getScreenSize:
+ *     Return the max X & Y screen sizes. Needs to be called again, if you 
+ *     change screen orientation.
+ *********************************************************************************
+ */
+
+void lcd128x64getScreenSize (int *x, int *y)
+{
+  *x = maxX ;
+  *y = maxY ;
+}
+
+
+/*
+ *********************************************************************************
+ * Standard Graphical Functions
+ *********************************************************************************
+ */
+
+
+/*
+ * lcd128x64point:
+ *     Plot a pixel.
+ *********************************************************************************
+ */
+
+void lcd128x64point (int x, int y, int colour)
+{
+  lastX = x ;
+  lastY = y ;
+
+  lcd128x64orientCoordinates (&x, &y) ;
+
+  if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT))
+    return ;
+
+  frameBuffer [x + y * LCD_WIDTH] = colour ;
+}
+
+
+/*
+ * lcd128x64line: lcd128x64lineTo:
+ *     Classic Bressenham Line code
+ *********************************************************************************
+ */
+
+void lcd128x64line (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 (;;)
+  {
+    lcd128x64point (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 lcd128x64lineTo (int x, int y, int colour)
+{
+  lcd128x64line (lastX, lastY, x, y, colour) ;
+}
+
+
+/*
+ * lcd128x64rectangle:
+ *     A rectangle is a spoilt days fishing
+ *********************************************************************************
+ */
+
+void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled)
+{
+  register int x ;
+
+  if (filled)
+  {
+    /**/ if (x1 == x2)
+      lcd128x64line (x1, y1, x2, y2, colour) ;
+    else if (x1 < x2)
+      for (x = x1 ; x <= x2 ; ++x)
+       lcd128x64line (x, y1, x, y2, colour) ;
+    else
+      for (x = x2 ; x <= x1 ; ++x)
+       lcd128x64line (x, y1, x, y2, colour) ;
+  }
+  else
+  {
+    lcd128x64line   (x1, y1, x2, y1, colour) ;
+    lcd128x64lineTo (x2, y2, colour) ;
+    lcd128x64lineTo (x1, y2, colour) ;
+    lcd128x64lineTo (x1, y1, colour) ;
+  }
+}
+
+
+/*
+ * lcd128x64circle:
+ *      This is the midpoint circle algorithm.
+ *********************************************************************************
+ */
+
+void lcd128x64circle (int x, int y, int r, int colour, int filled)
+{
+  int ddF_x = 1 ;
+  int ddF_y = -2 * r ;
+
+  int f = 1 - r ;
+  int x1 = 0 ;
+  int y1 = r ;
+
+  if (filled)
+  {
+    lcd128x64line (x, y + r, x, y - r, colour) ;
+    lcd128x64line (x + r, y, x - r, y, colour) ;
+  }
+  else
+  {
+    lcd128x64point (x, y + r, colour) ;
+    lcd128x64point (x, y - r, colour) ;
+    lcd128x64point (x + r, y, colour) ;
+    lcd128x64point (x - r, y, colour) ;
+  }
+
+  while (x1 < y1)
+  {
+    if (f >= 0)
+    {
+      y1-- ;
+      ddF_y += 2 ;
+      f += ddF_y ;
+    }
+    x1++ ;
+    ddF_x += 2 ;
+    f += ddF_x ;
+    if (filled)
+    {
+      lcd128x64line (x + x1, y + y1, x - x1, y + y1, colour) ;
+      lcd128x64line (x + x1, y - y1, x - x1, y - y1, colour) ;
+      lcd128x64line (x + y1, y + x1, x - y1, y + x1, colour) ;
+      lcd128x64line (x + y1, y - x1, x - y1, y - x1, colour) ;
+    }
+    else
+    {
+      lcd128x64point (x + x1, y + y1, colour) ; lcd128x64point (x - x1, y + y1, colour) ;
+      lcd128x64point (x + x1, y - y1, colour) ; lcd128x64point (x - x1, y - y1, colour) ;
+      lcd128x64point (x + y1, y + x1, colour) ; lcd128x64point (x - y1, y + x1, colour) ;
+      lcd128x64point (x + y1, y - x1, colour) ; lcd128x64point (x - y1, y - x1, colour) ;
+    }
+  }
+}
+
+
+/*
+ * lcd128x64ellipse:
+ *     Fast ellipse drawing algorithm by 
+ *      John Kennedy
+ *     Mathematics Department
+ *     Santa Monica College
+ *     1900 Pico Blvd.
+ *     Santa Monica, CA 90405
+ *     jrkennedy6@gmail.com
+ *     -Confirned in email this algorithm is in the public domain -GH-
+ *********************************************************************************
+ */
+
+static void plot4ellipsePoints (int cx, int cy, int x, int y, int colour, int filled)
+{
+  if (filled)
+  {
+    lcd128x64line (cx + x, cy + y, cx - x, cy + y, colour) ;
+    lcd128x64line (cx - x, cy - y, cx + x, cy - y, colour) ;
+  }
+  else
+  {
+    lcd128x64point (cx + x, cy + y, colour) ;
+    lcd128x64point (cx - x, cy + y, colour) ;
+    lcd128x64point (cx - x, cy - y, colour) ;
+    lcd128x64point (cx + x, cy - y, colour) ;
+  }
+}
+
+void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled)
+{
+  int x, y ;
+  int xChange, yChange, ellipseError ;
+  int twoAsquare, twoBsquare ;
+  int stoppingX, stoppingY ;
+
+  twoAsquare = 2 * xRadius * xRadius ;
+  twoBsquare = 2 * yRadius * yRadius ;
+
+  x = xRadius ;
+  y = 0 ;
+
+  xChange = yRadius * yRadius * (1 - 2 * xRadius) ;
+  yChange = xRadius * xRadius ;
+
+  ellipseError = 0 ;
+  stoppingX    = twoBsquare * xRadius ;
+  stoppingY    = 0 ;
+
+  while (stoppingX >= stoppingY)       // 1st set of points
+  {
+    plot4ellipsePoints (cx, cy, x, y, colour, filled) ;
+    ++y ;
+    stoppingY    += twoAsquare ;
+    ellipseError += yChange ;
+    yChange      += twoAsquare ;
+
+    if ((2 * ellipseError + xChange) > 0 )
+    {
+      --x ;
+      stoppingX    -= twoBsquare ;
+      ellipseError += xChange ;
+      xChange      += twoBsquare ;
+    }
+  }
+
+  x = 0 ;
+  y = yRadius ;
+
+  xChange = yRadius * yRadius ;
+  yChange = xRadius * xRadius * (1 - 2 * yRadius) ;
+
+  ellipseError = 0 ;
+  stoppingX    = 0 ;
+  stoppingY    = twoAsquare * yRadius ;
+
+  while (stoppingX <= stoppingY)       //2nd set of points
+  {
+    plot4ellipsePoints (cx, cy, x, y, colour, filled) ;
+    ++x ;
+    stoppingX    += twoBsquare ;
+    ellipseError += xChange ;
+    xChange      += twoBsquare ;
+
+    if ((2 * ellipseError + yChange) > 0 )
+    {
+      --y ;
+      stoppingY -= twoAsquare ;
+      ellipseError += yChange ;
+      yChange += twoAsquare ;
+    }
+  }
+}
+
+
+/*
+ * lcd128x64putchar:
+ *     Print a single character to the screen
+ *********************************************************************************
+ */
+
+void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol)
+{
+  int y1, y2 ;
+
+  unsigned char line ;
+  unsigned char *fontPtr ;
+
+// Can't print if we're offscreen
+
+//if ((x < 0) || (x >= (maxX - fontWidth)) || (y < 0) || (y >= (maxY - fontHeight)))
+//  return ;
+
+  fontPtr = font + c * fontHeight ;
+
+  for (y1 = fontHeight - 1 ; y1 >= 0 ; --y1)
+  {
+    y2 = y + y1 ;
+    line = *fontPtr++ ;
+    lcd128x64point (x + 0, y2, (line & 0x80) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 1, y2, (line & 0x40) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 2, y2, (line & 0x20) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 3, y2, (line & 0x10) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 4, y2, (line & 0x08) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 5, y2, (line & 0x04) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 6, y2, (line & 0x02) == 0 ? bgCol : fgCol) ;
+    lcd128x64point (x + 7, y2, (line & 0x01) == 0 ? bgCol : fgCol) ;
+  }
+}
+
+
+/*
+ * lcd128x64puts:
+ *     Send a string to the display. Obeys \n and \r formatting
+ *********************************************************************************
+ */
+
+void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol)
+{
+  int c, mx, my ;
+
+  mx = x ; my = y ;
+
+  while (*str)
+  {
+    c = *str++ ;
+
+    if (c == '\r')
+    {
+      mx = x ;
+      continue ;
+    }
+
+    if (c == '\n')
+    {
+      mx  = x ;
+      my -= fontHeight ;
+      continue ;
+    }
+
+    lcd128x64putchar (mx, my, c, bgCol, fgCol) ;
+
+    mx += fontWidth ;
+    if (mx >= (maxX - fontWidth))
+    {
+      mx  = 0 ;
+      my -= fontHeight ;
+    }
+  }
+}
+
+
+/*
+ * lcd128x64clear:
+ *     Clear the display to the given colour.
+ *********************************************************************************
+ */
+
+void lcd128x64clear (int colour)
+{
+  register int i ;
+  register unsigned char *ptr = frameBuffer ;
+
+  for (i = 0 ; i < (maxX * maxY) ; ++i)
+    *ptr++ = colour ;
+}
+
+
+
+
+/*
+ * lcd128x64setup:
+ *     Initialise the display and GPIO.
+ *********************************************************************************
+ */
+
+int lcd128x64setup (void)
+{
+  int i ;
+
+  for (i = 0 ; i < 8 ; ++i)
+    pinMode (i, OUTPUT) ;
+
+  digitalWrite (CS1,    1) ;
+  digitalWrite (CS2,    1) ;
+  digitalWrite (STROBE, 0) ;
+  digitalWrite (RS,     1) ;
+
+  pinMode (CS1,    OUTPUT) ;
+  pinMode (CS2,    OUTPUT) ;
+  pinMode (STROBE, OUTPUT) ;
+  pinMode (RS,     OUTPUT) ;
+
+  sendCommand (0x3F, CS1) ;    // Display ON
+  sendCommand (0xC0, CS1) ;    // Set display start line to 0
+
+  sendCommand (0x3F, CS2) ;    // Display ON
+  sendCommand (0xC0, CS2) ;    // Set display start line to 0
+
+  lcd128x64clear          (0) ;
+  lcd128x64setOrientation (0) ;
+  lcd128x64update         () ;
+
+  return 0 ;
+}
diff --git a/devLib/lcd128x64.h b/devLib/lcd128x64.h
new file mode 100644 (file)
index 0000000..b448bbc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * lcd128x64.h:
+ *
+ * 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/>.
+ ***********************************************************************
+ */
+
+extern void lcd128x64setOrigin         (int x, int y) ;
+extern void lcd128x64setOrientation    (int orientation) ;
+extern void lcd128x64orientCoordinates (int *x, int *y) ;
+extern void lcd128x64getScreenSize     (int *x, int *y) ;
+extern void lcd128x64point             (int  x, int  y, int colour) ;
+extern void lcd128x64line              (int x0, int y0, int x1, int y1, int colour) ;
+extern void lcd128x64lineTo            (int  x, int  y, int colour) ;
+extern void lcd128x64rectangle         (int x1, int y1, int x2, int y2, int colour, int filled) ;
+extern void lcd128x64circle            (int  x, int  y, int  r, int colour, int filled) ;
+extern void lcd128x64ellipse           (int cx, int cy, int xRadius, int yRadius, int colour, int filled) ;
+extern void lcd128x64putchar           (int  x, int  y, int c, int bgCol, int fgCol) ;
+extern void lcd128x64puts              (int  x, int  y, const char *str, int bgCol, int fgCol) ;
+extern void lcd128x64update            (void) ;
+extern void lcd128x64clear             (int colour) ;
+
+extern int  lcd128x64setup             (void) ;
diff --git a/devLib/maxdetect.c b/devLib/maxdetect.c
new file mode 100755 (executable)
index 0000000..23eabf8
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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 <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 high to low on the bus
+ *********************************************************************************
+ */
+
+static void maxDetectLowHighWait (const int pin)
+{
+  unsigned int timeOut = millis () + 2000 ;
+
+  while (digitalRead (pin) == HIGH)
+    if (millis () > timeOut)
+      return ;
+
+  while (digitalRead (pin) == LOW)
+    if (millis () > timeOut)
+      return ;
+}
+
+
+/*
+ * 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)
+  {
+    maxDetectLowHighWait (pin) ;
+
+// 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] ;
+
+// 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
+
+  maxDetectLowHighWait (pin) ;
+
+// 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 ;
+
+  return checksum == localBuf [4] ;
+}
+
+
+/*
+ * readRHT03:
+ *     Read the Temperature & Humidity from an RHT03 sensor
+ *********************************************************************************
+ */
+
+int readRHT03 (const int pin, int *temp, int *rh)
+{
+  static unsigned int nextTime   = 0 ;
+  static          int lastTemp   = 0 ;
+  static          int lastRh     = 0 ;
+  static          int lastResult = TRUE ;
+
+  unsigned char buffer [4] ;
+
+// Don't read more than once a second
+
+  if (millis () < nextTime)
+  {
+    *temp = lastTemp ;
+    *rh   = lastRh ;
+    return lastResult ;
+  }
+  
+  lastResult = maxDetectRead (pin, buffer) ;
+
+  if (lastResult)
+  {
+    *temp      = lastTemp   = (buffer [2] * 256 + buffer [3]) ;
+    *rh        = lastRh     = (buffer [0] * 256 + buffer [1]) ;
+    nextTime   = millis () + 2000 ;
+    return TRUE ;
+  }
+  else
+  {
+    return FALSE ;
+  }
+}
diff --git a/devLib/maxdetect.h b/devLib/maxdetect.h
new file mode 100755 (executable)
index 0000000..a1fd742
--- /dev/null
@@ -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 (file)
index 0000000..4475c7f
--- /dev/null
@@ -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 (file)
index 0000000..4965314
--- /dev/null
@@ -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 (file)
index 0000000..1b1c0dd
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * piFace.:
+ *     Arduino compatable (ish) Wiring library for the Raspberry Pi
+ *     Copyright (c) 2012-2013 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 ;
+}
similarity index 100%
rename from wiringPi/piNes.c
rename to devLib/piNes.c
similarity index 100%
rename from wiringPi/piNes.h
rename to devLib/piNes.h
diff --git a/examples/Gertboard/7segments.c b/examples/Gertboard/7segments.c
new file mode 100644 (file)
index 0000000..8797e49
--- /dev/null
@@ -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 (file)
index 0000000..7569261
--- /dev/null
@@ -0,0 +1,74 @@
+#
+# Makefile:
+#      Gertboard - Examples using wiringPi
+#
+#      Copyright (c) 2013 Gordon Henderson
+#################################################################################
+
+#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
+       @echo [link]
+       @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS)
+
+buttons:       buttons.o
+       @echo [link]
+       @$(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS)
+
+7segments:     7segments.o
+       @echo [link]
+       @$(CC) -o $@ 7segments.o $(LDFLAGS) $(LDLIBS)
+
+voltmeter:     voltmeter.o
+       @echo [link]
+       @$(CC) -o $@ voltmeter.o $(LDFLAGS) $(LDLIBS)
+
+temperature:   temperature.o
+       @echo [link]
+       @$(CC) -o $@ temperature.o $(LDFLAGS) $(LDLIBS)
+
+vumeter:       vumeter.o
+       @echo [link]
+       @$(CC) -o $@ vumeter.o $(LDFLAGS) $(LDLIBS)
+
+record:        record.o
+       @echo [link]
+       @$(CC) -o $@ record.o $(LDFLAGS) $(LDLIBS)
+
+.c.o:
+       @echo [CC] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+       @echo [Clean]
+       @rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/Gertboard/buttons.c b/examples/Gertboard/buttons.c
new file mode 100644 (file)
index 0000000..5f76764
--- /dev/null
@@ -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) ;
+  }
+}
similarity index 61%
rename from examples/gertboard.c
rename to examples/Gertboard/gertboard.c
index f02e27db5eacfba5ae026a4b64523aa19fb48403..aefcb1244fef781f056a9e28bde353bd31b4719d 100644 (file)
@@ -6,8 +6,8 @@
  *             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
- *     copy this value to D/A port 1 and use a 'scope on both D/A ports
- *     to check all's well.
+ *     plot the input value on the terminal as a sort of vertical scrolling
+ *     oscilloscipe.
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  */
 
 #include <stdio.h>
-#include <stdint.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
 #include <math.h>
 
-#define        B_SIZE  200
-#undef DO_TIMING
+// 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 ;
-  uint32_t x1 ;
+  int i, inputValue ;
   int  buffer [B_SIZE] ;
+  int   cols ;
+  struct winsize w ;
 
-#ifdef DO_TIMING
-  unsigned int now, then ;
-#endif
 
   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 () ;
 
-  if (wiringPiSetupSys () < 0)
-    return -1 ;
+// Initialise the Gertboard analog hardware at pin 100
 
-  if (gertboardSPISetup () < 0)
-    return 1 ;
+  gertboardAnalogSetup (100) ;
 
-// Generate a Sine Wave
+// Generate a Sine Wave and store in our buffer
 
   for (i = 0 ; i < B_SIZE ; ++i)
   {
@@ -66,28 +73,23 @@ int main (void)
     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 (;;)
   {
-#ifdef DO_TIMING
-    then = millis () ;
-#endif
-
     for (i = 0 ; i < B_SIZE ; ++i)
     {
-      gertboardAnalogWrite (0, buffer [i]) ;
+      analogWrite (100, buffer [i]) ;
 
-#ifndef        DO_TIMING
-      x1 = gertboardAnalogRead (0) ;
-      gertboardAnalogWrite (1, x1 >> 2) ;      // 10-bit A/D, 8-bit D/A
-#endif
-    }
+      inputValue = analogRead (100) ;
 
-#ifdef DO_TIMING
-    now = millis () ;
-    printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ;
-    printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ;
-#endif
+// 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 (file)
index 0000000..71d8718
--- /dev/null
@@ -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 (file)
index 0000000..5985a12
--- /dev/null
@@ -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 (file)
index 0000000..c4d2113
--- /dev/null
@@ -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 (file)
index 0000000..9643ace
--- /dev/null
@@ -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 ;
+}
index defd510bb69f6a51634845129c69d3b361c4ca27..f1e172519f516ae32cf487dd841c39495e98ccbe 100644 (file)
@@ -30,15 +30,19 @@ INCLUDE     = -I/usr/local/include
 CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
 
 LDFLAGS        = -L/usr/local/lib
-LDLIBS    = -lwiringPi -lpthread -lm
+LDLIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
 
 # Should not alter anything below this line
 ###############################################################################
 
-SRC    =       blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c     \
-               piface.c gertboard.c nes.c                                      \
-               pwm.c tone.c servo.c                                            \
-               delayTest.c serialRead.c serialTest.c okLed.c
+SRC    =       blink.c blink8.c blink12.c                                      \
+               pwm.c                                                           \
+               speed.c wfi.c isr.c isr-osc.c                                   \
+               lcd.c clock.c                                                   \
+               nes.c                                                           \
+               softPwm.c softTone.c                                            \
+               delayTest.c serialRead.c serialTest.c okLed.c ds1302.c          \
+               rht03.c
 
 OBJ    =       $(SRC:.c=.o)
 
@@ -55,13 +59,13 @@ blink:      blink.o
        @echo [link]
        @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
 
-test1: test1.o
+blink8:        blink8.o
        @echo [link]
-       @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS)
-       
-test2: test2.o
+       @$(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS)
+
+blink12:       blink12.o
        @echo [link]
-       @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS)
+       @$(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS)
 
 speed: speed.o
        @echo [link]
@@ -71,6 +75,10 @@ lcd: lcd.o
        @echo [link]
        @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS)
 
+clock: clock.o
+       @echo [link]
+       @$(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS)
+
 wfi:   wfi.o
        @echo [link]
        @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS)
@@ -83,22 +91,26 @@ isr-osc:    isr-osc.o
        @echo [link]
        @$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS)
 
-piface:        piface.o
-       @echo [link]
-       @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS)
-
-gertboard:     gertboard.o
-       @echo [link]
-       @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS)
-
 nes:   nes.o
        @echo [link]
        @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) 
 
+rht03: rht03.o
+       @echo [link]
+       @$(CC) -o $@ rht03.o $(LDFLAGS) $(LDLIBS) 
+
 pwm:   pwm.o
        @echo [link]
        @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS)
 
+softPwm:       softPwm.o
+       @echo [link]
+       @$(CC) -o $@ softPwm.o $(LDFLAGS) $(LDLIBS)
+
+softTone:      softTone.o
+       @echo [link]
+       @$(CC) -o $@ softTone.o $(LDFLAGS) $(LDLIBS)
+
 delayTest:     delayTest.o
        @echo [link]
        @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS)
@@ -119,9 +131,9 @@ tone:       tone.o
        @echo [link]
        @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS)
 
-servo: servo.o
+ds1302:        ds1302.o
        @echo [link]
-       @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS)
+       @$(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS)
 
 
 .c.o:
@@ -129,7 +141,8 @@ servo:      servo.o
        @$(CC) -c $(CFLAGS) $< -o $@
 
 clean:
-       rm -f $(OBJ) *~ core tags $(BINS)
+       @echo "[Clean]"
+       @rm -f $(OBJ) *~ core tags $(BINS)
 
 tags:  $(SRC)
        @echo [ctags]
diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile
new file mode 100644 (file)
index 0000000..0bde334
--- /dev/null
@@ -0,0 +1,85 @@
+#
+# Makefile:
+#      wiringPi - Wiring Compatable library for the Raspberry Pi
+#      https://projects.drogon.net/wiring-pi
+#
+#      Copyright (c) 2012 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#      Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Lesser General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+#DEBUG = -g -O0
+DEBUG  = -O3
+CC     = gcc
+INCLUDE        = -I/usr/local/include
+CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LDFLAGS        = -L/usr/local/lib
+LDLIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
+
+# 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
+       @echo [link]
+       @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
+
+buttons:       buttons.o
+       @echo [link]
+       @$(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS)
+
+reaction:      reaction.o
+       @echo [link]
+       @$(CC) -o $@ reaction.o $(LDFLAGS) $(LDLIBS)
+
+ladder:        ladder.o
+       @echo [link]
+       @$(CC) -o $@ ladder.o $(LDFLAGS) $(LDLIBS)
+
+metro: metro.o
+       @echo [link]
+       @$(CC) -o $@ metro.o $(LDFLAGS) $(LDLIBS)
+
+motor: motor.o
+       @echo [link]
+       @$(CC) -o $@ motor.o $(LDFLAGS) $(LDLIBS)
+
+.c.o:
+       @echo [CC] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+       @echo "[Clean]"
+       @rm -f $(OBJ) *~ core tags $(BINS)
+
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/examples/PiFace/blink.c b/examples/PiFace/blink.c
new file mode 100644 (file)
index 0000000..ffb8a2e
--- /dev/null
@@ -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 (file)
index 0000000..147a4bd
--- /dev/null
@@ -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 100755 (executable)
index 0000000..4f08a6f
--- /dev/null
@@ -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 (file)
index 0000000..a4a8c1d
--- /dev/null
@@ -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 (file)
index 0000000..14f5539
--- /dev/null
@@ -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 (file)
index 0000000..5084508
--- /dev/null
@@ -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 ;
+}
index bb9f8569dd4916247b09e737e42fb0f8693abd8b..c27a20e3004f1d3082acbe6cb76dcc48af97acaa 100644 (file)
@@ -34,16 +34,14 @@ int main (void)
 {
   printf ("Raspberry Pi blink\n") ;
 
-  if (wiringPiSetup () == -1)
-    return 1 ;
-
+  wiringPiSetup () ;
   pinMode (LED, OUTPUT) ;
 
   for (;;)
   {
-    digitalWrite (LED, 1) ;    // On
+    digitalWrite (LED, HIGH) ; // On
     delay (500) ;              // mS
-    digitalWrite (LED, 0) ;    // Off
+    digitalWrite (LED, LOW) ;  // Off
     delay (500) ;
   }
   return 0 ;
similarity index 70%
rename from examples/test1.c
rename to examples/blink12.c
index 4c75711f16b8d99e590397080c393c3f4e97e6bd..c9b3d506ef285135de119a7ded768511dc1e42ab 100644 (file)
@@ -1,8 +1,7 @@
 /*
- * test1.c:
- *     Simple test program to test the wiringPi functions
- *     This is a sequencer to make a patter appear on 8 LEDs
- *     connected to the GPIO pins.
+ * blink12.c:
+ *     Simple sequence over the first 12 GPIO pins - LEDs
+ *     Aimed at the Gertboard, but it's fairly generic.
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
+#include <wiringPi.h>
 
 // Simple sequencer data
 //     Triplets of LED, On/Off and delay
 
-uint8_t data [] =
+int data [] =
 {
             0, 1, 1,
             1, 1, 1,
@@ -44,15 +39,23 @@ uint8_t data [] =
   3, 0, 0,  5, 1, 1,
   4, 0, 0,  6, 1, 1,
   5, 0, 0,  7, 1, 1,
-  6, 0, 1,
-  7, 0, 1,
+  6, 0, 0, 11, 1, 1,
+  7, 0, 0, 10, 1, 1,
+ 11, 0, 0, 13, 1, 1,
+ 10, 0, 0, 12, 1, 1,
+ 13, 0, 1,
+ 12, 0, 1,
 
   0, 0, 1,     // Extra delay
 
 // Back again
 
-            7, 1, 1,
-            6, 1, 1,
+           12, 1, 1,
+           13, 1, 1,
+ 12, 0, 0, 10, 1, 1,
+ 13, 0, 0, 11, 1, 1,
+ 10, 0, 0,  7, 1, 1,
+ 11, 0, 0,  6, 1, 1,
   7, 0, 0,  5, 1, 1,
   6, 0, 0,  4, 1, 1,
   5, 0, 0,  3, 1, 1,
@@ -64,7 +67,7 @@ uint8_t data [] =
 
   0, 0, 1,     // Extra delay
 
-  9, 9, 9,     // End marker
+  0, 9, 0,     // End marker
 
 } ;
 
@@ -75,16 +78,17 @@ int main (void)
   int dataPtr ;
   int l, s, d ;
 
-  printf ("Raspberry Pi wiringPi test program\n") ;
+  printf ("Raspberry Pi - 12-LED Sequence\n") ;
+  printf ("==============================\n") ;
+  printf ("\n") ;
+  printf ("Connect LEDs up to the first 8 GPIO pins, then pins 11, 10, 13, 12 in\n") ;
+  printf ("    that order, then sit back and watch the show!\n") ;
 
-  if (wiringPiSetup () == -1)
-    exit (1) ;
+  wiringPiSetup () ;
 
-  for (pin = 0 ; pin < 8 ; ++pin)
+  for (pin = 0 ; pin < 14 ; ++pin)
     pinMode (pin, OUTPUT) ;
 
-  pinMode (8, INPUT) ;         // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor
-
   dataPtr = 0 ;
 
   for (;;)
@@ -93,18 +97,14 @@ int main (void)
     s = data [dataPtr++] ;     // State
     d = data [dataPtr++] ;     // Duration (10ths)
 
-    if ((l + s + d) == 27)
+    if (s == 9)                        // 9 -> End Marker
     {
       dataPtr = 0 ;
       continue ;
     }
 
     digitalWrite (l, s) ;
-
-    if (digitalRead (8) == 0)  // Pressed as our switch shorts to ground
-      delay (d * 10) ; // Faster!
-    else
-      delay (d * 100) ;
+    delay        (d * 100) ;
   }
 
   return 0 ;
similarity index 66%
rename from examples/test2.c
rename to examples/blink8.c
index 580591e98b09f409eadf62d3ee9be3ec6ef4e067..602d3c05965402d782f956f121d64bb962fb6c04 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * test2.c:
- *     This tests the hardware PWM channel.
+ * blink8.c:
+ *     Simple sequence over the first 8 GPIO pins - LEDs
+ *     Aimed at the Gertboard, but it's fairly generic.
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#include <wiringPi.h>
 
 int main (void)
 {
-  int bright ;
+  int i, led ;
 
-  printf ("Raspberry Pi wiringPi PWM test program\n") ;
+  printf ("Raspberry Pi - 8-LED Sequencer\n") ;
+  printf ("==============================\n") ;
+  printf ("\n") ;
+  printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ;
 
-  if (wiringPiSetup () == -1)
-    exit (1) ;
+  wiringPiSetup () ;
 
-  pinMode (1, PWM_OUTPUT) ;
+  for (i = 0 ; i < 8 ; ++i)
+    pinMode (i, OUTPUT) ;
 
   for (;;)
   {
-    for (bright = 0 ; bright < 1024 ; ++bright)
+    for (led = 0 ; led < 8 ; ++led)
     {
-      pwmWrite (1, bright) ;
-      delay (1) ;
+      digitalWrite (led, 1) ;
+      delay (100) ;
     }
 
-    for (bright = 1023 ; bright >= 0 ; --bright)
+    for (led = 0 ; led < 8 ; ++led)
     {
-      pwmWrite (1, bright) ;
-      delay (1) ;
+      digitalWrite (led, 0) ;
+      delay (100) ;
     }
   }
-
-  return 0 ;
 }
diff --git a/examples/clock.c b/examples/clock.c
new file mode 100644 (file)
index 0000000..9a53210
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * clock.c:
+ *     Demo of the 128x64 graphics based LCD driver.
+ *     This is designed to drive the parallel interface LCD drivers
+ *     based on the popular 12864H controller chip.
+ *
+ *     This test program assumes the following:
+ *             (Which is currently hard-wired into the driver)
+ *
+ *     GPIO 0-7 is connected to display data pins 0-7.
+ *     GPIO 10 is CS1
+ *     GPIO 11 is CS2
+ *     GPIO 12 is STROBE
+ *     GPIO 10 is RS
+ *
+ * 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 <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <math.h>
+
+#include <wiringPi.h>
+#include <lcd128x64.h>
+
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+double clockRadius ;
+double thickness, barLen ;
+int maxX, maxY ;
+
+double rads (double degs)
+{
+  return degs * M_PI / 180.0 ;
+}
+
+void drawClockHands (void)
+{
+  time_t t ;
+  struct tm *now ;
+  double angle, p, x0, y0, x1, y1 ;
+  int h24, h, m, s ;
+  char text [20] ;
+
+  time (&t) ;
+  now = localtime (&t) ;
+
+  h24 = now->tm_hour ;
+  m   = now->tm_min ;
+  s   = now->tm_sec ;
+
+  h = h24 ;
+  if (h > 12)
+    h -= 12 ;
+
+// Hour hand
+
+  angle = h * 30 + m * 0.5 ;
+  x0 = sin (rads (angle)) * (clockRadius * 0.75) ;
+  y0 = cos (rads (angle)) * (clockRadius * 0.75) ;
+  for (p = -3.0 ; p <= 3.0 ; p += 0.2)
+  {
+    x1 = sin (rads (angle + p)) * (clockRadius * 0.7) ;
+    y1 = cos (rads (angle + p)) * (clockRadius * 0.7) ;
+    lcd128x64line (0, 0, x1, y1, 1) ;
+    lcd128x64lineTo (x0, y0, 1) ;
+  }
+
+// Minute hand
+
+  angle = m * 6 ;
+  x0 = sin (rads (angle)) * (clockRadius * 0.9) ;
+  y0 = cos (rads (angle)) * (clockRadius * 0.9) ;
+  for (p = -1.0 ; p <= 1.0 ; p += 0.2)
+  {
+    x1 = sin (rads (angle + p)) * (clockRadius * 0.85) ;
+    y1 = cos (rads (angle + p)) * (clockRadius * 0.85) ;
+    lcd128x64line (0, 0, x1, y1, 1) ;
+    lcd128x64lineTo (x0, y0, 1) ;
+  }
+
+// Second hand
+
+  angle = s * 6 ;
+  x0 = sin (rads (angle)) * (clockRadius * 0.2) ;
+  y0 = cos (rads (angle)) * (clockRadius * 0.2) ;
+  x1 = sin (rads (angle)) * (clockRadius * 0.95) ;
+  y1 = cos (rads (angle)) * (clockRadius * 0.95) ;
+  lcd128x64line (0 - x0, 0 - y0, x1, y1, 1) ;
+  lcd128x64circle (0, 0, clockRadius * 0.1,  0, 1) ;
+  lcd128x64circle (0, 0, clockRadius * 0.05, 1, 1) ;
+
+// Text:
+
+  sprintf (text, "%02d:%02d:%02d", h24, m, s) ;
+  lcd128x64puts (32, 24, text, 0, 1) ;
+
+  sprintf (text, "%2d/%2d/%2d", now->tm_mday, now->tm_mon + 1, now->tm_year - 100) ;
+  lcd128x64puts (32, -23, text, 0, 1) ;
+}
+
+void drawClockFace (void)
+{
+  int m ;
+  double d, px1, py1, px2, py2 ;
+
+  lcd128x64clear (0) ;
+  lcd128x64circle (0,0, clockRadius, 1, TRUE) ;
+  lcd128x64circle (0,0, clockRadius - thickness, 0, TRUE) ;
+
+// The four big indicators for 12,15,30 and 45
+
+  lcd128x64rectangle (- 3,  clockRadius - barLen, 3,  clockRadius,     1, TRUE) ;      // 12
+  lcd128x64rectangle (clockRadius - barLen, 3,  clockRadius, -3, 1, TRUE) ;    // 3
+  lcd128x64rectangle (- 3, -clockRadius + barLen, 3, -clockRadius, 1, TRUE) ;  // 6
+  lcd128x64rectangle (-clockRadius + barLen, 3, -clockRadius, -3, 1, TRUE) ;   // 9
+
+
+// Smaller 5 and 1 minute ticks
+
+  for (m = 0 ; m < 60 ; ++m)
+  {
+    px1 = sin (rads (m * 6)) * clockRadius ;
+    py1 = cos (rads (m * 6)) * clockRadius ;
+    if ((m % 5) == 0)
+      d = barLen ;
+    else 
+      d = barLen / 2.0 ;
+
+    px2 = sin (rads (m * 6)) * (clockRadius - d) ;
+    py2 = cos (rads (m * 6)) * (clockRadius - d) ;
+    lcd128x64line (px1, py1, px2, py2, 1) ;
+  }
+}
+
+void setup (void)
+{
+  lcd128x64getScreenSize (&maxX, &maxY) ;
+  clockRadius = maxY / 2 - 1 ;
+  thickness = maxX / 48 ;
+  barLen = thickness * 4 ;
+  lcd128x64setOrigin (32, 32) ;
+}
+
+
+
+
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
+
+int main (int argc, char *argv [])
+{
+  time_t now ;
+
+  wiringPiSetup () ;
+
+  lcd128x64setup () ;
+
+  setup () ;
+  for (;;)
+  {
+    drawClockFace  () ;
+    drawClockHands () ;
+    lcd128x64update () ;
+
+    now = time (NULL) ;
+    while (time (NULL) == now)
+      delay (10) ;
+  }
+  
+
+  return 0 ;
+}
diff --git a/examples/ds1302.c b/examples/ds1302.c
new file mode 100644 (file)
index 0000000..f1e9e20
--- /dev/null
@@ -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/gertboard.png b/examples/gertboard.png
deleted file mode 100644 (file)
index 03c5cdd..0000000
Binary files a/examples/gertboard.png and /dev/null differ
index 2bef54af13a60b95ad87fbfc67d2961722eb016e..abc6aec994fcdf7f774f186ce6d75d298d96bd3a 100644 (file)
 #include <wiringPi.h>
 
 
-// What GPIO input are we using?
-//     This is a wiringPi pin number
-
-#define        BUTTON_PIN      0
-
 // globalCounter:
 //     Global variable to count interrupts
 //     Should be declared volatile to make sure the compiler doesn't cache it.
 
-static volatile int globalCounter = 0 ;
+static volatile int globalCounter [8] ;
 
 
 /*
@@ -55,10 +50,14 @@ static volatile int globalCounter = 0 ;
  *********************************************************************************
  */
 
-void myInterrupt (void)
-{
-  ++globalCounter ;
-}
+void myInterrupt0 (void) { ++globalCounter [0] ; }
+void myInterrupt1 (void) { ++globalCounter [1] ; }
+void myInterrupt2 (void) { ++globalCounter [2] ; }
+void myInterrupt3 (void) { ++globalCounter [3] ; }
+void myInterrupt4 (void) { ++globalCounter [4] ; }
+void myInterrupt5 (void) { ++globalCounter [5] ; }
+void myInterrupt6 (void) { ++globalCounter [6] ; }
+void myInterrupt7 (void) { ++globalCounter [7] ; }
 
 
 /*
@@ -69,30 +68,42 @@ void myInterrupt (void)
 
 int main (void)
 {
-  int myCounter = 0 ;
+  int gotOne, pin ;
+  int myCounter [8] ;
 
-  if (wiringPiSetup () < 0)
-  {
-    fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
+  for (pin = 0 ; pin < 8 ; ++pin) 
+    globalCounter [pin] = myCounter [pin] = 0 ;
 
-  if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0)
-  {
-    fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
+  wiringPiSetup () ;
 
+  wiringPiISR (0, INT_EDGE_FALLING, &myInterrupt0) ;
+  wiringPiISR (1, INT_EDGE_FALLING, &myInterrupt1) ;
+  wiringPiISR (2, INT_EDGE_FALLING, &myInterrupt2) ;
+  wiringPiISR (3, INT_EDGE_FALLING, &myInterrupt3) ;
+  wiringPiISR (4, INT_EDGE_FALLING, &myInterrupt4) ;
+  wiringPiISR (5, INT_EDGE_FALLING, &myInterrupt5) ;
+  wiringPiISR (6, INT_EDGE_FALLING, &myInterrupt6) ;
+  wiringPiISR (7, INT_EDGE_FALLING, &myInterrupt7) ;
 
   for (;;)
   {
+    gotOne = 0 ;
     printf ("Waiting ... ") ; fflush (stdout) ;
 
-    while (myCounter == globalCounter)
-      delay (100) ;
-
-    printf (" Done. counter: %5d\n", globalCounter) ;
-    myCounter = globalCounter ;
+    for (;;)
+    {
+      for (pin = 0 ; pin < 8 ; ++pin)
+      {
+       if (globalCounter [pin] != myCounter [pin])
+       {
+         printf (" Int on pin %d: Counter: %5d\n", pin, globalCounter [pin]) ;
+         myCounter [pin] = globalCounter [pin] ;
+         ++gotOne ;
+       }
+      }
+      if (gotOne != 0)
+       break ;
+    }
   }
 
   return 0 ;
index 6024917f897d6e6151c341179c7002800c488c2b..c01358557e40ba99d3c2377c60959aeef9f9c817 100644 (file)
@@ -4,7 +4,19 @@
  *     This is designed to drive the parallel interface LCD drivers
  *     based in the Hitachi HD44780U controller and compatables.
  *
- * Copyright (c) 2012 Gordon Henderson.
+ *     This test program assumes the following:
+ *
+ *     8-bit displays:
+ *             GPIO 0-7 is connected to display data pins 0-7.
+ *             GPIO 11 is the RS pin.
+ *             GPIO 10 is the Strobe/E pin.
+ *
+ *     For 4-bit interface:
+ *             GPIO 4-7 is connected to display data pins 4-7.
+ *             GPIO 11 is the RS pin.
+ *             GPIO 10 is the Strobe/E pin.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #include <wiringPi.h>
 #include <lcd.h>
 
-int main (void)
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+static unsigned char newChar [8] = 
 {
-  int i, j ;
-  int fd1, fd2 ; 
+  0b11111,
+  0b10001,
+  0b10001,
+  0b10101,
+  0b11111,
+  0b10001,
+  0b10001,
+  0b11111,
+} ;
+
+
+int usage (const char *progName)
+{
+  fprintf (stderr, "Usage: %s bits cols rows\n", progName) ;
+  return EXIT_FAILURE ;
+}
+
+static const char *message =
+  "                    "
+  "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
+  "                    " ;
+
+void scrollMessage (int lcd, int line, int width)
+{
+  char buf [32] ;
+  static int position = 0 ;
+
+  strncpy (buf, &message [position], width) ;
+  buf [width] = 0 ;
+  lcdPosition (lcd, 0, line) ;
+  lcdPuts (lcd, buf) ;
+
+  if (++position == (strlen (message) - width))
+    position = 0 ;
+}
+
+static void pingPong (int lcd, int cols)
+{
+  static int position = 0 ;
+  static int dir      = 0 ;
+
+  if (dir == 0)                // Setup
+  {
+    dir = 1 ;
+    lcdPosition (lcd, 0, 3) ;
+    lcdPutchar (lcd, '*') ;
+    return ;
+  }
 
-  char message1 [256] ;
-  char message2 [256] ;
-  char buf1 [30] ;
-  char buf2 [30] ;
+  lcdPosition (lcd, position, 3) ;
+  lcdPutchar (lcd, ' ') ;
+  position += dir ;
+
+  if (position == cols)
+  {
+    dir = -1 ;
+    --position ;
+  }
+  
+  if (position < 0)
+  {
+    dir = 1 ;
+    ++position ;
+  }
+
+  lcdPosition (lcd, position, 3) ;
+  lcdPutchar (lcd, '#') ;
+}
+
+
+
+static void waitForEnter (void)
+{
+  printf ("Press ENTER to continue: ") ;
+  (void)fgetc (stdin) ;
+}
+
+int main (int argc, char *argv[])
+{
+  int i ;
+  int lcd ;
+  int bits, rows, cols ;
 
   struct tm *t ;
   time_t tim ;
 
-  printf ("Raspberry Pi LCD test program\n") ;
+  char buf [32] ;
 
-  if (wiringPiSetup () == -1)
-    exit (1) ;
+  if (argc != 4)
+    return usage (argv [0]) ;
 
-  fd1 = lcdInit (4, 20, 4, 8,  9, 4,5,6,7,0,0,0,0) ;
-  fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ;
+  printf ("Raspberry Pi LCD test\n") ;
+  printf ("=====================\n") ;
 
-//fd1 = lcdInit (4, 20, 8, 8,  9, 0,1,2,3,4,5,6,7) ;
-//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ;
+  bits = atoi (argv [1]) ;
+  cols = atoi (argv [2]) ;
+  rows = atoi (argv [3]) ;
 
-  if (fd1 == -1)
+  if (!((rows == 1) || (rows == 2) || (rows == 4)))
   {
-    printf ("lcdInit 1 failed\n") ;
-    return 1 ;
+    fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ;
+    return EXIT_FAILURE ;
   }
 
-  if (fd2 == -1)
+  if (!((cols == 16) || (cols == 20)))
   {
-    printf ("lcdInit 2 failed\n") ;
-    return 1 ;
+    fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ;
+    return EXIT_FAILURE ;
   }
 
-  sleep (1) ;
+  wiringPiSetup () ;
 
-  lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ;
-  lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, "  --------------") ;
-/*
-  lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, "   00:00:00") ;
-  lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, "   DD:MM:YY") ;
-*/
+  if (bits == 4)
+    lcd = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ;
+  else
+    lcd = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ;
+
+  if (lcd < 0)
+  {
+    fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ;
+    return -1 ;
+  }
+
+  lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "Gordon Henderson") ;
 
-  lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ;
-  lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ;
+  if (rows > 1)
+  {
+    lcdPosition (lcd, 0, 1) ;
+    for (i = 0 ; i < (cols - 1) ; ++i)
+      lcdPutchar (lcd, '*') ;
+    lcdPutchar (lcd, '2') ;
+
+    if (rows == 4)
+    {
+      lcdPosition (lcd, 0, 2) ;
+      for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
+        lcdPuts (lcd, "=-") ;
+      lcdPuts (lcd, "=3") ;
+
+      lcdPosition (lcd, 0, 3) ;
+      for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
+        lcdPuts (lcd, "-=") ;
+      lcdPuts (lcd, "-4") ;
+    }
+  }
 
   sleep (2) ;
 
-  sprintf (message1, "%s", "                  http://projects.drogon.net/                    ") ;
-  sprintf (message2, "%s", "                This is a long message to go into the smaller display just for a demonstration of what we can do.                ") ;
+  lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "  wiringpi.com  ") ;
+
+
+  waitForEnter () ;
+
+  lcdCharDef  (lcd, 2, newChar) ;
+
+  lcdClear    (lcd) ;
+  lcdPosition (lcd, 0, 0) ;
+  lcdPuts     (lcd, "User Char: ") ;
+  lcdPutchar  (lcd, 2) ;
+
+  lcdCursor      (lcd, TRUE) ;
+  lcdCursorBlink (lcd, TRUE) ;
+
+  waitForEnter () ;
+
+  lcdCursor      (lcd, FALSE) ;
+  lcdCursorBlink (lcd, FALSE) ;
+
 
   for (;;)
   {
-    i = 0 ;
-    j = 0 ;
-    for (;;)
-    {
-      strncpy (buf1, &message1 [i], 20) ;
-      buf1 [20] = 0 ;
-      lcdPosition (fd1, 0, 1) ;
-      lcdPuts (fd1, buf1) ;
-      ++i ;
-      if (i == strlen (message1) - 20)
-       i = 0 ;
-
-      strncpy (buf2, &message2 [j], 16) ;
-      buf2 [16] = 0 ;
-      lcdPosition (fd2, 0, 1) ;
-      lcdPuts (fd2, buf2) ;
-      ++j ;
-      if (j == strlen (message2) - 16)
-       j = 0 ;
-
-      tim = time (NULL) ;
-      t = localtime (&tim) ;
-
-      sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
-      lcdPosition (fd1, 5, 2) ;
-      lcdPuts (fd1, buf1) ;
-
-      sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
-      lcdPosition (fd1, 4, 3) ;
-      lcdPuts (fd1, buf1) ;
-
-      delay (250) ;
-    }
+    delay (250) ;
+
+    scrollMessage (lcd, 0, cols) ;
+    
+    if (rows == 1)
+      continue ;
+
+    tim = time (NULL) ;
+    t = localtime (&tim) ;
+
+    sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
+
+    lcdPosition (lcd, (cols - 8) / 2, 1) ;
+    lcdPuts     (lcd, buf) ;
+
+    if (rows == 2)
+      continue ;
+
+    sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
+
+    lcdPosition (lcd, (cols - 10) / 2, 2) ;
+    lcdPuts     (lcd, buf) ;
+
+    pingPong (lcd, cols) ;
   }
 
   return 0 ;
index 9b3a170ca3200caedcac70f2d22d2310bacfcbd5..930f266b5c4a387870bd81982382f0cafa95b1a7 100644 (file)
 #include <wiringPi.h>
 #include <softPwm.h>
 
+// The OK/Act LED is connected to BCM_GPIO pin 16
+
 #define OK_LED  16
 
 int main ()
 {
   int fd, i ;
 
+  wiringPiSetupGpio () ;
+
+// Change the trigger on the OK/Act LED to "none"
+
   if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0)
   {
     fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ;
     return 1 ;
   }
-
   write (fd, "none\n", 5) ;
   close (fd) ;
 
-  if (wiringPiSetupGpio () < 0)
-  {
-    fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
-
   softPwmCreate (OK_LED, 0, 100) ;
 
   for (;;)
index c1fc3317c79912eefab0498dc935fd95c2975e92..816c8322e357db2f56458a1bd4689aa61f75c64f 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * pwm.c:
- *     Test of the software PWM driver. Needs 12 LEDs connected
- *     to the Pi.
+ *     This tests the hardware PWM channel.
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
 #include <wiringPi.h>
-#include <softPwm.h>
-
-#define RANGE          100
-#define        NUM_LEDS         12
-
-int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ;
 
-int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ;
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
 
-int main ()
+int main (void)
 {
-  int i, j ;
-  char buf [80] ;
+  int bright ;
 
-  if (wiringPiSetup () == -1)
-  {
-    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
-
-  for (i = 0 ; i < NUM_LEDS ; ++i)
-  {
-    softPwmCreate (ledMap [i], 0, RANGE) ;
-    printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ;
-  }
+  printf ("Raspberry Pi wiringPi PWM test program\n") ;
 
-  fgets (buf, 80, stdin) ;
+  if (wiringPiSetup () == -1)
+    exit (1) ;
 
-// Bring all up one by one:
+  pinMode (1, PWM_OUTPUT) ;
 
-  for (i = 0 ; i < NUM_LEDS ; ++i)
-    for (j = 0 ; j <= 100 ; ++j)
+  for (;;)
+  {
+    for (bright = 0 ; bright < 1024 ; ++bright)
     {
-      softPwmWrite (ledMap [i], j) ;
-      delay (10) ;
+      pwmWrite (1, bright) ;
+      delay (1) ;
     }
 
-  fgets (buf, 80, stdin) ;
-
-// Down fast
-
-  for (i = 100 ; i > 0 ; --i)
-  {
-    for (j = 0 ; j < NUM_LEDS ; ++j)
-      softPwmWrite (ledMap [j], i) ;
-    delay (10) ;
+    for (bright = 1023 ; bright >= 0 ; --bright)
+    {
+      pwmWrite (1, bright) ;
+      delay (1) ;
+    }
   }
 
-  fgets (buf, 80, stdin) ;
-
-  for (;;)
-  {
-    for (i = 0 ; i < NUM_LEDS ; ++i)
-      softPwmWrite (ledMap [i], values [i]) ;
-
-    delay (50) ;
-
-    i = values [0] ;
-    for (j = 0 ; j < NUM_LEDS - 1 ; ++j)
-      values [j] = values [j + 1] ;
-    values [NUM_LEDS - 1] = i ;
-  }
+  return 0 ;
 }
old mode 100644 (file)
new mode 100755 (executable)
similarity index 60%
rename from examples/piface.c
rename to examples/rht03.c
index 0f00960..e0cc116
@@ -1,8 +1,6 @@
 /*
- * piFace.c:
- *     Simple test for the PiFace interface board.
- *
- *     Read the buttons and output the same to the LEDs
+ * rht03.c:
+ *     Driver for the MaxDetect series sensors
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
 
-int outputs [4] = { 0,0,0,0 } ;
-
-void scanButton (int button)
-{
-  if (digitalRead (button) == LOW)
-  {
-    outputs [button] ^= 1 ;
-    digitalWrite (button, outputs [button]) ;
-  }
+#include <wiringPi.h>
+#include <maxdetect.h>
 
-  while (digitalRead (button) == LOW)
-    delay (1) ;
-}
+#define        RHT03_PIN       0
 
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
 
 int main (void)
 {
-  int pin, button ;
-
-  printf ("Raspberry Pi wiringPiFace test program\n") ;
+  int temp, rh ;
+  int newTemp, newRh ;
 
-  if (wiringPiSetupPiFace () == -1)
-    exit (1) ;
-
-// Enable internal pull-ups
-
-  for (pin = 0 ; pin < 8 ; ++pin)
-    pullUpDnControl (pin, PUD_UP) ;
+  temp = rh = newTemp = newRh = 0 ;
 
+  wiringPiSetup () ;
+  piHiPri       (55) ;
 
   for (;;)
   {
-    for (button = 0 ; button < 4 ; ++button)
-      scanButton (button) ;
-    delay (1) ;
+    delay (100) ;
+
+    if (!readRHT03 (RHT03_PIN, &newTemp, &newRh))
+      continue ;
+
+    if ((temp != newTemp) || (rh != newRh))
+    {
+      temp = newTemp ;
+      rh   = newRh ;
+      printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ;
+    }
   }
 
   return 0 ;
diff --git a/examples/softPwm.c b/examples/softPwm.c
new file mode 100644 (file)
index 0000000..11f7ad0
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * softPwm.c:
+ *     Test of the software PWM driver. Needs 8 LEDs connected
+ *     to the Pi - e.g. Ladder 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 <errno.h>
+#include <string.h>
+
+#include <wiringPi.h>
+#include <softPwm.h>
+
+#define RANGE          100
+#define        NUM_LEDS          8
+
+int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7 } ;
+
+int values [NUM_LEDS] = { 0, 25, 50, 75, 100, 75, 50, 25 } ;
+
+int main ()
+{
+  int i, j ;
+  char buf [80] ;
+
+  wiringPiSetup ()  ;
+
+  for (i = 0 ; i < NUM_LEDS ; ++i)
+  {
+    softPwmCreate (ledMap [i], 0, RANGE) ;
+    printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ;
+  }
+
+  fgets (buf, 80, stdin) ;
+
+// Bring all up one by one:
+
+  for (i = 0 ; i < NUM_LEDS ; ++i)
+    for (j = 0 ; j <= 100 ; ++j)
+    {
+      softPwmWrite (ledMap [i], j) ;
+      delay (10) ;
+    }
+
+  fgets (buf, 80, stdin) ;
+
+// All Down
+
+  for (i = 100 ; i > 0 ; --i)
+  {
+    for (j = 0 ; j < NUM_LEDS ; ++j)
+      softPwmWrite (ledMap [j], i) ;
+    delay (10) ;
+  }
+
+  fgets (buf, 80, stdin) ;
+
+  for (;;)
+  {
+    for (i = 0 ; i < NUM_LEDS ; ++i)
+      softPwmWrite (ledMap [i], values [i]) ;
+
+    delay (50) ;
+
+    i = values [0] ;
+    for (j = 0 ; j < NUM_LEDS - 1 ; ++j)
+      values [j] = values [j + 1] ;
+    values [NUM_LEDS - 1] = i ;
+  }
+}
similarity index 92%
rename from examples/tone.c
rename to examples/softTone.c
index 0e8a47d85a842eb090270ba64d3876401de4f23a..2f46783e9ac915e451b21b687f33da8d19dd050c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * tone.c:
+ * softTone.c:
  *     Test of the softTone module in wiringPi
  *     Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v
  *
@@ -38,11 +38,7 @@ int main ()
 {
   int i ;
 
-  if (wiringPiSetup () == -1)
-  {
-    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
+  wiringPiSetup () ;
 
   softToneCreate (PIN) ;
 
@@ -55,5 +51,4 @@ int main ()
       delay (500) ;
     }
   }
-
 }
index 863317ee25bdc55fff2a5b0f2f16f1a5d1a25d32..0a42b36291473907b133c0e67967900a0938eada 100644 (file)
 
 #define        FAST_COUNT      10000000
 #define        SLOW_COUNT       1000000
+#define        PASSES                 5
 
-
-int main (void)
+void speedTest (int pin, int maxCount)
 {
-  int i ;
-  uint32_t start, end, count, sum, perSec ;
-
-  printf ("Raspberry Pi wiringPi speed test program\n") ;
-
-// Start the standard way
-
-  if (wiringPiSetup () == -1)
-    exit (1) ;
-
-  printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ;
-
-  pinMode (0, OUTPUT) ;
+  int count, sum, perSec, i ;
+  unsigned int start, end ;
 
   sum = 0 ;
-  for (i = 0 ; i < 3 ; ++i)
-  {
-    printf ("  Pass: %d: ", i) ;
-    fflush (stdout) ;
 
+  for (i = 0 ; i < PASSES ; ++i)
+  {
     start = millis () ;
-    for (count = 0 ; count < FAST_COUNT ; ++count)
-      digitalWrite (0, 1) ;
+    for (count = 0 ; count < maxCount ; ++count)
+      digitalWrite (pin, 1) ;
     end = millis () ;
-    printf (" %8dmS\n", end - start) ;
+    printf (" %6d", end - start) ;
+    fflush (stdout) ;
     sum += (end - start) ;
   }
-  digitalWrite (0, 0) ;
-  printf ("   Average: %8dmS", sum / 3) ;
-  perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
-  printf (": %6d/sec\n", perSec) ;
 
+  digitalWrite (pin, 0) ;
+  printf (". Av: %6dmS", sum / PASSES) ;
+  perSec = (int)(double)maxCount / (double)((double)sum / (double)PASSES) * 1000.0 ;
+  printf (": %7d/sec\n", perSec) ;
+}
 
-  printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ;
-
-  if (wiringPiSetupGpio () == -1)
-    exit (1) ;
 
-  pinMode (17, OUTPUT) ;
+int main (void)
+{
+  printf ("Raspberry Pi wiringPi GPIO speed test program\n") ;
+  printf ("=============================================\n") ;
 
-  sum = 0 ;
-  for (i = 0 ; i < 3 ; ++i)
-  {
-    printf ("  Pass: %d: ", i) ;
-    fflush (stdout) ;
+// Start the standard way
 
-    start = millis () ;
-    for (count = 0 ; count < 10000000 ; ++count)
-      digitalWrite (17, 1) ;
-    end = millis () ;
-    printf (" %8dmS\n", end - start) ;
-    sum += (end - start) ;
-  }
-  digitalWrite (17, 0) ;
-  printf ("   Average: %8dmS", sum / 3) ;
-  perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
-  printf (": %6d/sec\n", perSec) ;
+  printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ;
+  wiringPiSetup () ;
+  pinMode (0, OUTPUT) ;
+  speedTest (0, FAST_COUNT) ;
 
+// GPIO
 
-// Switch to SYS mode:
+  printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ;
+  wiringPiSetupGpio () ;
+  pinMode (17, OUTPUT) ;
+  speedTest (17, FAST_COUNT) ;
 
-  if (wiringPiSetupSys () == -1)
-    exit (1) ;
+// Phys
 
-  printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
+  printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ;
+  wiringPiSetupPhys () ;
+  pinMode (11, OUTPUT) ;
+  speedTest (11, FAST_COUNT) ;
 
-  sum = 0 ;
-  for (i = 0 ; i < 3 ; ++i)
-  {
-    printf ("  Pass: %d: ", i) ;
-    fflush (stdout) ;
+// Switch to SYS mode:
 
-    start = millis () ;
-    for (count = 0 ; count < SLOW_COUNT ; ++count)
-      digitalWrite (17, 1) ;
-    end = millis () ;
-    printf (" %8dmS\n", end - start) ;
-    sum += (end - start) ;
-  }
-  digitalWrite (17, 0) ;
-  printf ("   Average: %8dmS", sum / 3) ;
-  perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
-  printf (": %6d/sec\n", perSec) ;
+  system ("/usr/local/bin/gpio export 17 out") ;
+  printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
+  wiringPiSetupSys () ;
+  speedTest (17, SLOW_COUNT) ;
 
   return 0 ;
 }
index a04396218f32c67ca1131fdebb63d5cab353215a..52b01509fe74c5b61c2d6f84345391a491102be5 100644 (file)
@@ -30,20 +30,20 @@ INCLUDE     = -I/usr/local/include
 CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
 
 LDFLAGS        = -L/usr/local/lib
-LIBS    = -lwiringPi -lpthread -lm
+LIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
 
 # May not need to  alter anything below this line
 ###############################################################################
 
-SRC    =       gpio.c
+SRC    =       gpio.c extensions.c
 
 OBJ    =       $(SRC:.c=.o)
 
 all:           gpio
 
-gpio:  gpio.o
+gpio:  $(OBJ)
        @echo [Link]
-       @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
        
 .c.o:
        @echo [Compile] $<
@@ -51,7 +51,8 @@ gpio: gpio.o
 
 .PHONEY:       clean
 clean:
-       rm -f $(OBJ) gpio *~ core tags *.bak
+       @echo "[Clean]"
+       @rm -f $(OBJ) gpio *~ core tags *.bak
 
 .PHONEY:       tags
 tags:  $(SRC)
@@ -78,3 +79,6 @@ depend:
        makedepend -Y $(SRC)
 
 # DO NOT DELETE
+
+gpio.o: extensions.h
+extensions.o: extensions.h
diff --git a/gpio/extensions.c b/gpio/extensions.c
new file mode 100644 (file)
index 0000000..c08d1c1
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * extensions.c:
+ *     Part of the GPIO program to test, peek, poke and otherwise
+ *     noodle with the GPIO hardware on 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 <stdint.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 <mcp23017.h>
+#include <mcp23s08.h>
+#include <mcp23s17.h>
+#include <sr595.h>
+
+#include "extensions.h"
+
+extern int wiringPiDebug ;
+
+#ifndef TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+// Local structure to hold details
+
+struct extensionFunctionStruct
+{
+  const char *name ;
+  int  (*function)(char *progName, int pinBase, char *params) ;
+} ;
+
+
+/*
+ * extractInt:
+ *     Check & return an integer at the given location (prefixed by a :)
+ *********************************************************************************
+ */
+
+static char *extractInt (char *progName, char *p, int *num)
+{
+  if (*p != ':')
+  {
+    fprintf (stderr, "%s: colon expected\n", progName) ;
+    return NULL ;
+  }
+
+  ++p ;
+
+  if (!isdigit (*p))
+  {
+    fprintf (stderr, "%s: digit expected\n", progName) ;
+    return NULL ;
+  }
+
+  *num = strtol (p, NULL, 0) ;
+  while (isdigit (*p))
+    ++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 < 0x03) || (i2c > 0x77))
+  {
+    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    return FALSE ;
+  }
+
+  mcp23008Setup (pinBase, i2c) ;
+
+  return TRUE ;
+}
+
+
+/*
+ * doExtensionMcp23017:
+ *     MCP23008 - 16-bit I2C GPIO expansion chip
+ *     mcp23002: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))
+  {
+    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", 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))
+  {
+    fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if ((port < 0) || (port > 7))
+  {
+    fprintf (stderr, "%s: port address (%d) out of range\n", 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))
+  {
+    fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
+    return FALSE ;
+  }
+
+  if ((params = extractInt (progName, params, &port)) == NULL)
+    return FALSE ;
+
+  if ((port < 0) || (port > 7))
+  {
+    fprintf (stderr, "%s: port address (%d) out of range\n", 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))
+  {
+    fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", 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 ;
+}
+
+
+/*
+ * Function list
+ *********************************************************************************
+ */
+
+struct extensionFunctionStruct extensionFunctions [] = 
+{
+  { "mcp23008",                &doExtensionMcp23008    },
+  { "mcp23017",                &doExtensionMcp23017    },
+  { "mcp23s08",                &doExtensionMcp23s08    },
+  { "mcp23s17",                &doExtensionMcp23s17    },
+  { "sr595",           &doExtensionSr595        },
+  { NULL,              NULL                    },
+} ;
+
+
+/*
+ * doExtension:
+ *     Load in a wiringPi extension
+ *********************************************************************************
+ */
+
+int doExtension (char *progName, char *extensionData)
+{
+  char *p ;
+  char *extension = extensionData ;
+  struct extensionFunctionStruct *extensionFn ;
+  int pinBase = 0 ;
+
+// Get the extension extension name by finding the first colon
+
+  p = extension ;
+  while (*p != ':')
+  {
+    if (!*p)   // ran out of characters
+    {
+      fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
+      return FALSE ;
+    }
+    ++p ;
+  }
+
+  *p++ = 0 ;
+
+  if (!isdigit (*p))
+  {
+    fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
+    return FALSE ;
+  }
+
+  while (isdigit (*p))
+  {
+    if (pinBase > 1000000000)
+    {
+      fprintf (stderr, "%s: pinBase too large\n", progName) ;
+      return FALSE ;
+    }
+
+    pinBase = pinBase * 10 + (*p - '0') ;
+    ++p ;
+  }
+
+  if (pinBase < 64)
+  {
+    fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", 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\n", progName, extension) ;
+  return FALSE ;
+}
diff --git a/gpio/extensions.h b/gpio/extensions.h
new file mode 100644 (file)
index 0000000..5d27123
--- /dev/null
@@ -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-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/>.
+ ***********************************************************************
+ */
+
+
+extern int doExtension (char *progName, char *extensionData) ;
index ec65519a9004b4b4cbba51cb7bf6513e285623c5..ae4df4e5ab73a191a913624a315262dd224499cf 100644 (file)
@@ -1,15 +1,19 @@
-.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"
+.TH "GPIO" "March 2013" "Command-Line access to Raspberry Pi's GPIO"
 
 .SH NAME
-gpio \- Command-line access to Raspberry Pi and PiFace GPIO
+gpio \- Command-line access to Raspberry Pi's GPIO
 
 .SH SYNOPSIS
 .B gpio
 .B \-v
 .PP
 .B gpio
-.B [ \-g ]
-.B read/write/wb/pwm/clock/mode ...
+.B [ \-g | \-1 ]
+.B mode/read/write/aread/awrite/wb/pwm/clock ...
+.PP
+.B gpio
+.B [ \-x extension:params ]
+.B mode/read/write/aread/awrite/pwm ...
 .PP
 .B gpio
 .B [ \-p ]
@@ -17,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
 .B ...
 .PP
 .B gpio
-.B readall
+.B readall/reset
 .PP
 .B gpio
 .B unexportall/exports
@@ -27,6 +31,10 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
 .B ...
 .PP
 .B gpio
+.B wfi
+.B ...
+.PP
+.B gpio
 .B drive
 group value
 .PP
@@ -73,12 +81,28 @@ Output the current version including the board revision of the Raspberry Pi.
 .TP
 .B \-g
 Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
-\fINOTE:\fR The BCM_GPIO pin numbers are always used with the 
+\fINote:\fR The BCM_GPIO pin numbers are always used with the 
 export and edge commands.
 
+.TP
+.B \-1
+Use the physical pin numbers rather than wiringPi pin numbers.
+\fINote:\fR that this applies to the P1 connector only. It is not possible to
+use pins on the Revision 2 P5 connector this way, and as with \-g the
+BCM_GPIO pin numbers are always used with the export and edge commands.
+
+.TP
+.B \-x extension
+This causes the named extension to be initialised. Extensions
+comprise of a name (e.g. mcp23017) followed by a colon, then the
+pin-base, then more optional parameters depending on the extension type.
+See the web page on http://wiringpi.com/the-gpio-utility/
+
 .TP
 .B \-p
-Use the PiFace interface board and its corresponding pin numbers.
+Use the PiFace interface board and its corresponding pin numbers. The PiFace
+will always appear at pin number 200 in the gpio command. You can assign any
+pin numbers you like in your own programs though.
 
 .TP
 .B read <pin>
@@ -102,6 +126,11 @@ Output a table of all GPIO pins values. The values represent the actual values r
 if the pin is in input mode, or the last value written if the pin is in output
 mode.
 
+.TP
+.B reset
+Resets the GPIO - As much as it's possible to do. All pins are set to input
+mode and all the internal pull-up/down resistors are disconnected (tristate mode).
+
 .TP
 .B pwm <pin> <value>
 Write a PWM value (0-1023) to the given pin. The pin needs to be put
@@ -157,6 +186,12 @@ requiring root/sudo.
 .B unexport
 Un-Export a GPIO pin in the /sys/class/gpio directory.
 
+.TP
+.B wfi <pin> <mode>
+This set the given pin to the supplied interrupt mode: rising, falling
+or both then waits for the interrupt to happen. It's a non-busy wait,
+so does not consume and CPU while it's waiting.
+
 .TP
 .B drive
 group value
@@ -207,26 +242,26 @@ The board jumpers need to be in-place to do this operation.
 
 .PP
 .TS
-r r r l.
-WiringPi       GPIO-r1 GPIO-r2 Function
+c c c c l.
+WiringPi       GPIO-r1 GPIO-r2 P1-Phys Function
 _
-0      17      17
-1      18      18      (PWM)
-2      21      27
-3      22      22
-4      23      23
-5      24      24
-6      25      25
-7      4       4
-8      0       2       I2C: SDA0
-9      1       3       I2C: SCL0
-10     8       8       SPI: CE0
-11     7       7       SPI: CE1
-12     10      10      SPI: MOSI
-13     9       9       SPI: MISO
-14     11      11      SPI: SCLK
-15     14      14      TxD
-16     15      16      RxD
+ 0     17      17      11      
+ 1     18      18      12      (PWM)
+ 2     21      27      13
+ 3     22      22      15
+ 4     23      23      16
+ 5     24      24      18
+ 6     25      25      22
+ 7     4       4       7
+ 8     0       2       3       I2C: SDA0
+ 9     1       3       5       I2C: SCL0
+10     8       8       24      SPI: CE0
+11     7       7       26      SPI: CE1
+12     10      10      19      SPI: MOSI
+13     9       9       21      SPI: MISO
+14     11      11      23      SPI: SCLK
+15     14      14      8       TxD
+16     15      16      10      RxD
 17     -       28
 18     -       29
 19     -       30
@@ -272,7 +307,7 @@ pin numbers.
 .LP
 WiringPi's home page
 .IP
-https://projects.drogon.net/raspberry-pi/wiringpi/
+http://wiringpi.com/
 
 .SH AUTHOR
 
@@ -284,7 +319,7 @@ Please report bugs to <projects@drogon.net>
 
 .SH COPYRIGHT
 
-Copyright (c) 2012 Gordon Henderson
+Copyright (c) 2012-2013 Gordon Henderson
 This is free software; see the source for copying conditions. There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
index e71e432f310ac06ff9c5479621fc6c5948795e22..8e17ae0f7169333f3128d051dc1c842558f81e6f 100644 (file)
@@ -2,7 +2,7 @@
  * gpio.c:
  *     Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
  *     Pi's GPIO.
- *     Copyright (c) 2012 Gordon Henderson
+ *     Copyright (c) 2012-2013 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <ctype.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <wiringPi.h>
+
 #include <gertboard.h>
+#include <piFace.h>
+
+#include "extensions.h"
 
 extern int wiringPiDebug ;
 
@@ -42,22 +48,26 @@ extern int wiringPiDebug ;
 #  define      FALSE   (1==2)
 #endif
 
-#define        VERSION "1.12"
+#define        VERSION         "2.02"
+#define        I2CDETECT       "/usr/sbin/i2cdetect"
 
 static int wpMode ;
 
 char *usage = "Usage: gpio -v\n"
               "       gpio -h\n"
-              "       gpio [-g] <read/write/wb/pwm/clock/mode> ...\n"
+              "       gpio [-g|-1] [-x extension:params] ...\n"
               "       gpio [-p] <read/write/wb> ...\n"
-             "       gpio readall\n"
-             "       gpio unexportall/exports ...\n"
+              "       gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
+             "       gpio readall/reset\n"
+             "       gpio unexportall/exports\n"
              "       gpio export/edge/unexport ...\n"
+             "       gpio wfi <pin> <mode>\n"
              "       gpio drive <group> <value>\n"
              "       gpio pwm-bal/pwm-ms \n"
              "       gpio pwmr <range> \n"
              "       gpio pwmc <divider> \n"
              "       gpio load spi/i2c\n"
+             "       gpio i2cd/i2cdetect\n"
              "       gpio gbr <channel>\n"
              "       gpio gbw <channel> <value>" ;     // No trailing newline needed here.
 
@@ -195,6 +205,37 @@ static void doLoad (int argc, char *argv [])
 }
 
 
+/*
+ * doI2Cdetect:
+ *     Run the i2cdetect command with the right runes for this Pi revision
+ *********************************************************************************
+ */
+
+static void doI2Cdetect (int argc, char *argv [])
+{
+  int port = piBoardRev () == 1 ? 0 : 1 ;
+  char command [128] ;
+  struct stat statBuf ;
+
+  if (stat (I2CDETECT, &statBuf) < 0)
+  {
+    fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
+    return ;
+  }
+
+  if (!moduleLoaded ("i2c_dev"))
+  {
+    fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
+    return ;
+  }
+
+  sprintf (command, "%s -y %d", I2CDETECT, port) ;
+  if (system (command) < 0)
+    fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
+
+}
+
+
 /*
  * doReadall:
  *     Read all the GPIO pins
@@ -215,27 +256,39 @@ static char *alts [] =
   "IN  ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
 } ;
 
+static int wpiToPhys [64] =
+{
+  11, 12, 13, 15, 16, 18, 22,  7,      //  0...7
+   3,  5,                              //  8...9
+  24, 26, 19, 21, 23,                  // 10..14
+   8, 10,                              // 15..16
+   3,  4,  5,  6,                      // 17..20
+             0,0,0,0,0,0,0,0,0,0,0,    // 20..31
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    // 32..47
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    // 47..63
+} ;
+
 static void doReadall (void)
 {
   int pin ;
 
-  printf ("+----------+------+--------+------+-------+\n") ;
-  printf ("| wiringPi | GPIO | Name   | Mode | Value |\n") ;
-  printf ("+----------+------+--------+------+-------+\n") ;
+  printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ;
+  printf ("| wiringPi | GPIO | Phys | Name   | Mode | Value |\n") ;
+  printf ("+----------+------+------+--------+------+-------+\n") ;
 
-  for (pin = 0 ; pin < 64 ; ++pin)
+  for (pin = 0 ; pin < 64 ; ++pin)     // Crude, but effective
   {
     if (wpiPinToGpio (pin) == -1)
       continue ;
 
-    printf ("| %6d   | %3d  | %s | %s | %s  |\n",
-       pin, wpiPinToGpio (pin),
+    printf ("| %6d   | %3d  | %3d  | %s | %s | %s  |\n",
+       pin, wpiPinToGpio (pin), wpiToPhys [pin],
        pinNames [pin], 
        alts [getAlt (pin)], 
        digitalRead (pin) == HIGH ? "High" : "Low ") ;
   }
 
-  printf ("+----------+------+--------+------+-------+\n") ;
+  printf ("+----------+------+------+--------+------+-------+\n") ;
 }
 
 
@@ -252,9 +305,7 @@ static void doExports (int argc, char *argv [])
   char fName [128] ;
   char buf [16] ;
 
-// Rather crude, but who knows what others are up to...
-
-  for (first = 0, i = 0 ; i < 64 ; ++i)
+  for (first = 0, i = 0 ; i < 64 ; ++i)        // Crude, but effective
   {
 
 // Try to read the direction
@@ -386,6 +437,52 @@ void doExport (int argc, char *argv [])
 }
 
 
+/*
+ * doWfi:
+ *     gpio wfi pin mode
+ *     Wait for Interrupt on a given pin.
+ *     Slight cheat here - it's easier to actually use ISR now (which calls
+ *     gpio to set the pin modes!) then we simply sleep, and expect the thread
+ *     to exit the program. Crude but effective.
+ *********************************************************************************
+ */
+
+static void wfi (void)
+  { exit (0) ; }
+
+void doWfi (int argc, char *argv [])
+{
+  int pin, mode ;
+
+  if (argc != 4)
+  {
+    fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  pin  = atoi (argv [2]) ;
+
+  /**/ if (strcasecmp (argv [3], "rising")  == 0) mode = INT_EDGE_RISING ;
+  else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ;
+  else if (strcasecmp (argv [3], "both")    == 0) mode = INT_EDGE_BOTH ;
+  else
+  {
+    fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ;
+    exit (1) ;
+  }
+
+  if (wiringPiISR (pin, mode, &wfi) < 0)
+  {
+    fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ;
+    exit (1) ;
+  }
+
+  for (;;)
+    delay (9999) ;
+}
+
+
+
 /*
  * doEdge:
  *     gpio edge pin mode
@@ -499,7 +596,7 @@ void doUnexport (int argc, char *argv [])
  *********************************************************************************
  */
 
-void doUnexportall (int argc, char *argv [])
+void doUnexportall (char *progName)
 {
   FILE *fd ;
   int pin ;
@@ -508,7 +605,7 @@ void doUnexportall (int argc, char *argv [])
   {
     if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
     {
-      fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
+      fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
       exit (1) ;
     }
     fprintf (fd, "%d\n", pin) ;
@@ -517,6 +614,30 @@ void doUnexportall (int argc, char *argv [])
 }
 
 
+/*
+ * doReset:
+ *     Reset the GPIO pins - as much as we can do
+ *********************************************************************************
+ */
+
+static void doReset (char *progName)
+{
+  int pin ;
+
+  doUnexportall (progName) ;
+
+  for (pin = 0 ; pin < 64 ; ++pin)
+  {
+    if (wpiPinToGpio (pin) == -1)
+      continue ;
+
+    digitalWrite    (pin, LOW) ;
+    pinMode         (pin, INPUT) ;
+    pullUpDnControl (pin, PUD_OFF) ;
+  }
+}
+
+
 /*
  * doMode:
  *     gpio mode pin mode ...
@@ -536,9 +657,6 @@ void doMode (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   mode = argv [3] ;
 
   /**/ if (strcasecmp (mode, "in")     == 0) pinMode         (pin, INPUT) ;
@@ -604,7 +722,7 @@ static void doGbw (int argc, char *argv [])
 
   if (argc != 4)
   {
-    fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
+    fprintf (stderr, "Usage: %s gbw <channel> <value>\n", argv [0]) ;
     exit (1) ;
   }
 
@@ -613,23 +731,23 @@ static void doGbw (int argc, char *argv [])
 
   if ((channel < 0) || (channel > 1))
   {
-    fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
+    fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
     exit (1) ;
   }
 
   if ((value < 0) || (value > 1023))
   {
-    fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
+    fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
     exit (1) ;
   }
 
-  if (gertboardSPISetup () == -1)
+  if (gertboardAnalogSetup (64) < 0)
   {
     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
     exit (1) ;
   }
 
-  gertboardAnalogWrite (channel, value) ;
+  analogWrite (64 + channel, value) ;
 }
 
 
@@ -654,21 +772,20 @@ static void doGbr (int argc, char *argv [])
 
   if ((channel < 0) || (channel > 1))
   {
-    fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
+    fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
     exit (1) ;
   }
 
-  if (gertboardSPISetup () == -1)
+  if (gertboardAnalogSetup (64) < 0)
   {
     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
     exit (1) ;
   }
 
-  printf ("%d\n",gertboardAnalogRead (channel)) ;
+  printf ("%d\n", analogRead (64 + channel)) ;
 }
 
 
-
 /*
  * doWrite:
  *     gpio write pin value
@@ -687,9 +804,6 @@ static void doWrite (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
     val = 1 ;
   else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
@@ -703,6 +817,31 @@ static void doWrite (int argc, char *argv [])
     digitalWrite (pin, HIGH) ;
 }
 
+
+/*
+ * doAwriterite:
+ *     gpio awrite pin value
+ *********************************************************************************
+ */
+
+static void doAwrite (int argc, char *argv [])
+{
+  int pin, val ;
+
+  if (argc != 4)
+  {
+    fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  pin = atoi (argv [2]) ;
+
+  val = atoi (argv [3]) ;
+
+  analogWrite (pin, val) ;
+}
+
+
 /*
  * doWriteByte:
  *     gpio write value
@@ -742,19 +881,57 @@ void doRead (int argc, char *argv [])
   }
 
   pin = atoi (argv [2]) ;
+  val = digitalRead (pin) ;
+
+  printf ("%s\n", val == 0 ? "0" : "1") ;
+}
+
+
+/*
+ * doAread:
+ *     Read an analog pin and return the value
+ *********************************************************************************
+ */
+
+void doAread (int argc, char *argv []) 
+{
+  int pin, val ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
+  if (argc != 3)
   {
-    printf ("0\n") ;
-    return ;
+    fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
+    exit (1) ;
   }
 
-  val = digitalRead (pin) ;
+  pin = atoi (argv [2]) ;
+
+  val = analogRead (pin) ;
 
   printf ("%s\n", val == 0 ? "0" : "1") ;
 }
 
 
+/*
+ * doToggle:
+ *     Toggle an IO pin
+ *********************************************************************************
+ */
+
+void doToggle (int argc, char *argv [])
+{
+  int pin ;
+
+  if (argc != 3)
+  {
+    fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  pin = atoi (argv [2]) ;
+
+  digitalWrite (pin, !digitalRead (pin)) ;
+}
+
 /*
  * doClock:
  *     Output a clock on a pin
@@ -773,9 +950,6 @@ void doClock (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   freq = atoi (argv [3]) ;
 
   gpioClockSet (pin, freq) ;
@@ -800,9 +974,6 @@ void doPwm (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   val = atoi (argv [3]) ;
 
   pwmWrite (pin, val) ;
@@ -885,16 +1056,34 @@ int main (int argc, char *argv [])
     return 1 ;
   }
 
+// Help
+
   if (strcasecmp (argv [1], "-h") == 0)
   {
     printf ("%s: %s\n", argv [0], usage) ;
     return 0 ;
   }
 
-  if (strcasecmp (argv [1], "-v") == 0)
+// Sort of a special:
+
+  if (strcmp (argv [1], "-R") == 0)
+  {
+    printf ("%d\n", piBoardRev ()) ;
+    return 0 ;
+  }
+
+// Version & Warranty
+
+  if (strcmp (argv [1], "-V") == 0)
+  {
+    printf ("%d\n", piBoardRev ()) ;
+    return 0 ;
+  }
+
+  if (strcmp (argv [1], "-v") == 0)
   {
     printf ("gpio version: %s\n", VERSION) ;
-    printf ("Copyright (c) 2012 Gordon Henderson\n") ;
+    printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
     printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
     printf ("For details type: %s -warranty\n", argv [0]) ;
     printf ("\n") ;
@@ -905,7 +1094,7 @@ int main (int argc, char *argv [])
   if (strcasecmp (argv [1], "-warranty") == 0)
   {
     printf ("gpio version: %s\n", VERSION) ;
-    printf ("Copyright (c) 2012 Gordon Henderson\n") ;
+    printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
     printf ("\n") ;
     printf ("    This program is free software; you can redistribute it and/or modify\n") ;
     printf ("    it under the terms of the GNU Leser General Public License as published\n") ;
@@ -934,8 +1123,8 @@ int main (int argc, char *argv [])
   /**/ if (strcasecmp (argv [1], "exports"    ) == 0)  { doExports     (argc, argv) ;  return 0 ; }
   else if (strcasecmp (argv [1], "export"     ) == 0)  { doExport      (argc, argv) ;  return 0 ; }
   else if (strcasecmp (argv [1], "edge"       ) == 0)  { doEdge        (argc, argv) ;  return 0 ; }
-  else if (strcasecmp (argv [1], "unexportall") == 0)  { doUnexportall (argc, argv) ;  return 0 ; }
   else if (strcasecmp (argv [1], "unexport"   ) == 0)  { doUnexport    (argc, argv) ;  return 0 ; }
+  else if (strcasecmp (argv [1], "unexportall") == 0)  { doUnexportall (argv [0]) ;    return 0 ; }
 
 // Check for load command:
 
@@ -948,13 +1137,9 @@ int main (int argc, char *argv [])
 
 // Check for -g argument
 
-  if (strcasecmp (argv [1], "-g") == 0)
+  /**/ if (strcasecmp (argv [1], "-g") == 0)
   {
-    if (wiringPiSetupGpio () == -1)
-    {
-      fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
-      exit (1) ;
-    }
+    wiringPiSetupGpio () ;
 
     for (i = 2 ; i < argc ; ++i)
       argv [i - 1] = argv [i] ;
@@ -962,15 +1147,23 @@ int main (int argc, char *argv [])
     wpMode = WPI_MODE_GPIO ;
   }
 
+// Check for -1 argument
+
+  else if (strcasecmp (argv [1], "-1") == 0)
+  {
+    wiringPiSetupPhys () ;
+
+    for (i = 2 ; i < argc ; ++i)
+      argv [i - 1] = argv [i] ;
+    --argc ;
+    wpMode = WPI_MODE_PHYS ;
+  }
+
 // Check for -p argument for PiFace
 
   else if (strcasecmp (argv [1], "-p") == 0)
   {
-    if (wiringPiSetupPiFaceForGpioProg () == -1)
-    {
-      fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
-      exit (1) ;
-    }
+    piFaceSetup (200) ;
 
     for (i = 2 ; i < argc ; ++i)
       argv [i - 1] = argv [i] ;
@@ -982,38 +1175,65 @@ int main (int argc, char *argv [])
 
   else
   {
-    if (wiringPiSetup () == -1)
-    {
-      fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
-      exit (1) ;
-    }
+    wiringPiSetup () ;
     wpMode = WPI_MODE_PINS ;
   }
 
-// Check for PWM or Pad Drive operations
+// Check for -x argument to load in a new extension
 
-  if (wpMode != WPI_MODE_PIFACE)
+  if (strcasecmp (argv [1], "-x") == 0)
   {
-    if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode  (PWM_MODE_BAL) ;   return 0 ; }
-    if (strcasecmp (argv [1], "pwm-ms")  == 0) { doPwmMode  (PWM_MODE_MS) ;    return 0 ; }
-    if (strcasecmp (argv [1], "pwmr")    == 0) { doPwmRange (argc, argv) ;     return 0 ; }
-    if (strcasecmp (argv [1], "pwmc")    == 0) { doPwmClock (argc, argv) ;     return 0 ; }
-    if (strcasecmp (argv [1], "drive")   == 0) { doPadDrive (argc, argv) ;     return 0 ; }
+    if (argc < 3)
+    {
+      fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
+      exit (EXIT_FAILURE) ;
+    }
+
+    if (!doExtension (argv [0], argv [2]))     // Prints its own error messages
+      exit (EXIT_FAILURE) ;
+
+    for (i = 3 ; i < argc ; ++i)
+      argv [i - 2] = argv [i] ;
+    argc -= 2 ;
   }
 
-// Check for wiring commands
+  if (argc <= 1)
+  {
+    fprintf (stderr, "%s: no command given\n", argv [0]) ;
+    exit (EXIT_FAILURE) ;
+  }
 
-  /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall   () ;
-  else if (strcasecmp (argv [1], "read" )    == 0) doRead      (argc, argv) ;
-  else if (strcasecmp (argv [1], "write")    == 0) doWrite     (argc, argv) ;
-  else if (strcasecmp (argv [1], "wb")       == 0) doWriteByte (argc, argv) ;
-  else if (strcasecmp (argv [1], "pwm"  )    == 0) doPwm       (argc, argv) ;
-  else if (strcasecmp (argv [1], "clock")    == 0) doClock     (argc, argv) ;
-  else if (strcasecmp (argv [1], "mode" )    == 0) doMode      (argc, argv) ;
+// Core wiringPi functions
+
+  /**/ if (strcasecmp (argv [1], "mode"   ) == 0) doMode      (argc, argv) ;
+  else if (strcasecmp (argv [1], "read"   ) == 0) doRead      (argc, argv) ;
+  else if (strcasecmp (argv [1], "write"  ) == 0) doWrite     (argc, argv) ;
+  else if (strcasecmp (argv [1], "pwm"    ) == 0) doPwm       (argc, argv) ;
+  else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite    (argc, argv) ;
+  else if (strcasecmp (argv [1], "aread"  ) == 0) doAread     (argc, argv) ;
+
+// GPIO Nicies
+
+  else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
+
+// Pi Specifics
+
+  else if (strcasecmp (argv [1], "pwm-bal"  ) == 0) doPwmMode   (PWM_MODE_BAL) ;
+  else if (strcasecmp (argv [1], "pwm-ms"   ) == 0) doPwmMode   (PWM_MODE_MS) ;
+  else if (strcasecmp (argv [1], "pwmr"     ) == 0) doPwmRange  (argc, argv) ;
+  else if (strcasecmp (argv [1], "pwmc"     ) == 0) doPwmClock  (argc, argv) ;
+  else if (strcasecmp (argv [1], "drive"    ) == 0) doPadDrive  (argc, argv) ;
+  else if (strcasecmp (argv [1], "readall"  ) == 0) doReadall   () ;
+  else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
+  else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect (argc, argv) ;
+  else if (strcasecmp (argv [1], "reset"    ) == 0) doReset     (argv [0]) ;
+  else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte (argc, argv) ;
+  else if (strcasecmp (argv [1], "clock"    ) == 0) doClock     (argc, argv) ;
+  else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi       (argc, argv) ;
   else
   {
     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
-    exit (1) ;
+    exit (EXIT_FAILURE) ;
   }
   return 0 ;
 }
diff --git a/gpio/pintest b/gpio/pintest
new file mode 100755 (executable)
index 0000000..83ca12a
--- /dev/null
@@ -0,0 +1,193 @@
+#!/bin/bash
+#
+# pintest
+#      Test the Pi's GPIO port
+# Copyright (c) 2013 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#      Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Lesser General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+# logErr pin, expected got
+################################################################################
+
+logErr ()
+{
+  if [ $errs = 0 ]; then
+    echo ""
+  fi
+  echo " --> Pin $1 failure. Expected $2, got $3"
+  let errs+=1
+}
+
+
+# printErrorCount
+################################################################################
+
+printErrCount()
+{
+  if [ $errs = 0 ]; then
+    echo "No faults detected."
+  elif [ $errs = 1 ]; then
+    echo "One fault detected."
+  else
+    echo "$errs faults detected"
+  fi
+}
+
+
+# testPins start end
+################################################################################
+
+testPins()
+{
+  start=$1
+    end=$2
+   errs=0
+
+  printf "%30s %2d:%2d: "  "$3" $1 $2
+
+# Set range to inputs
+
+  for i in `seq $start $end`; do
+    gpio mode $i in
+  done
+
+# Enable internal pull-ups and expect to read high
+
+  for i in `seq $start $end`; do
+    gpio mode $i up
+    if [ `gpio read $i` = 0 ]; then
+      logErr $i 1 0
+    fi
+  done
+
+# Enable internal pull-downs and expect to read low
+
+  for i in `seq $start $end`; do
+    gpio mode $i down
+    if [ `gpio read $i` = 1 ]; then
+      echo "Pin $i failure - expected 0, got 1"
+      let errs+=1
+    fi
+  done
+
+# Remove the internal pull up/downs
+
+  for i in `seq $start $end`; do
+    gpio mode $i tri
+  done
+
+  if [ $errs = 0 ]; then
+    echo " OK"
+  else
+    printErrCount
+  fi
+
+  let totErrs+=errs
+}
+
+
+intro()
+{
+  revision=`gpio -V`
+  cat <<EOF
+PinTest
+=======
+
+This is a simple utility to test the GPIO pins on your revision $revision
+Raspberry Pi.
+
+NOTE: All GPIO peripherals must be removed to perform this test. This
+  includes serial, I2C and SPI connections. You may get incorrect results
+  if something is connected and it interferes with the test.
+
+This test can only test the input side of things. It uses the internal
+pull-up and pull-down resistors to simulate inputs. It does not test
+the output drivers.
+
+You will need to reboot your Pi after this test if you wish to use the 
+serial port as it will be left in GPIO mode rather than serial mode.
+
+Please make sure everything is removed and press the ENTER key to continue,
+EOF
+
+  echo -n "or Control-C to abort... "
+  read a
+}
+
+
+# Start here
+################################################################################
+
+intro
+gpio unexportall
+gpio reset
+
+   errs=0
+totErrs=0
+
+echo ""
+
+# Main pins
+
+testPins 0 7 "The main 8 GPIO pins"
+
+# P5 pins, if a rev 2:
+
+if [ $revision = 2 ]; then
+  testPins 17 20 "The 4 pins on the P5 connector"
+fi
+
+# SPI
+
+testPins 10 14 "The 5 SPI pins"
+
+# Serial
+
+testPins 15 16 "The serial pins"
+
+# I2C - Needs somewhat different testing
+#      due to the on-board pull-up's
+
+echo -n "                  The I2C pins  8: 9: "
+errs=0
+gpio mode 8 in
+gpio mode 9 in
+
+if [ `gpio read 8` = 0 ]; then
+  echo "Pin 8 failure - expected 1, got 0"
+  let errs+=1
+fi
+
+if [ `gpio read 9` = 0 ]; then
+  echo "Pin 9 failure - expected 1, got 0"
+  let errs+=1
+fi
+
+if [ $errs = 0 ]; then
+  echo " OK"
+else
+  printErrCount
+fi
+
+echo ""
+if [ $totErrs != 0 ]; then
+  echo ""
+  echo "Faults detected! Output of 'readall':"
+  gpio readall
+fi
diff --git a/pins/Makefile b/pins/Makefile
new file mode 100644 (file)
index 0000000..5e200c2
--- /dev/null
@@ -0,0 +1,18 @@
+
+SRC    =       pins.tex
+
+
+all:           ${SRC}
+       @echo   Generating DVI
+       @latex  pins.tex
+
+pins.dvi:      pins.tex
+       @latex  pins.tex
+
+pdf:   pins.dvi
+       @dvipdf pins.dvi
+
+
+.PHONEY:       clean
+clean:
+       @rm -f *.dvi *.aux *.log *.ps *.toc *.bak *~
diff --git a/pins/pins.pdf b/pins/pins.pdf
new file mode 100644 (file)
index 0000000..bd9629d
Binary files /dev/null and b/pins/pins.pdf differ
diff --git a/pins/pins.tex b/pins/pins.tex
new file mode 100644 (file)
index 0000000..c3753e9
--- /dev/null
@@ -0,0 +1,116 @@
+\documentclass[12pt,a4paper]{article}
+\parskip 1ex
+\parindent 0em
+\thispagestyle{empty}
+\pagestyle{plain}
+\pagenumbering{arabic}
+\setlength{\topmargin}{0pt}
+\setlength{\headheight}{0pt}
+\setlength{\headsep}{0pt}
+\setlength{\topskip}{0pt}
+\setlength{\textheight}{240mm}
+\setlength{\footskip}{5ex}
+\setlength{\oddsidemargin}{0pt}
+\setlength{\evensidemargin}{0pt}
+\setlength{\textwidth}{160mm}
+\usepackage[dvips]{graphics,color}
+\usepackage{helvet}
+\renewcommand{\familydefault}{\sfdefault}
+\begin{document}
+\begin{sffamily}
+\definecolor{rtb-black}{rgb}  {0.0, 0.0, 0.0}
+\definecolor{rtb-navy}{rgb}   {0.0, 0.0, 0.5}
+\definecolor{rtb-green}{rgb}  {0.0, 0.5, 0.0}
+\definecolor{rtb-teal}{rgb}   {0.0, 0.5, 0.5}
+\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0}
+\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5}
+\definecolor{rtb-olive}{rgb}  {0.5, 0.5, 0.0}
+\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7}
+\definecolor{rtb-grey}{rgb}   {0.5, 0.5, 0.5}
+\definecolor{rtb-blue}{rgb}   {0.0, 0.0, 1.0}
+\definecolor{rtb-lime}{rgb}   {0.0, 1.0, 0.0}
+\definecolor{rtb-aqua}{rgb}   {0.0, 1.0, 1.0}
+\definecolor{rtb-red}{rgb}    {1.0, 0.0, 0.0}
+\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0}
+\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0}
+\definecolor{rtb-white}{rgb}  {1.0, 1.0, 1.0}
+
+\begin{center}
+\bfseries{WiringPi: GPIO Pin Numbering Tables}\\
+\tt{http://wiringpi.com/}
+\end{center}
+
+\begin{center}
+\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|}
+\hline
+\multicolumn{8}{|c|}{\bfseries{P1: The Main GPIO connector}}\\
+\hline
+\hline
+WiringPi Pin   & BCM GPIO      & Name  & \multicolumn{2}{|c||}{Header} & Name  & BCM GPIO      & WiringPi Pin\\
+\hline
+\hline
+       &                       & \textcolor{rtb-red}{3.3v}     & \raggedleft{1} &  2 & \textcolor{rtb-maroon}{5v}      &       & \\
+\hline
+8      & Rv1:0 - Rv2:2         & \textcolor{rtb-aqua}{SDA}     & \raggedleft{3} &  4 & \textcolor{rtb-maroon}{5v}      &       & \\
+\hline
+9      & Rv1:1 - Rv2:3         & \textcolor{rtb-aqua}{SCL}     & \raggedleft{5} &  6 & \textcolor{rtb-black}{0v}       &       & \\
+\hline
+7      & 4                     & \textcolor{rtb-green}{GPIO7}  & \raggedleft{7} &  8 & \textcolor{rtb-yellow}{TxD}     & 14    & 15\\
+\hline
+       &                       & \textcolor{rtb-black}{0v}     & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD}     & 15    & 16\\
+\hline
+0      & 17                    & \textcolor{rtb-green}{GPIO0}  & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1}   & 18    & 1\\
+\hline
+2      & Rv1:21 - Rv2:27       & \textcolor{rtb-green}{GPIO2}  & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v}      &       & \\
+\hline
+3      & 22                    & \textcolor{rtb-green}{GPIO3}  & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4}   & 23    & 4\\
+\hline
+       &                       & \textcolor{rtb-red}{3.3v}     & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5}   & 24    & 5\\
+\hline
+12     & 10                    & \textcolor{rtb-teal}{MOSI}    & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v}      &       & \\
+\hline
+13     & 9                     & \textcolor{rtb-teal}{MISO}    & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6}   & 25    & 6\\
+\hline
+14     & 11                    & \textcolor{rtb-teal}{SCLK}    & \raggedleft{23} & 24 & \textcolor{rtb-teal}{CE0}      & 8     & 10\\
+\hline
+       &                       & \textcolor{rtb-black}{0v}     & \raggedleft{25} & 26 & \textcolor{rtb-teal}{CE1}      & 7     & 11\\
+\hline
+\hline
+WiringPi Pin   & BCM GPIO      & Name  & \multicolumn{2}{|c||}{Header} & Name  & BCM GPIO      & WiringPi Pin\\
+\hline
+\end{tabular}
+\end{center}
+
+Note the differences between Revision 1 and Revision 2 Raspberry
+Pi's. The Revision 2 is readily identifiable by the presence of the 2
+mounting holes.
+
+The revision 2 Raspberry Pi has an additional GPIO connector, P5, which is next to the main P1 GPIO
+connector:
+
+\begin{center}
+\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|}
+\hline
+\multicolumn{8}{|c|}{\bfseries{P5: Secondary GPIO connector (Rev. 2 Pi only)}}\\
+\hline
+\hline
+WiringPi Pin   & BCM GPIO      & Name  & \multicolumn{2}{|c||}{Header} & Name  & BCM GPIO      & WiringPi Pin\\
+\hline
+\hline
+       &               & \textcolor{rtb-maroon}{5v}    & \raggedleft{1} &  2 & \textcolor{rtb-red}{3.3v}       &       &       \\
+\hline
+17     & 28            & \textcolor{rtb-green}{GPIO8}  & \raggedleft{3} &  4 & \textcolor{rtb-green}{GPIO9}    & 29    & 18    \\
+\hline
+19     & 30            & \textcolor{rtb-green}{GPIO10} & \raggedleft{5} &  6 & \textcolor{rtb-green}{GPIO11}   & 31    & 20    \\
+\hline
+       &               & \textcolor{rtb-black}{0v}     & \raggedleft{7} &  8 & \textcolor{rtb-black}{0v}       &       &       \\
+\hline
+\hline
+WiringPi Pin   & BCM GPIO      & Name  & \multicolumn{2}{|c||}{Header} & Name  & BCM GPIO      & WiringPi Pin\\
+\hline
+\end{tabular}
+\end{center}
+
+
+\end{sffamily}
+\end{document}
index c6a45559b06b4f3f244cea7eece4b3884cb7fcc0..8ece853792c8b47df6dc0da0257ce16e5e727b51 100644 (file)
@@ -21,7 +21,7 @@
 #    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
 #################################################################################
 
-DYN_VERS_MAJ=1
+DYN_VERS_MAJ=2
 DYN_VERS_MIN=0
 
 VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
@@ -35,26 +35,25 @@ DYNAMIC=libwiringPi.so.$(VERSION)
 DEBUG  = -O2
 CC     = gcc
 INCLUDE        = -I.
-CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC
+CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC
 
 LIBS    =
 
 # Should not alter anything below this line
 ###############################################################################
 
-SRC    =       wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c  \
-               gertboard.c                                             \
-               piNes.c                                                 \
-               lcd.c piHiPri.c piThread.c                              \
-               wiringPiSPI.c                                           \
-               softPwm.c softServo.c softTone.c
-
-SRC_I2C        =       wiringPiI2C.c
+SRC    =       wiringPi.c                                              \
+               wiringSerial.c wiringShift.c                            \
+               piHiPri.c piThread.c                                    \
+               wiringPiSPI.c wiringPiI2C.c                             \
+               softPwm.c softTone.c                                    \
+               mcp23s08.c mcp23008.c                                   \
+               mcp23s17.c mcp23017.c sr595.c pcf8574.c                 \
+               mcp3002.c mcp4802.c mcp3422.c                           \
+               drc.c
 
 OBJ    =       $(SRC:.c=.o)
 
-OBJ_I2C        =       $(SRC_I2C:.c=.o)
-
 all:           $(DYNAMIC)
 
 static:                $(STATIC)
@@ -67,11 +66,7 @@ $(STATIC):   $(OBJ)
 
 $(DYNAMIC):    $(OBJ)
        @echo "[Link (Dynamic)]"
-       @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)
-
-i2c:   $(OBJ) $(OBJ_I2C)
-       @echo "[Link (Dynamic + I2C)]"
-       @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C)
+       @$(CC) -shared -Wl,-soname,libwiringPi.so -o libwiringPi.so.$(VERSION) -lpthread $(OBJ)
 
 .c.o:
        @echo [Compile] $<
@@ -79,37 +74,48 @@ i2c:        $(OBJ) $(OBJ_I2C)
 
 .PHONEY:       clean
 clean:
-       rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
+       @echo "[Clean]"
+       @rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
 
 .PHONEY:       tags
 tags:  $(SRC)
        @echo [ctags]
        @ctags $(SRC)
 
-.PHONEY:       install
-install:       $(DYNAMIC)
-       @echo "[Install]"
-       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/lib
+
+.PHONEY:       install-headers
+install-headers:
+       @echo "[Install Headers]"
        @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/include
        @install -m 0644 wiringPi.h             $(DESTDIR)$(PREFIX)/include
        @install -m 0644 wiringSerial.h         $(DESTDIR)$(PREFIX)/include
        @install -m 0644 wiringShift.h          $(DESTDIR)$(PREFIX)/include
-       @install -m 0644 gertboard.h            $(DESTDIR)$(PREFIX)/include
-       @install -m 0644 piNes.h                $(DESTDIR)$(PREFIX)/include
        @install -m 0644 softPwm.h              $(DESTDIR)$(PREFIX)/include
-       @install -m 0644 softServo.h            $(DESTDIR)$(PREFIX)/include
        @install -m 0644 softTone.h             $(DESTDIR)$(PREFIX)/include
-       @install -m 0644 lcd.h                  $(DESTDIR)$(PREFIX)/include
        @install -m 0644 wiringPiSPI.h          $(DESTDIR)$(PREFIX)/include
        @install -m 0644 wiringPiI2C.h          $(DESTDIR)$(PREFIX)/include
-       @install -m 0755 libwiringPi.so.$(VERSION)                $(DESTDIR)$(PREFIX)/lib
-       @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
-       @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1
+       @install -m 0644 mcp23008.h             $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp23017.h             $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp23s08.h             $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp23s17.h             $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp3002.h              $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp4802.h              $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 mcp3422.h              $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 sr595.h                $(DESTDIR)$(PREFIX)/include
+       @install -m 0644 pcf8574.h              $(DESTDIR)$(PREFIX)/include
+
+.PHONEY:       install
+install:       $(DYNAMIC) install-headers
+       @echo "[Install Dynamic Lib]"
+       @install -m 0755 -d                                             $(DESTDIR)$(PREFIX)/lib
+       @install -m 0755 libwiringPi.so.$(VERSION)                      $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
+       @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)       $(DESTDIR)/lib/libwiringPi.so
        @ldconfig
 
 .PHONEY:       install-static
-install-static:        $(STATIC)
-       @echo "[Install Static]"
+install-static:        $(STATIC) install-headers
+       @echo "[Install Static Lib]"
+       @install -m 0755 -d                     $(DESTDIR)$(PREFIX)/lib
        @install -m 0755 libwiringPi.a          $(DESTDIR)$(PREFIX)/lib
 
 .PHONEY:       uninstall
@@ -118,14 +124,19 @@ uninstall:
        @rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h
        @rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h
        @rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h
-       @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
-       @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
        @rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h
-       @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
        @rm -f $(DESTDIR)$(PREFIX)/include/softTone.h
-       @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
        @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
        @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp23008.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp23017.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp23s08.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp23s17.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp3002.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp4802.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/mcp3422.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/sr595.h
+       @rm -f $(DESTDIR)$(PREFIX)/include/pcf8574.h
        @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
        @ldconfig
 
@@ -137,16 +148,21 @@ depend:
 # DO NOT DELETE
 
 wiringPi.o: wiringPi.h
-wiringPiFace.o: wiringPi.h
 wiringSerial.o: wiringSerial.h
 wiringShift.o: wiringPi.h wiringShift.h
-gertboard.o: wiringPiSPI.h gertboard.h
-piNes.o: wiringPi.h piNes.h
-lcd.o: wiringPi.h lcd.h
 piHiPri.o: wiringPi.h
 piThread.o: wiringPi.h
-wiringPiSPI.o: wiringPiSPI.h
+wiringPiSPI.o: wiringPi.h wiringPiSPI.h
+wiringPiI2C.o: wiringPi.h wiringPiI2C.h
 softPwm.o: wiringPi.h softPwm.h
-softServo.o: wiringPi.h softServo.h
 softTone.o: wiringPi.h softTone.h
-wiringPiI2C.o: wiringPi.h wiringPiI2C.h
+mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
+mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h
+mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
+mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h
+sr595.o: wiringPi.h sr595.h
+pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h
+mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h
+mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
+mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h
+drc.o: wiringPi.h wiringSerial.h drc.h
diff --git a/wiringPi/README b/wiringPi/README
deleted file mode 100644 (file)
index c79754e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-WiringPi: An implementation of most of the Arduino Wiring
-       functions for the Raspberry Pi,
-       along with many more features and libraries to support
-       hardware, etc. on the Raspberry Pi
-
-Full details at:
-       https://projects.drogon.net/raspberry-pi/wiringpi/
-
diff --git a/wiringPi/drc.c b/wiringPi/drc.c
new file mode 100644 (file)
index 0000000..07baf17
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * drc.c:
+ *     Extend wiringPi with the DRC control protocll 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/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include "wiringPi.h"
+#include "wiringSerial.h"
+
+#include "drc.h"
+
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+
+/*
+ * 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) ;
+
+  /**/ 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 drcSetup (const int pinBase, const int numPins, const char *device)
+{
+  int fd ;
+  int ok, tries ;
+  time_t then ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = serialOpen (device, 115200)) < 0)
+    return wiringPiFailure (WPI_ALMOST, "Unable to open DRC device (%s): %s", device, strerror (errno)) ;
+
+  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 ; ++tries)
+  {
+    serialPutchar (fd, '@') ;
+    then = time (NULL) + 2 ;
+    while (time (NULL) < then)
+      if (serialDataAvail (fd))
+      {
+        if (serialGetchar (fd) == '@')
+        {
+          ok = TRUE ;
+          break ;
+        }
+      }
+    if (ok)
+      break ;
+  }
+
+  if (!ok)
+  {
+    serialClose (fd) ;
+    return wiringPiFailure (WPI_FATAL, "Unable to communidate with DRC device") ;
+  }
+
+  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 0 ;
+}
diff --git a/wiringPi/drc.h b/wiringPi/drc.h
new file mode 100644 (file)
index 0000000..c2c4ff3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * drc.h:
+ *     Extend wiringPi with the DRC control protocll 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
+
+int drcSetup (const int pinBase, const int numPins, const char *device) ;
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c
new file mode 100644 (file)
index 0000000..d21d237
--- /dev/null
@@ -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 fd ;
+
+  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 0 ;
+}
diff --git a/wiringPi/mcp23008.h b/wiringPi/mcp23008.h
new file mode 100644 (file)
index 0000000..e9299a8
--- /dev/null
@@ -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/mcp23017.c b/wiringPi/mcp23017.c
new file mode 100644 (file)
index 0000000..5174195
--- /dev/null
@@ -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 fd ;
+
+  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 0 ;
+}
diff --git a/wiringPi/mcp23017.h b/wiringPi/mcp23017.h
new file mode 100644 (file)
index 0000000..79b4d7b
--- /dev/null
@@ -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 (file)
index 0000000..d0acb5e
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 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)
+{
+  int    x ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0)
+    return x ;
+
+  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 0 ;
+}
diff --git a/wiringPi/mcp23s08.h b/wiringPi/mcp23s08.h
new file mode 100644 (file)
index 0000000..ebf93d1
--- /dev/null
@@ -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 (file)
index 0000000..c2d1be3
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * 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)
+{
+  int    x ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0)
+    return x ;
+
+  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 0 ;
+}
diff --git a/wiringPi/mcp23s17.h b/wiringPi/mcp23s17.h
new file mode 100644 (file)
index 0000000..3b2a808
--- /dev/null
@@ -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 (file)
index 0000000..c4e6b27
--- /dev/null
@@ -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 (file)
index 0000000..58bc038
--- /dev/null
@@ -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 (file)
index 0000000..2e7d5cf
--- /dev/null
@@ -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] << 7) | (spiData [1] >> 1)) & 0x3FF ;
+}
+
+
+/*
+ * mcp3002Setup:
+ *     Create a new wiringPi device node for an mcp2003 on the Pi's
+ *     SPI interface.
+ *********************************************************************************
+ */
+
+int mcp3002Setup (const int pinBase, int spiChannel)
+{
+  struct wiringPiNodeStruct *node ;
+
+  if (wiringPiSPISetup (spiChannel, 1000000) < 0)
+    return -1 ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd         = spiChannel ;
+  node->analogRead = myAnalogRead ;
+
+  return 0 ;
+}
diff --git a/wiringPi/mcp3002.h b/wiringPi/mcp3002.h
new file mode 100644 (file)
index 0000000..0cd727f
--- /dev/null
@@ -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/mcp3422.c b/wiringPi/mcp3422.c
new file mode 100644 (file)
index 0000000..8e26d76
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * mcp3422.c:
+ *     Extend wiringPi with the MCP3422 I2C ADC 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 <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/spi/spidev.h>
+
+#include <wiringPi.h>
+#include <wiringPiI2C.h>
+
+#include "mcp3422.h"
+
+
+/*
+ * myAnalogRead:
+ *     Read a channel from the device
+ *********************************************************************************
+ */
+
+int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
+{
+  unsigned char config, b0, b1, b2, b3 ;
+  int value = 0 ;
+
+// One-shot mode, trigger plus the other configs.
+
+  config = 0x80 | ((chan - node->pinBase) << 5) | (node->data0 << 2) | (node->data1) ;
+  
+  wiringPiI2CWrite (node->fd, config) ;
+
+  switch (node->data0) // Sample rate
+  {
+    case MCP3422_SR_3_75:                      // 18 bits
+      delay (270) ;
+      b0 = wiringPiI2CRead (node->fd) ;
+      b1 = wiringPiI2CRead (node->fd) ;
+      b2 = wiringPiI2CRead (node->fd) ;
+      b3 = wiringPiI2CRead (node->fd) ;
+      value = ((b0 & 3) << 16) | (b1 << 8) | b2 ;
+      break ;
+
+    case MCP3422_SR_15:                                // 16 bits
+      delay ( 70) ;
+      b0 = wiringPiI2CRead (node->fd) ;
+      b1 = wiringPiI2CRead (node->fd) ;
+      b2 = wiringPiI2CRead (node->fd) ;
+      value = (b0 << 8) | b1 ;
+      break ;
+
+    case MCP3422_SR_60:                                // 14 bits
+      delay ( 17) ;
+      b0 = wiringPiI2CRead (node->fd) ;
+      b1 = wiringPiI2CRead (node->fd) ;
+      b2 = wiringPiI2CRead (node->fd) ;
+      value = ((b0 & 0x3F) << 8) | b1 ;
+      break ;
+
+    case MCP3422_SR_240:                       // 12 bits
+      delay (  5) ;
+      b0 = wiringPiI2CRead (node->fd) ;
+      b1 = wiringPiI2CRead (node->fd) ;
+      b2 = wiringPiI2CRead (node->fd) ;
+      value = ((b0 & 0x0F) << 8) | b1 ;
+      break ;
+  }
+
+  return value ;
+}
+
+
+/*
+ * mcp3422Setup:
+ *     Create a new wiringPi device node for the mcp3422
+ *********************************************************************************
+ */
+
+int mcp3422Setup (int pinBase, int i2cAddress, int channels, int sampleRate, int gain)
+{
+  int fd ;
+  struct wiringPiNodeStruct *node ;
+
+  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
+    return fd ;
+
+  node = wiringPiNewNode (pinBase, channels) ;
+
+  node->data0      = sampleRate ;
+  node->data1      = gain ;
+  node->analogRead = myAnalogRead ;
+
+  return 0 ;
+}
diff --git a/wiringPi/mcp3422.h b/wiringPi/mcp3422.h
new file mode 100644 (file)
index 0000000..8b4e350
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * mcp3422.c:
+ *     Extend wiringPi with the MCP3422 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_3_75 0
+#define        MCP3422_SR_15   1
+#define        MCP3422_SR_60   2
+#define        MCP3422_SR_240  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 channels, int sampleRate, int gain) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp4802.c b/wiringPi/mcp4802.c
new file mode 100644 (file)
index 0000000..5c5c17a
--- /dev/null
@@ -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 -1 ;
+
+  node = wiringPiNewNode (pinBase, 2) ;
+
+  node->fd          = spiChannel ;
+  node->analogWrite = myAnalogWrite ;
+
+  return 0 ;
+}
diff --git a/wiringPi/mcp4802.h b/wiringPi/mcp4802.h
new file mode 100644 (file)
index 0000000..effa024
--- /dev/null
@@ -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 (file)
index 0000000..ce9c533
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * pcf8574.c:
+ *     Extend wiringPi with the PFC8574 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 PFC8574 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 PFC8574 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 fd ;
+
+  node = wiringPiNewNode (pinBase, 8) ;
+
+  node->fd              = fd ;
+  node->pinMode         = myPinMode ;
+  node->digitalRead     = myDigitalRead ;
+  node->digitalWrite    = myDigitalWrite ;
+  node->data2           = wiringPiI2CRead (fd) ;
+
+  return 0 ;
+}
diff --git a/wiringPi/pcf8574.h b/wiringPi/pcf8574.h
new file mode 100644 (file)
index 0000000..3cad2dd
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * pfc8574.h:
+ *     Extend wiringPi with the PFC8574 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 pfc8574Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
index e7e06b432f6e8a9170e2460b61e857c6b75077c4..d2f3b4e9cc867a58b6d365990bfcdde3c877a9a6 100644 (file)
  *********************************************************************************
  */
 
-int piHiPri (int pri)
+int piHiPri (const int pri)
 {
   struct sched_param sched ;
 
   memset (&sched, 0, sizeof(sched)) ;
 
   if (pri > sched_get_priority_max (SCHED_RR))
-    pri = sched_get_priority_max (SCHED_RR) ;
+    sched.sched_priority = sched_get_priority_max (SCHED_RR) ;
+  else
+    sched.sched_priority = pri ;
 
-  sched.sched_priority = pri ;
   return sched_setscheduler (0, SCHED_RR, &sched) ;
 }
index b568dfb45ca509131f1c013403b35fb79d38a1fc..a4f0fc43f6b0fc3e0dc434c1cef9087e0833a982 100644 (file)
@@ -28,7 +28,7 @@
 #include "wiringPi.h"
 #include "softPwm.h"
 
-#define        MAX_PINS        64
+#define        MAX_PINS        1024
 
 // The PWM Frequency is derived from the "pulse time" below. Essentially,
 //     the frequency is a function of the range and this pulse time.
@@ -93,7 +93,7 @@ static PI_THREAD (softPwmThread)
 
 void softPwmWrite (int pin, int value)
 {
-  pin &= 63 ;
+  pin &= (MAX_PINS - 1) ;
 
   /**/ if (value < 0)
     value = 0 ;
index 846362726fdb8fbbe20fe7e38774cffa8d0ff135..b4a89f8a250ee8ca803cf20e88b6986937e54087 100644 (file)
@@ -36,7 +36,7 @@
 
 #define        PULSE_TIME      100
 
-static int frewqs [MAX_PINS] ;
+static int freqs [MAX_PINS] ;
 
 static int newPin = -1 ;
 
@@ -49,7 +49,7 @@ static int newPin = -1 ;
 
 static PI_THREAD (softToneThread)
 {
-  int pin, frewq, halfPeriod ;
+  int pin, freq, halfPeriod ;
 
   pin    = newPin ;
   newPin = -1 ;
@@ -58,12 +58,12 @@ static PI_THREAD (softToneThread)
 
   for (;;)
   {
-    frewq = frewqs [pin] ;
-    if (frewq == 0)
+    freq = freqs [pin] ;
+    if (freq == 0)
       delay (1) ;
     else
     {
-      halfPeriod = 500000 / frewq ;
+      halfPeriod = 500000 / freq ;
 
       digitalWrite (pin, HIGH) ;
       delayMicroseconds (halfPeriod) ;
@@ -83,16 +83,16 @@ static PI_THREAD (softToneThread)
  *********************************************************************************
  */
 
-void softToneWrite (int pin, int frewq)
+void softToneWrite (int pin, int freq)
 {
   pin &= 63 ;
 
-  /**/ if (frewq < 0)
-    frewq = 0 ;
-  else if (frewq > 5000)       // Max 5KHz
-    frewq = 5000 ;
+  /**/ if (freq < 0)
+    freq = 0 ;
+  else if (freq > 5000)        // Max 5KHz
+    freq = 5000 ;
 
-  frewqs [pin] = frewq ;
+  freqs [pin] = freq ;
 }
 
 
@@ -109,7 +109,7 @@ int softToneCreate (int pin)
   pinMode      (pin, OUTPUT) ;
   digitalWrite (pin, LOW) ;
 
-  frewqs [pin] = 0 ;
+  freqs [pin] = 0 ;
 
   newPin = pin ;
   res = piThreadCreate (softToneThread) ;
index 80c64fe64cc8bd92865fcce8f715d952757041b7..d8b4e54cee8afc0f2de34a56e31ad22bafbfada0 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 #endif
 
 extern int  softToneCreate (int pin) ;
-extern void softToneWrite  (int pin, int frewq) ;
+extern void softToneWrite  (int pin, int freq) ;
 
 #ifdef __cplusplus
 }
diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c
new file mode 100644 (file)
index 0000000..87210c2
--- /dev/null
@@ -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 0 ;
+}
diff --git a/wiringPi/sr595.h b/wiringPi/sr595.h
new file mode 100644 (file)
index 0000000..4a26dc7
--- /dev/null
@@ -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
index a68ae33e0565cbd9e39bb36b373b2315d31c703b..b8e381a27cd819f809f69974473c165e57a8986a 100644 (file)
@@ -53,6 +53,7 @@
 
 
 #include <stdio.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <ctype.h>
 
 #include "wiringPi.h"
 
-// Function stubs
-
-void (*pinMode)           (int pin, int mode) ;
-int  (*getAlt)            (int pin) ;
-void (*pullUpDnControl)   (int pin, int pud) ;
-void (*digitalWrite)      (int pin, int value) ;
-void (*digitalWriteByte)  (int value) ;
-void (*pwmWrite)          (int pin, int value) ;
-void (*gpioClockSet)      (int pin, int value) ;
-void (*setPadDrive)       (int group, int value) ;
-int  (*digitalRead)       (int pin) ;
-int  (*waitForInterrupt)  (int pin, int mS) ;
-void (*pwmSetMode)        (int mode) ;
-void (*pwmSetRange)       (unsigned int range) ;
-void (*pwmSetClock)       (int divisor) ;
-
-
 #ifndef        TRUE
 #define        TRUE    (1==1)
 #define        FALSE   (1==2)
 #endif
 
+// Environment Variables
+
+#define        ENV_DEBUG       "WIRINGPI_DEBUG"
+#define        ENV_CODES       "WIRINGPI_CODES"
+
+
+// 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)
+
+static struct wiringPiNodeStruct *wiringPiNodes = NULL ;
+
 // BCM Magic
 
 #define        BCM_PASSWORD            0x5A000000
@@ -192,8 +189,11 @@ static volatile uint32_t *gpio ;
 static volatile uint32_t *pwm ;
 static volatile uint32_t *clk ;
 static volatile uint32_t *pads ;
+
+#ifdef USE_TIMER
 static volatile uint32_t *timer ;
 static volatile uint32_t *timerIrqRaw ;
+#endif
 
 // Time for easy calculations
 
@@ -202,10 +202,13 @@ static uint64_t epochMilli, epochMicro ;
 // Misc
 
 static int wiringPiMode = WPI_MODE_UNINITIALISED ;
+static volatile int    pinPass = -1 ;
+static pthread_mutex_t pinMutex ;
 
-// Debugging
+// Debugging & Return codes
 
-int wiringPiDebug = FALSE ;
+int wiringPiDebug       = FALSE ;
+int wiringPiReturnCodes = FALSE ;
 
 // sysFds:
 //     Map a file descriptor from the /sys/class/gpio/gpioX/value
@@ -223,17 +226,17 @@ static void (*isrFunctions [64])(void) ;
 
 // pinToGpio:
 //     Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
-//     Cope for 2 different board revieions here
+//     Cope for 2 different board revisions here.
 
 static int *pinToGpio ;
 
 static int pinToGpioR1 [64] =
 {
-  17, 18, 21, 22, 23, 24, 25, 4,       // From the Original Wiki - GPIO 0 through 7
-   0,  1,                              // I2C  - SDA0, SCL0
-   8,  7,                              // SPI  - CE1, CE0
-  10,  9, 11,                          // SPI  - MOSI, MISO, SCLK
-  14, 15,                              // UART - Tx, Rx
+  17, 18, 21, 22, 23, 24, 25, 4,       // From the Original Wiki - GPIO 0 through 7:   wpi  0 -  7
+   0,  1,                              // I2C  - SDA0, SCL0                            wpi  8 -  9
+   8,  7,                              // SPI  - CE1, CE0                              wpi 10 - 11
+  10,  9, 11,                          // SPI  - MOSI, MISO, SCLK                      wpi 12 - 14
+  14, 15,                              // UART - Tx, Rx                                wpi 15 - 16
 
 // Padding:
 
@@ -259,8 +262,65 @@ static int pinToGpioR2 [64] =
 } ;
 
 
+// physToGpio:
+//     Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin
+//     Cope for 2 different board revisions here.
+
+static int *physToGpio ;
+
+static int physToGpioR1 [64] =
+{
+  -1,          // 0
+  -1, -1,      // 1, 2
+   0, -1,
+   1, -1,
+   4, 14,
+  -1, 15,
+  17, 18,
+  21, -1,
+  22, 23,
+  -1, 24,
+  10, -1,
+   9, 25,
+  11,  8,
+  -1,  7,      // 25, 26
+
+// Padding:
+
+                                              -1, -1, -1, -1, -1,      // ... 31
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,      // ... 47
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,      // ... 63
+} ;
+
+static int physToGpioR2 [64] =
+{
+  -1,          // 0
+  -1, -1,      // 1, 2
+   2, -1,
+   3, -1,
+   4, 14,
+  -1, 15,
+  17, 18,
+  27, -1,
+  22, 23,
+  -1, 24,
+  10, -1,
+   9, 25,
+  11,  8,
+  -1,  7,      // 25, 26
+
+// Padding:
+
+                                              -1, -1, -1, -1, -1,      // ... 31
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,      // ... 47
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,      // ... 63
+} ;
+
+
 // gpioToGPFSEL:
-//     Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
+//     Map a BCM_GPIO pin to it's Function Selection
+//     control port. (GPFSEL 0-5)
+//     Groups of 10 - 3 bits per Function - 30 bits per port
 
 static uint8_t gpioToGPFSEL [] =
 {
@@ -295,7 +355,6 @@ static uint8_t gpioToGPSET [] =
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 } ;
 
-
 // gpioToGPCLR:
 //     (Word) offset to the GPIO Clear registers for each GPIO pin
 
@@ -376,6 +435,7 @@ static uint8_t gpioToPwmALT [] =
           0,         0,         0,         0,         0,         0,         0,         0,      // 56 -> 63
 } ;
 
+
 // gpioToPwmPort
 //     The port value to put a GPIO pin into PWM mode
 
@@ -395,7 +455,7 @@ static uint8_t gpioToPwmPort [] =
 // gpioToGpClkALT:
 //     ALT value to put a GPIO pin into GP Clock mode.
 //     On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21
-//     for clocks 0 and 1 respectivey, however I'll include the full
+//     for clocks 0 and 1 respectively, however I'll include the full
 //     list for completeness - maybe one day...
 
 #define        GPIO_CLOCK_SOURCE       1
@@ -449,23 +509,34 @@ static uint8_t gpioToClkDiv [] =
 
 
 /*
- * wpiPinToGpio:
- *     Translate a wiringPi Pin number to native GPIO pin number.
- *     (We don't use this here, prefering to just do the lookup directly,
- *     but it's been requested!)
+ * wiringPiFailure:
+ *     Fail. Or not.
  *********************************************************************************
  */
 
-int wpiPinToGpio (int wpiPin)
+int wiringPiFailure (int fatal, const char *message, ...)
 {
-  return pinToGpio [wpiPin & 63] ;
+  va_list argp ;
+  char buffer [1024] ;
+
+  if (!fatal && wiringPiReturnCodes)
+    return -1 ;
+
+  va_start (argp, message) ;
+    vsnprintf (buffer, 1023, message, argp) ;
+  va_end (argp) ;
+
+  fprintf (stderr, "%s", buffer) ;
+  exit (EXIT_FAILURE) ;
+
+  return 0 ;
 }
 
 
 /*
  * piBoardRev:
  *     Return a number representing the hardware revision of the board.
- *     Revision is currently 1 or 2. -1 is returned on error.
+ *     Revision is currently 1 or 2.
  *
  *     Much confusion here )-:
  *     Seems there are some boards with 0000 in them (mistake in manufacture)
@@ -488,7 +559,7 @@ int wpiPinToGpio (int wpiPin)
  *********************************************************************************
  */
 
-static void piBoardRevOops (char *why)
+static void piBoardRevOops (const char *why)
 {
   fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
   fprintf (stderr, " -> %s\n", why) ;
@@ -556,6 +627,58 @@ int piBoardRev (void)
 }
 
 
+/*
+ * wpiPinToGpio:
+ *     Translate a wiringPi Pin number to native GPIO pin number.
+ *     Provided for external support.
+ *********************************************************************************
+ */
+
+int wpiPinToGpio (int wpiPin)
+{
+  return pinToGpio [wpiPin & 63] ;
+}
+
+
+/*
+ * physPinToGpio:
+ *     Translate a physical Pin number to native GPIO pin number.
+ *     Provided for external support.
+ *********************************************************************************
+ */
+
+int physPinToGpio (int physPin)
+{
+  return physToGpio [physPin & 63] ;
+}
+
+
+/*
+ * setPadDrive:
+ *     Set the PAD driver value
+ *********************************************************************************
+ */
+
+void setPadDrive (int group, int value)
+{
+  uint32_t wrVal ;
+
+  if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+  {
+    if ((group < 0) || (group > 2))
+      return ;
+
+    wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
+    *(pads + group + 11) = wrVal ;
+
+    if (wiringPiDebug)
+    {
+      printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
+      printf ("Read : %08X\n", *(pads + group + 11)) ;
+    }
+  }
+}
+
 
 /*
  * getAlt:
@@ -564,12 +687,19 @@ int piBoardRev (void)
  *********************************************************************************
  */
 
-int getAltGpio (int pin)
+int getAlt (int pin)
 {
   int fSel, shift, alt ;
 
   pin &= 63 ;
 
+  /**/ if (wiringPiMode == WPI_MODE_PINS)
+    pin = pinToGpio [pin] ;
+  else if (wiringPiMode == WPI_MODE_PHYS)
+    pin = physToGpio [pin] ;
+  else if (wiringPiMode != WPI_MODE_GPIO)
+    return 0 ;
+
   fSel    = gpioToGPFSEL [pin] ;
   shift   = gpioToShift  [pin] ;
 
@@ -578,70 +708,66 @@ int getAltGpio (int pin)
   return alt ;
 }
 
-int getAltWPi (int pin)
-{
-  return getAltGpio (pinToGpio [pin & 63]) ;
-}
-
-int getAltSys (int pin)
-{
-  return 0 ;
-}
-
 
 /*
- * pwmControl:
- *     Allow the user to control some of the PWM functions
+ * pwmSetMode:
+ *     Select the native "balanced" mode, or standard mark:space mode
  *********************************************************************************
  */
 
-void pwmSetModeWPi (int mode)
+void pwmSetMode (int mode)
 {
-  if (mode == PWM_MODE_MS)
-    *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
-  else
-    *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
+  if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+  {
+    if (mode == PWM_MODE_MS)
+      *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
+    else
+      *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
+  }
 }
 
-void pwmSetModeSys (int mode)
-{
-  return ;
-}
 
+/*
+ * pwmSetRange:
+ *     Set the PWM range register. We set both range registers to the same
+ *     value. If you want different in your own code, then write your own.
+ *********************************************************************************
+ */
 
-void pwmSetRangeWPi (unsigned int range)
+void pwmSetRange (unsigned int range)
 {
-  *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
-  *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
+  if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+  {
+    *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
+    *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
+  }
 }
 
-void pwmSetRangeSys (unsigned int range)
-{
-  return ;
-}
 
 /*
- * pwmSetClockWPi:
+ * pwmSetClock:
  *     Set/Change the PWM clock. Originally my code, but changed
  *     (for the better!) by Chris Hall, <chris@kchall.plus.com>
  *     after further study of the manual and testing with a 'scope
  *********************************************************************************
  */
 
-void pwmSetClockWPi (int divisor)
+void pwmSetClock (int divisor)
 {
   uint32_t pwm_control ;
   divisor &= 4095 ;
 
-  if (wiringPiDebug)
-    printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
+  if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+  {
+    if (wiringPiDebug)
+      printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
 
-  pwm_control = *(pwm + PWM_CONTROL) ;         // preserve PWM_CONTROL
+    pwm_control = *(pwm + PWM_CONTROL) ;               // preserve PWM_CONTROL
 
 // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
 // stays high.
 
-  *(pwm + PWM_CONTROL) = 0 ;                   // Stop PWM
+    *(pwm + PWM_CONTROL) = 0 ;                         // Stop PWM
 
 // Stop PWM clock before changing divisor. The delay after this does need to
 // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
@@ -649,226 +775,249 @@ void pwmSetClockWPi (int divisor)
 // adjusted the clock sometimes switches to very slow, once slow further DIV
 // adjustments do nothing and it's difficult to get out of this mode.
 
-  *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
-    delayMicroseconds (110) ;                  // prevents clock going sloooow
+    *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ;       // Stop PWM Clock
+      delayMicroseconds (110) ;                        // prevents clock going sloooow
 
-  while ((*(clk + PWMCLK_CNTL) & 0x80) != 0)   // Wait for clock to be !BUSY
-    delayMicroseconds (1) ;
+    while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
+      delayMicroseconds (1) ;
 
-  *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (divisor << 12) ;
+    *(clk + PWMCLK_DIV)  = BCM_PASSWORD | (divisor << 12) ;
 
-  *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
-  *(pwm + PWM_CONTROL) = pwm_control ;         // restore PWM_CONTROL
+    *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ;       // Start PWM clock
+    *(pwm + PWM_CONTROL) = pwm_control ;               // restore PWM_CONTROL
 
-  if (wiringPiDebug)
-    printf ("Set     to: %d. Now    : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
-}
-
-void pwmSetClockSys (int divisor)
-{
-  return ;
+    if (wiringPiDebug)
+      printf ("Set     to: %d. Now    : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
+  }
 }
 
 
-#ifdef notYetReady
 /*
- * pinED01:
- * pinED10:
- *     Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
- *     Pin must already be in input mode with appropriate pull up/downs set.
+ * gpioClockSet:
+ *     Set the freuency on a GPIO clock pin
  *********************************************************************************
  */
 
-void pinEnableED01Pi (int pin)
+void gpioClockSet (int pin, int freq)
 {
-  pin = pinToGpio [pin & 63] ;
-}
-#endif
+  int divi, divr, divf ;
 
+  pin &= 63 ;
 
+  /**/ if (wiringPiMode == WPI_MODE_PINS)
+    pin = pinToGpio [pin] ;
+  else if (wiringPiMode == WPI_MODE_PHYS)
+    pin = physToGpio [pin] ;
+  else if (wiringPiMode != WPI_MODE_GPIO)
+    return ;
+  
+  divi = 19200000 / freq ;
+  divr = 19200000 % freq ;
+  divf = (int)((double)divr * 4096.0 / 19200000.0) ;
 
-/*
- * digitalWrite:
- *     Set an output bit
- *********************************************************************************
- */
+  if (divi > 4095)
+    divi = 4095 ;
 
-void digitalWriteWPi (int pin, int value)
-{
-  pin = pinToGpio [pin & 63] ;
+  *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ;             // Stop GPIO Clock
+  while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0)                            // ... and wait
+    ;
 
-  if (value == LOW)
-    *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
-  else
-    *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
+  *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ;           // Set dividers
+  *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ;      // Start Clock
 }
 
-void digitalWriteGpio (int pin, int value)
-{
-  pin &= 63 ;
 
-  if (value == LOW)
-    *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
 else
-    *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
-}
+/*
+ * wiringPiFindNode:
*      Locate our device node
+ *********************************************************************************
+ */
 
-void digitalWriteSys (int pin, int value)
+static struct wiringPiNodeStruct *wiringPiFindNode (int pin)
 {
-  pin &= 63 ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  if (sysFds [pin] != -1)
-  {
-    if (value == LOW)
-      write (sysFds [pin], "0\n", 2) ;
+  while (node != NULL)
+    if ((pin >= node->pinBase) && (pin <= node->pinMax))
+      return node ;
     else
-      write (sysFds [pin], "1\n", 2) ;
-  }
+      node = node->next ;
+
+  return NULL ;
 }
 
 
 /*
- * digitalWriteByte:
- *     Write an 8-bit byte to the first 8 GPIO pins - try to do it as
- *     fast as possible.
- *     However it still needs 2 operations to set the bits, so any external
- *     hardware must not rely on seeing a change as there will be a change 
- *     to set the outputs bits to zero, then another change to set the 1's
+ * wiringPiNewNode:
+ *     Create a new GPIO node into the wiringPi handling system
  *********************************************************************************
  */
 
-void digitalWriteByteGpio (int value)
+static void pinModeDummy             (struct wiringPiNodeStruct *node, int pin, int mode)  { return ; }
+static void pullUpDnControlDummy     (struct wiringPiNodeStruct *node, int pin, int pud)   { return ; }
+static int  digitalReadDummy         (struct wiringPiNodeStruct *node, int pin)            { return LOW ; }
+static void digitalWriteDummy        (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+static void pwmWriteDummy            (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+static int  analogReadDummy          (struct wiringPiNodeStruct *node, int pin)            { return 0 ; }
+static void analogWriteDummy         (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+
+struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
 {
-  uint32_t pinSet = 0 ;
-  uint32_t pinClr = 0 ;
-  int mask = 1 ;
-  int pin ;
+  int    pin ;
+  struct wiringPiNodeStruct *node ;
 
-  for (pin = 0 ; pin < 8 ; ++pin)
-  {
-    if ((value & mask) == 0)
-      pinClr |= (1 << pinToGpio [pin]) ;
-    else
-      pinSet |= (1 << pinToGpio [pin]) ;
+// Minimum pin base is 64
 
-    mask <<= 1 ;
-  }
+  if (pinBase < 64)
+    (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ;
 
-  *(gpio + gpioToGPCLR [0]) = pinClr ;
-  *(gpio + gpioToGPSET [0]) = pinSet ;
-}
+// Check all pins in-case there is overlap:
 
-void digitalWriteByteSys (int value)
-{
-  int mask = 1 ;
-  int pin ;
+  for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin)
+    if (wiringPiFindNode (pin) != NULL)
+      (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ;
 
-  for (pin = 0 ; pin < 8 ; ++pin)
-  {
-    digitalWriteSys (pinToGpio [pin], value & mask) ;
-    mask <<= 1 ;
-  }
+  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->digitalWrite    = digitalWriteDummy ;
+  node->pwmWrite        = pwmWriteDummy ;
+  node->analogRead      = analogReadDummy ;
+  node->analogWrite     = analogWriteDummy ;
+  node->next            = wiringPiNodes ;
+  wiringPiNodes         = node ;
+
+  return node ;
 }
 
 
+#ifdef notYetReady
 /*
- * pwmWrite:
- *     Set an output PWM value
+ * pinED01:
+ * pinED10:
+ *     Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
+ *     Pin must already be in input mode with appropriate pull up/downs set.
  *********************************************************************************
  */
 
-void pwmWriteGpio (int pin, int value)
+void pinEnableED01Pi (int pin)
 {
-  int port ;
-
-  pin  = pin & 63 ;
-  port = gpioToPwmPort [pin] ;
-
-  *(pwm + port) = value ;
+  pin = pinToGpio [pin & 63] ;
 }
+#endif
 
-void pwmWriteWPi (int pin, int value)
-{
-  pwmWriteGpio (pinToGpio [pin & 63], value) ;
-}
 
-void pwmWriteSys (int pin, int value)
-{
-  return ;
-}
+/*
+ *********************************************************************************
+ * Core Functions
+ *********************************************************************************
+ */
 
 
 /*
- * gpioClockSet:
- *     Set the freuency on a GPIO clock pin
+ * pinMode:
+ *     Sets the mode of a pin to be input, output or PWM output
  *********************************************************************************
  */
 
-void gpioClockSetGpio (int pin, int freq)
+void pinMode (int pin, int mode)
 {
-  int divi, divr, divf ;
+  int    fSel, shift, alt ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  pin &= 63 ;
-  
-  divi = 19200000 / freq ;
-  divr = 19200000 % freq ;
-  divf = (int)((double)divr * 4096.0 / 19200000.0) ;
+  if ((pin & PI_GPIO_MASK) == 0)               // On-board pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return ;
 
-  if (divi > 4095)
-    divi = 4095 ;
+    fSel    = gpioToGPFSEL [pin] ;
+    shift   = gpioToShift  [pin] ;
 
-  *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ;             // Stop GPIO Clock
-  while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0)                            // ... and wait
-    ;
+    /**/ if (mode == INPUT)
+      *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
+    else if (mode == OUTPUT)
+      *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
+    else if (mode == PWM_OUTPUT)
+    {
+      if ((alt = gpioToPwmALT [pin]) == 0)     // Not a PWM pin
+       return ;
 
-  *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ;           // Set dividers
-  *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ;      // Start Clock
-}
+// Set pin to PWM mode
 
-void gpioClockSetWPi (int pin, int freq)
-{
-  gpioClockSetGpio (pinToGpio [pin & 63], freq) ;
-}
+      *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
+      delayMicroseconds (110) ;                // See comments in pwmSetClockWPi
 
-void gpioClockSetSys (int pin, int freq)
-{
-  return ;
+      pwmSetMode  (PWM_MODE_BAL) ;     // Pi default mode
+      pwmSetRange (1024) ;             // Default range of 1024
+      pwmSetClock (32) ;                       // 19.2 / 32 = 600KHz - Also starts the PWM
+    }
+    else if (mode == GPIO_CLOCK)
+    {
+      if ((alt = gpioToGpClkALT0 [pin]) == 0)  // Not a GPIO_CLOCK pin
+       return ;
+
+// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
+
+      *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
+      delayMicroseconds (110) ;
+      gpioClockSet      (pin, 100000) ;
+    }
+  }
+  else
+  {
+    if ((node = wiringPiFindNode (pin)) != NULL)
+      node->pinMode (node, pin, mode) ;
+    return ;
+  }
 }
 
 
 /*
- * setPadDrive:
- *     Set the PAD driver value
+ * pullUpDownCtrl:
+ *     Control the internal pull-up/down resistors on a GPIO pin
+ *     The Arduino only has pull-ups and these are enabled by writing 1
+ *     to a port when in input mode - this paradigm doesn't quite apply
+ *     here though.
  *********************************************************************************
  */
 
-void setPadDriveWPi (int group, int value)
+void pullUpDnControl (int pin, int pud)
 {
-  uint32_t wrVal ;
-
-  if ((group < 0) || (group > 2))
-    return ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
-  *(pads + group + 11) = wrVal ;
+  if ((pin & PI_GPIO_MASK) == 0)               // On-Board Pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return ;
 
-  if (wiringPiDebug)
+    *(gpio + GPPUD)              = pud & 3 ;           delayMicroseconds (5) ;
+    *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;   delayMicroseconds (5) ;
+    
+    *(gpio + GPPUD)              = 0 ;                 delayMicroseconds (5) ;
+    *(gpio + gpioToPUDCLK [pin]) = 0 ;                 delayMicroseconds (5) ;
+  }
+  else                                         // Extension module
   {
-    printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
-    printf ("Read : %08X\n", *(pads + group + 11)) ;
+    if ((node = wiringPiFindNode (pin)) != NULL)
+      node->pullUpDnControl (node, pin, pud) ;
+    return ;
   }
 }
 
-void setPadDriveGpio (int group, int value)
-{
-  setPadDriveWPi (group, value) ;
-}
-
-void setPadDriveSys (int group, int value)
-{
-  return ;
-}
-
 
 /*
  * digitalRead:
@@ -876,134 +1025,202 @@ void setPadDriveSys (int group, int value)
  *********************************************************************************
  */
 
-int digitalReadWPi (int pin)
+int digitalRead (int pin)
 {
-  pin = pinToGpio [pin & 63] ;
+  char c ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
+
+  if ((pin & PI_GPIO_MASK) == 0)               // On-Board Pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)        // Sys mode
+    {
+      if (sysFds [pin] == -1)
+       return LOW ;
 
-  if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
-    return HIGH ;
+      lseek  (sysFds [pin], 0L, SEEK_SET) ;
+      read   (sysFds [pin], &c, 1) ;
+      return (c == '0') ? LOW : HIGH ;
+    }
+    else if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return LOW ;
+
+    if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
+      return HIGH ;
+    else
+      return LOW ;
+  }
   else
-    return LOW ;
+  {
+    if ((node = wiringPiFindNode (pin)) == NULL)
+      return LOW ;
+    return node->digitalRead (node, pin) ;
+  }
 }
 
-int digitalReadGpio (int pin)
-{
-  pin &= 63 ;
 
-  if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
-    return HIGH ;
-  else
-    return LOW ;
-}
+/*
+ * digitalWrite:
+ *     Set an output bit
+ *********************************************************************************
+ */
 
-int digitalReadSys (int pin)
+void digitalWrite (int pin, int value)
 {
-  char c ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  pin &= 63 ;
-
-  if (sysFds [pin] == -1)
-    return 0 ;
+  if ((pin & PI_GPIO_MASK) == 0)               // On-Board Pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)        // Sys mode
+    {
+      if (sysFds [pin] != -1)
+      {
+       if (value == LOW)
+         write (sysFds [pin], "0\n", 2) ;
+       else
+         write (sysFds [pin], "1\n", 2) ;
+      }
+      return ;
+    }
+    else if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return ;
 
-  lseek (sysFds [pin], 0L, SEEK_SET) ;
-  read  (sysFds [pin], &c, 1) ;
-  return (c == '0') ? 0 : 1 ;
+    if (value == LOW)
+      *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
+    else
+      *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
+  }
+  else
+  {
+    if ((node = wiringPiFindNode (pin)) != NULL)
+      node->digitalWrite (node, pin, value) ;
+  }
 }
 
 
 /*
- * pullUpDownCtrl:
- *     Control the internal pull-up/down resistors on a GPIO pin
- *     The Arduino only has pull-ups and these are enabled by writing 1
- *     to a port when in input mode - this paradigm doesn't quite apply
- *     here though.
+ * pwmWrite:
+ *     Set an output PWM value
  *********************************************************************************
  */
 
-void pullUpDnControlGpio (int pin, int pud)
+void pwmWrite (int pin, int value)
 {
-  pin &= 63 ;
-  pud &=  3 ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  *(gpio + GPPUD)              = pud ;                 delayMicroseconds (5) ;
-  *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;     delayMicroseconds (5) ;
-  
-  *(gpio + GPPUD)              = 0 ;                   delayMicroseconds (5) ;
-  *(gpio + gpioToPUDCLK [pin]) = 0 ;                   delayMicroseconds (5) ;
-}
+  if ((pin & PI_GPIO_MASK) == 0)               // On-Board Pin
+  {
+    /**/ if (wiringPiMode == WPI_MODE_PINS)
+      pin = pinToGpio [pin] ;
+    else if (wiringPiMode == WPI_MODE_PHYS)
+      pin = physToGpio [pin] ;
+    else if (wiringPiMode != WPI_MODE_GPIO)
+      return ;
 
-void pullUpDnControlWPi (int pin, int pud)
-{
-  pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
+    *(pwm + gpioToPwmPort [pin]) = value ;
+  }
+  else
+  {
+    if ((node = wiringPiFindNode (pin)) != NULL)
+      node->pwmWrite (node, pin, value) ;
+  }
 }
 
-void pullUpDnControlSys (int pin, int pud)
+
+/*
+ * analogRead:
+ *     Read the analog value of a given Pin. 
+ *     There is no on-board Pi analog hardware,
+ *     so this needs to go to a new node.
+ *********************************************************************************
+ */
+
+int analogRead (int pin)
 {
-  return ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
+
+  if ((node = wiringPiFindNode (pin)) == NULL)
+    return 0 ;
+  else
+    return node->analogRead (node, pin) ;
 }
 
 
 /*
- * pinMode:
- *     Sets the mode of a pin to be input, output or PWM output
+ * analogWrite:
+ *     Write the analog value to the given Pin. 
+ *     There is no on-board Pi analog hardware,
+ *     so this needs to go to a new node.
  *********************************************************************************
  */
 
-void pinModeGpio (int pin, int mode)
+void analogWrite (int pin, int value)
 {
-//  register int barrier ;
+  struct wiringPiNodeStruct *node = wiringPiNodes ;
 
-  int fSel, shift, alt ;
+  if ((node = wiringPiFindNode (pin)) == NULL)
+    return ;
 
-  pin &= 63 ;
+  node->analogWrite (node, pin, value) ;
+}
 
-  fSel    = gpioToGPFSEL [pin] ;
-  shift   = gpioToShift  [pin] ;
 
-  /**/ if (mode == INPUT)
-    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
-  else if (mode == OUTPUT)
-    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
-  else if (mode == PWM_OUTPUT)
-  {
-    if ((alt = gpioToPwmALT [pin]) == 0)       // Not a PWM pin
-      return ;
 
-// Set pin to PWM mode
+/*
+ * digitalWriteByte:
+ *     Pi Specific
+ *     Write an 8-bit byte to the first 8 GPIO pins - try to do it as
+ *     fast as possible.
+ *     However it still needs 2 operations to set the bits, so any external
+ *     hardware must not rely on seeing a change as there will be a change 
+ *     to set the outputs bits to zero, then another change to set the 1's
+ *********************************************************************************
+ */
 
-    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
-    delayMicroseconds (110) ;          // See comments in pwmSetClockWPi
+void digitalWriteByte (int value)
+{
+  uint32_t pinSet = 0 ;
+  uint32_t pinClr = 0 ;
+  int mask = 1 ;
+  int pin ;
 
-    pwmSetModeWPi  (PWM_MODE_BAL) ;    // Pi default mode
-    pwmSetRangeWPi (1024) ;            // Default range of 1024
-    pwmSetClockWPi (32) ;              // 19.2 / 32 = 600KHz - Also starts the PWM
+  /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
+  {
+    for (pin = 0 ; pin < 8 ; ++pin)
+    {
+      digitalWrite (pin, value & mask) ;
+      mask <<= 1 ;
+    }
+    return ;
   }
-  else if (mode == GPIO_CLOCK)
+  else
   {
-    if ((alt = gpioToGpClkALT0 [pin]) == 0)    // Not a GPIO_CLOCK pin
-      return ;
+    for (pin = 0 ; pin < 8 ; ++pin)
+    {
+      if ((value & mask) == 0)
+       pinClr |= (1 << pinToGpio [pin]) ;
+      else
+       pinSet |= (1 << pinToGpio [pin]) ;
 
-// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
+      mask <<= 1 ;
+    }
 
-    *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
-    delayMicroseconds (110) ;
-    gpioClockSetGpio (pin, 100000) ;
+    *(gpio + gpioToGPCLR [0]) = pinClr ;
+    *(gpio + gpioToGPSET [0]) = pinSet ;
   }
 }
 
-void pinModeWPi (int pin, int mode)
-{
-  pinModeGpio (pinToGpio [pin & 63], mode) ;
-}
-
-void pinModeSys (int pin, int mode)
-{
-  return ;
-}
-
 
 /*
  * waitForInterrupt:
+ *     Pi Specific.
  *     Wait for Interrupt on a GPIO pin.
  *     This is actually done via the /sys/class/gpio interface regardless of
  *     the wiringPi access mode in-use. Maybe sometime it might get a better
@@ -1011,13 +1228,18 @@ void pinModeSys (int pin, int mode)
  *********************************************************************************
  */
 
-int waitForInterruptSys (int pin, int mS)
+int waitForInterrupt (int pin, int mS)
 {
   int fd, x ;
   uint8_t c ;
   struct pollfd polls ;
 
-  if ((fd = sysFds [pin & 63]) == -1)
+  /**/ if (wiringPiMode == WPI_MODE_PINS)
+    pin = pinToGpio [pin] ;
+  else if (wiringPiMode == WPI_MODE_PHYS)
+    pin = physToGpio [pin] ;
+
+  if ((fd = sysFds [pin]) == -1)
     return -2 ;
 
 // Setup poll structure
@@ -1037,16 +1259,6 @@ int waitForInterruptSys (int pin, int mS)
   return x ;
 }
 
-int waitForInterruptWPi (int pin, int mS)
-{
-  return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
-}
-
-int waitForInterruptGpio (int pin, int mS)
-{
-  return waitForInterruptSys (pin, mS) ;
-}
-
 
 /*
  * interruptHandler:
@@ -1058,12 +1270,15 @@ int waitForInterruptGpio (int pin, int mS)
 
 static void *interruptHandler (void *arg)
 {
-  int myPin = *(int *)arg ;
+  int myPin ;
 
   (void)piHiPri (55) ; // Only effective if we run as root
 
+  myPin   = pinPass ;
+  pinPass = -1 ;
+
   for (;;)
-    if (waitForInterruptSys (myPin, -1) > 0)
+    if (waitForInterrupt (myPin, -1) > 0)
       isrFunctions [myPin] () ;
 
   return NULL ;
@@ -1072,6 +1287,7 @@ static void *interruptHandler (void *arg)
 
 /*
  * wiringPiISR:
+ *     Pi Specific.
  *     Take the details and create an interrupt handler that will do a call-
  *     back to the user supplied function.
  *********************************************************************************
@@ -1080,22 +1296,24 @@ static void *interruptHandler (void *arg)
 int wiringPiISR (int pin, int mode, void (*function)(void))
 {
   pthread_t threadId ;
+  const char *modeS ;
   char fName   [64] ;
-  char *modeS ;
   char  pinS [8] ;
   pid_t pid ;
   int   count, i ;
-  uint8_t c ;
+  char  c ;
+  int   bcmGpioPin ;
 
   pin &= 63 ;
 
-  if (wiringPiMode == WPI_MODE_UNINITIALISED)
-  {
-    fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
-    exit (EXIT_FAILURE) ;
-  }
+  /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
+    return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
   else if (wiringPiMode == WPI_MODE_PINS)
-    pin = pinToGpio [pin] ;
+    bcmGpioPin = pinToGpio [pin] ;
+  else if (wiringPiMode == WPI_MODE_PHYS)
+    bcmGpioPin = physToGpio [pin] ;
+  else
+    bcmGpioPin = pin ;
 
 // Now export the pin and set the right edge
 //     We're going to use the gpio program to do this, so it assumes
@@ -1112,7 +1330,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
     else
       modeS = "both" ;
 
-    sprintf (pinS, "%d", pin) ;
+    sprintf (pinS, "%d", bcmGpioPin) ;
 
     if ((pid = fork ()) < 0)   // Fail
       return pid ;
@@ -1127,23 +1345,29 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
   }
 
 // Now pre-open the /sys/class node - it may already be open if
-//     we are in Sys mode, but this will do no harm.
+//     we are in Sys mode or if we call here twice, if-so, we'll close it.
+
+  if (sysFds [bcmGpioPin] != -1)
+    close (sysFds [bcmGpioPin]) ;
 
-  sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
-  if ((sysFds [pin] = open (fName, O_RDWR)) < 0)
+  sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ;
+  if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
     return -1 ;
 
 // Clear any initial pending interrupt
 
-  ioctl (sysFds [pin], FIONREAD, &count) ;
+  ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ;
   for (i = 0 ; i < count ; ++i)
-    read (sysFds [pin], &c, 1) ;
+    read (sysFds [bcmGpioPin], &c, 1) ;
 
   isrFunctions [pin] = function ;
 
-  pthread_create (&threadId, NULL, interruptHandler, &pin) ;
-
-  delay (1) ;
+  pthread_mutex_lock (&pinMutex) ;
+    pinPass = pin ;
+    pthread_create (&threadId, NULL, interruptHandler, NULL) ;
+    while (pinPass != -1)
+      delay (1) ;
+  pthread_mutex_unlock (&pinMutex) ;
 
   return 0 ;
 }
@@ -1152,7 +1376,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
 /*
  * initialiseEpoch:
  *     Initialise our start-of-time variable to be the current unix
- *     time in milliseconds.
+ *     time in milliseconds and microseconds.
  *********************************************************************************
  */
 
@@ -1165,9 +1389,10 @@ static void initialiseEpoch (void)
   epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
 }
 
+
 /*
  * delay:
- *     Wait for some number of milli seconds
+ *     Wait for some number of milliseconds
  *********************************************************************************
  */
 
@@ -1280,124 +1505,66 @@ int wiringPiSetup (void)
   int      fd ;
   int      boardRev ;
 
-  if (geteuid () != 0)
-  {
-    fprintf (stderr, "wiringPi:\n  Must be root to call wiringPiSetup().\n  (Did you forget sudo?)\n") ;
-    exit (EXIT_FAILURE) ;
-  }
-
-  if (getenv ("WIRINGPI_DEBUG") != NULL)
-  {
-    printf ("wiringPi: Debug mode enabled\n") ;
+  if (getenv (ENV_DEBUG) != NULL)
     wiringPiDebug = TRUE ;
-  }
+
+  if (getenv (ENV_CODES) != NULL)
+    wiringPiReturnCodes = TRUE ;
+
+  if (geteuid () != 0)
+    (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ;
 
   if (wiringPiDebug)
     printf ("wiringPi: wiringPiSetup called\n") ;
 
-            pinMode =           pinModeWPi ;
-             getAlt =            getAltWPi ;
-    pullUpDnControl =   pullUpDnControlWPi ;
-       digitalWrite =      digitalWriteWPi ;
-   digitalWriteByte = digitalWriteByteGpio ;   // Same code
-       gpioClockSet =      gpioClockSetWPi ;
-           pwmWrite =          pwmWriteWPi ;
-        setPadDrive =       setPadDriveWPi ;
-        digitalRead =       digitalReadWPi ;
-   waitForInterrupt =  waitForInterruptWPi ;
-         pwmSetMode =        pwmSetModeWPi ;
-        pwmSetRange =       pwmSetRangeWPi ;
-        pwmSetClock =       pwmSetClockWPi ;
-  
   boardRev = piBoardRev () ;
 
   if (boardRev == 1)
-    pinToGpio = pinToGpioR1 ;
+  {
+     pinToGpio =  pinToGpioR1 ;
+    physToGpio = physToGpioR1 ;
+  }
   else
-    pinToGpio = pinToGpioR2 ;
+  {
+     pinToGpio =  pinToGpioR2 ;
+    physToGpio = physToGpioR2 ;
+  }
 
 // Open the master /dev/memory device
 
   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
 
 // GPIO:
 
   gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
   if ((int32_t)gpio == -1)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
 
 // PWM
 
   pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
   if ((int32_t)pwm == -1)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
  
 // Clock control (needed for PWM)
 
   clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ;
   if ((int32_t)clk == -1)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
  
 // The drive pads
 
   pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
   if ((int32_t)pads == -1)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
 
+#ifdef USE_TIMER
 // The system timer
 
   timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
   if ((int32_t)timer == -1)
-  {
-    if (wiringPiDebug)
-    {
-      int serr = errno ;
-       fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
-      errno = serr ;
-    }
-    return -1 ;
-  }
+    return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;
 
 // Set the timer to free-running, 1MHz.
 //     0xF9 is 249, the timer divide is base clock / (divide+1)
@@ -1406,6 +1573,7 @@ int wiringPiSetup (void)
   *(timer + TIMER_CONTROL) = 0x0000280 ;
   *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
   timerIrqRaw = timer + TIMER_IRQ_RAW ;
+#endif
 
   initialiseEpoch () ;
 
@@ -1426,40 +1594,39 @@ int wiringPiSetup (void)
 
 int wiringPiSetupGpio (void)
 {
-  int x  ;
-
-  if (geteuid () != 0)
-  {
-    fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ;
-    exit (EXIT_FAILURE) ;
-  }
-
-  if ((x = wiringPiSetup ()) < 0)
-    return x ;
+  (void)wiringPiSetup () ;
 
   if (wiringPiDebug)
     printf ("wiringPi: wiringPiSetupGpio called\n") ;
 
-            pinMode =           pinModeGpio ;
-             getAlt =            getAltGpio ;
-    pullUpDnControl =   pullUpDnControlGpio ;
-       digitalWrite =      digitalWriteGpio ;
-   digitalWriteByte =  digitalWriteByteGpio ;
-       gpioClockSet =      gpioClockSetGpio ;
-           pwmWrite =          pwmWriteGpio ;
-        setPadDrive =       setPadDriveGpio ;
-        digitalRead =       digitalReadGpio ;
-   waitForInterrupt =  waitForInterruptGpio ;
-         pwmSetMode =        pwmSetModeWPi ;
-        pwmSetRange =       pwmSetRangeWPi ;
-        pwmSetClock =       pwmSetClockWPi ;
-
   wiringPiMode = WPI_MODE_GPIO ;
 
   return 0 ;
 }
 
 
+/*
+ * wiringPiSetupPhys:
+ *     Must be called once at the start of your program execution.
+ *
+ * Phys setup: Initialises the system into Physical Pin mode and uses the
+ *     memory mapped hardware directly.
+ *********************************************************************************
+ */
+
+int wiringPiSetupPhys (void)
+{
+  (void)wiringPiSetup () ;
+
+  if (wiringPiDebug)
+    printf ("wiringPi: wiringPiSetupPhys called\n") ;
+
+  wiringPiMode = WPI_MODE_PHYS ;
+
+  return 0 ;
+}
+
+
 /*
  * wiringPiSetupSys:
  *     Must be called once at the start of your program execution.
@@ -1475,32 +1642,27 @@ int wiringPiSetupSys (void)
   int pin ;
   char fName [128] ;
 
-  if (getenv ("WIRINGPI_DEBUG") != NULL)
+  if (getenv (ENV_DEBUG) != NULL)
     wiringPiDebug = TRUE ;
 
+  if (getenv (ENV_CODES) != NULL)
+    wiringPiReturnCodes = TRUE ;
+
   if (wiringPiDebug)
     printf ("wiringPi: wiringPiSetupSys called\n") ;
 
-            pinMode =           pinModeSys ;
-             getAlt =            getAltSys ;
-    pullUpDnControl =   pullUpDnControlSys ;
-       digitalWrite =      digitalWriteSys ;
-   digitalWriteByte =  digitalWriteByteSys ;
-       gpioClockSet =      gpioClockSetSys ;
-           pwmWrite =          pwmWriteSys ;
-        setPadDrive =       setPadDriveSys ;
-        digitalRead =       digitalReadSys ;
-   waitForInterrupt =  waitForInterruptSys ;
-         pwmSetMode =        pwmSetModeSys ;
-        pwmSetRange =       pwmSetRangeSys ;
-        pwmSetClock =       pwmSetClockSys ;
-
   boardRev = piBoardRev () ;
 
   if (boardRev == 1)
-    pinToGpio = pinToGpioR1 ;
+  {
+     pinToGpio =  pinToGpioR1 ;
+    physToGpio = physToGpioR1 ;
+  }
   else
-    pinToGpio = pinToGpioR2 ;
+  {
+     pinToGpio =  pinToGpioR2 ;
+    physToGpio = physToGpioR2 ;
+  }
 
 // Open and scan the directory, looking for exported GPIOs, and pre-open
 //     the 'value' interface to speed things up for later
index 18c6da51733e89aa12995b21447555147859b8ab..600c8518960abca88bf707c711ab8d83a795577a 100644 (file)
@@ -29,7 +29,8 @@
 #define        WPI_MODE_PINS            0
 #define        WPI_MODE_GPIO            1
 #define        WPI_MODE_GPIO_SYS        2
-#define        WPI_MODE_PIFACE          3
+#define        WPI_MODE_PHYS            3
+#define        WPI_MODE_PIFACE          4
 #define        WPI_MODE_UNINITIALISED  -1
 
 // Pin modes
 
 #define        PI_THREAD(X)    void *X (void *dummy)
 
+// Failure modes
+
+#define        WPI_FATAL       (1==1)
+#define        WPI_ALMOST      (1==2)
+
+
+// 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) ;
+  void   (*digitalWrite)    (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 ;
+} ;
+
 
 // Function prototypes
 //     c++ wrappers thanks to a comment by Nick Lott
 extern "C" {
 #endif
 
-// Basic wiringPi functions
+// Internal
+
+extern int wiringPiFailure (int fatal, const char *message, ...) ;
+
+// Core wiringPi functions
+
+extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
 
 extern int  wiringPiSetup       (void) ;
 extern int  wiringPiSetupSys    (void) ;
 extern int  wiringPiSetupGpio   (void) ;
-extern int  wiringPiSetupPiFace (void) ;
+extern int  wiringPiSetupPhys   (void) ;
 
-extern int  piBoardRev          (void) ;
-extern int  wpiPinToGpio        (int wpiPin) ;
+extern void pinMode             (int pin, int mode) ;
+extern void pullUpDnControl     (int pin, int pud) ;
+extern int  digitalRead         (int pin) ;
+extern void digitalWrite        (int pin, int value) ;
+extern void pwmWrite            (int pin, int value) ;
+extern int  analogRead          (int pin) ;
+extern void analogWrite         (int pin, int value) ;
+
+// PiFace specifics 
+//     (Deprecated)
 
+extern int  wiringPiSetupPiFace (void) ;
 extern int  wiringPiSetupPiFaceForGpioProg (void) ;    // Don't use this - for gpio program only
 
-extern void (*pinMode)           (int pin, int mode) ;
-extern int  (*getAlt)            (int pin) ;
-extern void (*pullUpDnControl)   (int pin, int pud) ;
-extern void (*digitalWrite)      (int pin, int value) ;
-extern void (*digitalWriteByte)  (int value) ;
-extern void (*gpioClockSet)      (int pin, int freq) ;
-extern void (*pwmWrite)          (int pin, int value) ;
-extern void (*setPadDrive)       (int group, int value) ;
-extern int  (*digitalRead)       (int pin) ;
-extern void (*pwmSetMode)        (int mode) ;
-extern void (*pwmSetRange)       (unsigned int range) ;
-extern void (*pwmSetClock)       (int divisor) ;
+// On-Board Raspberry Pi hardware specific stuff
+
+extern int  piBoardRev          (void) ;
+extern int  wpiPinToGpio        (int wpiPin) ;
+extern int  physPinToGpio       (int physPin) ;
+extern void setPadDrive         (int group, int value) ;
+extern int  getAlt              (int pin) ;
+extern void digitalWriteByte    (int value) ;
+extern void pwmSetMode          (int mode) ;
+extern void pwmSetRange         (unsigned int range) ;
+extern void pwmSetClock         (int divisor) ;
+extern void gpioClockSet        (int pin, int freq) ;
 
 // Interrupts
+//     (Also Pi hardware specific)
 
-extern int  (*waitForInterrupt) (int pin, int mS) ;
+extern int  waitForInterrupt    (int pin, int mS) ;
 extern int  wiringPiISR         (int pin, int mode, void (*function)(void)) ;
 
 // Threads
 
-extern int  piThreadCreate (void *(*fn)(void *)) ;
-extern void piLock         (int key) ;
-extern void piUnlock       (int key) ;
+extern int  piThreadCreate      (void *(*fn)(void *)) ;
+extern void piLock              (int key) ;
+extern void piUnlock            (int key) ;
 
 // Schedulling priority
 
-extern int piHiPri (int pri) ;
-
+extern int piHiPri (const int pri) ;
 
 // Extras from arduino land
 
diff --git a/wiringPi/wiringPiFace.c b/wiringPi/wiringPiFace.c
deleted file mode 100644 (file)
index ac3c6fa..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * wiringPiFace:
- *     Arduino compatable (ish) Wiring library for the Raspberry Pi
- *     Copyright (c) 2012 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 <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <linux/spi/spidev.h>
-
-#include "wiringPi.h"
-
-
-// The SPI bus parameters
-//     Variables as they need to be passed as pointers later on
-
-static char       *spiDevice = "/dev/spidev0.0" ;
-static uint8_t     spiMode   = 0 ;
-static uint8_t     spiBPW    = 8 ;
-static uint32_t    spiSpeed  = 5000000 ;
-static uint16_t    spiDelay  = 0;
-
-// Locals here to keep track of everything
-
-static int spiFd ;
-
-// The MCP23S17 doesn't have bit-set operations, so it's
-//     cheaper to keep a copy here than to read/modify/write it
-
-uint8_t dataOutRegister = 0 ;
-uint8_t     pudRegister = 0 ;
-
-// MCP23S17 Registers
-
-#define        IOCON           0x0A
-
-#define        IODIRA          0x00
-#define        IPOLA           0x02
-#define        GPINTENA        0x04
-#define        DEFVALA         0x06
-#define        INTCONA         0x08
-#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        GPPUB           0x0D
-#define        INTFB           0x0F
-#define        INTCAPB         0x11
-#define        GPIOB           0x13
-#define        OLATB           0x15
-
-// Bits in the IOCON register
-
-#define        IOCON_BANK_MODE 0x80
-#define        IOCON_MIRROR    0x40
-#define        IOCON_SEQOP     0x20
-#define        IOCON_DISSLW    0x10
-#define        IOCON_HAEN      0x08
-#define        IOCON_ODR       0x04
-#define        IOCON_INTPOL    0x02
-#define        IOCON_UNUSED    0x01
-
-// Default initialisation mode
-
-#define        IOCON_INIT      (IOCON_SEQOP)
-
-// Command codes
-
-#define        CMD_WRITE       0x40
-#define CMD_READ       0x41
-
-
-/*
- * writeByte:
- *     Write a byte to a register on the MCP23S17 on the SPI bus.
- *     This is using the synchronous access mechanism.
- *********************************************************************************
- */
-
-static void writeByte (uint8_t reg, uint8_t data)
-{
-  uint8_t spiBufTx [3] ;
-  uint8_t spiBufRx [3] ;
-  struct spi_ioc_transfer spi ;
-
-  spiBufTx [0] = CMD_WRITE ;
-  spiBufTx [1] = reg ;
-  spiBufTx [2] = data ;
-
-  spi.tx_buf        = (unsigned long)spiBufTx ;
-  spi.rx_buf        = (unsigned long)spiBufRx ;
-  spi.len           = 3 ;
-  spi.delay_usecs   = spiDelay ;
-  spi.speed_hz      = spiSpeed ;
-  spi.bits_per_word = spiBPW ;
-
-  ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;
-}
-
-/*
- * readByte:
- *     Read a byte from a register on the MCP23S17 on the SPI bus.
- *     This is the synchronous access mechanism.
- *     What appears to happen is that the data returned is at
- *     the same offset as the number of bytes written to the device. So if we
- *     write 2 bytes (e.g. command then register number), then the data returned
- *     will by at the 3rd byte...
- *********************************************************************************
- */
-
-static uint8_t readByte (uint8_t reg)
-{
-  uint8_t tx [4] ;
-  uint8_t rx [4] ;
-  struct spi_ioc_transfer spi ;
-
-  tx [0] = CMD_READ ;
-  tx [1] = reg ;
-  tx [2] = 0 ;
-
-  spi.tx_buf        = (unsigned long)tx ;
-  spi.rx_buf        = (unsigned long)rx ;
-  spi.len           = 3 ;
-  spi.delay_usecs   = spiDelay ;
-  spi.speed_hz      = spiSpeed ;
-  spi.bits_per_word = spiBPW ;
-
-  ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ;
-
-  return rx [2] ;
-}
-
-
-/*
- * digitalWritePiFace:
- *     Perform the digitalWrite function on the PiFace board
- *********************************************************************************
- */
-
-void digitalWritePiFace (int pin, int value)
-{
-  uint8_t mask = 1 << pin ;
-
-  if (value == 0)
-    dataOutRegister &= (~mask) ;
-  else
-    dataOutRegister |=   mask ;
-
-  writeByte (GPIOA, dataOutRegister) ;
-}
-
-void digitalWriteBytePiFace (int value)
-{
-  writeByte (GPIOA, value) ;
-}
-
-
-void digitalWritePiFaceSpecial (int pin, int value)
-{
-  uint8_t mask = 1 << pin ;
-  uint8_t old ;
-
-  old = readByte (GPIOA) ;
-
-  if (value == 0)
-    old &= (~mask) ;
-  else
-    old |=   mask ;
-
-  writeByte (GPIOA, old) ;
-}
-
-
-/*
- * digitalReadPiFace:
- *     Perform the digitalRead function on the PiFace board
- *********************************************************************************
- */
-
-int digitalReadPiFace (int pin)
-{
-  uint8_t mask = 1 << pin ;
-
-  if ((readByte (GPIOB) & mask) != 0)
-    return HIGH ;
-  else
-    return LOW ;
-}
-
-
-/*
- * pullUpDnControlPiFace:
- *     Perform the pullUpDnControl function on the PiFace board
- *********************************************************************************
- */
-
-void pullUpDnControlPiFace (int pin, int pud)
-{
-  uint8_t mask = 1 << pin ;
-
-  if (pud == PUD_UP)
-    pudRegister |=   mask ;
-  else
-    pudRegister &= (~mask) ;
-
-  writeByte (GPPUB, pudRegister) ;
-
-}
-
-
-void pullUpDnControlPiFaceSpecial (int pin, int pud)
-{
-  uint8_t mask = 1 << pin ;
-  uint8_t old ;
-
-  old = readByte (GPPUB) ;
-
-  if (pud == PUD_UP)
-    old |=   mask ;
-  else
-    old &= (~mask) ;
-
-  writeByte (GPPUB, old) ;
-
-}
-
-
-
-/*
- * Dummy functions that are not used in this mode
- *********************************************************************************
- */
-
-void pinModePiFace          (int pin, int mode)  {}
-void pwmWritePiFace         (int pin, int value) {}
-int  waitForInterruptPiFace (int pin, int mS)    { return 0 ; }
-
-
-/*
- * wiringPiSetupPiFace
- *     Setup the SPI interface and initialise the MCP23S17 chip
- *********************************************************************************
- */
-
-static int _wiringPiSetupPiFace (void)
-{
-  if ((spiFd = open (spiDevice, O_RDWR)) < 0)
-    return -1 ;
-
-// Set SPI parameters
-//     Why are we doing a read after write?
-//     I don't know - just blindliy copying an example elsewhere... -GH-
-
-  if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0)
-    return -1 ;
-
-  if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0)
-    return -1 ;
-
-  if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
-    return -1 ;
-
-  if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
-    return -1 ;
-
-  if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
-    return -1 ;
-
-  if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
-    return -1 ;
-
-// Setup the MCP23S17
-
-  writeByte (IOCON, IOCON_INIT) ;
-
-  writeByte (IODIRA, 0x00) ;   // Port A -> Outputs
-  writeByte (IODIRB, 0xFF) ;   // Port B -> Inputs
-
-  return 0 ;
-}
-
-
-int wiringPiSetupPiFace (void)
-{
-  int x = _wiringPiSetupPiFace () ;
-
-  if (x != 0)
-    return x ;
-
-  writeByte (GPIOA, 0x00) ;    // Set all outptus off
-  writeByte (GPPUB, 0x00) ;    // Disable any pull-ups on port B
-
-           pinMode =              pinModePiFace ;
-   pullUpDnControl =      pullUpDnControlPiFace ;
-      digitalWrite =         digitalWritePiFace ;
-  digitalWriteByte =     digitalWriteBytePiFace ;
-          pwmWrite =             pwmWritePiFace ;
-       digitalRead =          digitalReadPiFace ;
-  waitForInterrupt =     waitForInterruptPiFace ;
-
-  return 0 ;
-}
-
-
-/*
- * wiringPiSetupPiFaceForGpioProg:
- *     Setup the SPI interface and initialise the MCP23S17 chip
- *     Special version for the gpio program
- *********************************************************************************
- */
-
-
-int wiringPiSetupPiFaceForGpioProg (void)
-{
-  int x = _wiringPiSetupPiFace () ;
-
-  if (x != 0)
-    return x ;
-
-           pinMode =                 pinModePiFace ;
-   pullUpDnControl =  pullUpDnControlPiFaceSpecial ;
-      digitalWrite =     digitalWritePiFaceSpecial ;
-  digitalWriteByte =        digitalWriteBytePiFace ;
-          pwmWrite =                pwmWritePiFace ;
-       digitalRead =             digitalReadPiFace ;
-  waitForInterrupt =        waitForInterruptPiFace ;
-
-  return 0 ;
-}
index 93fe1d3c4ad672fe1a2cf34b2f1a103e416f233d..d370b607aa31f87c5ccfd605eb49a8807c7bfbfe 100644 (file)
  ***********************************************************************
  */
 
+/*
+ * Notes:
+ *     The Linux I2C code is actually the same (almost) as the SMBus code.
+ *     SMBus is System Management Bus - and in essentially I2C with some
+ *     additional functionality added, and stricter controls on the electrical
+ *     specifications, etc. however I2C does work well with it and the
+ *     protocols work over both.
+ *
+ *     I'm directly including the SMBus functions here as some Linux distros
+ *     lack the correct header files, and also some header files are GPLv2
+ *     rather than the LGPL that wiringPi is released under - presumably because
+ *     originally no-one expected I2C/SMBus to be used outside the kernel -
+ *     however enter the Raspberry Pi with people now taking directly to I2C
+ *     devices without going via the kernel...
+ *
+ *     This may ultimately reduce the flexibility of this code, but it won't be
+ *     hard to maintain it and keep it current, should things change.
+ *
+ *     Information here gained from: kernel/Documentation/i2c/dev-interface
+ *     as well as other online resources.
+ *********************************************************************************
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include <linux/i2c-dev.h>
 
 #include "wiringPi.h"
 #include "wiringPiI2C.h"
 
+// I2C definitions
+
+#define I2C_SLAVE      0x0703
+#define I2C_SMBUS      0x0720  /* SMBus-level access */
+
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE        0
+
+// SMBus transaction types
+
+#define I2C_SMBUS_QUICK                    0
+#define I2C_SMBUS_BYTE             1
+#define I2C_SMBUS_BYTE_DATA        2 
+#define I2C_SMBUS_WORD_DATA        3
+#define I2C_SMBUS_PROC_CALL        4
+#define I2C_SMBUS_BLOCK_DATA       5
+#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
+#define I2C_SMBUS_BLOCK_PROC_CALL   7          /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA    8
+
+// SMBus messages
+
+#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */    
+#define I2C_SMBUS_I2C_BLOCK_MAX        32      /* Not specified but we use same structure */
+
+// Structures used in the ioctl() calls
+
+union i2c_smbus_data
+{
+  uint8_t  byte ;
+  uint16_t word ;
+  uint8_t  block [I2C_SMBUS_BLOCK_MAX + 2] ;   // block [0] is used for length + one more for PEC
+} ;
+
+struct i2c_smbus_ioctl_data
+{
+  char read_write ;
+  uint8_t command ;
+  int size ;
+  union i2c_smbus_data *data ;
+} ;
+
+static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data)
+{
+  struct i2c_smbus_ioctl_data args ;
+
+  args.read_write = rw ;
+  args.command    = command ;
+  args.size       = size ;
+  args.data       = data ;
+  return ioctl (fd, I2C_SMBUS, &args) ;
+}
+
 
 /*
  * wiringPiI2CRead:
 
 int wiringPiI2CRead (int fd)
 {
-  return i2c_smbus_read_byte (fd) ;
+  union i2c_smbus_data data ;
+
+  if (i2c_smbus_access (fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data))
+    return -1 ;
+  else
+    return data.byte & 0xFF ;
 }
 
 
@@ -52,12 +135,22 @@ int wiringPiI2CRead (int fd)
 
 int wiringPiI2CReadReg8 (int fd, int reg)
 {
-  return i2c_smbus_read_byte_data (fd, reg) ;
+  union i2c_smbus_data data;
+
+  if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data))
+    return -1 ;
+  else
+    return data.byte & 0xFF ;
 }
 
 int wiringPiI2CReadReg16 (int fd, int reg)
 {
-  return i2c_smbus_read_word_data (fd, reg) ;
+  union i2c_smbus_data data;
+
+  if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data))
+    return -1 ;
+  else
+    return data.byte & 0xFF ;
 }
 
 
@@ -69,7 +162,7 @@ int wiringPiI2CReadReg16 (int fd, int reg)
 
 int wiringPiI2CWrite (int fd, int data)
 {
-  return i2c_smbus_write_byte (fd, data) ;
+  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ;
 }
 
 
@@ -79,14 +172,41 @@ int wiringPiI2CWrite (int fd, int data)
  *********************************************************************************
  */
 
-int wiringPiI2CWriteReg8 (int fd, int reg, int data)
+int wiringPiI2CWriteReg8 (int fd, int reg, int value)
 {
-  return i2c_smbus_write_byte_data (fd, reg, data) ;
+  union i2c_smbus_data data ;
+
+  data.byte = value ;
+  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ;
 }
 
-int wiringPiI2CWriteReg16 (int fd, int reg, int data)
+int wiringPiI2CWriteReg16 (int fd, int reg, int value)
 {
-  return i2c_smbus_write_word_data (fd, reg, data) ;
+  union i2c_smbus_data data ;
+
+  data.word = value ;
+  return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
+}
+
+
+/*
+ * wiringPiI2CSetupInterface:
+ *     Undocumented access to set the interface explicitly - might be used
+ *     for the Pi's 2nd I2C interface...
+ *********************************************************************************
+ */
+
+int wiringPiI2CSetupInterface (const char *device, int devId)
+{
+  int fd ;
+
+  if ((fd = open (device, O_RDWR)) < 0)
+    return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ;
+
+  if (ioctl (fd, I2C_SLAVE, devId) < 0)
+    return wiringPiFailure (WPI_ALMOST, "Unable to select I2C device: %s\n", strerror (errno)) ;
+
+  return fd ;
 }
 
 
@@ -96,27 +216,17 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int data)
  *********************************************************************************
  */
 
-int wiringPiI2CSetup (int devId)
+int wiringPiI2CSetup (const int devId)
 {
-  int rev, fd ;
-  char *device ;
+  int rev ;
+  const char *device ;
 
-  if ((rev = piBoardRev ()) < 0)
-  {
-    fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ;
-    exit (1) ;
-  }
+  rev = piBoardRev () ;
 
   if (rev == 1)
     device = "/dev/i2c-0" ;
   else
     device = "/dev/i2c-1" ;
 
-  if ((fd = open (device, O_RDWR)) < 0)
-    return -1 ;
-
-  if (ioctl (fd, I2C_SLAVE, devId) < 0)
-    return -1 ;
-
-  return fd ;
+  return wiringPiI2CSetupInterface (device, devId) ;
 }
index 6710ff46df640e98bd4644dec521467a1216943d..6db8c688e49575f31d919ab841f8762576eefbfb 100644 (file)
 extern "C" {
 #endif
 
-extern int wiringPiI2CRead       (int fd) ;
-extern int wiringPiI2CReadReg8   (int fd, int reg) ;
-extern int wiringPiI2CReadReg16  (int fd, int reg) ;
+extern int wiringPiI2CRead           (int fd) ;
+extern int wiringPiI2CReadReg8       (int fd, int reg) ;
+extern int wiringPiI2CReadReg16      (int fd, int reg) ;
 
-extern int wiringPiI2CWrite      (int fd, int data) ;
-extern int wiringPiI2CWriteReg8  (int fd, int reg, int data) ;
-extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;
+extern int wiringPiI2CWrite          (int fd, int data) ;
+extern int wiringPiI2CWriteReg8      (int fd, int reg, int data) ;
+extern int wiringPiI2CWriteReg16     (int fd, int reg, int data) ;
 
-int wiringPiI2CSetup             (int devId) ;
+extern int wiringPiI2CSetupInterface (const char *device, int devId) ;
+extern int wiringPiI2CSetup          (const int devId) ;
 
 #ifdef __cplusplus
 }
index 44414985318a3bcee99ebfd38173ea5bea18242e..ded07ba6797a315313316e9998b3b19b2cfdaf0f 100644 (file)
 
 #include <stdint.h>
 #include <fcntl.h>
+#include <errno.h>
+#include <string.h>
 #include <sys/ioctl.h>
 #include <linux/spi/spidev.h>
 
+#include "wiringPi.h"
+
 #include "wiringPiSPI.h"
 
 
 // The SPI bus parameters
 //     Variables as they need to be passed as pointers later on
 
-static char       *spiDev0 = "/dev/spidev0.0" ;
-static char       *spiDev1 = "/dev/spidev0.1" ;
-static uint8_t     spiMode   = 0 ;
-static uint8_t     spiBPW    = 8 ;
-static uint16_t    spiDelay  = 0;
+const static char       *spiDev0  = "/dev/spidev0.0" ;
+const static char       *spiDev1  = "/dev/spidev0.1" ;
+const static uint8_t     spiMode  = 0 ;
+const static uint8_t     spiBPW   = 8 ;
+const static uint16_t    spiDelay = 0 ;
 
 static uint32_t    spiSpeeds [2] ;
 static int         spiFds [2] ;
@@ -95,7 +99,7 @@ int wiringPiSPISetup (int channel, int speed)
   channel &= 1 ;
 
   if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0)
-    return -1 ;
+    return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ;
 
   spiSpeeds [channel] = speed ;
   spiFds    [channel] = fd ;
@@ -104,14 +108,14 @@ int wiringPiSPISetup (int channel, int speed)
 //     Why are we reading it afterwriting it? I've no idea, but for now I'm blindly
 //     copying example code I've seen online...
 
-  if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode)         < 0) return -1 ;
-  if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode)         < 0) return -1 ;
-
-  if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ;
-  if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ;
+  if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode)         < 0)
+    return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ;
+  
+  if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
+    return wiringPiFailure (WPI_ALMOST, "SPI BPW Change failure: %s\n", strerror (errno)) ;
 
   if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed)   < 0) return -1 ;
-  if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed)   < 0) return -1 ;
+    return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ;
 
   return fd ;
 }
index 28ec598e5645874ce8af79c43ad8345d7d8d2ac9..ca976a996ffb06c89473dde21e6c3b6db0d384c0 100644 (file)
@@ -41,7 +41,7 @@
  *********************************************************************************
  */
 
-int serialOpen (char *device, int baud)
+int serialOpen (const char *device, const int baud)
 {
   struct termios options ;
   speed_t myBaud ;
@@ -60,6 +60,7 @@ int serialOpen (char *device, int baud)
     case   1200:       myBaud =   B1200 ; break ;
     case   1800:       myBaud =   B1800 ; break ;
     case   2400:       myBaud =   B2400 ; break ;
+    case   4800:       myBaud =   B4800 ; break ;
     case   9600:       myBaud =   B9600 ; break ;
     case  19200:       myBaud =  B19200 ; break ;
     case  38400:       myBaud =  B38400 ; break ;
@@ -116,7 +117,7 @@ int serialOpen (char *device, int baud)
  *********************************************************************************
  */
 
-void serialFlush (int fd)
+void serialFlush (const int fd)
 {
   tcflush (fd, TCIOFLUSH) ;
 }
@@ -128,7 +129,7 @@ void serialFlush (int fd)
  *********************************************************************************
  */
 
-void serialClose (int fd)
+void serialClose (const int fd)
 {
   close (fd) ;
 }
@@ -140,7 +141,7 @@ void serialClose (int fd)
  *********************************************************************************
  */
 
-void serialPutchar (int fd, unsigned char c)
+void serialPutchar (const int fd, const unsigned char c)
 {
   write (fd, &c, 1) ;
 }
@@ -152,7 +153,7 @@ void serialPutchar (int fd, unsigned char c)
  *********************************************************************************
  */
 
-void serialPuts (int fd, char *s)
+void serialPuts (const int fd, const char *s)
 {
   write (fd, s, strlen (s)) ;
 }
@@ -163,7 +164,7 @@ void serialPuts (int fd, char *s)
  *********************************************************************************
  */
 
-void serialPrintf (int fd, char *message, ...)
+void serialPrintf (const int fd, const char *message, ...)
 {
   va_list argp ;
   char buffer [1024] ;
@@ -182,7 +183,7 @@ void serialPrintf (int fd, char *message, ...)
  *********************************************************************************
  */
 
-int serialDataAvail (int fd)
+int serialDataAvail (const int fd)
 {
   int result ;
 
@@ -201,7 +202,7 @@ int serialDataAvail (int fd)
  *********************************************************************************
  */
 
-int serialGetchar (int fd)
+int serialGetchar (const int fd)
 {
   uint8_t x ;
 
index 1a4198c9f7f201cf640dd065f47fb729386a7f05..430dc73118a36c3310bac400b4ff7d7af466c36c 100644 (file)
 extern "C" {
 #endif
 
-extern int   serialOpen      (char *device, int baud) ;
-extern void  serialClose     (int fd) ;
-extern void  serialFlush     (int fd) ;
-extern void  serialPutchar   (int fd, unsigned char c) ;
-extern void  serialPuts      (int fd, char *s) ;
-extern void  serialPrintf    (int fd, char *message, ...) ;
-extern int   serialDataAvail (int fd) ;
-extern int   serialGetchar   (int fd) ;
+extern int   serialOpen      (const char *device, const int baud) ;
+extern void  serialClose     (const int fd) ;
+extern void  serialFlush     (const int fd) ;
+extern void  serialPutchar   (const int fd, const unsigned char c) ;
+extern void  serialPuts      (const int fd, const char *s) ;
+extern void  serialPrintf    (const int fd, const char *message, ...) ;
+extern int   serialDataAvail (const int fd) ;
+extern int   serialGetchar   (const int fd) ;
 
 #ifdef __cplusplus
 }
index b9b7a44f672679283fbbb7b56a34a39863a39643..3df94e8ae03017f2e6f9438dfdc6b15cf96ab7d3 100644 (file)
@@ -56,7 +56,6 @@ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order)
   return value;
 }
 
-
 /*
  * shiftOut:
  *     Shift data out to a clocked source
index a3f4581b0df73ee798dd943df66420542bd3a888..419ade411f408b09e91fa451dfb0e82922aa4275 100644 (file)
@@ -33,8 +33,8 @@
 extern "C" {
 #endif
 
-extern uint8_t shiftIn  (uint8_t dPin, uint8_t cPin, uint8_t order) ;
-extern void    shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
+extern uint8_t shiftIn      (uint8_t dPin, uint8_t cPin, uint8_t order) ;
+extern void    shiftOut     (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
 
 #ifdef __cplusplus
 }