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
 
 
   ./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
 Gordon Henderson
 
 projects@drogon.net
index 0fce86a5ec3925878b2d8ee330e72f1de01568a6..7789b2eba205801581acb565686f402ff62a0479 100644 (file)
@@ -16,7 +16,7 @@ accepted to Github....
 
 Please see
 
 
 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
 
 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
 }
 
 if [ x$1 = "xclean" ]; then
-  echo Cleaning
-  echo
   cd wiringPi
   cd wiringPi
-  make clean
+  echo -n "wiringPi:  "        ; make clean
+  cd ../devLib
+  echo -n "DevLib:    "        ; make clean
   cd ../gpio
   cd ../gpio
-  make clean
+  echo -n "gpio:      "        ; make clean
   cd ../examples
   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
   exit
 fi
 
 if [ x$1 = "xuninstall" ]; then
-  echo Uninstalling
-  echo
-  echo "WiringPi library"
   cd wiringPi
   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
   cd ../gpio
-  sudo make uninstall
-  cd ..
+  echo -n "gpio:     " ; sudo make uninstall
   exit
 fi
 
   exit
 fi
 
@@ -44,25 +44,20 @@ fi
   echo "====================="
   echo
 
   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
-  echo "WiringPi library"
+  echo "WiringPi Library"
   cd wiringPi
   sudo make uninstall
   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
   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/
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
  ***********************************************************************
  */
 
  ***********************************************************************
  */
 
-#define        MAX_LCDS        8
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #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
 }
 
 #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 <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
 
 
 #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 ;
 {
   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] ;
 
 {
   uint8_t spiData [2] ;
 
@@ -120,3 +121,44 @@ int gertboardSPISetup (void)
 
   return 0 ;
 }
 
   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 "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) ;
 
 extern int  gertboardSPISetup    (void) ;
 
+// New
+
+extern int  gertboardAnalogSetup (const int pinBase) ;
+
 #ifdef __cplusplus
 }
 #endif
 #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 <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <stdarg.h>
 
 #include <stdarg.h>
 
-#include "wiringPi.h"
+#include <wiringPi.h>
+
 #include "lcd.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_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_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
 
 #define        LCD_FUNC_F      0x04
 #define        LCD_FUNC_N      0x08
 
 struct lcdDataStruct
 {
 
 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] ;
 
 } ;
 
 struct lcdDataStruct *lcds [MAX_LCDS] ;
 
+static int lcdControl ;
+
+// Row offsets
+
+static const int rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
+
 
 /*
  * strobe:
 
 /*
  * 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 ()
 {
 
 // 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)
   {
 
   if (lcd->bits == 4)
   {
-    d4 = (data >> 4) & 0x0F;
+    d4 = (myData >> 4) & 0x0F;
     for (i = 0 ; i < 4 ; ++i)
     {
       digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
     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) ;
 
     }
     strobe (lcd) ;
 
-    d4 = data & 0x0F ;
+    d4 = myData & 0x0F ;
     for (i = 0 ; i < 4 ; ++i)
     {
       digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
     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)
     {
   {
     for (i = 0 ; i < 8 ; ++i)
     {
-      digitalWrite (lcd->dataPins [i], (data & 1)) ;
-      data >>= 1 ;
+      digitalWrite (lcd->dataPins [i], (myData & 1)) ;
+      myData >>= 1 ;
     }
   }
   strobe (lcd) ;
     }
   }
   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) ;
 {
   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->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) ;
 }
   }
   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] ;
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
+
   putCommand (lcd, LCD_HOME) ;
   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] ;
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
+
   putCommand (lcd, LCD_CLEAR) ;
   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) ;
 }
 
 {
   struct lcdDataStruct *lcd = lcds [fd] ;
   putCommand (lcd, command) ;
 }
 
+
 /*
  * lcdPosition:
 /*
  * 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] ;
 
   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])) ;
   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:
 }
 
 
 /*
  * 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) ;
 {
   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++) ;
 {
   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] ;
 {
   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 ;
 
 {
   static int initialised = 0 ;
 
-  uint8_t func ;
+  unsigned char func ;
   int i ;
   int lcdFd = -1 ;
   struct lcdDataStruct *lcd ;
   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 ;
 
   if (lcdFd == -1)
     return -1 ;
 
-  lcd = malloc (sizeof (struct lcdDataStruct)) ;
+  lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ;
   if (lcd == NULL)
     return -1 ;
 
   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->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 ;
 
   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
 
 
 // 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 ;
 }
 
   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
  *             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>
  ***********************************************************************
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  */
 
 #include <stdio.h>
  */
 
 #include <stdio.h>
-#include <stdint.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
 #include <math.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>
 
 #include <wiringPi.h>
 #include <gertboard.h>
 int main (void)
 {
   double angle ;
 int main (void)
 {
   double angle ;
-  int i ;
-  uint32_t x1 ;
+  int i, inputValue ;
   int  buffer [B_SIZE] ;
   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 ("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)
   {
 
   for (i = 0 ; i < B_SIZE ; ++i)
   {
@@ -66,28 +73,23 @@ int main (void)
     buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ;
   }
 
     buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ;
   }
 
+// Loop, output the sine wave on analog out port 0, read it into A-D port 0
+//     and display it on the screen
 
   for (;;)
   {
 
   for (;;)
   {
-#ifdef DO_TIMING
-    then = millis () ;
-#endif
-
     for (i = 0 ; i < B_SIZE ; ++i)
     {
     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 ;
   }
 
   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
 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
 ###############################################################################
 
 
 # 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)
 
 
 OBJ    =       $(SRC:.c=.o)
 
@@ -55,13 +59,13 @@ blink:      blink.o
        @echo [link]
        @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
 
        @echo [link]
        @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
 
-test1: test1.o
+blink8:        blink8.o
        @echo [link]
        @echo [link]
-       @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS)
-       
-test2: test2.o
+       @$(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS)
+
+blink12:       blink12.o
        @echo [link]
        @echo [link]
-       @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS)
+       @$(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS)
 
 speed: speed.o
        @echo [link]
 
 speed: speed.o
        @echo [link]
@@ -71,6 +75,10 @@ lcd: lcd.o
        @echo [link]
        @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS)
 
        @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)
 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)
 
        @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) 
 
 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)
 
 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)
 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)
 
        @echo [link]
        @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS)
 
-servo: servo.o
+ds1302:        ds1302.o
        @echo [link]
        @echo [link]
-       @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS)
+       @$(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS)
 
 
 .c.o:
 
 
 .c.o:
@@ -129,7 +141,8 @@ servo:      servo.o
        @$(CC) -c $(CFLAGS) $< -o $@
 
 clean:
        @$(CC) -c $(CFLAGS) $< -o $@
 
 clean:
-       rm -f $(OBJ) *~ core tags $(BINS)
+       @echo "[Clean]"
+       @rm -f $(OBJ) *~ core tags $(BINS)
 
 tags:  $(SRC)
        @echo [ctags]
 
 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") ;
 
 {
   printf ("Raspberry Pi blink\n") ;
 
-  if (wiringPiSetup () == -1)
-    return 1 ;
-
+  wiringPiSetup () ;
   pinMode (LED, OUTPUT) ;
 
   for (;;)
   {
   pinMode (LED, OUTPUT) ;
 
   for (;;)
   {
-    digitalWrite (LED, 1) ;    // On
+    digitalWrite (LED, HIGH) ; // On
     delay (500) ;              // mS
     delay (500) ;              // mS
-    digitalWrite (LED, 0) ;    // Off
+    digitalWrite (LED, LOW) ;  // Off
     delay (500) ;
   }
   return 0 ;
     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>
  ***********************************************************************
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
+#include <wiringPi.h>
 
 // Simple sequencer data
 //     Triplets of LED, On/Off and delay
 
 
 // Simple sequencer data
 //     Triplets of LED, On/Off and delay
 
-uint8_t data [] =
+int data [] =
 {
             0, 1, 1,
             1, 1, 1,
 {
             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,
   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
 
 
   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,
   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
 
 
   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 ;
 
   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 (pin, OUTPUT) ;
 
-  pinMode (8, INPUT) ;         // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor
-
   dataPtr = 0 ;
 
   for (;;)
   dataPtr = 0 ;
 
   for (;;)
@@ -93,18 +97,14 @@ int main (void)
     s = data [dataPtr++] ;     // State
     d = data [dataPtr++] ;     // Duration (10ths)
 
     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) ;
     {
       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 ;
   }
 
   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>
  ***********************************************************************
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#include <wiringPi.h>
 
 int main (void)
 {
 
 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 (;;)
   {
-    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>
 
 
 #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.
 
 // 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 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 (;;)
   {
 
   for (;;)
   {
+    gotOne = 0 ;
     printf ("Waiting ... ") ; fflush (stdout) ;
 
     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 ;
   }
 
   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.
  *
  *     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/
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #include <wiringPi.h>
 #include <lcd.h>
 
 #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 ;
 
 
   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) ;
 
 
   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 (;;)
   {
 
   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 ;
   }
 
   return 0 ;
index 9b3a170ca3200caedcac70f2d22d2310bacfcbd5..930f266b5c4a387870bd81982382f0cafa95b1a7 100644 (file)
 #include <wiringPi.h>
 #include <softPwm.h>
 
 #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 ;
 
 #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 ;
   }
   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) ;
 
   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 (;;)
   softPwmCreate (OK_LED, 0, 100) ;
 
   for (;;)
index c1fc3317c79912eefab0498dc935fd95c2975e92..816c8322e357db2f56458a1bd4689aa61f75c64f 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * pwm.c:
 /*
  * 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>
  ***********************************************************************
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
  ***********************************************************************
  */
 
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
 #include <wiringPi.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>
  ***********************************************************************
  *
  * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
  ***********************************************************************
  ***********************************************************************
  */
 
  ***********************************************************************
  */
 
-#include <wiringPi.h>
-
 #include <stdio.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 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 (;;)
   {
-    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 ;
   }
 
   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
  *
  *     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 ;
 
 {
   int i ;
 
-  if (wiringPiSetup () == -1)
-  {
-    fprintf (stdout, "oops: %s\n", strerror (errno)) ;
-    return 1 ;
-  }
+  wiringPiSetup () ;
 
   softToneCreate (PIN) ;
 
 
   softToneCreate (PIN) ;
 
@@ -55,5 +51,4 @@ int main ()
       delay (500) ;
     }
   }
       delay (500) ;
     }
   }
-
 }
 }
index 863317ee25bdc55fff2a5b0f2f16f1a5d1a25d32..0a42b36291473907b133c0e67967900a0938eada 100644 (file)
 
 #define        FAST_COUNT      10000000
 #define        SLOW_COUNT       1000000
 
 #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 ;
 
   sum = 0 ;
-  for (i = 0 ; i < 3 ; ++i)
-  {
-    printf ("  Pass: %d: ", i) ;
-    fflush (stdout) ;
 
 
+  for (i = 0 ; i < PASSES ; ++i)
+  {
     start = millis () ;
     start = millis () ;
-    for (count = 0 ; count < FAST_COUNT ; ++count)
-      digitalWrite (0, 1) ;
+    for (count = 0 ; count < maxCount ; ++count)
+      digitalWrite (pin, 1) ;
     end = millis () ;
     end = millis () ;
-    printf (" %8dmS\n", end - start) ;
+    printf (" %6d", end - start) ;
+    fflush (stdout) ;
     sum += (end - start) ;
   }
     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 ;
 }
 
   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
 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
 ###############################################################################
 
 
 # May not need to  alter anything below this line
 ###############################################################################
 
-SRC    =       gpio.c
+SRC    =       gpio.c extensions.c
 
 OBJ    =       $(SRC:.c=.o)
 
 all:           gpio
 
 
 OBJ    =       $(SRC:.c=.o)
 
 all:           gpio
 
-gpio:  gpio.o
+gpio:  $(OBJ)
        @echo [Link]
        @echo [Link]
-       @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
+       @$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
        
 .c.o:
        @echo [Compile] $<
        
 .c.o:
        @echo [Compile] $<
@@ -51,7 +51,8 @@ gpio: gpio.o
 
 .PHONEY:       clean
 clean:
 
 .PHONEY:       clean
 clean:
-       rm -f $(OBJ) gpio *~ core tags *.bak
+       @echo "[Clean]"
+       @rm -f $(OBJ) gpio *~ core tags *.bak
 
 .PHONEY:       tags
 tags:  $(SRC)
 
 .PHONEY:       tags
 tags:  $(SRC)
@@ -78,3 +79,6 @@ depend:
        makedepend -Y $(SRC)
 
 # DO NOT DELETE
        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
 
 .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
 
 .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 ]
 .PP
 .B gpio
 .B [ \-p ]
@@ -17,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
 .B ...
 .PP
 .B gpio
 .B ...
 .PP
 .B gpio
-.B readall
+.B readall/reset
 .PP
 .B gpio
 .B unexportall/exports
 .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 ...
 .PP
 .B gpio
+.B wfi
+.B ...
+.PP
+.B gpio
 .B drive
 group value
 .PP
 .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.
 .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.
 
 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
 .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>
 
 .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.
 
 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
 .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.
 
 .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
 .TP
 .B drive
 group value
@@ -207,26 +242,26 @@ The board jumpers need to be in-place to do this operation.
 
 .PP
 .TS
 
 .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
 17     -       28
 18     -       29
 19     -       30
@@ -272,7 +307,7 @@ pin numbers.
 .LP
 WiringPi's home page
 .IP
 .LP
 WiringPi's home page
 .IP
-https://projects.drogon.net/raspberry-pi/wiringpi/
+http://wiringpi.com/
 
 .SH AUTHOR
 
 
 .SH AUTHOR
 
@@ -284,7 +319,7 @@ Please report bugs to <projects@drogon.net>
 
 .SH COPYRIGHT
 
 
 .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.
 
 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.
  * 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/
  ***********************************************************************
  * This file is part of wiringPi:
  *     https://projects.drogon.net/raspberry-pi/wiringpi/
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <ctype.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
-#include <sys/types.h>
 #include <fcntl.h>
 #include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <wiringPi.h>
 
 #include <wiringPi.h>
+
 #include <gertboard.h>
 #include <gertboard.h>
+#include <piFace.h>
+
+#include "extensions.h"
 
 extern int wiringPiDebug ;
 
 
 extern int wiringPiDebug ;
 
@@ -42,22 +48,26 @@ extern int wiringPiDebug ;
 #  define      FALSE   (1==2)
 #endif
 
 #  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"
 
 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 [-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 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 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.
 
              "       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
 /*
  * doReadall:
  *     Read all the GPIO pins
@@ -215,27 +256,39 @@ static char *alts [] =
   "IN  ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
 } ;
 
   "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 ;
 
 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 ;
 
   {
     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 ") ;
   }
 
        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] ;
 
   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
   {
 
 // 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
 /*
  * 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 ;
 {
   FILE *fd ;
   int pin ;
@@ -508,7 +605,7 @@ void doUnexportall (int argc, char *argv [])
   {
     if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
     {
   {
     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) ;
       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 ...
 /*
  * doMode:
  *     gpio mode pin mode ...
@@ -536,9 +657,6 @@ void doMode (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
 
   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) ;
   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)
   {
 
   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) ;
   }
 
     exit (1) ;
   }
 
@@ -613,23 +731,23 @@ static void doGbw (int argc, char *argv [])
 
   if ((channel < 0) || (channel > 1))
   {
 
   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))
   {
     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) ;
   }
 
     exit (1) ;
   }
 
-  if (gertboardSPISetup () == -1)
+  if (gertboardAnalogSetup (64) < 0)
   {
     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
     exit (1) ;
   }
 
   {
     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))
   {
 
   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) ;
   }
 
     exit (1) ;
   }
 
-  if (gertboardSPISetup () == -1)
+  if (gertboardAnalogSetup (64) < 0)
   {
     fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
     exit (1) ;
   }
 
   {
     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
 /*
  * doWrite:
  *     gpio write pin value
@@ -687,9 +804,6 @@ static void doWrite (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
 
   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))
   /**/ 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) ;
 }
 
     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
 /*
  * doWriteByte:
  *     gpio write value
@@ -742,19 +881,57 @@ void doRead (int argc, char *argv [])
   }
 
   pin = atoi (argv [2]) ;
   }
 
   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") ;
 }
 
 
 
   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
 /*
  * doClock:
  *     Output a clock on a pin
@@ -773,9 +950,6 @@ void doClock (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   freq = atoi (argv [3]) ;
 
   gpioClockSet (pin, freq) ;
   freq = atoi (argv [3]) ;
 
   gpioClockSet (pin, freq) ;
@@ -800,9 +974,6 @@ void doPwm (int argc, char *argv [])
 
   pin = atoi (argv [2]) ;
 
 
   pin = atoi (argv [2]) ;
 
-  if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
-    return ;
-
   val = atoi (argv [3]) ;
 
   pwmWrite (pin, val) ;
   val = atoi (argv [3]) ;
 
   pwmWrite (pin, val) ;
@@ -885,16 +1056,34 @@ int main (int argc, char *argv [])
     return 1 ;
   }
 
     return 1 ;
   }
 
+// Help
+
   if (strcasecmp (argv [1], "-h") == 0)
   {
     printf ("%s: %s\n", argv [0], usage) ;
     return 0 ;
   }
 
   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 ("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") ;
     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) ;
   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") ;
     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 ; }
   /**/ 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], "unexport"   ) == 0)  { doUnexport    (argc, argv) ;  return 0 ; }
+  else if (strcasecmp (argv [1], "unexportall") == 0)  { doUnexportall (argv [0]) ;    return 0 ; }
 
 // Check for load command:
 
 
 // Check for load command:
 
@@ -948,13 +1137,9 @@ int main (int argc, char *argv [])
 
 // Check for -g argument
 
 
 // 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] ;
 
     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 ;
   }
 
     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)
   {
 // 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] ;
 
     for (i = 2 ; i < argc ; ++i)
       argv [i - 1] = argv [i] ;
@@ -982,38 +1175,65 @@ int main (int argc, char *argv [])
 
   else
   {
 
   else
   {
-    if (wiringPiSetup () == -1)
-    {
-      fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
-      exit (1) ;
-    }
+    wiringPiSetup () ;
     wpMode = WPI_MODE_PINS ;
   }
 
     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]) ;
   else
   {
     fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
-    exit (1) ;
+    exit (EXIT_FAILURE) ;
   }
   return 0 ;
 }
   }
   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/>.
 #################################################################################
 
 #    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)
 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.
 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
 ###############################################################################
 
 
 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    =       $(SRC:.c=.o)
 
-OBJ_I2C        =       $(SRC_I2C:.c=.o)
-
 all:           $(DYNAMIC)
 
 static:                $(STATIC)
 all:           $(DYNAMIC)
 
 static:                $(STATIC)
@@ -67,11 +66,7 @@ $(STATIC):   $(OBJ)
 
 $(DYNAMIC):    $(OBJ)
        @echo "[Link (Dynamic)]"
 
 $(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] $<
 
 .c.o:
        @echo [Compile] $<
@@ -79,37 +74,48 @@ i2c:        $(OBJ) $(OBJ_I2C)
 
 .PHONEY:       clean
 clean:
 
 .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:       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 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 softPwm.h              $(DESTDIR)$(PREFIX)/include
-       @install -m 0644 softServo.h            $(DESTDIR)$(PREFIX)/include
        @install -m 0644 softTone.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 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
        @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
        @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/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/softPwm.h
-       @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
        @rm -f $(DESTDIR)$(PREFIX)/include/softTone.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/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
 
        @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
        @ldconfig
 
@@ -137,16 +148,21 @@ depend:
 # DO NOT DELETE
 
 wiringPi.o: wiringPi.h
 # DO NOT DELETE
 
 wiringPi.o: wiringPi.h
-wiringPiFace.o: wiringPi.h
 wiringSerial.o: wiringSerial.h
 wiringShift.o: wiringPi.h wiringShift.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
 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
 softPwm.o: wiringPi.h softPwm.h
-softServo.o: wiringPi.h softServo.h
 softTone.o: wiringPi.h softTone.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))
 {
   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) ;
 }
   return sched_setscheduler (0, SCHED_RR, &sched) ;
 }
index b568dfb45ca509131f1c013403b35fb79d38a1fc..a4f0fc43f6b0fc3e0dc434c1cef9087e0833a982 100644 (file)
@@ -28,7 +28,7 @@
 #include "wiringPi.h"
 #include "softPwm.h"
 
 #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.
 
 // 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)
 {
 
 void softPwmWrite (int pin, int value)
 {
-  pin &= 63 ;
+  pin &= (MAX_PINS - 1) ;
 
   /**/ if (value < 0)
     value = 0 ;
 
   /**/ if (value < 0)
     value = 0 ;
index 846362726fdb8fbbe20fe7e38774cffa8d0ff135..b4a89f8a250ee8ca803cf20e88b6986937e54087 100644 (file)
@@ -36,7 +36,7 @@
 
 #define        PULSE_TIME      100
 
 
 #define        PULSE_TIME      100
 
-static int frewqs [MAX_PINS] ;
+static int freqs [MAX_PINS] ;
 
 static int newPin = -1 ;
 
 
 static int newPin = -1 ;
 
@@ -49,7 +49,7 @@ static int newPin = -1 ;
 
 static PI_THREAD (softToneThread)
 {
 
 static PI_THREAD (softToneThread)
 {
-  int pin, frewq, halfPeriod ;
+  int pin, freq, halfPeriod ;
 
   pin    = newPin ;
   newPin = -1 ;
 
   pin    = newPin ;
   newPin = -1 ;
@@ -58,12 +58,12 @@ static PI_THREAD (softToneThread)
 
   for (;;)
   {
 
   for (;;)
   {
-    frewq = frewqs [pin] ;
-    if (frewq == 0)
+    freq = freqs [pin] ;
+    if (freq == 0)
       delay (1) ;
     else
     {
       delay (1) ;
     else
     {
-      halfPeriod = 500000 / frewq ;
+      halfPeriod = 500000 / freq ;
 
       digitalWrite (pin, HIGH) ;
       delayMicroseconds (halfPeriod) ;
 
       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 ;
 
 {
   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) ;
 
   pinMode      (pin, OUTPUT) ;
   digitalWrite (pin, LOW) ;
 
-  frewqs [pin] = 0 ;
+  freqs [pin] = 0 ;
 
   newPin = pin ;
   res = piThreadCreate (softToneThread) ;
 
   newPin = pin ;
   res = piThreadCreate (softToneThread) ;
index 80c64fe64cc8bd92865fcce8f715d952757041b7..d8b4e54cee8afc0f2de34a56e31ad22bafbfada0 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 #endif
 
 extern int  softToneCreate (int pin) ;
 #endif
 
 extern int  softToneCreate (int pin) ;
-extern void softToneWrite  (int pin, int frewq) ;
+extern void softToneWrite  (int pin, int freq) ;
 
 #ifdef __cplusplus
 }
 
 #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 <stdio.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <ctype.h>
 
 #include "wiringPi.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
 
 #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
 // 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 ;
 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 ;
 static volatile uint32_t *timer ;
 static volatile uint32_t *timerIrqRaw ;
+#endif
 
 // Time for easy calculations
 
 
 // Time for easy calculations
 
@@ -202,10 +202,13 @@ static uint64_t epochMilli, epochMicro ;
 // Misc
 
 static int wiringPiMode = WPI_MODE_UNINITIALISED ;
 // 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
 
 // 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
 
 // 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] =
 {
 
 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:
 
 
 // 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:
 // 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 [] =
 {
 
 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,
 } ;
 
    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
 
 // 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
 } ;
 
           0,         0,         0,         0,         0,         0,         0,         0,      // 56 -> 63
 } ;
 
+
 // gpioToPwmPort
 //     The port value to put a GPIO pin into PWM mode
 
 // 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
 // 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
 //     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.
 }
 
 
 /*
  * 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)
  *
  *     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) ;
 {
   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:
 
 /*
  * getAlt:
@@ -564,12 +687,19 @@ int piBoardRev (void)
  *********************************************************************************
  */
 
  *********************************************************************************
  */
 
-int getAltGpio (int pin)
+int getAlt (int pin)
 {
   int fSel, shift, alt ;
 
   pin &= 63 ;
 
 {
   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] ;
 
   fSel    = gpioToGPFSEL [pin] ;
   shift   = gpioToShift  [pin] ;
 
@@ -578,70 +708,66 @@ int getAltGpio (int pin)
   return alt ;
 }
 
   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
  *********************************************************************************
  */
 
  *     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 ;
 
 {
   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.
 
 
 // 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
 
 // 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.
 
 // 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
     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:
 
 /*
  * 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
   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:
 
 /*
  * 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
  *     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 ;
 
 {
   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
     return -2 ;
 
 // Setup poll structure
@@ -1037,16 +1259,6 @@ int waitForInterruptSys (int pin, int mS)
   return x ;
 }
 
   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:
 
 /*
  * interruptHandler:
@@ -1058,12 +1270,15 @@ int waitForInterruptGpio (int pin, int mS)
 
 static void *interruptHandler (void *arg)
 {
 
 static void *interruptHandler (void *arg)
 {
-  int myPin = *(int *)arg ;
+  int myPin ;
 
   (void)piHiPri (55) ; // Only effective if we run as root
 
 
   (void)piHiPri (55) ; // Only effective if we run as root
 
+  myPin   = pinPass ;
+  pinPass = -1 ;
+
   for (;;)
   for (;;)
-    if (waitForInterruptSys (myPin, -1) > 0)
+    if (waitForInterrupt (myPin, -1) > 0)
       isrFunctions [myPin] () ;
 
   return NULL ;
       isrFunctions [myPin] () ;
 
   return NULL ;
@@ -1072,6 +1287,7 @@ static void *interruptHandler (void *arg)
 
 /*
  * wiringPiISR:
 
 /*
  * wiringPiISR:
+ *     Pi Specific.
  *     Take the details and create an interrupt handler that will do a call-
  *     back to the user supplied function.
  *********************************************************************************
  *     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 ;
 int wiringPiISR (int pin, int mode, void (*function)(void))
 {
   pthread_t threadId ;
+  const char *modeS ;
   char fName   [64] ;
   char fName   [64] ;
-  char *modeS ;
   char  pinS [8] ;
   pid_t pid ;
   int   count, i ;
   char  pinS [8] ;
   pid_t pid ;
   int   count, i ;
-  uint8_t c ;
+  char  c ;
+  int   bcmGpioPin ;
 
   pin &= 63 ;
 
 
   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)
   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
 
 // 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" ;
 
     else
       modeS = "both" ;
 
-    sprintf (pinS, "%d", pin) ;
+    sprintf (pinS, "%d", bcmGpioPin) ;
 
     if ((pid = fork ()) < 0)   // Fail
       return pid ;
 
     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
   }
 
 // 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
 
     return -1 ;
 
 // Clear any initial pending interrupt
 
-  ioctl (sysFds [pin], FIONREAD, &count) ;
+  ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ;
   for (i = 0 ; i < count ; ++i)
   for (i = 0 ; i < count ; ++i)
-    read (sysFds [pin], &c, 1) ;
+    read (sysFds [bcmGpioPin], &c, 1) ;
 
   isrFunctions [pin] = function ;
 
 
   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 ;
 }
 
   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
 /*
  * 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) ;
 }
 
   epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
 }
 
+
 /*
  * delay:
 /*
  * 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 ;
 
   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 ;
     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") ;
 
 
   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)
   boardRev = piBoardRev () ;
 
   if (boardRev == 1)
-    pinToGpio = pinToGpioR1 ;
+  {
+     pinToGpio =  pinToGpioR1 ;
+    physToGpio = physToGpioR1 ;
+  }
   else
   else
-    pinToGpio = pinToGpioR2 ;
+  {
+     pinToGpio =  pinToGpioR2 ;
+    physToGpio = physToGpioR2 ;
+  }
 
 // Open the master /dev/memory device
 
   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
 
 // 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)
 
 // 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)
 
 // 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)
  
 // 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)
  
 // 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)
 // 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)
 
 // 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 ;
   *(timer + TIMER_CONTROL) = 0x0000280 ;
   *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
   timerIrqRaw = timer + TIMER_IRQ_RAW ;
+#endif
 
   initialiseEpoch () ;
 
 
   initialiseEpoch () ;
 
@@ -1426,40 +1594,39 @@ int wiringPiSetup (void)
 
 int wiringPiSetupGpio (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") ;
 
 
   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 ;
 }
 
 
   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.
 /*
  * wiringPiSetupSys:
  *     Must be called once at the start of your program execution.
@@ -1475,32 +1642,27 @@ int wiringPiSetupSys (void)
   int pin ;
   char fName [128] ;
 
   int pin ;
   char fName [128] ;
 
-  if (getenv ("WIRINGPI_DEBUG") != NULL)
+  if (getenv (ENV_DEBUG) != NULL)
     wiringPiDebug = TRUE ;
 
     wiringPiDebug = TRUE ;
 
+  if (getenv (ENV_CODES) != NULL)
+    wiringPiReturnCodes = TRUE ;
+
   if (wiringPiDebug)
     printf ("wiringPi: wiringPiSetupSys called\n") ;
 
   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)
   boardRev = piBoardRev () ;
 
   if (boardRev == 1)
-    pinToGpio = pinToGpioR1 ;
+  {
+     pinToGpio =  pinToGpioR1 ;
+    physToGpio = physToGpioR1 ;
+  }
   else
   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
 
 // 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_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        WPI_MODE_UNINITIALISED  -1
 
 // Pin modes
 
 #define        PI_THREAD(X)    void *X (void *dummy)
 
 
 #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
 
 // Function prototypes
 //     c++ wrappers thanks to a comment by Nick Lott
 extern "C" {
 #endif
 
 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  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 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
 
 // 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  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
 
 
 // Schedulling priority
 
-extern int piHiPri (int pri) ;
-
+extern int piHiPri (const int pri) ;
 
 // Extras from arduino land
 
 
 // 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 <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include <linux/i2c-dev.h>
 
 #include "wiringPi.h"
 #include "wiringPiI2C.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:
 
 /*
  * wiringPiI2CRead:
 
 int wiringPiI2CRead (int fd)
 {
 
 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)
 {
 
 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)
 {
 }
 
 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)
 {
 
 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 (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 "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
 }
 
 #ifdef __cplusplus
 }
index 44414985318a3bcee99ebfd38173ea5bea18242e..ded07ba6797a315313316e9998b3b19b2cfdaf0f 100644 (file)
 
 #include <stdint.h>
 #include <fcntl.h>
 
 #include <stdint.h>
 #include <fcntl.h>
+#include <errno.h>
+#include <string.h>
 #include <sys/ioctl.h>
 #include <linux/spi/spidev.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
 
 #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] ;
 
 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)
   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 ;
 
   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...
 
 //     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_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 ;
 }
 
   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 ;
 {
   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   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 ;
     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) ;
 }
 {
   tcflush (fd, TCIOFLUSH) ;
 }
@@ -128,7 +129,7 @@ void serialFlush (int fd)
  *********************************************************************************
  */
 
  *********************************************************************************
  */
 
-void serialClose (int fd)
+void serialClose (const int fd)
 {
   close (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) ;
 }
 {
   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)) ;
 }
 {
   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] ;
 {
   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 ;
 
 {
   int result ;
 
@@ -201,7 +202,7 @@ int serialDataAvail (int fd)
  *********************************************************************************
  */
 
  *********************************************************************************
  */
 
-int serialGetchar (int fd)
+int serialGetchar (const int fd)
 {
   uint8_t x ;
 
 {
   uint8_t x ;
 
index 1a4198c9f7f201cf640dd065f47fb729386a7f05..430dc73118a36c3310bac400b4ff7d7af466c36c 100644 (file)
 extern "C" {
 #endif
 
 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
 }
 
 #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;
 }
 
   return value;
 }
 
-
 /*
  * shiftOut:
  *     Shift data out to a clocked source
 /*
  * shiftOut:
  *     Shift data out to a clocked source
index a3f4581b0df73ee798dd943df66420542bd3a888..419ade411f408b09e91fa451dfb0e82922aa4275 100644 (file)
@@ -33,8 +33,8 @@
 extern "C" {
 #endif
 
 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
 }
 
 #ifdef __cplusplus
 }