diff --git a/INSTALL b/INSTALL
index 8a6d38e..8e0c43c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -30,18 +30,6 @@ To un-install wiringPi:
./build uninstall
-
-I2C:
-
-If your system has the correct i2c-dev libraries and headers installed,
-then the I2C helpers will be compiled into wiringPi. If you want to
-use the I2C helpers and don't have them installed, then under Raspbian,
-issue the command:
-
- sudo apt-get install libi2c-dev
-
-Consult the documentation for your system if you are not running Raspbian.
-
Gordon Henderson
projects@drogon.net
diff --git a/README.TXT b/README.TXT
index 0fce86a..7789b2e 100644
--- a/README.TXT
+++ b/README.TXT
@@ -16,7 +16,7 @@ accepted to Github....
Please see
- https://projects.drogon.net/raspberry-pi/wiringpi/
+ http://wiringpi.com/
for the official documentation, etc. and the best way to submit bug reports, etc.
is by sending an email to projects@drogon.net
diff --git a/build b/build
index cbb1a4f..048ebb3 100755
--- a/build
+++ b/build
@@ -14,28 +14,28 @@ check-make-ok()
}
if [ x$1 = "xclean" ]; then
- echo Cleaning
- echo
cd wiringPi
- make clean
+ echo -n "wiringPi: " ; make clean
+ cd ../devLib
+ echo -n "DevLib: " ; make clean
cd ../gpio
- make clean
+ echo -n "gpio: " ; make clean
cd ../examples
- make clean
+ echo -n "Examples: " ; make clean
+ cd Gertboard
+ echo -n "Gertboard: " ; make clean
+ cd ../PiFace
+ echo -n "PiFace: " ; make clean
exit
fi
if [ x$1 = "xuninstall" ]; then
- echo Uninstalling
- echo
- echo "WiringPi library"
cd wiringPi
- sudo make uninstall
- echo
- echo "GPIO Utility"
+ echo -n "wiringPi: " ; sudo make uninstall
+ cd ../devLib
+ echo -n "DevLib: " ; sudo make uninstall
cd ../gpio
- sudo make uninstall
- cd ..
+ echo -n "gpio: " ; sudo make uninstall
exit
fi
@@ -44,25 +44,20 @@ fi
echo "====================="
echo
-# Check for I2C being installed...
-# ... and if-so, then automatically make the I2C helpers
-
- if [ -f /usr/include/linux/i2c-dev.h ]; then
- grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h
- if [ $? = 0 ]; then
- target=i2c
- echo "Building wiringPi with the I2C helper libraries."
- else
- target=all
- echo "The wiringPi I2C helper libraries will not be built."
- fi
- fi
-
echo
- echo "WiringPi library"
+ echo "WiringPi Library"
cd wiringPi
sudo make uninstall
- make $target
+ make
+ check-make-ok
+ sudo make install
+ check-make-ok
+
+ echo
+ echo "WiringPi Devices Library"
+ cd ../devLib
+ sudo make uninstall
+ make
check-make-ok
sudo make install
check-make-ok
diff --git a/devLib/Makefile b/devLib/Makefile
new file mode 100644
index 0000000..a106d93
--- /dev/null
+++ b/devLib/Makefile
@@ -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 .
+#################################################################################
+
+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
index 0000000..cf64de7
--- /dev/null
+++ b/devLib/ds1302.c
@@ -0,0 +1,240 @@
+/*
+ * ds1302.c:
+ * Real Time clock
+ *
+ * Copyright (c) 2013 Gordon Henderson.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wiringPi. If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include "ds1302.h"
+
+// Register defines
+
+#define RTC_SECS 0
+#define RTC_MINS 1
+#define RTC_HOURS 2
+#define RTC_DATE 3
+#define RTC_MONTH 4
+#define RTC_DAY 5
+#define RTC_YEAR 6
+#define RTC_WP 7
+#define RTC_TC 8
+#define RTC_BM 31
+
+
+// Locals
+
+static int dPin, cPin, sPin ;
+
+/*
+ * dsShiftIn:
+ * Shift a number in from the chip, LSB first. Note that the data is
+ * sampled on the trailing edge of the last clock, so it's valid immediately.
+ *********************************************************************************
+ */
+
+static unsigned int dsShiftIn (void)
+{
+ uint8_t value = 0 ;
+ int i ;
+
+ pinMode (dPin, INPUT) ; delayMicroseconds (1) ;
+
+ for (i = 0 ; i < 8 ; ++i)
+ {
+ value |= (digitalRead (dPin) << i) ;
+ digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
+ digitalWrite (cPin, LOW) ; delayMicroseconds (1) ;
+ }
+
+ return value;
+}
+
+
+/*
+ * dsShiftOut:
+ * A normal LSB-first shift-out, just slowed down a bit - the Pi is
+ * a bit faster than the chip can handle.
+ *********************************************************************************
+ */
+
+static void dsShiftOut (unsigned int data)
+{
+ int i ;
+
+ pinMode (dPin, OUTPUT) ;
+
+ for (i = 0 ; i < 8 ; ++i)
+ {
+ digitalWrite (dPin, data & (1 << i)) ; delayMicroseconds (1) ;
+ digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ;
+ digitalWrite (cPin, LOW) ; delayMicroseconds (1) ;
+ }
+}
+
+
+/*
+ * ds1302regRead: ds1302regWrite:
+ * Read/Write a value to an RTC Register or RAM location on the chip
+ *********************************************************************************
+ */
+
+static unsigned int ds1302regRead (const int reg)
+{
+ unsigned int data ;
+
+ digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+ dsShiftOut (reg) ;
+ data = dsShiftIn () ;
+ digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
+
+ return data ;
+}
+
+static void ds1302regWrite (const int reg, const unsigned int data)
+{
+ digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+ dsShiftOut (reg) ;
+ dsShiftOut (data) ;
+ digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302rtcWrite: ds1302rtcRead:
+ * Writes/Reads the data to/from the RTC register
+ *********************************************************************************
+ */
+
+unsigned int ds1302rtcRead (const int reg)
+{
+ return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ;
+}
+
+void ds1302rtcWrite (int reg, unsigned int data)
+{
+ ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ;
+}
+
+
+/*
+ * ds1302ramWrite: ds1302ramRead:
+ * Writes/Reads the data to/from the RTC register
+ *********************************************************************************
+ */
+
+unsigned int ds1302ramRead (const int addr)
+{
+ return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ;
+}
+
+void ds1302ramWrite (const int addr, const unsigned int data)
+{
+ ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ;
+}
+
+/*
+ * ds1302clockRead:
+ * Read all 8 bytes of the clock in a single operation
+ *********************************************************************************
+ */
+
+void ds1302clockRead (int clockData [8])
+{
+ int i ;
+ unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ;
+
+ digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+
+ dsShiftOut (regVal) ;
+ for (i = 0 ; i < 8 ; ++i)
+ clockData [i] = dsShiftIn () ;
+
+ digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302clockWrite:
+ * Write all 8 bytes of the clock in a single operation
+ *********************************************************************************
+ */
+
+void ds1302clockWrite (const int clockData [8])
+{
+ int i ;
+ unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ;
+
+ digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ;
+
+ dsShiftOut (regVal) ;
+ for (i = 0 ; i < 8 ; ++i)
+ dsShiftOut (clockData [i]) ;
+
+ digitalWrite (sPin, LOW) ; delayMicroseconds (1) ;
+}
+
+
+/*
+ * ds1302trickleCharge:
+ * Set the bits on the trickle charger.
+ * Probably best left alone...
+ *********************************************************************************
+ */
+
+void ds1302trickleCharge (const int diodes, const int resistors)
+{
+ if (diodes + resistors == 0)
+ ds1302rtcWrite (RTC_TC, 0x5C) ; // Disabled
+ else
+ ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ;
+}
+
+
+
+
+/*
+ * ds1302setup:
+ * Initialise the chip & remember the pins we're using
+ *********************************************************************************
+ */
+
+void ds1302setup (const int clockPin, const int dataPin, const int csPin)
+{
+ dPin = dataPin ;
+ cPin = clockPin ;
+ sPin = csPin ;
+
+ digitalWrite (dPin, LOW) ;
+ digitalWrite (cPin, LOW) ;
+ digitalWrite (sPin, LOW) ;
+
+ pinMode (dPin, OUTPUT) ;
+ pinMode (cPin, OUTPUT) ;
+ pinMode (sPin, OUTPUT) ;
+
+ ds1302rtcWrite (RTC_WP, 0) ; // Remove write-protect
+}
diff --git a/wiringPi/lcd.h b/devLib/ds1302.h
similarity index 58%
rename from wiringPi/lcd.h
rename to devLib/ds1302.h
index beebb75..e82b3ed 100644
--- a/wiringPi/lcd.h
+++ b/devLib/ds1302.h
@@ -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/
@@ -24,22 +22,22 @@
***********************************************************************
*/
-#define MAX_LCDS 8
-
#ifdef __cplusplus
extern "C" {
#endif
-extern void lcdHome (int fd) ;
-extern void lcdClear (int fd) ;
-extern void lcdSendCommand (int fd, uint8_t command) ;
-extern void lcdPosition (int fd, int x, int y) ;
-extern void lcdPutchar (int fd, uint8_t data) ;
-extern void lcdPuts (int fd, char *string) ;
-extern void lcdPrintf (int fd, char *message, ...) ;
+extern unsigned int ds1302rtcRead (const int reg) ;
+extern void ds1302rtcWrite (const int reg, const unsigned int data) ;
+
+extern unsigned int ds1302ramRead (const int addr) ;
+extern void ds1302ramWrite (const int addr, const unsigned int data) ;
+
+extern void ds1302clockRead (int clockData [8]) ;
+extern void ds1302clockWrite (const int clockData [8]) ;
+
+extern void ds1302trickleCharge (const int diodes, const int resistors) ;
-extern int lcdInit (int rows, int cols, int bits, int rs, int strb,
- int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
+extern void ds1302setup (const int clockPin, const int dataPin, const int csPin) ;
#ifdef __cplusplus
}
diff --git a/devLib/font.h b/devLib/font.h
new file mode 100644
index 0000000..ce99e16
--- /dev/null
+++ b/devLib/font.h
@@ -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 '' */
+ 0x00, /* 00000000 */
+ 0x10, /* 00010000 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 128 0x80 '' */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x0c, /* 00001100 */
+ 0x78, /* 01111000 */
+
+ /* 129 0x81 '' */
+ 0xcc, /* 11001100 */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 130 0x82 '' */
+ 0x0c, /* 00001100 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 131 0x83 '' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 132 0x84 '' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 133 0x85 '' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 134 0x86 '' */
+ 0x30, /* 00110000 */
+ 0x30, /* 00110000 */
+ 0x78, /* 01111000 */
+ 0x0c, /* 00001100 */
+ 0x7c, /* 01111100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 135 0x87 '' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x7e, /* 01111110 */
+ 0x0c, /* 00001100 */
+ 0x38, /* 00111000 */
+
+ /* 136 0x88 '' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 137 0x89 '' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 138 0x8a '' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 139 0x8b '' */
+ 0x66, /* 01100110 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 140 0x8c '' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 141 0x8d '' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x00, /* 00000000 */
+ 0x38, /* 00111000 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x3c, /* 00111100 */
+ 0x00, /* 00000000 */
+
+ /* 142 0x8e '' */
+ 0xc6, /* 11000110 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 143 0x8f '' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xfe, /* 11111110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+
+ /* 144 0x90 '' */
+ 0x18, /* 00011000 */
+ 0x30, /* 00110000 */
+ 0xfe, /* 11111110 */
+ 0xc0, /* 11000000 */
+ 0xf8, /* 11111000 */
+ 0xc0, /* 11000000 */
+ 0xfe, /* 11111110 */
+ 0x00, /* 00000000 */
+
+ /* 145 0x91 '' */
+ 0x00, /* 00000000 */
+ 0x00, /* 00000000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0xd8, /* 11011000 */
+ 0x7e, /* 01111110 */
+ 0x00, /* 00000000 */
+
+ /* 146 0x92 '' */
+ 0x3e, /* 00111110 */
+ 0x6c, /* 01101100 */
+ 0xcc, /* 11001100 */
+ 0xfe, /* 11111110 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xce, /* 11001110 */
+ 0x00, /* 00000000 */
+
+ /* 147 0x93 '' */
+ 0x7c, /* 01111100 */
+ 0x82, /* 10000010 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 148 0x94 '' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 149 0x95 '' */
+ 0x30, /* 00110000 */
+ 0x18, /* 00011000 */
+ 0x7c, /* 01111100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 150 0x96 '' */
+ 0x78, /* 01111000 */
+ 0x84, /* 10000100 */
+ 0x00, /* 00000000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 151 0x97 '' */
+ 0x60, /* 01100000 */
+ 0x30, /* 00110000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0x76, /* 01110110 */
+ 0x00, /* 00000000 */
+
+ /* 152 0x98 '' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7e, /* 01111110 */
+ 0x06, /* 00000110 */
+ 0xfc, /* 11111100 */
+
+ /* 153 0x99 '' */
+ 0xc6, /* 11000110 */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x6c, /* 01101100 */
+ 0x38, /* 00111000 */
+ 0x00, /* 00000000 */
+
+ /* 154 0x9a '' */
+ 0xc6, /* 11000110 */
+ 0x00, /* 00000000 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0xc6, /* 11000110 */
+ 0x7c, /* 01111100 */
+ 0x00, /* 00000000 */
+
+ /* 155 0x9b '' */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0xc0, /* 11000000 */
+ 0xc0, /* 11000000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 156 0x9c '' */
+ 0x38, /* 00111000 */
+ 0x6c, /* 01101100 */
+ 0x64, /* 01100100 */
+ 0xf0, /* 11110000 */
+ 0x60, /* 01100000 */
+ 0x66, /* 01100110 */
+ 0xfc, /* 11111100 */
+ 0x00, /* 00000000 */
+
+ /* 157 0x9d '' */
+ 0x66, /* 01100110 */
+ 0x66, /* 01100110 */
+ 0x3c, /* 00111100 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x7e, /* 01111110 */
+ 0x18, /* 00011000 */
+ 0x18, /* 00011000 */
+
+ /* 158 0x9e '' */
+ 0xf8, /* 11111000 */
+ 0xcc, /* 11001100 */
+ 0xcc, /* 11001100 */
+ 0xfa, /* 11111010 */
+ 0xc6, /* 11000110 */
+ 0xcf, /* 11001111 */
+ 0xc6, /* 11000110 */
+ 0xc7, /* 11000111 */
+
+ /* 159 0x9f '' */
+ 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 */
+
+};
diff --git a/wiringPi/gertboard.c b/devLib/gertboard.c
similarity index 68%
rename from wiringPi/gertboard.c
rename to devLib/gertboard.c
index a8795d3..5aeaef7 100644
--- a/wiringPi/gertboard.c
+++ b/devLib/gertboard.c
@@ -38,16 +38,17 @@
#include
#include
-#include "wiringPiSPI.h"
+#include
+#include
#include "gertboard.h"
// The A-D convertor won't run at more than 1MHz @ 3.3v
-#define SPI_ADC_SPEED 1000000
-#define SPI_DAC_SPEED 1000000
-#define SPI_A2D 0
-#define SPI_D2A 1
+#define SPI_ADC_SPEED 1000000
+#define SPI_DAC_SPEED 1000000
+#define SPI_A2D 0
+#define SPI_D2A 1
/*
@@ -57,7 +58,7 @@
*********************************************************************************
*/
-void gertboardAnalogWrite (int chan, int value)
+void gertboardAnalogWrite (const int chan, const int value)
{
uint8_t spiData [2] ;
uint8_t chanBits, dataBits ;
@@ -84,7 +85,7 @@ void gertboardAnalogWrite (int chan, int value)
*********************************************************************************
*/
-int gertboardAnalogRead (int chan)
+int gertboardAnalogRead (const int chan)
{
uint8_t spiData [2] ;
@@ -120,3 +121,44 @@ int gertboardSPISetup (void)
return 0 ;
}
+
+
+/*
+ * New wiringPi node extension methods.
+ *********************************************************************************
+ */
+
+static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan)
+{
+ return gertboardAnalogRead (chan - node->pinBase) ;
+}
+
+static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value)
+{
+ gertboardAnalogWrite (chan - node->pinBase, value) ;
+}
+
+
+/*
+ * gertboardAnalogSetup:
+ * Create a new wiringPi device node for the analog devices on the
+ * Gertboard. We create one node with 2 pins - each pin being read
+ * and write - although the operations actually go to different
+ * hardware devices.
+ *********************************************************************************
+ */
+
+int gertboardAnalogSetup (const int pinBase)
+{
+ struct wiringPiNodeStruct *node ;
+ int x ;
+
+ if (( x = gertboardSPISetup ()) != 0)
+ return x;
+
+ node = wiringPiNewNode (pinBase, 2) ;
+ node->analogRead = myAnalogRead ;
+ node->analogWrite = myAnalogWrite ;
+
+ return 0 ;
+}
diff --git a/wiringPi/gertboard.h b/devLib/gertboard.h
similarity index 86%
rename from wiringPi/gertboard.h
rename to devLib/gertboard.h
index 98fd1e7..3fa1919 100644
--- a/wiringPi/gertboard.h
+++ b/devLib/gertboard.h
@@ -30,10 +30,16 @@
extern "C" {
#endif
-extern void gertboardAnalogWrite (int chan, int value) ;
-extern int gertboardAnalogRead (int chan) ;
+// Old routines
+
+extern void gertboardAnalogWrite (const int chan, const int value) ;
+extern int gertboardAnalogRead (const int chan) ;
extern int gertboardSPISetup (void) ;
+// New
+
+extern int gertboardAnalogSetup (const int pinBase) ;
+
#ifdef __cplusplus
}
#endif
diff --git a/wiringPi/lcd.c b/devLib/lcd.c
similarity index 64%
rename from wiringPi/lcd.c
rename to devLib/lcd.c
index f123db2..6c0e474 100644
--- a/wiringPi/lcd.c
+++ b/devLib/lcd.c
@@ -26,29 +26,40 @@
#include
#include
-#include
#include
-#include "wiringPi.h"
+#include
+
#include "lcd.h"
-// Commands
+#ifndef TRUE
+# define TRUE (1==1)
+# define FALSE (1==2)
+#endif
+
+// HD44780U Commands
#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_ENTRY 0x04
-#define LCD_ON_OFF 0x08
+#define LCD_CTRL 0x08
#define LCD_CDSHIFT 0x10
#define LCD_FUNC 0x20
#define LCD_CGRAM 0x40
#define LCD_DGRAM 0x80
-#define LCD_ENTRY_SH 0x01
-#define LCD_ENTRY_ID 0x02
+// Bits in the entry register
+
+#define LCD_ENTRY_SH 0x01
+#define LCD_ENTRY_ID 0x02
+
+// Bits in the control register
-#define LCD_ON_OFF_B 0x01
-#define LCD_ON_OFF_C 0x02
-#define LCD_ON_OFF_D 0x04
+#define LCD_BLINK_CTRL 0x01
+#define LCD_CURSOR_CTRL 0x02
+#define LCD_DISPLAY_CTRL 0x04
+
+// Bits in the function register
#define LCD_FUNC_F 0x04
#define LCD_FUNC_N 0x08
@@ -58,13 +69,20 @@
struct lcdDataStruct
{
- uint8_t bits, rows, cols ;
- uint8_t rsPin, strbPin ;
- uint8_t dataPins [8] ;
+ int bits, rows, cols ;
+ int rsPin, strbPin ;
+ int dataPins [8] ;
+ int cx, cy ;
} ;
struct lcdDataStruct *lcds [MAX_LCDS] ;
+static int lcdControl ;
+
+// Row offsets
+
+static const int rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
+
/*
* strobe:
@@ -73,7 +91,7 @@ struct lcdDataStruct *lcds [MAX_LCDS] ;
*********************************************************************************
*/
-static void strobe (struct lcdDataStruct *lcd)
+static void strobe (const struct lcdDataStruct *lcd)
{
// Note timing changes for new version of delayMicroseconds ()
@@ -89,13 +107,14 @@ static void strobe (struct lcdDataStruct *lcd)
*********************************************************************************
*/
-static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
+static void sendDataCmd (const struct lcdDataStruct *lcd, unsigned char data)
{
- uint8_t i, d4 ;
+ register unsigned char myData = data ;
+ unsigned char i, d4 ;
if (lcd->bits == 4)
{
- d4 = (data >> 4) & 0x0F;
+ d4 = (myData >> 4) & 0x0F;
for (i = 0 ; i < 4 ; ++i)
{
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
@@ -103,7 +122,7 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
}
strobe (lcd) ;
- d4 = data & 0x0F ;
+ d4 = myData & 0x0F ;
for (i = 0 ; i < 4 ; ++i)
{
digitalWrite (lcd->dataPins [i], (d4 & 1)) ;
@@ -114,8 +133,8 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
{
for (i = 0 ; i < 8 ; ++i)
{
- digitalWrite (lcd->dataPins [i], (data & 1)) ;
- data >>= 1 ;
+ digitalWrite (lcd->dataPins [i], (myData & 1)) ;
+ myData >>= 1 ;
}
}
strobe (lcd) ;
@@ -128,22 +147,24 @@ static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data)
*********************************************************************************
*/
-static void putCommand (struct lcdDataStruct *lcd, uint8_t command)
+static void putCommand (const struct lcdDataStruct *lcd, unsigned char command)
{
digitalWrite (lcd->rsPin, 0) ;
sendDataCmd (lcd, command) ;
+ delay (2) ;
}
-static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
+static void put4Command (const struct lcdDataStruct *lcd, unsigned char command)
{
- uint8_t i ;
+ register unsigned char myCommand = command ;
+ register unsigned char i ;
digitalWrite (lcd->rsPin, 0) ;
for (i = 0 ; i < 4 ; ++i)
{
- digitalWrite (lcd->dataPins [i], (command & 1)) ;
- command >>= 1 ;
+ digitalWrite (lcd->dataPins [i], (myCommand & 1)) ;
+ myCommand >>= 1 ;
}
strobe (lcd) ;
}
@@ -151,7 +172,7 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
/*
*********************************************************************************
- * User Code below here
+ * User Callable code below here
*********************************************************************************
*/
@@ -161,16 +182,66 @@ static void put4Command (struct lcdDataStruct *lcd, uint8_t command)
*********************************************************************************
*/
-void lcdHome (int fd)
+void lcdHome (const int fd)
{
struct lcdDataStruct *lcd = lcds [fd] ;
+
putCommand (lcd, LCD_HOME) ;
+ lcd->cx = lcd->cy = 0 ;
+ delay (5) ;
}
-void lcdClear (int fd)
+void lcdClear (const int fd)
{
struct lcdDataStruct *lcd = lcds [fd] ;
+
putCommand (lcd, LCD_CLEAR) ;
+ putCommand (lcd, LCD_HOME) ;
+ lcd->cx = lcd->cy = 0 ;
+ delay (5) ;
+}
+
+
+/*
+ * lcdDisplay: lcdCursor: lcdCursorBlink:
+ * Turn the display, cursor, cursor blinking on/off
+ *********************************************************************************
+ */
+
+void lcdDisplay (const int fd, int state)
+{
+ struct lcdDataStruct *lcd = lcds [fd] ;
+
+ if (state)
+ lcdControl |= LCD_DISPLAY_CTRL ;
+ else
+ lcdControl &= ~LCD_DISPLAY_CTRL ;
+
+ putCommand (lcd, LCD_CTRL | lcdControl) ;
+}
+
+void lcdCursor (const int fd, int state)
+{
+ struct lcdDataStruct *lcd = lcds [fd] ;
+
+ if (state)
+ lcdControl |= LCD_CURSOR_CTRL ;
+ else
+ lcdControl &= ~LCD_CURSOR_CTRL ;
+
+ putCommand (lcd, LCD_CTRL | lcdControl) ;
+}
+
+void lcdCursorBlink (const int fd, int state)
+{
+ struct lcdDataStruct *lcd = lcds [fd] ;
+
+ if (state)
+ lcdControl |= LCD_BLINK_CTRL ;
+ else
+ lcdControl &= ~LCD_BLINK_CTRL ;
+
+ putCommand (lcd, LCD_CTRL | lcdControl) ;
}
@@ -180,40 +251,77 @@ void lcdClear (int fd)
*********************************************************************************
*/
-void lcdSendCommand (int fd, uint8_t command)
+void lcdSendCommand (const int fd, unsigned char command)
{
struct lcdDataStruct *lcd = lcds [fd] ;
putCommand (lcd, command) ;
}
+
/*
* lcdPosition:
- * Update the position of the cursor on the display
+ * Update the position of the cursor on the display.
+ * Ignore invalid locations.
*********************************************************************************
*/
-
-void lcdPosition (int fd, int x, int y)
+void lcdPosition (const int fd, int x, int y)
{
- static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ;
struct lcdDataStruct *lcd = lcds [fd] ;
+ if ((x > lcd->cols) || (x < 0))
+ return ;
+ if ((y > lcd->rows) || (y < 0))
+ return ;
+
putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ;
+
+ lcd->cx = x ;
+ lcd->cy = y ;
+}
+
+
+/*
+ * lcdCharDef:
+ * Defines a new character in the CGRAM
+ *********************************************************************************
+ */
+
+void lcdCharDef (const int fd, int index, unsigned char data [8])
+{
+ struct lcdDataStruct *lcd = lcds [fd] ;
+ int i ;
+
+ putCommand (lcd, LCD_CGRAM | ((index & 7) << 3)) ;
+
+ digitalWrite (lcd->rsPin, 1) ;
+ for (i = 0 ; i < 8 ; ++i)
+ sendDataCmd (lcd, data [i]) ;
}
/*
* lcdPutchar:
- * Send a data byte to be displayed on the display
+ * Send a data byte to be displayed on the display. We implement a very
+ * simple terminal here - with line wrapping, but no scrolling. Yet.
*********************************************************************************
*/
-void lcdPutchar (int fd, uint8_t data)
+void lcdPutchar (const int fd, unsigned char data)
{
struct lcdDataStruct *lcd = lcds [fd] ;
digitalWrite (lcd->rsPin, 1) ;
- sendDataCmd (lcd, data) ;
+ sendDataCmd (lcd, data) ;
+
+ if (++lcd->cx == lcd->cols)
+ {
+ lcd->cx = 0 ;
+ if (++lcd->cy == lcd->rows)
+ lcd->cy = 0 ;
+
+ putCommand (lcd, lcd->cx + (LCD_DGRAM | rowOff [lcd->cy])) ;
+ }
}
@@ -223,7 +331,7 @@ void lcdPutchar (int fd, uint8_t data)
*********************************************************************************
*/
-void lcdPuts (int fd, char *string)
+void lcdPuts (const int fd, const char *string)
{
while (*string)
lcdPutchar (fd, *string++) ;
@@ -236,7 +344,7 @@ void lcdPuts (int fd, char *string)
*********************************************************************************
*/
-void lcdPrintf (int fd, char *message, ...)
+void lcdPrintf (const int fd, const char *message, ...)
{
va_list argp ;
char buffer [1024] ;
@@ -256,12 +364,14 @@ void lcdPrintf (int fd, char *message, ...)
*********************************************************************************
*/
-int lcdInit (int rows, int cols, int bits, int rs, int strb,
- int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)
+int lcdInit (const int rows, const int cols, const int bits,
+ const int rs, const int strb,
+ const int d0, const int d1, const int d2, const int d3, const int d4,
+ const int d5, const int d6, const int d7)
{
static int initialised = 0 ;
- uint8_t func ;
+ unsigned char func ;
int i ;
int lcdFd = -1 ;
struct lcdDataStruct *lcd ;
@@ -298,7 +408,7 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
if (lcdFd == -1)
return -1 ;
- lcd = malloc (sizeof (struct lcdDataStruct)) ;
+ lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ;
if (lcd == NULL)
return -1 ;
@@ -307,6 +417,8 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
lcd->bits = 8 ; // For now - we'll set it properly later.
lcd->rows = rows ;
lcd->cols = cols ;
+ lcd->cx = 0 ;
+ lcd->cy = 0 ;
lcd->dataPins [0] = d0 ;
lcd->dataPins [1] = d1 ;
@@ -371,10 +483,13 @@ int lcdInit (int rows, int cols, int bits, int rs, int strb,
// Rest of the initialisation sequence
- putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ;
- putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ;
- putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ;
- putCommand (lcd, LCD_CLEAR) ; delay (5) ;
+ lcdDisplay (lcdFd, TRUE) ;
+ lcdCursor (lcdFd, FALSE) ;
+ lcdCursorBlink (lcdFd, FALSE) ;
+ lcdClear (lcdFd) ;
+
+ putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ;
+ putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ;
return lcdFd ;
}
diff --git a/devLib/lcd.h b/devLib/lcd.h
new file mode 100644
index 0000000..0a0e598
--- /dev/null
+++ b/devLib/lcd.h
@@ -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 .
+ ***********************************************************************
+ */
+
+#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
index 0000000..accd5c3
--- /dev/null
+++ b/devLib/lcd128x64.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#include
+
+#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
index 0000000..b448bbc
--- /dev/null
+++ b/devLib/lcd128x64.h
@@ -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 .
+ ***********************************************************************
+ */
+
+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
index 0000000..23eabf8
--- /dev/null
+++ b/devLib/maxdetect.c
@@ -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 .
+ ***********************************************************************
+ */
+
+//#include
+//#include
+//#include
+
+#include
+
+#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
index 0000000..a1fd742
--- /dev/null
+++ b/devLib/maxdetect.h
@@ -0,0 +1,40 @@
+/*
+ * maxdetect.h:
+ * Driver for the MaxDetect series sensors
+ *
+ * Copyright (c) 2013 Gordon Henderson.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wiringPi. If not, see .
+ ***********************************************************************
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Main generic function
+
+int maxDetectRead (const int pin, unsigned char buffer [4]) ;
+
+// Individual sensors
+
+int readRHT03 (const int pin, int *temp, int *rh) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/piFace.c b/devLib/piFace.c
new file mode 100644
index 0000000..4475c7f
--- /dev/null
+++ b/devLib/piFace.c
@@ -0,0 +1,112 @@
+/*
+ * piFace.:
+ * This file to interface with the PiFace peripheral device which
+ * has an MCP23S17 GPIO device connected via the SPI bus.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+
+#include
+#include
+
+#include
+#include
+
+#include "piFace.h"
+
+
+/*
+ * myDigitalWrite:
+ * Perform the digitalWrite function on the PiFace board
+ *********************************************************************************
+ */
+
+void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+ digitalWrite (pin + 16, value) ;
+}
+
+
+/*
+ * myDigitalRead:
+ * Perform the digitalRead function on the PiFace board
+ * With a slight twist - if we read from base + 8, then we
+ * read from the output latch...
+ *********************************************************************************
+ */
+
+int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+ if ((pin - node->pinBase) >= 8)
+ return digitalRead (pin + 8) ;
+ else
+ return digitalRead (pin + 16 + 8) ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ * Perform the pullUpDnControl function on the PiFace board
+ *********************************************************************************
+ */
+
+void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud)
+{
+ pullUpDnControl (pin + 16 + 8, pud) ;
+}
+
+
+/*
+ * piFaceSetup
+ * We're going to create an instance of the mcp23s17 here, then
+ * provide our own read/write routines on-top of it...
+ * The supplied PiFace code (in Pithon) treats it as an 8-bit device
+ * where you write the output ports and read the input port using the
+ * same pin numbers, however I have had a request to be able to read
+ * the output port, so reading 8..15 will read the output latch.
+ *********************************************************************************
+ */
+
+int piFaceSetup (const int pinBase)
+{
+ int i ;
+ struct wiringPiNodeStruct *node ;
+
+// Create an mcp23s17 instance:
+
+ mcp23s17Setup (pinBase + 16, 0, 0) ;
+
+// Set the direction bits
+
+ for (i = 0 ; i < 8 ; ++i)
+ {
+ pinMode (pinBase + 16 + i, OUTPUT) ; // Port A is the outputs
+ pinMode (pinBase + 16 + 8 + i, INPUT) ; // Port B inputs.
+ }
+
+ node = wiringPiNewNode (pinBase, 16) ;
+ node->digitalRead = myDigitalRead ;
+ node->digitalWrite = myDigitalWrite ;
+ node->pullUpDnControl = myPullUpDnControl ;
+
+ return 0 ;
+}
diff --git a/devLib/piFace.h b/devLib/piFace.h
new file mode 100644
index 0000000..4965314
--- /dev/null
+++ b/devLib/piFace.h
@@ -0,0 +1,32 @@
+/*
+ * piFace.h:
+ * Control the PiFace Interface board for the Raspberry Pi
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wiringPi. If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int piFaceSetup (const int pinBase) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c
new file mode 100644
index 0000000..1b1c0dd
--- /dev/null
+++ b/devLib/piFaceOld.c
@@ -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 .
+ ***********************************************************************
+ */
+
+
+#include
+#include
+
+#include
+#include
+
+#include "../wiringPi/mcp23x0817.h"
+
+#include "piFace.h"
+
+#define PIFACE_SPEED 4000000
+#define PIFACE_DEVNO 0
+
+
+
+/*
+ * writeByte:
+ * Write a byte to a register on the MCP23S17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static void writeByte (uint8_t reg, uint8_t data)
+{
+ uint8_t spiData [4] ;
+
+ spiData [0] = CMD_WRITE ;
+ spiData [1] = reg ;
+ spiData [2] = data ;
+
+ wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ;
+}
+
+/*
+ * readByte:
+ * Read a byte from a register on the MCP23S17 on the SPI bus.
+ *********************************************************************************
+ */
+
+static uint8_t readByte (uint8_t reg)
+{
+ uint8_t spiData [4] ;
+
+ spiData [0] = CMD_READ ;
+ spiData [1] = reg ;
+
+ wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ;
+
+ return spiData [2] ;
+}
+
+
+/*
+ * myDigitalWrite:
+ * Perform the digitalWrite function on the PiFace board
+ *********************************************************************************
+ */
+
+void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
+{
+ uint8_t mask, old ;
+
+ pin -= node->pinBase ;
+ mask = 1 << pin ;
+ old = readByte (MCP23x17_GPIOA) ;
+
+ if (value == 0)
+ old &= (~mask) ;
+ else
+ old |= mask ;
+
+ writeByte (MCP23x17_GPIOA, old) ;
+}
+
+
+/*
+ * myDigitalRead:
+ * Perform the digitalRead function on the PiFace board
+ *********************************************************************************
+ */
+
+int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
+{
+ uint8_t mask, reg ;
+
+ mask = 1 << ((pin - node->pinBase) & 7) ;
+
+ if (pin < 8)
+ reg = MCP23x17_GPIOB ; // Input regsiter
+ else
+ reg = MCP23x17_OLATA ; // Output latch regsiter
+
+ if ((readByte (reg) & mask) != 0)
+ return HIGH ;
+ else
+ return LOW ;
+}
+
+
+/*
+ * myPullUpDnControl:
+ * Perform the pullUpDnControl function on the PiFace board
+ *********************************************************************************
+ */
+
+void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud)
+{
+ uint8_t mask, old ;
+
+ mask = 1 << (pin - node->pinBase) ;
+ old = readByte (MCP23x17_GPPUB) ;
+
+ if (pud == 0)
+ old &= (~mask) ;
+ else
+ old |= mask ;
+
+ writeByte (MCP23x17_GPPUB, old) ;
+}
+
+
+/*
+ * piFaceSetup
+ * Setup the SPI interface and initialise the MCP23S17 chip
+ * We create one node with 16 pins - each if the first 8 pins being read
+ * and write - although the operations actually go to different
+ * hardware ports. The top 8 let you read the state of the output register.
+ *********************************************************************************
+ */
+
+int piFaceSetup (const int pinBase)
+{
+ int x ;
+ struct wiringPiNodeStruct *node ;
+
+ if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0)
+ return x ;
+
+// Setup the MCP23S17
+
+ writeByte (MCP23x17_IOCON, IOCON_INIT) ;
+ writeByte (MCP23x17_IODIRA, 0x00) ; // Port A -> Outputs
+ writeByte (MCP23x17_IODIRB, 0xFF) ; // Port B -> Inputs
+
+ node = wiringPiNewNode (pinBase, 16) ;
+ node->digitalRead = myDigitalRead ;
+ node->digitalWrite = myDigitalWrite ;
+ node->pullUpDnControl = myPullUpDnControl ;
+
+ return 0 ;
+}
diff --git a/wiringPi/piNes.c b/devLib/piNes.c
similarity index 100%
rename from wiringPi/piNes.c
rename to devLib/piNes.c
diff --git a/wiringPi/piNes.h b/devLib/piNes.h
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
index 0000000..8797e49
--- /dev/null
+++ b/examples/Gertboard/7segments.c
@@ -0,0 +1,221 @@
+/*
+ * 7segments.c:
+ * Simple test program to see if we can drive a 7-segment LED
+ * display using the GPIO and little else on the Raspberry Pi
+ *
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#undef PHOTO_HACK
+
+#include
+
+#include
+#include
+#include
+#include
+
+/*
+ * Segment mapping
+ *
+ * --a--
+ * | |
+ * f b
+ * | |
+ * --g--
+ * | |
+ * e c
+ * | |
+ * --d-- p
+ */
+
+// GPIO Pin Mapping
+
+static int digits [6] = { 7, 11, 10, 13, 12, 14 } ;
+static int segments [7] = { 6, 5, 4, 3, 2, 1, 0 } ;
+
+
+static const int segmentDigits [] =
+{
+// a b c d e f g Segments
+// 6 5 4 3 2 1 0, // wiringPi pin No.
+
+ 1, 1, 1, 1, 1, 1, 0, // 0
+ 0, 1, 1, 0, 0, 0, 0, // 1
+ 1, 1, 0, 1, 1, 0, 1, // 2
+ 1, 1, 1, 1, 0, 0, 1, // 3
+ 0, 1, 1, 0, 0, 1, 1, // 4
+ 1, 0, 1, 1, 0, 1, 1, // 5
+ 1, 0, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 0, 0, 0, 0, // 7
+ 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 0, 1, 1, // 9
+ 1, 1, 1, 0, 1, 1, 1, // A
+ 0, 0, 1, 1, 1, 1, 1, // b
+ 1, 0, 0, 1, 1, 1, 0, // C
+ 0, 1, 1, 1, 1, 0, 1, // d
+ 1, 0, 0, 1, 1, 1, 1, // E
+ 1, 0, 0, 0, 1, 1, 1, // F
+ 0, 0, 0, 0, 0, 0, 0, // blank
+} ;
+
+
+// display:
+// A global variable which is written to by the main program and
+// read from by the thread that updates the display. Only the first
+// 6 characters are used.
+
+char display [8] ;
+
+
+/*
+ * displayDigits:
+ * This is our thread that's run concurrently with the main program.
+ * Essentially sit in a loop, parsing and displaying the data held in
+ * the "display" global.
+ *********************************************************************************
+ */
+
+PI_THREAD (displayDigits)
+{
+ int digit, segment ;
+ int index, d, segVal ;
+
+ piHiPri (50) ;
+
+ for (;;)
+ {
+ for (digit = 0 ; digit < 6 ; ++digit)
+ {
+ for (segment = 0 ; segment < 7 ; ++segment)
+ {
+ d = toupper (display [digit]) ;
+ /**/ if ((d >= '0') && (d <= '9')) // Digit
+ index = d - '0' ;
+ else if ((d >= 'A') && (d <= 'F')) // Hex
+ index = d - 'A' + 10 ;
+ else
+ index = 16 ; // Blank
+
+ segVal = segmentDigits [index * 7 + segment] ;
+
+ digitalWrite (segments [segment], segVal) ;
+ }
+ digitalWrite (digits [digit], 1) ;
+ delay (2) ;
+ digitalWrite (digits [digit], 0) ;
+ }
+ }
+}
+
+
+/*
+ * setup:
+ * Initialise the hardware and start the thread
+ *********************************************************************************
+ */
+
+void setup (void)
+{
+ int i, c ;
+
+ wiringPiSetup () ;
+
+// 7 segments
+
+ for (i = 0 ; i < 7 ; ++i)
+ { digitalWrite (segments [i], 0) ; pinMode (segments [i], OUTPUT) ; }
+
+// 6 digits
+
+ for (i = 0 ; i < 6 ; ++i)
+ { digitalWrite (digits [i], 0) ; pinMode (digits [i], OUTPUT) ; }
+
+ strcpy (display, " ") ;
+ piThreadCreate (displayDigits) ;
+ delay (10) ; // Just to make sure it's started
+
+// Quick countdown LED test sort of thing
+
+ c = 999999 ;
+ for (i = 0 ; i < 10 ; ++i)
+ {
+ sprintf (display, "%06d", c) ;
+ delay (400) ;
+ c -= 111111 ;
+ }
+
+ strcpy (display, " ") ;
+ delay (400) ;
+
+#ifdef PHOTO_HACK
+ sprintf (display, "%s", "123456") ;
+ for (;;)
+ delay (1000) ;
+#endif
+
+}
+
+
+/*
+ * teenager:
+ * No explanation needed. (Nor one given!)
+ *********************************************************************************
+ */
+
+void teenager (void)
+{
+ char *message = " feedbeef babe cafe b00b " ;
+ int i ;
+
+ for (i = 0 ; i < strlen (message) - 4 ; ++i)
+ {
+ strncpy (display, &message [i], 6) ;
+ delay (200) ;
+ }
+ delay (1000) ;
+ for (i = 0 ; i < 3 ; ++i)
+ {
+ strcpy (display, " ") ;
+ delay (150) ;
+ strcpy (display, " b00b ") ;
+ delay (250) ;
+ }
+ delay (1000) ;
+ strcpy (display, " ") ;
+ delay (1000) ;
+}
+
+
+/*
+ *********************************************************************************
+ * main:
+ * Let the fun begin
+ *********************************************************************************
+ */
+
+int main (void)
+{
+ struct tm *t ;
+ time_t tim ;
+
+ setup () ;
+ teenager () ;
+
+ tim = time (NULL) ;
+ for (;;)
+ {
+ while (time (NULL) == tim)
+ delay (5) ;
+
+ tim = time (NULL) ;
+ t = localtime (&tim) ;
+
+ sprintf (display, "%02d%02d%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
+
+ delay (500) ;
+ }
+
+ return 0 ;
+}
diff --git a/examples/Gertboard/Makefile b/examples/Gertboard/Makefile
new file mode 100644
index 0000000..7569261
--- /dev/null
+++ b/examples/Gertboard/Makefile
@@ -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
index 0000000..5f76764
--- /dev/null
+++ b/examples/Gertboard/buttons.c
@@ -0,0 +1,83 @@
+/*
+ * buttons.c:
+ * Read the Gertboard buttons. Each one will act as an on/off
+ * tiggle switch for 3 different LEDs
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+// Array to keep track of our LEDs
+
+int leds [] = { 0, 0, 0 } ;
+
+// scanButton:
+// See if a button is pushed, if so, then flip that LED and
+// wait for the button to be let-go
+
+void scanButton (int button)
+{
+ if (digitalRead (button) == HIGH) // Low is pushed
+ return ;
+
+ leds [button] ^= 1 ; // Invert state
+ digitalWrite (4 + button, leds [button]) ;
+
+ while (digitalRead (button) == LOW) // Wait for release
+ delay (10) ;
+}
+
+int main (void)
+{
+ int i ;
+
+ printf ("Raspberry Pi Gertboard Button Test\n") ;
+
+ wiringPiSetup () ;
+
+// Setup the outputs:
+// Pins 3, 4, 5, 6 and 7 output:
+// We're not using 3 or 4, but make sure they're off anyway
+// (Using same hardware config as blink12.c)
+
+ for (i = 3 ; i < 8 ; ++i)
+ {
+ pinMode (i, OUTPUT) ;
+ digitalWrite (i, 0) ;
+ }
+
+// Setup the inputs
+
+ for (i = 0 ; i < 3 ; ++i)
+ {
+ pinMode (i, INPUT) ;
+ pullUpDnControl (i, PUD_UP) ;
+ leds [i] = 0 ;
+ }
+
+ for (;;)
+ {
+ for (i = 0 ; i < 3 ; ++i)
+ scanButton (i) ;
+ delay (1) ;
+ }
+}
diff --git a/examples/gertboard.c b/examples/Gertboard/gertboard.c
similarity index 61%
rename from examples/gertboard.c
rename to examples/Gertboard/gertboard.c
index f02e27d..aefcb12 100644
--- a/examples/gertboard.c
+++ b/examples/Gertboard/gertboard.c
@@ -6,8 +6,8 @@
* D/A port 0 jumpered to A/D port 0.
*
* We output a sine wave on D/A port 0 and sample A/D port 0. We then
- * copy this value to D/A port 1 and use a 'scope on both D/A ports
- * to check all's well.
+ * plot the input value on the terminal as a sort of vertical scrolling
+ * oscilloscipe.
*
* Copyright (c) 2012-2013 Gordon Henderson.
***********************************************************************
@@ -30,11 +30,13 @@
*/
#include
-#include
+#include
+#include
#include
-#define B_SIZE 200
-#undef DO_TIMING
+// Gertboard D to A is an 8-bit unit.
+
+#define B_SIZE 256
#include
#include
@@ -42,23 +44,28 @@
int main (void)
{
double angle ;
- int i ;
- uint32_t x1 ;
+ int i, inputValue ;
int buffer [B_SIZE] ;
+ int cols ;
+ struct winsize w ;
-#ifdef DO_TIMING
- unsigned int now, then ;
-#endif
printf ("Raspberry Pi Gertboard SPI test program\n") ;
+ printf ("=======================================\n") ;
+
+ ioctl (fileno (stdin), TIOCGWINSZ, &w);
+ cols = w.ws_col - 2 ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+// (or want) to run as root
+
+ wiringPiSetupSys () ;
- if (wiringPiSetupSys () < 0)
- return -1 ;
+// Initialise the Gertboard analog hardware at pin 100
- if (gertboardSPISetup () < 0)
- return 1 ;
+ gertboardAnalogSetup (100) ;
-// Generate a Sine Wave
+// Generate a Sine Wave and store in our buffer
for (i = 0 ; i < B_SIZE ; ++i)
{
@@ -66,28 +73,23 @@ int main (void)
buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ;
}
+// Loop, output the sine wave on analog out port 0, read it into A-D port 0
+// and display it on the screen
for (;;)
{
-#ifdef DO_TIMING
- then = millis () ;
-#endif
-
for (i = 0 ; i < B_SIZE ; ++i)
{
- gertboardAnalogWrite (0, buffer [i]) ;
+ analogWrite (100, buffer [i]) ;
-#ifndef DO_TIMING
- x1 = gertboardAnalogRead (0) ;
- gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A
-#endif
- }
+ inputValue = analogRead (100) ;
-#ifdef DO_TIMING
- now = millis () ;
- printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ;
- printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ;
-#endif
+// We don't need to wory about the scale or sign - the analog hardware is
+// a 10-bit value, so 0-1023. Just scale this to our terminal
+
+ printf ("%*s\n", (inputValue * cols) / 1023, "*") ;
+ delay (2) ;
+ }
}
return 0 ;
diff --git a/examples/Gertboard/record.c b/examples/Gertboard/record.c
new file mode 100644
index 0000000..71d8718
--- /dev/null
+++ b/examples/Gertboard/record.c
@@ -0,0 +1,60 @@
+/*
+ * record.c:
+ * Record some audio via the Gertboard
+ *
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#include
+#include
+
+#define B_SIZE 40000
+
+int main ()
+{
+ int i ;
+ struct timeval tStart, tEnd, tTaken ;
+ unsigned char buffer [B_SIZE] ;
+
+ printf ("\n") ;
+ printf ("Gertboard demo: Recorder\n") ;
+ printf ("========================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+// (or want) to run as root
+
+ wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+ gertboardAnalogSetup (100) ;
+
+ gettimeofday (&tStart, NULL) ;
+
+ for (i = 0 ; i < B_SIZE ; ++i)
+ buffer [i] = analogRead (100) >> 2 ;
+
+ gettimeofday (&tEnd, NULL) ;
+
+ timersub (&tEnd, &tStart, &tTaken) ;
+
+ printf ("Time taken for %d reads: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ;
+
+ gettimeofday (&tStart, NULL) ;
+
+ for (i = 0 ; i < B_SIZE ; ++i)
+ analogWrite (100, buffer [i]) ;
+
+ gettimeofday (&tEnd, NULL) ;
+
+ timersub (&tEnd, &tStart, &tTaken) ;
+
+ printf ("Time taken for %d writes: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ;
+
+ return 0 ;
+}
+
diff --git a/examples/Gertboard/temperature.c b/examples/Gertboard/temperature.c
new file mode 100644
index 0000000..5985a12
--- /dev/null
+++ b/examples/Gertboard/temperature.c
@@ -0,0 +1,78 @@
+/*
+ * temperature.c:
+ * Demonstrate use of the Gertboard A to D converter to make
+ * a simple thermometer using the LM35.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+
+#include
+#include
+
+int main ()
+{
+ int x1, x2 ;
+ double v1, v2 ;
+
+ printf ("\n") ;
+ printf ("Gertboard demo: Simple Thermemeter\n") ;
+ printf ("==================================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+// (or want) to run as root
+
+ wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+ gertboardAnalogSetup (100) ;
+
+ printf ("\n") ;
+ printf ("| Channel 0 | Channel 1 | Temperature 1 | Temperature 2 |\n") ;
+
+ for (;;)
+ {
+
+// Read the 2 channels:
+
+ x1 = analogRead (100) ;
+ x2 = analogRead (101) ;
+
+// Convert to a voltage:
+
+ v1 = (double)x1 / 1023.0 * 3.3 ;
+ v2 = (double)x2 / 1023.0 * 3.3 ;
+
+// Print
+
+ printf ("| %6.3f | %6.3f |", v1, v2) ;
+
+// Print Temperature of both channels by converting the LM35 reading
+// to a temperature. Fortunately these are easy: 0.01 volts per C.
+
+ printf (" %4.1f | %4.1f |\r", v1 * 100.0, v2 * 100.0) ;
+ fflush (stdout) ;
+ }
+
+ return 0 ;
+}
+
diff --git a/examples/Gertboard/voltmeter.c b/examples/Gertboard/voltmeter.c
new file mode 100644
index 0000000..c4d2113
--- /dev/null
+++ b/examples/Gertboard/voltmeter.c
@@ -0,0 +1,73 @@
+/*
+ * voltmeter.c:
+ * Demonstrate use of the Gertboard A to D converter to make
+ * a simple voltmeter.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+
+#include
+#include
+
+int main ()
+{
+ int x1, x2 ;
+ double v1, v2 ;
+
+ printf ("\n") ;
+ printf ("Gertboard demo: Simple Voltmeters\n") ;
+ printf ("=================================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+// (or want) to run as root
+
+ wiringPiSetupSys () ;
+
+// Initialise the Gertboard analog hardware at pin 100
+
+ gertboardAnalogSetup (100) ;
+
+ printf ("\n") ;
+ printf ("| Channel 0 | Channel 1 |\n") ;
+
+ for (;;)
+ {
+
+// Read the 2 channels:
+
+ x1 = analogRead (100) ;
+ x2 = analogRead (101) ;
+
+// Convert to a voltage:
+
+ v1 = (double)x1 / 1023.0 * 3.3 ;
+ v2 = (double)x2 / 1023.0 * 3.3 ;
+
+// Print
+
+ printf ("| %6.3f | %6.3f |\r", v1, v2) ;
+ fflush (stdout) ;
+ }
+
+ return 0 ;
+}
+
diff --git a/examples/Gertboard/vumeter.c b/examples/Gertboard/vumeter.c
new file mode 100644
index 0000000..9643ace
--- /dev/null
+++ b/examples/Gertboard/vumeter.c
@@ -0,0 +1,152 @@
+/*
+ * vumeter.c:
+ * Simple VU meter
+ *
+ * Heres the theory:
+ * We will sample at 4000 samples/sec and put the data into a
+ * low-pass filter with a depth of 1000 samples. This will give
+ * us 1/4 a second of lag on the signal, but I think it might
+ * produce a more pleasing output.
+ *
+ * The input of the microphone should be at mid-pont with no
+ * sound input, but we might have to sample that too, to get
+ * our reference zero...
+ *
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#ifndef TRUE
+#define TRUE (1==1)
+#define FALSE (!TRUE)
+#endif
+
+#define B_SIZE 1000
+#define S_SIZE 128
+
+static int buffer [B_SIZE] ;
+static int bPtr = 0 ;
+
+/*
+ * ledPercent:
+ * Output the given value as a percentage on the LEDs
+ *********************************************************************************
+ */
+
+static void ledPercent (int percent)
+{
+ unsigned int output = 0 ;
+
+ if (percent > 11) output |= 0x01 ;
+ if (percent > 22) output |= 0x02 ;
+ if (percent > 33) output |= 0x04 ;
+ if (percent > 44) output |= 0x08 ;
+ if (percent > 55) output |= 0x10 ;
+ if (percent > 66) output |= 0x20 ;
+ if (percent > 77) output |= 0x40 ;
+ if (percent > 88) output |= 0x80 ;
+
+ digitalWriteByte (output) ;
+}
+
+static unsigned int tPeriod, tNextSampleTime ;
+
+/*
+ * sample:
+ * Get a sample from the Gertboard. If not enough time has elapsed
+ * since the last sample, then wait...
+ *********************************************************************************
+ */
+
+static void sample (void)
+{
+ unsigned int tFuture ;
+
+// Calculate the future sample time
+
+ tFuture = tPeriod + tNextSampleTime ;
+
+// Wait until the next sample time
+
+ while (micros () < tNextSampleTime)
+ ;
+
+ buffer [bPtr] = gertboardAnalogRead (0) ;
+
+ tNextSampleTime = tFuture ;
+}
+
+
+int main ()
+{
+ int quietLevel, min, max ;
+ int i, sum ;
+ unsigned int tStart, tEnd ;
+
+ printf ("\n") ;
+ printf ("Gertboard demo: VU Meter\n") ;
+ printf ("========================\n") ;
+
+ wiringPiSetup () ;
+ gertboardSPISetup () ;
+
+ ledPercent (0) ;
+ for (i = 0 ; i < 8 ; ++i)
+ pinMode (i, OUTPUT) ;
+
+ for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
+ buffer [bPtr] = 99 ;
+
+ tPeriod = 1000000 / 1000 ;
+
+ printf ("Shhhh.... ") ; fflush (stdout) ;
+ delay (1000) ;
+ printf ("Sampling quiet... ") ; fflush (stdout) ;
+
+ tStart = micros () ;
+
+ tNextSampleTime = micros () ;
+ for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
+ sample () ;
+
+ tEnd = micros () ;
+
+ quietLevel = 0 ;
+ max = 0 ;
+ min = 1024 ;
+ for (i = 0 ; i < B_SIZE ; ++i)
+ {
+ quietLevel += buffer [i] ;
+ if (buffer [i] > max) max = buffer [i] ;
+ if (buffer [i] < min) min = buffer [i] ;
+ }
+ quietLevel /= B_SIZE ;
+
+ printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ;
+
+ printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ;
+
+ for (bPtr = 0 ;;)
+ {
+ sample () ;
+ sum = 0 ;
+ for (i = 0 ; i < S_SIZE ; ++i)
+ sum += buffer [i] ;
+ sum /= S_SIZE ;
+ sum = abs (quietLevel - sum) ;
+ sum = (sum * 1000) / quietLevel ;
+ ledPercent (sum) ;
+ if (++bPtr > S_SIZE)
+ bPtr = 0 ;
+ }
+
+
+ return 0 ;
+}
diff --git a/examples/Makefile b/examples/Makefile
index defd510..f1e1725 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -30,15 +30,19 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
-LDLIBS = -lwiringPi -lpthread -lm
+LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm
# Should not alter anything below this line
###############################################################################
-SRC = blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c \
- piface.c gertboard.c nes.c \
- pwm.c tone.c servo.c \
- delayTest.c serialRead.c serialTest.c okLed.c
+SRC = blink.c blink8.c blink12.c \
+ pwm.c \
+ speed.c wfi.c isr.c isr-osc.c \
+ lcd.c clock.c \
+ nes.c \
+ softPwm.c softTone.c \
+ delayTest.c serialRead.c serialTest.c okLed.c ds1302.c \
+ rht03.c
OBJ = $(SRC:.c=.o)
@@ -55,13 +59,13 @@ blink: blink.o
@echo [link]
@$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS)
-test1: test1.o
+blink8: blink8.o
@echo [link]
- @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS)
-
-test2: test2.o
+ @$(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS)
+
+blink12: blink12.o
@echo [link]
- @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS)
+ @$(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS)
speed: speed.o
@echo [link]
@@ -71,6 +75,10 @@ lcd: lcd.o
@echo [link]
@$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS)
+clock: clock.o
+ @echo [link]
+ @$(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS)
+
wfi: wfi.o
@echo [link]
@$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS)
@@ -83,22 +91,26 @@ isr-osc: isr-osc.o
@echo [link]
@$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS)
-piface: piface.o
- @echo [link]
- @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS)
-
-gertboard: gertboard.o
- @echo [link]
- @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS)
-
nes: nes.o
@echo [link]
@$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS)
+rht03: rht03.o
+ @echo [link]
+ @$(CC) -o $@ rht03.o $(LDFLAGS) $(LDLIBS)
+
pwm: pwm.o
@echo [link]
@$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS)
+softPwm: softPwm.o
+ @echo [link]
+ @$(CC) -o $@ softPwm.o $(LDFLAGS) $(LDLIBS)
+
+softTone: softTone.o
+ @echo [link]
+ @$(CC) -o $@ softTone.o $(LDFLAGS) $(LDLIBS)
+
delayTest: delayTest.o
@echo [link]
@$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS)
@@ -119,9 +131,9 @@ tone: tone.o
@echo [link]
@$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS)
-servo: servo.o
+ds1302: ds1302.o
@echo [link]
- @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS)
+ @$(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS)
.c.o:
@@ -129,7 +141,8 @@ servo: servo.o
@$(CC) -c $(CFLAGS) $< -o $@
clean:
- rm -f $(OBJ) *~ core tags $(BINS)
+ @echo "[Clean]"
+ @rm -f $(OBJ) *~ core tags $(BINS)
tags: $(SRC)
@echo [ctags]
diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile
new file mode 100644
index 0000000..0bde334
--- /dev/null
+++ b/examples/PiFace/Makefile
@@ -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 .
+#################################################################################
+
+
+#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
index 0000000..ffb8a2e
--- /dev/null
+++ b/examples/PiFace/blink.c
@@ -0,0 +1,59 @@
+/*
+ * blink.c:
+ * Simple "blink" test for the PiFace interface board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+
+#include
+#include
+
+// Use 200 as the pin-base for the PiFace board, and pick a pin
+// for the LED that's not connected to a relay
+
+#define PIFACE 200
+#define LED (PIFACE+2)
+
+int main (int argc, char *argv [])
+{
+ printf ("Raspberry Pi PiFace Blink\n") ;
+ printf ("=========================\n") ;
+
+// Always initialise wiringPi. Use wiringPiSys() if you don't need
+// (or want) to run as root
+
+ wiringPiSetupSys () ;
+
+// Setup the PiFace board
+
+ piFaceSetup (PIFACE) ;
+
+ for (;;)
+ {
+ digitalWrite (LED, HIGH) ; // On
+ delay (500) ; // mS
+ digitalWrite (LED, LOW) ; // Off
+ delay (500) ;
+ }
+
+ return 0 ;
+}
diff --git a/examples/PiFace/buttons.c b/examples/PiFace/buttons.c
new file mode 100644
index 0000000..147a4bd
--- /dev/null
+++ b/examples/PiFace/buttons.c
@@ -0,0 +1,103 @@
+/*
+ * buttons.c:
+ * Simple test for the PiFace interface board.
+ *
+ * Read the buttons and output the same to the LEDs
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+
+#include
+#include
+
+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
index 0000000..4f08a6f
--- /dev/null
+++ b/examples/PiFace/ladder.c
@@ -0,0 +1,337 @@
+/*
+ * ladder.c:
+ *
+ * Gordon Henderson, June 2012
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#ifndef TRUE
+# define TRUE (1==1)
+# define FALSE (1==2)
+#endif
+
+#undef DEBUG
+
+#define NUM_LEDS 8
+
+
+// Map the LEDs to the hardware pins
+// using PiFace pin numbers here
+
+#define PIFACE 200
+
+const int ledMap [NUM_LEDS] =
+{
+// 0, 1, 2, 3, 4, 5, 6, 7, 8
+ 200, 201, 202, 203, 204, 205, 206, 207
+} ;
+
+
+// Some constants for our circuit simulation
+
+const double vBatt = 9.0 ; // Volts (ie. a PP3)
+const double capacitor = 0.001 ; // 1000uF
+const double rCharge = 2200.0 ; // ohms
+const double rDischarge = 68000.0 ; // ohms
+const double timeInc = 0.01 ; // Seconds
+
+double vCharge, vCap, vCapLast ;
+
+
+
+/*
+ * setup:
+ * Program the GPIO correctly and initialise the lamps
+ ***********************************************************************
+ */
+
+void setup (void)
+{
+ int i ;
+
+ wiringPiSetupSys () ;
+
+ if (piFaceSetup (200) == -1)
+ exit (1) ;
+
+// Enable internal pull-ups
+
+ for (i = 0 ; i < 8 ; ++i)
+ pullUpDnControl (PIFACE + i, PUD_UP) ;
+
+// Calculate the actual charging voltage - standard calculation of
+// vCharge = r2 / (r1 + r2) * vBatt
+//
+//
+// -----+--- vBatt
+// |
+// R1
+// |
+// +---+---- vCharge
+// | |
+// R2 C
+// | |
+// -----+---+-----
+
+ vCharge = rDischarge / (rCharge + rDischarge) * vBatt ;
+
+// Start with no charge
+
+ vCap = vCapLast = 0.0 ;
+}
+
+
+/*
+ * introLeds
+ * Put a little pattern on the LEDs to start with
+ *********************************************************************************
+ */
+
+void introLeds (void)
+{
+ int i, j ;
+
+
+ printf ("Pi Ladder\n") ;
+ printf ("=========\n\n") ;
+ printf (" vBatt: %6.2f volts\n", vBatt) ;
+ printf (" rCharge: %6.0f ohms\n", rCharge) ;
+ printf (" rDischarge: %6.0f ohms\n", rDischarge) ;
+ printf (" vCharge: %6.2f volts\n", vCharge) ;
+ printf (" capacitor: %6.0f uF\n", capacitor * 1000.0) ;
+
+// Flash 3 times:
+
+ for (j = 0 ; j < 3 ; ++j)
+ {
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 1) ;
+ delay (500) ;
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 0) ;
+ delay (100) ;
+ }
+
+// All On
+
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 1) ;
+ delay (500) ;
+
+// Countdown...
+
+ for (i = NUM_LEDS - 1 ; i >= 0 ; --i)
+ {
+ digitalWrite (ledMap [i], 0) ;
+ delay (100) ;
+ }
+ delay (500) ;
+}
+
+
+/*
+ * winningLeds
+ * Put a little pattern on the LEDs to start with
+ *********************************************************************************
+ */
+
+void winningLeds (void)
+{
+ int i, j ;
+
+// Flash 3 times:
+
+ for (j = 0 ; j < 3 ; ++j)
+ {
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 1) ;
+ delay (500) ;
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 0) ;
+ delay (100) ;
+ }
+
+// All On
+
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 1) ;
+ delay (500) ;
+
+// Countup...
+
+ for (i = 0 ; i < NUM_LEDS ; ++i)
+ {
+ digitalWrite (ledMap [i], 0) ;
+ delay (100) ;
+ }
+ delay (500) ;
+}
+
+
+/*
+ * chargeCapacitor: dischargeCapacitor:
+ * Add or remove charge to the capacitor.
+ * Standard capacitor formulae.
+ *********************************************************************************
+ */
+
+void chargeCapacitor (void)
+{
+ vCap = (vCapLast - vCharge) *
+ exp (- timeInc / (rCharge * capacitor)) + vCharge ;
+
+#ifdef DEBUG
+ printf ("+vCap: %7.4f\n", vCap) ;
+#endif
+
+ vCapLast = vCap ;
+}
+
+void dischargeCapacitor (void)
+{
+ vCap = vCapLast *
+ exp (- timeInc / (rDischarge * capacitor)) ;
+
+#ifdef DEBUG
+ printf ("-vCap: %7.4f\n", vCap) ;
+#endif
+
+ vCapLast = vCap ;
+}
+
+
+/*
+ * ledBargraph:
+ * Output the supplied number as a bargraph on the LEDs
+ *********************************************************************************
+ */
+
+void ledBargraph (double value, int topLedOn)
+{
+ int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ;
+ int i ;
+
+ if (topLed > NUM_LEDS)
+ topLed = NUM_LEDS ;
+
+ if (!topLedOn)
+ --topLed ;
+
+ for (i = 0 ; i < topLed ; ++i)
+ digitalWrite (ledMap [i], 1) ;
+
+ for (i = topLed ; i < NUM_LEDS ; ++i)
+ digitalWrite (ledMap [i], 0) ;
+}
+
+
+/*
+ * ledOnAction:
+ * Make sure the leading LED is on and check the button
+ *********************************************************************************
+ */
+
+void ledOnAction (void)
+{
+ if (digitalRead (PIFACE) == LOW)
+ {
+ chargeCapacitor () ;
+ ledBargraph (vCap, TRUE) ;
+ }
+}
+
+
+/*
+ * ledOffAction:
+ * Make sure the leading LED is off and check the button
+ *********************************************************************************
+ */
+
+void ledOffAction (void)
+{
+ dischargeCapacitor () ;
+
+// Are we still pushing the button?
+
+ if (digitalRead (PIFACE) == LOW)
+ {
+ vCap = vCapLast = 0.0 ;
+ ledBargraph (vCap, FALSE) ;
+
+// Wait until we release the button
+
+ while (digitalRead (PIFACE) == LOW)
+ delay (10) ;
+ }
+}
+
+
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
+
+int main (void)
+{
+ unsigned int then, ledOnTime, ledOffTime ;
+ unsigned int ourDelay = (int)(1000.0 * timeInc) ;
+
+ setup () ;
+ introLeds () ;
+
+// Setup the LED times - TODO reduce the ON time as the game progresses
+
+ ledOnTime = 1000 ;
+ ledOffTime = 1000 ;
+
+// This is our Gate/Squarewave loop
+
+ for (;;)
+ {
+
+// LED ON:
+
+ (void)ledBargraph (vCap, TRUE) ;
+ then = millis () + ledOnTime ;
+ while (millis () < then)
+ {
+ ledOnAction () ;
+ delay (ourDelay) ;
+ }
+
+// Have we won yet?
+// We need vCap to be in the top NUM_LEDS of the vCharge
+
+ if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge)) // Woo hoo!
+ {
+ winningLeds () ;
+ while (digitalRead (PIFACE) == HIGH)
+ delay (10) ;
+ while (digitalRead (PIFACE) == LOW)
+ delay (10) ;
+ vCap = vCapLast = 0.0 ;
+ }
+
+// LED OFF:
+
+ (void)ledBargraph (vCap, FALSE) ;
+ then = millis () + ledOffTime ;
+ while (millis () < then)
+ {
+ ledOffAction () ;
+ delay (ourDelay) ;
+ }
+
+ }
+
+ return 0 ;
+}
diff --git a/examples/PiFace/metro.c b/examples/PiFace/metro.c
new file mode 100644
index 0000000..a4a8c1d
--- /dev/null
+++ b/examples/PiFace/metro.c
@@ -0,0 +1,111 @@
+/*
+ * metronome.c:
+ * Simple test for the PiFace interface board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#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 \n", argv [0]) ;
+ exit (1) ;
+ }
+
+ if (strcmp (argv [1], "a") == 0)
+ middleA () ;
+
+ bpm = atoi (argv [1]) ;
+
+ if ((bpm < 40) || (bpm > 208))
+ {
+ printf ("%s range is 40 through 208 beats per minute\n", argv [0]) ;
+ exit (1) ;
+ }
+
+ msPerBeat = 60000 / bpm ;
+
+// Main loop:
+// Put some random LED pairs up for a few seconds, then blank ...
+
+ for (;;)
+ {
+ end = millis () + msPerBeat ;
+
+ digitalWrite (PIFACE + 0, state) ;
+ digitalWrite (PIFACE + 1, state) ;
+
+ while (millis () < end)
+ delayMicroseconds (500) ;
+
+ state ^= 1 ;
+ }
+
+ return 0 ;
+}
diff --git a/examples/PiFace/motor.c b/examples/PiFace/motor.c
new file mode 100644
index 0000000..14f5539
--- /dev/null
+++ b/examples/PiFace/motor.c
@@ -0,0 +1,120 @@
+/*
+ * motor.c:
+ * Use the PiFace board to demonstrate an H bridge
+ * circuit via the 2 relays.
+ * Then add on an external transsitor to help with PWM.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+int outputs [2] = { 0,0 } ;
+
+#define PIFACE_BASE 200
+#define PWM_OUT_PIN 204
+#define PWM_UP 202
+#define PWM_DOWN 203
+
+void scanButton (int button)
+{
+ if (digitalRead (PIFACE_BASE + button) == LOW)
+ {
+ outputs [button] ^= 1 ;
+ digitalWrite (PIFACE_BASE + button, outputs [button]) ;
+ printf ("Button %d pushed - output now: %s\n",
+ button, (outputs [button] == 0) ? "Off" : "On") ;
+ }
+
+ while (digitalRead (PIFACE_BASE + button) == LOW)
+ delay (1) ;
+}
+
+
+int main (void)
+{
+ int pin, button ;
+ int pwmValue = 0 ;
+
+ printf ("Raspberry Pi PiFace - Motor control\n") ;
+ printf ("==================================\n") ;
+ printf ("\n") ;
+ printf (
+"This program is designed to be used with a motor connected to the relays\n"
+"in an H-Bridge type configuration with optional speeed control via PWM.\n"
+"\n"
+"Use the leftmost buttons to turn each relay on and off, and the rigthmost\n"
+"buttons to increase ot decrease the PWM output on the control pin (pin\n"
+"4)\n\n") ;
+
+ wiringPiSetup () ;
+ piFaceSetup (PIFACE_BASE) ;
+ softPwmCreate (PWM_OUT_PIN, 100, 100) ;
+
+// Enable internal pull-ups & start with all off
+
+ for (pin = 0 ; pin < 8 ; ++pin)
+ {
+ pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ;
+ digitalWrite (PIFACE_BASE + pin, 0) ;
+ }
+
+ for (;;)
+ {
+ for (button = 0 ; button < 2 ; ++button)
+ scanButton (button) ;
+
+ if (digitalRead (PWM_UP) == LOW)
+ {
+ pwmValue += 10 ;
+ if (pwmValue > 100)
+ pwmValue = 100 ;
+
+ softPwmWrite (PWM_OUT_PIN, pwmValue) ;
+ printf ("PWM -> %3d\n", pwmValue) ;
+
+ while (digitalRead (PWM_UP) == LOW)
+ delay (5) ;
+ }
+
+ if (digitalRead (PWM_DOWN) == LOW)
+ {
+ pwmValue -= 10 ;
+ if (pwmValue < 0)
+ pwmValue = 0 ;
+
+ softPwmWrite (PWM_OUT_PIN, pwmValue) ;
+ printf ("PWM -> %3d\n", pwmValue) ;
+
+ while (digitalRead (PWM_DOWN) == LOW)
+ delay (5) ;
+ }
+
+ delay (5) ;
+ }
+
+ return 0 ;
+}
diff --git a/examples/PiFace/reaction.c b/examples/PiFace/reaction.c
new file mode 100644
index 0000000..5084508
--- /dev/null
+++ b/examples/PiFace/reaction.c
@@ -0,0 +1,194 @@
+/*
+ * reaction.c:
+ * Simple test for the PiFace interface board.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+
+int outputs [4] = { 0,0,0,0 } ;
+
+#define PIFACE 200
+
+/*
+ * light:
+ * Light up the given LED - actually lights up a pair
+ *********************************************************************************
+ */
+
+void light (int led, int value)
+{
+ led *= 2 ;
+ digitalWrite (PIFACE + led + 0, value) ;
+ digitalWrite (PIFACE + led + 1, value) ;
+}
+
+/*
+ * lightAll:
+ * All On or Off
+ *********************************************************************************
+ */
+
+void lightAll (int onoff)
+{
+ light (0, onoff) ;
+ light (1, onoff) ;
+ light (2, onoff) ;
+ light (3, onoff) ;
+}
+
+
+/*
+ * waitForNoButtons:
+ * Wait for all buttons to be released
+ *********************************************************************************
+ */
+
+void waitForNoButtons (void)
+{
+ int i, button ;
+
+ for (;;)
+ {
+ button = 0 ;
+ for (i = 0 ; i < 4 ; ++i)
+ button += digitalRead (PIFACE + i) ;
+
+ if (button == 4)
+ break ;
+ }
+}
+
+
+void scanButton (int button)
+{
+ if (digitalRead (PIFACE + button) == LOW)
+ {
+ outputs [button] ^= 1 ;
+ digitalWrite (PIFACE + button, outputs [button]) ;
+ }
+
+ while (digitalRead (PIFACE + button) == LOW)
+ delay (1) ;
+}
+
+
+int main (void)
+{
+ int i, j ;
+ int led, button ;
+ unsigned int start, stop ;
+
+ printf ("Raspberry Pi PiFace Reaction Timer\n") ;
+ printf ("==================================\n") ;
+
+ if (piFaceSetup (PIFACE) == -1)
+ exit (1) ;
+
+// Enable internal pull-ups
+
+ for (i = 0 ; i < 8 ; ++i)
+ pullUpDnControl (PIFACE + i, PUD_UP) ;
+
+
+// Main game loop:
+// Put some random LED pairs up for a few seconds, then blank ...
+
+ for (;;)
+ {
+ printf ("Press any button to start ... \n") ; fflush (stdout) ;
+
+ for (;;)
+ {
+ led = rand () % 4 ;
+ light (led, 1) ;
+ delay (10) ;
+ light (led, 0) ;
+
+ button = 0 ;
+ for (j = 0 ; j < 4 ; ++j)
+ button += digitalRead (PIFACE + j) ;
+
+ if (button != 4)
+ break ;
+ }
+
+ waitForNoButtons () ;
+
+ printf ("Wait for it ... ") ; fflush (stdout) ;
+
+ led = rand () % 4 ;
+ delay (rand () % 500 + 1000) ;
+ light (led, 1) ;
+
+ start = millis () ;
+ for (button = -1 ; button == -1 ; )
+ {
+ for (j = 0 ; j < 4 ; ++j)
+ if (digitalRead (PIFACE + j) == 0) // Pushed
+ {
+ button = j ;
+ break ;
+ }
+ }
+ stop = millis () ;
+ button = 3 - button ; // Correct for the buttons/LEDs reversed
+
+ light (led, 0) ;
+
+ waitForNoButtons () ;
+
+ light (led, 1) ;
+
+ if (button == led)
+ {
+ printf ("You got it in %3d mS\n", stop - start) ;
+ }
+ else
+ {
+ printf ("Missed: You pushed %d - LED was %d\n", button, led) ;
+ for (;;)
+ {
+ light (button, 1) ;
+ delay (100) ;
+ light (button, 0) ;
+ delay (100) ;
+ i = 0 ;
+ for (j = 0 ; j < 4 ; ++j)
+ i += digitalRead (PIFACE + j) ;
+ if (i != 4)
+ break ;
+ }
+
+ waitForNoButtons () ;
+ }
+ light (led, 0) ;
+ delay (4000) ;
+ }
+
+ return 0 ;
+}
diff --git a/examples/blink.c b/examples/blink.c
index bb9f856..c27a20e 100644
--- a/examples/blink.c
+++ b/examples/blink.c
@@ -34,16 +34,14 @@ int main (void)
{
printf ("Raspberry Pi blink\n") ;
- if (wiringPiSetup () == -1)
- return 1 ;
-
+ wiringPiSetup () ;
pinMode (LED, OUTPUT) ;
for (;;)
{
- digitalWrite (LED, 1) ; // On
+ digitalWrite (LED, HIGH) ; // On
delay (500) ; // mS
- digitalWrite (LED, 0) ; // Off
+ digitalWrite (LED, LOW) ; // Off
delay (500) ;
}
return 0 ;
diff --git a/examples/test1.c b/examples/blink12.c
similarity index 70%
rename from examples/test1.c
rename to examples/blink12.c
index 4c75711..c9b3d50 100644
--- a/examples/test1.c
+++ b/examples/blink12.c
@@ -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.
***********************************************************************
@@ -24,17 +23,13 @@
***********************************************************************
*/
-#include
-
#include
-#include
-#include
-
+#include
// Simple sequencer data
// Triplets of LED, On/Off and delay
-uint8_t data [] =
+int data [] =
{
0, 1, 1,
1, 1, 1,
@@ -44,15 +39,23 @@ uint8_t data [] =
3, 0, 0, 5, 1, 1,
4, 0, 0, 6, 1, 1,
5, 0, 0, 7, 1, 1,
- 6, 0, 1,
- 7, 0, 1,
+ 6, 0, 0, 11, 1, 1,
+ 7, 0, 0, 10, 1, 1,
+ 11, 0, 0, 13, 1, 1,
+ 10, 0, 0, 12, 1, 1,
+ 13, 0, 1,
+ 12, 0, 1,
0, 0, 1, // Extra delay
// Back again
- 7, 1, 1,
- 6, 1, 1,
+ 12, 1, 1,
+ 13, 1, 1,
+ 12, 0, 0, 10, 1, 1,
+ 13, 0, 0, 11, 1, 1,
+ 10, 0, 0, 7, 1, 1,
+ 11, 0, 0, 6, 1, 1,
7, 0, 0, 5, 1, 1,
6, 0, 0, 4, 1, 1,
5, 0, 0, 3, 1, 1,
@@ -64,7 +67,7 @@ uint8_t data [] =
0, 0, 1, // Extra delay
- 9, 9, 9, // End marker
+ 0, 9, 0, // End marker
} ;
@@ -75,16 +78,17 @@ int main (void)
int dataPtr ;
int l, s, d ;
- printf ("Raspberry Pi wiringPi test program\n") ;
+ printf ("Raspberry Pi - 12-LED Sequence\n") ;
+ printf ("==============================\n") ;
+ printf ("\n") ;
+ printf ("Connect LEDs up to the first 8 GPIO pins, then pins 11, 10, 13, 12 in\n") ;
+ printf (" that order, then sit back and watch the show!\n") ;
- if (wiringPiSetup () == -1)
- exit (1) ;
+ wiringPiSetup () ;
- for (pin = 0 ; pin < 8 ; ++pin)
+ for (pin = 0 ; pin < 14 ; ++pin)
pinMode (pin, OUTPUT) ;
- pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor
-
dataPtr = 0 ;
for (;;)
@@ -93,18 +97,14 @@ int main (void)
s = data [dataPtr++] ; // State
d = data [dataPtr++] ; // Duration (10ths)
- if ((l + s + d) == 27)
+ if (s == 9) // 9 -> End Marker
{
dataPtr = 0 ;
continue ;
}
digitalWrite (l, s) ;
-
- if (digitalRead (8) == 0) // Pressed as our switch shorts to ground
- delay (d * 10) ; // Faster!
- else
- delay (d * 100) ;
+ delay (d * 100) ;
}
return 0 ;
diff --git a/examples/test2.c b/examples/blink8.c
similarity index 66%
rename from examples/test2.c
rename to examples/blink8.c
index 580591e..602d3c0 100644
--- a/examples/test2.c
+++ b/examples/blink8.c
@@ -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.
***********************************************************************
@@ -22,37 +23,35 @@
***********************************************************************
*/
-#include
-
#include
-#include
-#include
+#include
int main (void)
{
- int bright ;
+ int i, led ;
- printf ("Raspberry Pi wiringPi PWM test program\n") ;
+ printf ("Raspberry Pi - 8-LED Sequencer\n") ;
+ printf ("==============================\n") ;
+ printf ("\n") ;
+ printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ;
- if (wiringPiSetup () == -1)
- exit (1) ;
+ wiringPiSetup () ;
- pinMode (1, PWM_OUTPUT) ;
+ for (i = 0 ; i < 8 ; ++i)
+ pinMode (i, OUTPUT) ;
for (;;)
{
- for (bright = 0 ; bright < 1024 ; ++bright)
+ for (led = 0 ; led < 8 ; ++led)
{
- pwmWrite (1, bright) ;
- delay (1) ;
+ digitalWrite (led, 1) ;
+ delay (100) ;
}
- for (bright = 1023 ; bright >= 0 ; --bright)
+ for (led = 0 ; led < 8 ; ++led)
{
- pwmWrite (1, bright) ;
- delay (1) ;
+ digitalWrite (led, 0) ;
+ delay (100) ;
}
}
-
- return 0 ;
}
diff --git a/examples/clock.c b/examples/clock.c
new file mode 100644
index 0000000..9a53210
--- /dev/null
+++ b/examples/clock.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#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
index 0000000..f1e9e20
--- /dev/null
+++ b/examples/ds1302.c
@@ -0,0 +1,238 @@
+/*
+ * ds1302.c:
+ * Real Time clock
+ *
+ * Copyright (c) 2013 Gordon Henderson.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wiringPi. If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+// 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
index 03c5cdd..0000000
Binary files a/examples/gertboard.png and /dev/null differ
diff --git a/examples/isr.c b/examples/isr.c
index 2bef54a..abc6aec 100644
--- a/examples/isr.c
+++ b/examples/isr.c
@@ -38,16 +38,11 @@
#include
-// What GPIO input are we using?
-// This is a wiringPi pin number
-
-#define BUTTON_PIN 0
-
// globalCounter:
// Global variable to count interrupts
// Should be declared volatile to make sure the compiler doesn't cache it.
-static volatile int globalCounter = 0 ;
+static volatile int globalCounter [8] ;
/*
@@ -55,10 +50,14 @@ static volatile int globalCounter = 0 ;
*********************************************************************************
*/
-void myInterrupt (void)
-{
- ++globalCounter ;
-}
+void myInterrupt0 (void) { ++globalCounter [0] ; }
+void myInterrupt1 (void) { ++globalCounter [1] ; }
+void myInterrupt2 (void) { ++globalCounter [2] ; }
+void myInterrupt3 (void) { ++globalCounter [3] ; }
+void myInterrupt4 (void) { ++globalCounter [4] ; }
+void myInterrupt5 (void) { ++globalCounter [5] ; }
+void myInterrupt6 (void) { ++globalCounter [6] ; }
+void myInterrupt7 (void) { ++globalCounter [7] ; }
/*
@@ -69,30 +68,42 @@ void myInterrupt (void)
int main (void)
{
- int myCounter = 0 ;
+ int gotOne, pin ;
+ int myCounter [8] ;
- if (wiringPiSetup () < 0)
- {
- fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
- return 1 ;
- }
+ for (pin = 0 ; pin < 8 ; ++pin)
+ globalCounter [pin] = myCounter [pin] = 0 ;
- if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0)
- {
- fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
- return 1 ;
- }
+ wiringPiSetup () ;
+ wiringPiISR (0, INT_EDGE_FALLING, &myInterrupt0) ;
+ wiringPiISR (1, INT_EDGE_FALLING, &myInterrupt1) ;
+ wiringPiISR (2, INT_EDGE_FALLING, &myInterrupt2) ;
+ wiringPiISR (3, INT_EDGE_FALLING, &myInterrupt3) ;
+ wiringPiISR (4, INT_EDGE_FALLING, &myInterrupt4) ;
+ wiringPiISR (5, INT_EDGE_FALLING, &myInterrupt5) ;
+ wiringPiISR (6, INT_EDGE_FALLING, &myInterrupt6) ;
+ wiringPiISR (7, INT_EDGE_FALLING, &myInterrupt7) ;
for (;;)
{
+ gotOne = 0 ;
printf ("Waiting ... ") ; fflush (stdout) ;
- while (myCounter == globalCounter)
- delay (100) ;
-
- printf (" Done. counter: %5d\n", globalCounter) ;
- myCounter = globalCounter ;
+ for (;;)
+ {
+ for (pin = 0 ; pin < 8 ; ++pin)
+ {
+ if (globalCounter [pin] != myCounter [pin])
+ {
+ printf (" Int on pin %d: Counter: %5d\n", pin, globalCounter [pin]) ;
+ myCounter [pin] = globalCounter [pin] ;
+ ++gotOne ;
+ }
+ }
+ if (gotOne != 0)
+ break ;
+ }
}
return 0 ;
diff --git a/examples/lcd.c b/examples/lcd.c
index 6024917..c013585 100644
--- a/examples/lcd.c
+++ b/examples/lcd.c
@@ -4,7 +4,19 @@
* This is designed to drive the parallel interface LCD drivers
* based in the Hitachi HD44780U controller and compatables.
*
- * Copyright (c) 2012 Gordon Henderson.
+ * This test program assumes the following:
+ *
+ * 8-bit displays:
+ * GPIO 0-7 is connected to display data pins 0-7.
+ * GPIO 11 is the RS pin.
+ * GPIO 10 is the Strobe/E pin.
+ *
+ * For 4-bit interface:
+ * GPIO 4-7 is connected to display data pins 4-7.
+ * GPIO 11 is the RS pin.
+ * GPIO 10 is the Strobe/E pin.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -35,94 +47,208 @@
#include
#include
-int main (void)
+#ifndef TRUE
+# define TRUE (1==1)
+# define FALSE (1==2)
+#endif
+
+static unsigned char newChar [8] =
{
- int i, j ;
- int fd1, fd2 ;
+ 0b11111,
+ 0b10001,
+ 0b10001,
+ 0b10101,
+ 0b11111,
+ 0b10001,
+ 0b10001,
+ 0b11111,
+} ;
+
+
+int usage (const char *progName)
+{
+ fprintf (stderr, "Usage: %s bits cols rows\n", progName) ;
+ return EXIT_FAILURE ;
+}
+
+static const char *message =
+ " "
+ "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
+ " " ;
+
+void scrollMessage (int lcd, int line, int width)
+{
+ char buf [32] ;
+ static int position = 0 ;
+
+ strncpy (buf, &message [position], width) ;
+ buf [width] = 0 ;
+ lcdPosition (lcd, 0, line) ;
+ lcdPuts (lcd, buf) ;
+
+ if (++position == (strlen (message) - width))
+ position = 0 ;
+}
+
+static void pingPong (int lcd, int cols)
+{
+ static int position = 0 ;
+ static int dir = 0 ;
+
+ if (dir == 0) // Setup
+ {
+ dir = 1 ;
+ lcdPosition (lcd, 0, 3) ;
+ lcdPutchar (lcd, '*') ;
+ return ;
+ }
- char message1 [256] ;
- char message2 [256] ;
- char buf1 [30] ;
- char buf2 [30] ;
+ lcdPosition (lcd, position, 3) ;
+ lcdPutchar (lcd, ' ') ;
+ position += dir ;
+
+ if (position == cols)
+ {
+ dir = -1 ;
+ --position ;
+ }
+
+ if (position < 0)
+ {
+ dir = 1 ;
+ ++position ;
+ }
+
+ lcdPosition (lcd, position, 3) ;
+ lcdPutchar (lcd, '#') ;
+}
+
+
+
+static void waitForEnter (void)
+{
+ printf ("Press ENTER to continue: ") ;
+ (void)fgetc (stdin) ;
+}
+
+int main (int argc, char *argv[])
+{
+ int i ;
+ int lcd ;
+ int bits, rows, cols ;
struct tm *t ;
time_t tim ;
- printf ("Raspberry Pi LCD test program\n") ;
+ char buf [32] ;
- if (wiringPiSetup () == -1)
- exit (1) ;
+ if (argc != 4)
+ return usage (argv [0]) ;
- fd1 = lcdInit (4, 20, 4, 8, 9, 4,5,6,7,0,0,0,0) ;
- fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ;
+ printf ("Raspberry Pi LCD test\n") ;
+ printf ("=====================\n") ;
-//fd1 = lcdInit (4, 20, 8, 8, 9, 0,1,2,3,4,5,6,7) ;
-//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ;
+ bits = atoi (argv [1]) ;
+ cols = atoi (argv [2]) ;
+ rows = atoi (argv [3]) ;
- if (fd1 == -1)
+ if (!((rows == 1) || (rows == 2) || (rows == 4)))
{
- printf ("lcdInit 1 failed\n") ;
- return 1 ;
+ fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ;
+ return EXIT_FAILURE ;
}
- if (fd2 == -1)
+ if (!((cols == 16) || (cols == 20)))
{
- printf ("lcdInit 2 failed\n") ;
- return 1 ;
+ fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ;
+ return EXIT_FAILURE ;
}
- sleep (1) ;
+ wiringPiSetup () ;
- lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ;
- lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, " --------------") ;
-/*
- lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, " 00:00:00") ;
- lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, " DD:MM:YY") ;
-*/
+ if (bits == 4)
+ lcd = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ;
+ else
+ lcd = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ;
+
+ if (lcd < 0)
+ {
+ fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ;
+ return -1 ;
+ }
+
+ lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, "Gordon Henderson") ;
- lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ;
- lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ;
+ if (rows > 1)
+ {
+ lcdPosition (lcd, 0, 1) ;
+ for (i = 0 ; i < (cols - 1) ; ++i)
+ lcdPutchar (lcd, '*') ;
+ lcdPutchar (lcd, '2') ;
+
+ if (rows == 4)
+ {
+ lcdPosition (lcd, 0, 2) ;
+ for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
+ lcdPuts (lcd, "=-") ;
+ lcdPuts (lcd, "=3") ;
+
+ lcdPosition (lcd, 0, 3) ;
+ for (i = 0 ; i < ((cols - 1) / 2) ; ++i)
+ lcdPuts (lcd, "-=") ;
+ lcdPuts (lcd, "-4") ;
+ }
+ }
sleep (2) ;
- sprintf (message1, "%s", " http://projects.drogon.net/ ") ;
- sprintf (message2, "%s", " This is a long message to go into the smaller display just for a demonstration of what we can do. ") ;
+ lcdPosition (lcd, 0, 0) ; lcdPuts (lcd, " wiringpi.com ") ;
+
+
+ waitForEnter () ;
+
+ lcdCharDef (lcd, 2, newChar) ;
+
+ lcdClear (lcd) ;
+ lcdPosition (lcd, 0, 0) ;
+ lcdPuts (lcd, "User Char: ") ;
+ lcdPutchar (lcd, 2) ;
+
+ lcdCursor (lcd, TRUE) ;
+ lcdCursorBlink (lcd, TRUE) ;
+
+ waitForEnter () ;
+
+ lcdCursor (lcd, FALSE) ;
+ lcdCursorBlink (lcd, FALSE) ;
+
for (;;)
{
- i = 0 ;
- j = 0 ;
- for (;;)
- {
- strncpy (buf1, &message1 [i], 20) ;
- buf1 [20] = 0 ;
- lcdPosition (fd1, 0, 1) ;
- lcdPuts (fd1, buf1) ;
- ++i ;
- if (i == strlen (message1) - 20)
- i = 0 ;
-
- strncpy (buf2, &message2 [j], 16) ;
- buf2 [16] = 0 ;
- lcdPosition (fd2, 0, 1) ;
- lcdPuts (fd2, buf2) ;
- ++j ;
- if (j == strlen (message2) - 16)
- j = 0 ;
-
- tim = time (NULL) ;
- t = localtime (&tim) ;
-
- sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
- lcdPosition (fd1, 5, 2) ;
- lcdPuts (fd1, buf1) ;
-
- sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
- lcdPosition (fd1, 4, 3) ;
- lcdPuts (fd1, buf1) ;
-
- delay (250) ;
- }
+ delay (250) ;
+
+ scrollMessage (lcd, 0, cols) ;
+
+ if (rows == 1)
+ continue ;
+
+ tim = time (NULL) ;
+ t = localtime (&tim) ;
+
+ sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ;
+
+ lcdPosition (lcd, (cols - 8) / 2, 1) ;
+ lcdPuts (lcd, buf) ;
+
+ if (rows == 2)
+ continue ;
+
+ sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ;
+
+ lcdPosition (lcd, (cols - 10) / 2, 2) ;
+ lcdPuts (lcd, buf) ;
+
+ pingPong (lcd, cols) ;
}
return 0 ;
diff --git a/examples/okLed.c b/examples/okLed.c
index 9b3a170..930f266 100644
--- a/examples/okLed.c
+++ b/examples/okLed.c
@@ -39,27 +39,26 @@
#include
#include
+// The OK/Act LED is connected to BCM_GPIO pin 16
+
#define OK_LED 16
int main ()
{
int fd, i ;
+ wiringPiSetupGpio () ;
+
+// Change the trigger on the OK/Act LED to "none"
+
if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0)
{
fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ;
return 1 ;
}
-
write (fd, "none\n", 5) ;
close (fd) ;
- if (wiringPiSetupGpio () < 0)
- {
- fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ;
- return 1 ;
- }
-
softPwmCreate (OK_LED, 0, 100) ;
for (;;)
diff --git a/examples/pwm.c b/examples/pwm.c
index c1fc331..816c832 100644
--- a/examples/pwm.c
+++ b/examples/pwm.c
@@ -1,7 +1,6 @@
/*
* pwm.c:
- * Test of the software PWM driver. Needs 12 LEDs connected
- * to the Pi.
+ * This tests the hardware PWM channel.
*
* Copyright (c) 2012-2013 Gordon Henderson.
***********************************************************************
@@ -23,71 +22,37 @@
***********************************************************************
*/
-#include
-#include
-#include
-
#include
-#include
-
-#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
+#include
+#include
-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 ;
}
diff --git a/examples/piface.c b/examples/rht03.c
old mode 100644
new mode 100755
similarity index 60%
rename from examples/piface.c
rename to examples/rht03.c
index 0f00960..e0cc116
--- a/examples/piface.c
+++ b/examples/rht03.c
@@ -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.
***********************************************************************
@@ -24,47 +22,42 @@
***********************************************************************
*/
-#include
-
#include
-#include
-#include
-int outputs [4] = { 0,0,0,0 } ;
-
-void scanButton (int button)
-{
- if (digitalRead (button) == LOW)
- {
- outputs [button] ^= 1 ;
- digitalWrite (button, outputs [button]) ;
- }
+#include
+#include
- while (digitalRead (button) == LOW)
- delay (1) ;
-}
+#define RHT03_PIN 0
+/*
+ ***********************************************************************
+ * The main program
+ ***********************************************************************
+ */
int main (void)
{
- int pin, button ;
-
- printf ("Raspberry Pi wiringPiFace test program\n") ;
+ int temp, rh ;
+ int newTemp, newRh ;
- if (wiringPiSetupPiFace () == -1)
- exit (1) ;
-
-// Enable internal pull-ups
-
- for (pin = 0 ; pin < 8 ; ++pin)
- pullUpDnControl (pin, PUD_UP) ;
+ temp = rh = newTemp = newRh = 0 ;
+ wiringPiSetup () ;
+ piHiPri (55) ;
for (;;)
{
- for (button = 0 ; button < 4 ; ++button)
- scanButton (button) ;
- delay (1) ;
+ delay (100) ;
+
+ if (!readRHT03 (RHT03_PIN, &newTemp, &newRh))
+ continue ;
+
+ if ((temp != newTemp) || (rh != newRh))
+ {
+ temp = newTemp ;
+ rh = newRh ;
+ printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ;
+ }
}
return 0 ;
diff --git a/examples/softPwm.c b/examples/softPwm.c
new file mode 100644
index 0000000..11f7ad0
--- /dev/null
+++ b/examples/softPwm.c
@@ -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.
+ ***********************************************************************
+ * 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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#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 ;
+ }
+}
diff --git a/examples/tone.c b/examples/softTone.c
similarity index 92%
rename from examples/tone.c
rename to examples/softTone.c
index 0e8a47d..2f46783 100644
--- a/examples/tone.c
+++ b/examples/softTone.c
@@ -1,5 +1,5 @@
/*
- * tone.c:
+ * softTone.c:
* Test of the softTone module in wiringPi
* Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v
*
@@ -38,11 +38,7 @@ int main ()
{
int i ;
- if (wiringPiSetup () == -1)
- {
- fprintf (stdout, "oops: %s\n", strerror (errno)) ;
- return 1 ;
- }
+ wiringPiSetup () ;
softToneCreate (PIN) ;
@@ -55,5 +51,4 @@ int main ()
delay (500) ;
}
}
-
}
diff --git a/examples/speed.c b/examples/speed.c
index 863317e..0a42b36 100644
--- a/examples/speed.c
+++ b/examples/speed.c
@@ -31,93 +31,65 @@
#define FAST_COUNT 10000000
#define SLOW_COUNT 1000000
+#define PASSES 5
-
-int main (void)
+void speedTest (int pin, int maxCount)
{
- int i ;
- uint32_t start, end, count, sum, perSec ;
-
- printf ("Raspberry Pi wiringPi speed test program\n") ;
-
-// Start the standard way
-
- if (wiringPiSetup () == -1)
- exit (1) ;
-
- printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ;
-
- pinMode (0, OUTPUT) ;
+ int count, sum, perSec, i ;
+ unsigned int start, end ;
sum = 0 ;
- for (i = 0 ; i < 3 ; ++i)
- {
- printf (" Pass: %d: ", i) ;
- fflush (stdout) ;
+ for (i = 0 ; i < PASSES ; ++i)
+ {
start = millis () ;
- for (count = 0 ; count < FAST_COUNT ; ++count)
- digitalWrite (0, 1) ;
+ for (count = 0 ; count < maxCount ; ++count)
+ digitalWrite (pin, 1) ;
end = millis () ;
- printf (" %8dmS\n", end - start) ;
+ printf (" %6d", end - start) ;
+ fflush (stdout) ;
sum += (end - start) ;
}
- digitalWrite (0, 0) ;
- printf (" Average: %8dmS", sum / 3) ;
- perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
- printf (": %6d/sec\n", perSec) ;
+ digitalWrite (pin, 0) ;
+ printf (". Av: %6dmS", sum / PASSES) ;
+ perSec = (int)(double)maxCount / (double)((double)sum / (double)PASSES) * 1000.0 ;
+ printf (": %7d/sec\n", perSec) ;
+}
- printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ;
-
- if (wiringPiSetupGpio () == -1)
- exit (1) ;
- pinMode (17, OUTPUT) ;
+int main (void)
+{
+ printf ("Raspberry Pi wiringPi GPIO speed test program\n") ;
+ printf ("=============================================\n") ;
- sum = 0 ;
- for (i = 0 ; i < 3 ; ++i)
- {
- printf (" Pass: %d: ", i) ;
- fflush (stdout) ;
+// Start the standard way
- start = millis () ;
- for (count = 0 ; count < 10000000 ; ++count)
- digitalWrite (17, 1) ;
- end = millis () ;
- printf (" %8dmS\n", end - start) ;
- sum += (end - start) ;
- }
- digitalWrite (17, 0) ;
- printf (" Average: %8dmS", sum / 3) ;
- perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
- printf (": %6d/sec\n", perSec) ;
+ printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ;
+ wiringPiSetup () ;
+ pinMode (0, OUTPUT) ;
+ speedTest (0, FAST_COUNT) ;
+// GPIO
-// Switch to SYS mode:
+ printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ;
+ wiringPiSetupGpio () ;
+ pinMode (17, OUTPUT) ;
+ speedTest (17, FAST_COUNT) ;
- if (wiringPiSetupSys () == -1)
- exit (1) ;
+// Phys
- printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
+ printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ;
+ wiringPiSetupPhys () ;
+ pinMode (11, OUTPUT) ;
+ speedTest (11, FAST_COUNT) ;
- sum = 0 ;
- for (i = 0 ; i < 3 ; ++i)
- {
- printf (" Pass: %d: ", i) ;
- fflush (stdout) ;
+// Switch to SYS mode:
- start = millis () ;
- for (count = 0 ; count < SLOW_COUNT ; ++count)
- digitalWrite (17, 1) ;
- end = millis () ;
- printf (" %8dmS\n", end - start) ;
- sum += (end - start) ;
- }
- digitalWrite (17, 0) ;
- printf (" Average: %8dmS", sum / 3) ;
- perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ;
- printf (": %6d/sec\n", perSec) ;
+ system ("/usr/local/bin/gpio export 17 out") ;
+ printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ;
+ wiringPiSetupSys () ;
+ speedTest (17, SLOW_COUNT) ;
return 0 ;
}
diff --git a/gpio/Makefile b/gpio/Makefile
index a043962..52b0150 100644
--- a/gpio/Makefile
+++ b/gpio/Makefile
@@ -30,20 +30,20 @@ INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
-LIBS = -lwiringPi -lpthread -lm
+LIBS = -lwiringPi -lwiringPiDev -lpthread -lm
# May not need to alter anything below this line
###############################################################################
-SRC = gpio.c
+SRC = gpio.c extensions.c
OBJ = $(SRC:.c=.o)
all: gpio
-gpio: gpio.o
+gpio: $(OBJ)
@echo [Link]
- @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS)
+ @$(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)
.c.o:
@echo [Compile] $<
@@ -51,7 +51,8 @@ gpio: gpio.o
.PHONEY: clean
clean:
- rm -f $(OBJ) gpio *~ core tags *.bak
+ @echo "[Clean]"
+ @rm -f $(OBJ) gpio *~ core tags *.bak
.PHONEY: tags
tags: $(SRC)
@@ -78,3 +79,6 @@ depend:
makedepend -Y $(SRC)
# DO NOT DELETE
+
+gpio.o: extensions.h
+extensions.o: extensions.h
diff --git a/gpio/extensions.c b/gpio/extensions.c
new file mode 100644
index 0000000..c08d1c1
--- /dev/null
+++ b/gpio/extensions.c
@@ -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 .
+ ***********************************************************************
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#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
index 0000000..5d27123
--- /dev/null
+++ b/gpio/extensions.h
@@ -0,0 +1,26 @@
+/*
+ * extensions.h:
+ * Part of the GPIO program to test, peek, poke and otherwise
+ * noodle with the GPIO hardware on the Raspberry Pi.
+ * Copyright (c) 2012-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 .
+ ***********************************************************************
+ */
+
+
+extern int doExtension (char *progName, char *extensionData) ;
diff --git a/gpio/gpio.1 b/gpio/gpio.1
index ec65519..ae4df4e 100644
--- a/gpio/gpio.1
+++ b/gpio/gpio.1
@@ -1,15 +1,19 @@
-.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO"
+.TH "GPIO" "March 2013" "Command-Line access to Raspberry Pi's GPIO"
.SH NAME
-gpio \- Command-line access to Raspberry Pi and PiFace GPIO
+gpio \- Command-line access to Raspberry Pi's GPIO
.SH SYNOPSIS
.B gpio
.B \-v
.PP
.B gpio
-.B [ \-g ]
-.B read/write/wb/pwm/clock/mode ...
+.B [ \-g | \-1 ]
+.B mode/read/write/aread/awrite/wb/pwm/clock ...
+.PP
+.B gpio
+.B [ \-x extension:params ]
+.B mode/read/write/aread/awrite/pwm ...
.PP
.B gpio
.B [ \-p ]
@@ -17,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.B ...
.PP
.B gpio
-.B readall
+.B readall/reset
.PP
.B gpio
.B unexportall/exports
@@ -27,6 +31,10 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO
.B ...
.PP
.B gpio
+.B wfi
+.B ...
+.PP
+.B gpio
.B drive
group value
.PP
@@ -73,12 +81,28 @@ Output the current version including the board revision of the Raspberry Pi.
.TP
.B \-g
Use the BCM_GPIO pins numbers rather than wiringPi pin numbers.
-\fINOTE:\fR The BCM_GPIO pin numbers are always used with the
+\fINote:\fR The BCM_GPIO pin numbers are always used with the
export and edge commands.
.TP
+.B \-1
+Use the physical pin numbers rather than wiringPi pin numbers.
+\fINote:\fR that this applies to the P1 connector only. It is not possible to
+use pins on the Revision 2 P5 connector this way, and as with \-g the
+BCM_GPIO pin numbers are always used with the export and edge commands.
+
+.TP
+.B \-x extension
+This causes the named extension to be initialised. Extensions
+comprise of a name (e.g. mcp23017) followed by a colon, then the
+pin-base, then more optional parameters depending on the extension type.
+See the web page on http://wiringpi.com/the-gpio-utility/
+
+.TP
.B \-p
-Use the PiFace interface board and its corresponding pin numbers.
+Use the PiFace interface board and its corresponding pin numbers. The PiFace
+will always appear at pin number 200 in the gpio command. You can assign any
+pin numbers you like in your own programs though.
.TP
.B read
@@ -103,6 +127,11 @@ 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
Write a PWM value (0-1023) to the given pin. The pin needs to be put
into PWM mode first.
@@ -158,6 +187,12 @@ requiring root/sudo.
Un-Export a GPIO pin in the /sys/class/gpio directory.
.TP
+.B wfi
+This set the given pin to the supplied interrupt mode: rising, falling
+or both then waits for the interrupt to happen. It's a non-busy wait,
+so does not consume and CPU while it's waiting.
+
+.TP
.B drive
group value
@@ -207,26 +242,26 @@ The board jumpers need to be in-place to do this operation.
.PP
.TS
-r r r l.
-WiringPi GPIO-r1 GPIO-r2 Function
+c c c c l.
+WiringPi GPIO-r1 GPIO-r2 P1-Phys Function
_
-0 17 17
-1 18 18 (PWM)
-2 21 27
-3 22 22
-4 23 23
-5 24 24
-6 25 25
-7 4 4
-8 0 2 I2C: SDA0
-9 1 3 I2C: SCL0
-10 8 8 SPI: CE0
-11 7 7 SPI: CE1
-12 10 10 SPI: MOSI
-13 9 9 SPI: MISO
-14 11 11 SPI: SCLK
-15 14 14 TxD
-16 15 16 RxD
+ 0 17 17 11
+ 1 18 18 12 (PWM)
+ 2 21 27 13
+ 3 22 22 15
+ 4 23 23 16
+ 5 24 24 18
+ 6 25 25 22
+ 7 4 4 7
+ 8 0 2 3 I2C: SDA0
+ 9 1 3 5 I2C: SCL0
+10 8 8 24 SPI: CE0
+11 7 7 26 SPI: CE1
+12 10 10 19 SPI: MOSI
+13 9 9 21 SPI: MISO
+14 11 11 23 SPI: SCLK
+15 14 14 8 TxD
+16 15 16 10 RxD
17 - 28
18 - 29
19 - 30
@@ -272,7 +307,7 @@ pin numbers.
.LP
WiringPi's home page
.IP
-https://projects.drogon.net/raspberry-pi/wiringpi/
+http://wiringpi.com/
.SH AUTHOR
@@ -284,7 +319,7 @@ Please report bugs to
.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.
diff --git a/gpio/gpio.c b/gpio/gpio.c
index e71e432..8e17ae0 100644
--- a/gpio/gpio.c
+++ b/gpio/gpio.c
@@ -2,7 +2,7 @@
* gpio.c:
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
* Pi's GPIO.
- * Copyright (c) 2012 Gordon Henderson
+ * Copyright (c) 2012-2013 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,14 +26,20 @@
#include
#include
#include
+#include
#include
#include
#include
-#include
#include
+#include
+#include
#include
+
#include
+#include
+
+#include "extensions.h"
extern int wiringPiDebug ;
@@ -42,22 +48,26 @@ extern int wiringPiDebug ;
# define FALSE (1==2)
#endif
-#define VERSION "1.12"
+#define VERSION "2.02"
+#define I2CDETECT "/usr/sbin/i2cdetect"
static int wpMode ;
char *usage = "Usage: gpio -v\n"
" gpio -h\n"
- " gpio [-g] ...\n"
+ " gpio [-g|-1] [-x extension:params] ...\n"
" gpio [-p] ...\n"
- " gpio readall\n"
- " gpio unexportall/exports ...\n"
+ " gpio ...\n"
+ " gpio readall/reset\n"
+ " gpio unexportall/exports\n"
" gpio export/edge/unexport ...\n"
+ " gpio wfi \n"
" gpio drive \n"
" gpio pwm-bal/pwm-ms \n"
" gpio pwmr \n"
" gpio pwmc \n"
" gpio load spi/i2c\n"
+ " gpio i2cd/i2cdetect\n"
" gpio gbr \n"
" gpio gbw " ; // No trailing newline needed here.
@@ -196,6 +206,37 @@ static void doLoad (int argc, char *argv [])
/*
+ * doI2Cdetect:
+ * Run the i2cdetect command with the right runes for this Pi revision
+ *********************************************************************************
+ */
+
+static void doI2Cdetect (int argc, char *argv [])
+{
+ int port = piBoardRev () == 1 ? 0 : 1 ;
+ char command [128] ;
+ struct stat statBuf ;
+
+ if (stat (I2CDETECT, &statBuf) < 0)
+ {
+ fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
+ return ;
+ }
+
+ if (!moduleLoaded ("i2c_dev"))
+ {
+ fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ;
+ return ;
+ }
+
+ sprintf (command, "%s -y %d", I2CDETECT, port) ;
+ if (system (command) < 0)
+ fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
+
+}
+
+
+/*
* doReadall:
* Read all the GPIO pins
*********************************************************************************
@@ -215,27 +256,39 @@ static char *alts [] =
"IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
} ;
+static int wpiToPhys [64] =
+{
+ 11, 12, 13, 15, 16, 18, 22, 7, // 0...7
+ 3, 5, // 8...9
+ 24, 26, 19, 21, 23, // 10..14
+ 8, 10, // 15..16
+ 3, 4, 5, 6, // 17..20
+ 0,0,0,0,0,0,0,0,0,0,0, // 20..31
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32..47
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 47..63
+} ;
+
static void doReadall (void)
{
int pin ;
- printf ("+----------+------+--------+------+-------+\n") ;
- printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ;
- printf ("+----------+------+--------+------+-------+\n") ;
+ printf ("+----------+-Rev%d-+------+--------+------+-------+\n", piBoardRev ()) ;
+ printf ("| wiringPi | GPIO | Phys | Name | Mode | Value |\n") ;
+ printf ("+----------+------+------+--------+------+-------+\n") ;
- for (pin = 0 ; pin < 64 ; ++pin)
+ for (pin = 0 ; pin < 64 ; ++pin) // Crude, but effective
{
if (wpiPinToGpio (pin) == -1)
continue ;
- printf ("| %6d | %3d | %s | %s | %s |\n",
- pin, wpiPinToGpio (pin),
+ printf ("| %6d | %3d | %3d | %s | %s | %s |\n",
+ pin, wpiPinToGpio (pin), wpiToPhys [pin],
pinNames [pin],
alts [getAlt (pin)],
digitalRead (pin) == HIGH ? "High" : "Low ") ;
}
- printf ("+----------+------+--------+------+-------+\n") ;
+ printf ("+----------+------+------+--------+------+-------+\n") ;
}
@@ -252,9 +305,7 @@ static void doExports (int argc, char *argv [])
char fName [128] ;
char buf [16] ;
-// Rather crude, but who knows what others are up to...
-
- for (first = 0, i = 0 ; i < 64 ; ++i)
+ for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective
{
// Try to read the direction
@@ -387,6 +438,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
* Easy access to changing the edge trigger on a GPIO pin
@@ -499,7 +596,7 @@ void doUnexport (int argc, char *argv [])
*********************************************************************************
*/
-void doUnexportall (int argc, char *argv [])
+void doUnexportall (char *progName)
{
FILE *fd ;
int pin ;
@@ -508,7 +605,7 @@ void doUnexportall (int argc, char *argv [])
{
if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
{
- fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
+ fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ;
exit (1) ;
}
fprintf (fd, "%d\n", pin) ;
@@ -518,6 +615,30 @@ void doUnexportall (int argc, char *argv [])
/*
+ * doReset:
+ * Reset the GPIO pins - as much as we can do
+ *********************************************************************************
+ */
+
+static void doReset (char *progName)
+{
+ int pin ;
+
+ doUnexportall (progName) ;
+
+ for (pin = 0 ; pin < 64 ; ++pin)
+ {
+ if (wpiPinToGpio (pin) == -1)
+ continue ;
+
+ digitalWrite (pin, LOW) ;
+ pinMode (pin, INPUT) ;
+ pullUpDnControl (pin, PUD_OFF) ;
+ }
+}
+
+
+/*
* doMode:
* gpio mode pin mode ...
*********************************************************************************
@@ -536,9 +657,6 @@ void doMode (int argc, char *argv [])
pin = atoi (argv [2]) ;
- if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
- return ;
-
mode = argv [3] ;
/**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
@@ -604,7 +722,7 @@ static void doGbw (int argc, char *argv [])
if (argc != 4)
{
- fprintf (stderr, "Usage: %s gbr \n", argv [0]) ;
+ fprintf (stderr, "Usage: %s gbw \n", argv [0]) ;
exit (1) ;
}
@@ -613,23 +731,23 @@ static void doGbw (int argc, char *argv [])
if ((channel < 0) || (channel > 1))
{
- fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
+ fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ;
exit (1) ;
}
if ((value < 0) || (value > 1023))
{
- fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
+ fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ;
exit (1) ;
}
- if (gertboardSPISetup () == -1)
+ if (gertboardAnalogSetup (64) < 0)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}
- gertboardAnalogWrite (channel, value) ;
+ analogWrite (64 + channel, value) ;
}
@@ -654,21 +772,20 @@ static void doGbr (int argc, char *argv [])
if ((channel < 0) || (channel > 1))
{
- fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
+ fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ;
exit (1) ;
}
- if (gertboardSPISetup () == -1)
+ if (gertboardAnalogSetup (64) < 0)
{
fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
exit (1) ;
}
- printf ("%d\n",gertboardAnalogRead (channel)) ;
+ printf ("%d\n", analogRead (64 + channel)) ;
}
-
/*
* doWrite:
* gpio write pin value
@@ -687,9 +804,6 @@ static void doWrite (int argc, char *argv [])
pin = atoi (argv [2]) ;
- if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
- return ;
-
/**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
val = 1 ;
else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
@@ -703,6 +817,31 @@ static void doWrite (int argc, char *argv [])
digitalWrite (pin, HIGH) ;
}
+
+/*
+ * doAwriterite:
+ * gpio awrite pin value
+ *********************************************************************************
+ */
+
+static void doAwrite (int argc, char *argv [])
+{
+ int pin, val ;
+
+ if (argc != 4)
+ {
+ fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ;
+ exit (1) ;
+ }
+
+ pin = atoi (argv [2]) ;
+
+ val = atoi (argv [3]) ;
+
+ analogWrite (pin, val) ;
+}
+
+
/*
* doWriteByte:
* gpio write value
@@ -742,20 +881,58 @@ void doRead (int argc, char *argv [])
}
pin = atoi (argv [2]) ;
+ val = digitalRead (pin) ;
+
+ printf ("%s\n", val == 0 ? "0" : "1") ;
+}
+
+
+/*
+ * doAread:
+ * Read an analog pin and return the value
+ *********************************************************************************
+ */
+
+void doAread (int argc, char *argv [])
+{
+ int pin, val ;
- if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
+ if (argc != 3)
{
- printf ("0\n") ;
- return ;
+ fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ;
+ exit (1) ;
}
- val = digitalRead (pin) ;
+ pin = atoi (argv [2]) ;
+
+ val = analogRead (pin) ;
printf ("%s\n", val == 0 ? "0" : "1") ;
}
/*
+ * doToggle:
+ * Toggle an IO pin
+ *********************************************************************************
+ */
+
+void doToggle (int argc, char *argv [])
+{
+ int pin ;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ;
+ exit (1) ;
+ }
+
+ pin = atoi (argv [2]) ;
+
+ digitalWrite (pin, !digitalRead (pin)) ;
+}
+
+/*
* doClock:
* Output a clock on a pin
*********************************************************************************
@@ -773,9 +950,6 @@ void doClock (int argc, char *argv [])
pin = atoi (argv [2]) ;
- if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
- return ;
-
freq = atoi (argv [3]) ;
gpioClockSet (pin, freq) ;
@@ -800,9 +974,6 @@ void doPwm (int argc, char *argv [])
pin = atoi (argv [2]) ;
- if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
- return ;
-
val = atoi (argv [3]) ;
pwmWrite (pin, val) ;
@@ -885,16 +1056,34 @@ int main (int argc, char *argv [])
return 1 ;
}
+// Help
+
if (strcasecmp (argv [1], "-h") == 0)
{
printf ("%s: %s\n", argv [0], usage) ;
return 0 ;
}
- if (strcasecmp (argv [1], "-v") == 0)
+// Sort of a special:
+
+ if (strcmp (argv [1], "-R") == 0)
+ {
+ printf ("%d\n", piBoardRev ()) ;
+ return 0 ;
+ }
+
+// Version & Warranty
+
+ if (strcmp (argv [1], "-V") == 0)
+ {
+ printf ("%d\n", piBoardRev ()) ;
+ return 0 ;
+ }
+
+ if (strcmp (argv [1], "-v") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
- printf ("Copyright (c) 2012 Gordon Henderson\n") ;
+ printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ;
@@ -905,7 +1094,7 @@ int main (int argc, char *argv [])
if (strcasecmp (argv [1], "-warranty") == 0)
{
printf ("gpio version: %s\n", VERSION) ;
- printf ("Copyright (c) 2012 Gordon Henderson\n") ;
+ printf ("Copyright (c) 2012-2013 Gordon Henderson\n") ;
printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ;
@@ -934,8 +1123,8 @@ int main (int argc, char *argv [])
/**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
- else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
+ else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; }
// Check for load command:
@@ -948,13 +1137,9 @@ int main (int argc, char *argv [])
// Check for -g argument
- if (strcasecmp (argv [1], "-g") == 0)
+ /**/ if (strcasecmp (argv [1], "-g") == 0)
{
- if (wiringPiSetupGpio () == -1)
- {
- fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
- exit (1) ;
- }
+ wiringPiSetupGpio () ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
@@ -962,15 +1147,23 @@ int main (int argc, char *argv [])
wpMode = WPI_MODE_GPIO ;
}
+// Check for -1 argument
+
+ else if (strcasecmp (argv [1], "-1") == 0)
+ {
+ wiringPiSetupPhys () ;
+
+ for (i = 2 ; i < argc ; ++i)
+ argv [i - 1] = argv [i] ;
+ --argc ;
+ wpMode = WPI_MODE_PHYS ;
+ }
+
// Check for -p argument for PiFace
else if (strcasecmp (argv [1], "-p") == 0)
{
- if (wiringPiSetupPiFaceForGpioProg () == -1)
- {
- fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
- exit (1) ;
- }
+ piFaceSetup (200) ;
for (i = 2 ; i < argc ; ++i)
argv [i - 1] = argv [i] ;
@@ -982,38 +1175,65 @@ int main (int argc, char *argv [])
else
{
- if (wiringPiSetup () == -1)
- {
- fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
- exit (1) ;
- }
+ wiringPiSetup () ;
wpMode = WPI_MODE_PINS ;
}
-// Check for PWM or Pad Drive operations
+// Check for -x argument to load in a new extension
- if (wpMode != WPI_MODE_PIFACE)
+ if (strcasecmp (argv [1], "-x") == 0)
{
- if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
- if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
- if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
- if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
- if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
+ if (argc < 3)
+ {
+ fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ;
+ exit (EXIT_FAILURE) ;
+ }
+
+ if (!doExtension (argv [0], argv [2])) // Prints its own error messages
+ exit (EXIT_FAILURE) ;
+
+ for (i = 3 ; i < argc ; ++i)
+ argv [i - 2] = argv [i] ;
+ argc -= 2 ;
}
-// Check for wiring commands
+ if (argc <= 1)
+ {
+ fprintf (stderr, "%s: no command given\n", argv [0]) ;
+ exit (EXIT_FAILURE) ;
+ }
- /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
- else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
- else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
- else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ;
- else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
- else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ;
- else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
+// Core wiringPi functions
+
+ /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
+ else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
+ else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ;
+ else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
+ else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ;
+ else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ;
+
+// GPIO Nicies
+
+ else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ;
+
+// Pi Specifics
+
+ else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ;
+ else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ;
+ else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ;
+ else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ;
+ else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
+ else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
+ else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
+ else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ;
+ else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ;
+ else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ;
+ else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ;
+ else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ;
else
{
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
- exit (1) ;
+ exit (EXIT_FAILURE) ;
}
return 0 ;
}
diff --git a/gpio/pintest b/gpio/pintest
new file mode 100755
index 0000000..83ca12a
--- /dev/null
+++ b/gpio/pintest
@@ -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 .
+#################################################################################
+
+
+# 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 <.
#################################################################################
-DYN_VERS_MAJ=1
+DYN_VERS_MAJ=2
DYN_VERS_MIN=0
VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN)
@@ -35,26 +35,25 @@ DYNAMIC=libwiringPi.so.$(VERSION)
DEBUG = -O2
CC = gcc
INCLUDE = -I.
-CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC
+CFLAGS = $(DEBUG) -Wformat=2 -Wall $(INCLUDE) -Winline -pipe -fPIC
LIBS =
# Should not alter anything below this line
###############################################################################
-SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \
- gertboard.c \
- piNes.c \
- lcd.c piHiPri.c piThread.c \
- wiringPiSPI.c \
- softPwm.c softServo.c softTone.c
-
-SRC_I2C = wiringPiI2C.c
+SRC = wiringPi.c \
+ wiringSerial.c wiringShift.c \
+ piHiPri.c piThread.c \
+ wiringPiSPI.c wiringPiI2C.c \
+ softPwm.c softTone.c \
+ mcp23s08.c mcp23008.c \
+ mcp23s17.c mcp23017.c sr595.c pcf8574.c \
+ mcp3002.c mcp4802.c mcp3422.c \
+ drc.c
OBJ = $(SRC:.c=.o)
-OBJ_I2C = $(SRC_I2C:.c=.o)
-
all: $(DYNAMIC)
static: $(STATIC)
@@ -67,11 +66,7 @@ $(STATIC): $(OBJ)
$(DYNAMIC): $(OBJ)
@echo "[Link (Dynamic)]"
- @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ)
-
-i2c: $(OBJ) $(OBJ_I2C)
- @echo "[Link (Dynamic + I2C)]"
- @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C)
+ @$(CC) -shared -Wl,-soname,libwiringPi.so -o libwiringPi.so.$(VERSION) -lpthread $(OBJ)
.c.o:
@echo [Compile] $<
@@ -79,37 +74,48 @@ i2c: $(OBJ) $(OBJ_I2C)
.PHONEY: clean
clean:
- rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
+ @echo "[Clean]"
+ @rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.*
.PHONEY: tags
tags: $(SRC)
@echo [ctags]
@ctags $(SRC)
-.PHONEY: install
-install: $(DYNAMIC)
- @echo "[Install]"
- @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
+
+.PHONEY: install-headers
+install-headers:
+ @echo "[Install Headers]"
@install -m 0755 -d $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringShift.h $(DESTDIR)$(PREFIX)/include
- @install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include
- @install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 softPwm.h $(DESTDIR)$(PREFIX)/include
- @install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include
- @install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include
@install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include
- @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
- @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
- @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1
+ @install -m 0644 mcp23008.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp23017.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp23s08.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp23s17.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp3002.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp4802.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 mcp3422.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 sr595.h $(DESTDIR)$(PREFIX)/include
+ @install -m 0644 pcf8574.h $(DESTDIR)$(PREFIX)/include
+
+.PHONEY: install
+install: $(DYNAMIC) install-headers
+ @echo "[Install Dynamic Lib]"
+ @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
+ @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION)
+ @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
@ldconfig
.PHONEY: install-static
-install-static: $(STATIC)
- @echo "[Install Static]"
+install-static: $(STATIC) install-headers
+ @echo "[Install Static Lib]"
+ @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
@install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib
.PHONEY: uninstall
@@ -118,14 +124,19 @@ uninstall:
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h
- @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h
- @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h
@rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h
- @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h
@rm -f $(DESTDIR)$(PREFIX)/include/softTone.h
- @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h
@rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp23008.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp23017.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp23s08.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp23s17.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp3002.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp4802.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/mcp3422.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/sr595.h
+ @rm -f $(DESTDIR)$(PREFIX)/include/pcf8574.h
@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
@ldconfig
@@ -137,16 +148,21 @@ depend:
# DO NOT DELETE
wiringPi.o: wiringPi.h
-wiringPiFace.o: wiringPi.h
wiringSerial.o: wiringSerial.h
wiringShift.o: wiringPi.h wiringShift.h
-gertboard.o: wiringPiSPI.h gertboard.h
-piNes.o: wiringPi.h piNes.h
-lcd.o: wiringPi.h lcd.h
piHiPri.o: wiringPi.h
piThread.o: wiringPi.h
-wiringPiSPI.o: wiringPiSPI.h
+wiringPiSPI.o: wiringPi.h wiringPiSPI.h
+wiringPiI2C.o: wiringPi.h wiringPiI2C.h
softPwm.o: wiringPi.h softPwm.h
-softServo.o: wiringPi.h softServo.h
softTone.o: wiringPi.h softTone.h
-wiringPiI2C.o: wiringPi.h wiringPiI2C.h
+mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h
+mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h
+mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h
+mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h
+sr595.o: wiringPi.h sr595.h
+pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h
+mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h
+mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h
+mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h
+drc.o: wiringPi.h wiringSerial.h drc.h
diff --git a/wiringPi/README b/wiringPi/README
deleted file mode 100644
index c79754e..0000000
--- a/wiringPi/README
+++ /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
index 0000000..07baf17
--- /dev/null
+++ b/wiringPi/drc.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+
+#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
index 0000000..c2c4ff3
--- /dev/null
+++ b/wiringPi/drc.h
@@ -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 .
+ ***********************************************************************
+ */
+
+#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
index 0000000..d21d237
--- /dev/null
+++ b/wiringPi/mcp23008.c
@@ -0,0 +1,149 @@
+/*
+ * mcp23008.c:
+ * Extend wiringPi with the MCP 23008 I2C GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..e9299a8
--- /dev/null
+++ b/wiringPi/mcp23008.h
@@ -0,0 +1,33 @@
+/*
+ * 23008.h:
+ * Extend wiringPi with the MCP 23008 I2C GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#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
index 0000000..5174195
--- /dev/null
+++ b/wiringPi/mcp23017.c
@@ -0,0 +1,195 @@
+/*
+ * mcp23017.c:
+ * Extend wiringPi with the MCP 23017 I2C GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..79b4d7b
--- /dev/null
+++ b/wiringPi/mcp23017.h
@@ -0,0 +1,33 @@
+/*
+ * 23017.h:
+ * Extend wiringPi with the MCP 23017 I2C GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp23017Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23s08.c b/wiringPi/mcp23s08.c
new file mode 100644
index 0000000..d0acb5e
--- /dev/null
+++ b/wiringPi/mcp23s08.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..ebf93d1
--- /dev/null
+++ b/wiringPi/mcp23s08.h
@@ -0,0 +1,33 @@
+/*
+ * 23s08.h:
+ * Extend wiringPi with the MCP 23s08 SPI GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23s17.c b/wiringPi/mcp23s17.c
new file mode 100644
index 0000000..c2d1be3
--- /dev/null
+++ b/wiringPi/mcp23s17.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..3b2a808
--- /dev/null
+++ b/wiringPi/mcp23s17.h
@@ -0,0 +1,33 @@
+/*
+ * 23s17.h:
+ * Extend wiringPi with the MCP 23s17 SPI GPIO expander chip
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp23s17Setup (int pinBase, int spiPort, int devId) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/mcp23x08.h b/wiringPi/mcp23x08.h
new file mode 100644
index 0000000..c4e6b27
--- /dev/null
+++ b/wiringPi/mcp23x08.h
@@ -0,0 +1,73 @@
+/*
+ * mcp23x17:
+ * Copyright (c) 2012-2013 Gordon Henderson
+ *
+ * Header file for code using the MCP23x17 GPIO expander chip.
+ * This comes in 2 flavours: MCP23017 which has an I2C interface,
+ * an the MXP23S17 which has an SPI interface.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+
+// MCP23x17 Registers
+
+#define IODIRA 0x00
+#define IPOLA 0x02
+#define GPINTENA 0x04
+#define DEFVALA 0x06
+#define INTCONA 0x08
+#define IOCON 0x0A
+#define GPPUA 0x0C
+#define INTFA 0x0E
+#define INTCAPA 0x10
+#define GPIOA 0x12
+#define OLATA 0x14
+
+#define IODIRB 0x01
+#define IPOLB 0x03
+#define GPINTENB 0x05
+#define DEFVALB 0x07
+#define INTCONB 0x09
+#define IOCONB 0x0B
+#define GPPUB 0x0D
+#define INTFB 0x0F
+#define INTCAPB 0x11
+#define GPIOB 0x13
+#define OLATB 0x15
+
+// Bits in the IOCON register
+
+#define IOCON_UNUSED 0x01
+#define IOCON_INTPOL 0x02
+#define IOCON_ODR 0x04
+#define IOCON_HAEN 0x08
+#define IOCON_DISSLW 0x10
+#define IOCON_SEQOP 0x20
+#define IOCON_MIRROR 0x40
+#define IOCON_BANK_MODE 0x80
+
+// Default initialisation mode
+
+#define IOCON_INIT (IOCON_SEQOP)
+
+// SPI Command codes
+
+#define CMD_WRITE 0x40
+#define CMD_READ 0x41
diff --git a/wiringPi/mcp23x0817.h b/wiringPi/mcp23x0817.h
new file mode 100644
index 0000000..58bc038
--- /dev/null
+++ b/wiringPi/mcp23x0817.h
@@ -0,0 +1,87 @@
+/*
+ * mcp23xxx:
+ * Copyright (c) 2012-2013 Gordon Henderson
+ *
+ * Header file for code using the MCP23x08 and 17 GPIO expander
+ * chips.
+ * This comes in 2 flavours: MCP230xx (08/17) which has an I2C
+ * interface, and the MXP23Sxx (08/17) which has an SPI interface.
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+// MCP23x08 Registers
+
+#define MCP23x08_IODIR 0x00
+#define MCP23x08_IPOL 0x01
+#define MCP23x08_GPINTEN 0x02
+#define MCP23x08_DEFVAL 0x03
+#define MCP23x08_INTCON 0x04
+#define MCP23x08_IOCON 0x05
+#define MCP23x08_GPPU 0x06
+#define MCP23x08_INTF 0x07
+#define MCP23x08_INTCAP 0x08
+#define MCP23x08_GPIO 0x09
+#define MCP23x08_OLAT 0x0A
+
+// MCP23x17 Registers
+
+#define MCP23x17_IODIRA 0x00
+#define MCP23x17_IPOLA 0x02
+#define MCP23x17_GPINTENA 0x04
+#define MCP23x17_DEFVALA 0x06
+#define MCP23x17_INTCONA 0x08
+#define MCP23x17_IOCON 0x0A
+#define MCP23x17_GPPUA 0x0C
+#define MCP23x17_INTFA 0x0E
+#define MCP23x17_INTCAPA 0x10
+#define MCP23x17_GPIOA 0x12
+#define MCP23x17_OLATA 0x14
+
+#define MCP23x17_IODIRB 0x01
+#define MCP23x17_IPOLB 0x03
+#define MCP23x17_GPINTENB 0x05
+#define MCP23x17_DEFVALB 0x07
+#define MCP23x17_INTCONB 0x09
+#define MCP23x17_IOCONB 0x0B
+#define MCP23x17_GPPUB 0x0D
+#define MCP23x17_INTFB 0x0F
+#define MCP23x17_INTCAPB 0x11
+#define MCP23x17_GPIOB 0x13
+#define MCP23x17_OLATB 0x15
+
+// Bits in the IOCON register
+
+#define IOCON_UNUSED 0x01
+#define IOCON_INTPOL 0x02
+#define IOCON_ODR 0x04
+#define IOCON_HAEN 0x08
+#define IOCON_DISSLW 0x10
+#define IOCON_SEQOP 0x20
+#define IOCON_MIRROR 0x40
+#define IOCON_BANK_MODE 0x80
+
+// Default initialisation mode
+
+#define IOCON_INIT (IOCON_SEQOP)
+
+// SPI Command codes
+
+#define CMD_WRITE 0x40
+#define CMD_READ 0x41
diff --git a/wiringPi/mcp3002.c b/wiringPi/mcp3002.c
new file mode 100644
index 0000000..2e7d5cf
--- /dev/null
+++ b/wiringPi/mcp3002.c
@@ -0,0 +1,76 @@
+/*
+ * mcp3002.c:
+ * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..0cd727f
--- /dev/null
+++ b/wiringPi/mcp3002.h
@@ -0,0 +1,33 @@
+/*
+ * mcp3002.c:
+ * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#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
index 0000000..8e26d76
--- /dev/null
+++ b/wiringPi/mcp3422.c
@@ -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 .
+ ***********************************************************************
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#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
index 0000000..8b4e350
--- /dev/null
+++ b/wiringPi/mcp3422.h
@@ -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 .
+ ***********************************************************************
+ */
+
+#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
index 0000000..5c5c17a
--- /dev/null
+++ b/wiringPi/mcp4802.c
@@ -0,0 +1,76 @@
+/*
+ * mcp4802.c:
+ * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..effa024
--- /dev/null
+++ b/wiringPi/mcp4802.h
@@ -0,0 +1,33 @@
+/*
+ * mcp4802.c:
+ * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor
+ * Copyright (c) 2012-2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int mcp4802Setup (int pinBase, int spiChannel) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/pcf8574.c b/wiringPi/pcf8574.c
new file mode 100644
index 0000000..ce9c533
--- /dev/null
+++ b/wiringPi/pcf8574.c
@@ -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 .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..3cad2dd
--- /dev/null
+++ b/wiringPi/pcf8574.h
@@ -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 .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int pfc8574Setup (const int pinBase, const int i2cAddress) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/piHiPri.c b/wiringPi/piHiPri.c
index e7e06b4..d2f3b4e 100644
--- a/wiringPi/piHiPri.c
+++ b/wiringPi/piHiPri.c
@@ -36,15 +36,16 @@
*********************************************************************************
*/
-int piHiPri (int pri)
+int piHiPri (const int pri)
{
struct sched_param sched ;
memset (&sched, 0, sizeof(sched)) ;
if (pri > sched_get_priority_max (SCHED_RR))
- pri = sched_get_priority_max (SCHED_RR) ;
+ sched.sched_priority = sched_get_priority_max (SCHED_RR) ;
+ else
+ sched.sched_priority = pri ;
- sched.sched_priority = pri ;
return sched_setscheduler (0, SCHED_RR, &sched) ;
}
diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c
index b568dfb..a4f0fc4 100644
--- a/wiringPi/softPwm.c
+++ b/wiringPi/softPwm.c
@@ -28,7 +28,7 @@
#include "wiringPi.h"
#include "softPwm.h"
-#define MAX_PINS 64
+#define MAX_PINS 1024
// The PWM Frequency is derived from the "pulse time" below. Essentially,
// the frequency is a function of the range and this pulse time.
@@ -93,7 +93,7 @@ static PI_THREAD (softPwmThread)
void softPwmWrite (int pin, int value)
{
- pin &= 63 ;
+ pin &= (MAX_PINS - 1) ;
/**/ if (value < 0)
value = 0 ;
diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c
index 8463627..b4a89f8 100644
--- a/wiringPi/softTone.c
+++ b/wiringPi/softTone.c
@@ -36,7 +36,7 @@
#define PULSE_TIME 100
-static int frewqs [MAX_PINS] ;
+static int freqs [MAX_PINS] ;
static int newPin = -1 ;
@@ -49,7 +49,7 @@ static int newPin = -1 ;
static PI_THREAD (softToneThread)
{
- int pin, frewq, halfPeriod ;
+ int pin, freq, halfPeriod ;
pin = newPin ;
newPin = -1 ;
@@ -58,12 +58,12 @@ static PI_THREAD (softToneThread)
for (;;)
{
- frewq = frewqs [pin] ;
- if (frewq == 0)
+ freq = freqs [pin] ;
+ if (freq == 0)
delay (1) ;
else
{
- halfPeriod = 500000 / frewq ;
+ halfPeriod = 500000 / freq ;
digitalWrite (pin, HIGH) ;
delayMicroseconds (halfPeriod) ;
@@ -83,16 +83,16 @@ static PI_THREAD (softToneThread)
*********************************************************************************
*/
-void softToneWrite (int pin, int frewq)
+void softToneWrite (int pin, int freq)
{
pin &= 63 ;
- /**/ if (frewq < 0)
- frewq = 0 ;
- else if (frewq > 5000) // Max 5KHz
- frewq = 5000 ;
+ /**/ if (freq < 0)
+ freq = 0 ;
+ else if (freq > 5000) // Max 5KHz
+ freq = 5000 ;
- frewqs [pin] = frewq ;
+ freqs [pin] = freq ;
}
@@ -109,7 +109,7 @@ int softToneCreate (int pin)
pinMode (pin, OUTPUT) ;
digitalWrite (pin, LOW) ;
- frewqs [pin] = 0 ;
+ freqs [pin] = 0 ;
newPin = pin ;
res = piThreadCreate (softToneThread) ;
diff --git a/wiringPi/softTone.h b/wiringPi/softTone.h
index 80c64fe..d8b4e54 100644
--- a/wiringPi/softTone.h
+++ b/wiringPi/softTone.h
@@ -31,7 +31,7 @@ extern "C" {
#endif
extern int softToneCreate (int pin) ;
-extern void softToneWrite (int pin, int frewq) ;
+extern void softToneWrite (int pin, int freq) ;
#ifdef __cplusplus
}
diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c
new file mode 100644
index 0000000..87210c2
--- /dev/null
+++ b/wiringPi/sr595.c
@@ -0,0 +1,109 @@
+/*
+ * sr595.c:
+ * Extend wiringPi with the 74x595 shift register as a GPIO
+ * expander chip.
+ * Note that the code can cope with a number of 595's
+ * daisy-chained together - up to 4 for now as we're storing
+ * the output "register" in a single unsigned int.
+ *
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+
+#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
index 0000000..4a26dc7
--- /dev/null
+++ b/wiringPi/sr595.h
@@ -0,0 +1,34 @@
+/*
+ * sr595.h:
+ * Extend wiringPi with the 74x595 shift registers.
+ * Copyright (c) 2013 Gordon Henderson
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with wiringPi.
+ * If not, see .
+ ***********************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int sr595Setup (const int pinBase, const int numPins,
+ const int dataPin, const int clockPin, const int latchPin) ;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c
index a68ae33..b8e381a 100644
--- a/wiringPi/wiringPi.c
+++ b/wiringPi/wiringPi.c
@@ -53,6 +53,7 @@
#include
+#include
#include
#include
#include
@@ -71,28 +72,24 @@
#include "wiringPi.h"
-// Function stubs
-
-void (*pinMode) (int pin, int mode) ;
-int (*getAlt) (int pin) ;
-void (*pullUpDnControl) (int pin, int pud) ;
-void (*digitalWrite) (int pin, int value) ;
-void (*digitalWriteByte) (int value) ;
-void (*pwmWrite) (int pin, int value) ;
-void (*gpioClockSet) (int pin, int value) ;
-void (*setPadDrive) (int group, int value) ;
-int (*digitalRead) (int pin) ;
-int (*waitForInterrupt) (int pin, int mS) ;
-void (*pwmSetMode) (int mode) ;
-void (*pwmSetRange) (unsigned int range) ;
-void (*pwmSetClock) (int divisor) ;
-
-
#ifndef TRUE
#define TRUE (1==1)
#define FALSE (1==2)
#endif
+// Environment Variables
+
+#define ENV_DEBUG "WIRINGPI_DEBUG"
+#define ENV_CODES "WIRINGPI_CODES"
+
+
+// Mask for the bottom 64 pins which belong to the Raspberry Pi
+// The others are available for the other devices
+
+#define PI_GPIO_MASK (0xFFFFFFC0)
+
+static struct wiringPiNodeStruct *wiringPiNodes = NULL ;
+
// BCM Magic
#define BCM_PASSWORD 0x5A000000
@@ -192,8 +189,11 @@ static volatile uint32_t *gpio ;
static volatile uint32_t *pwm ;
static volatile uint32_t *clk ;
static volatile uint32_t *pads ;
+
+#ifdef USE_TIMER
static volatile uint32_t *timer ;
static volatile uint32_t *timerIrqRaw ;
+#endif
// Time for easy calculations
@@ -202,10 +202,13 @@ static uint64_t epochMilli, epochMicro ;
// Misc
static int wiringPiMode = WPI_MODE_UNINITIALISED ;
+static volatile int pinPass = -1 ;
+static pthread_mutex_t pinMutex ;
-// Debugging
+// Debugging & Return codes
-int wiringPiDebug = FALSE ;
+int wiringPiDebug = FALSE ;
+int wiringPiReturnCodes = FALSE ;
// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value
@@ -223,17 +226,17 @@ static void (*isrFunctions [64])(void) ;
// pinToGpio:
// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin
-// Cope for 2 different board revieions here
+// Cope for 2 different board revisions here.
static int *pinToGpio ;
static int pinToGpioR1 [64] =
{
- 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7
- 0, 1, // I2C - SDA0, SCL0
- 8, 7, // SPI - CE1, CE0
- 10, 9, 11, // SPI - MOSI, MISO, SCLK
- 14, 15, // UART - Tx, Rx
+ 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7
+ 0, 1, // I2C - SDA0, SCL0 wpi 8 - 9
+ 8, 7, // SPI - CE1, CE0 wpi 10 - 11
+ 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14
+ 14, 15, // UART - Tx, Rx wpi 15 - 16
// Padding:
@@ -259,8 +262,65 @@ static int pinToGpioR2 [64] =
} ;
+// physToGpio:
+// Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin
+// Cope for 2 different board revisions here.
+
+static int *physToGpio ;
+
+static int physToGpioR1 [64] =
+{
+ -1, // 0
+ -1, -1, // 1, 2
+ 0, -1,
+ 1, -1,
+ 4, 14,
+ -1, 15,
+ 17, 18,
+ 21, -1,
+ 22, 23,
+ -1, 24,
+ 10, -1,
+ 9, 25,
+ 11, 8,
+ -1, 7, // 25, 26
+
+// Padding:
+
+ -1, -1, -1, -1, -1, // ... 31
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
+} ;
+
+static int physToGpioR2 [64] =
+{
+ -1, // 0
+ -1, -1, // 1, 2
+ 2, -1,
+ 3, -1,
+ 4, 14,
+ -1, 15,
+ 17, 18,
+ 27, -1,
+ 22, 23,
+ -1, 24,
+ 10, -1,
+ 9, 25,
+ 11, 8,
+ -1, 7, // 25, 26
+
+// Padding:
+
+ -1, -1, -1, -1, -1, // ... 31
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63
+} ;
+
+
// gpioToGPFSEL:
-// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
+// Map a BCM_GPIO pin to it's Function Selection
+// control port. (GPFSEL 0-5)
+// Groups of 10 - 3 bits per Function - 30 bits per port
static uint8_t gpioToGPFSEL [] =
{
@@ -295,7 +355,6 @@ static uint8_t gpioToGPSET [] =
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
} ;
-
// gpioToGPCLR:
// (Word) offset to the GPIO Clear registers for each GPIO pin
@@ -376,6 +435,7 @@ static uint8_t gpioToPwmALT [] =
0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63
} ;
+
// gpioToPwmPort
// The port value to put a GPIO pin into PWM mode
@@ -395,7 +455,7 @@ static uint8_t gpioToPwmPort [] =
// gpioToGpClkALT:
// ALT value to put a GPIO pin into GP Clock mode.
// On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21
-// for clocks 0 and 1 respectivey, however I'll include the full
+// for clocks 0 and 1 respectively, however I'll include the full
// list for completeness - maybe one day...
#define GPIO_CLOCK_SOURCE 1
@@ -449,23 +509,34 @@ static uint8_t gpioToClkDiv [] =
/*
- * wpiPinToGpio:
- * Translate a wiringPi Pin number to native GPIO pin number.
- * (We don't use this here, prefering to just do the lookup directly,
- * but it's been requested!)
+ * wiringPiFailure:
+ * Fail. Or not.
*********************************************************************************
*/
-int wpiPinToGpio (int wpiPin)
+int wiringPiFailure (int fatal, const char *message, ...)
{
- return pinToGpio [wpiPin & 63] ;
+ va_list argp ;
+ char buffer [1024] ;
+
+ if (!fatal && wiringPiReturnCodes)
+ return -1 ;
+
+ va_start (argp, message) ;
+ vsnprintf (buffer, 1023, message, argp) ;
+ va_end (argp) ;
+
+ fprintf (stderr, "%s", buffer) ;
+ exit (EXIT_FAILURE) ;
+
+ return 0 ;
}
/*
* piBoardRev:
* Return a number representing the hardware revision of the board.
- * Revision is currently 1 or 2. -1 is returned on error.
+ * Revision is currently 1 or 2.
*
* Much confusion here )-:
* Seems there are some boards with 0000 in them (mistake in manufacture)
@@ -488,7 +559,7 @@ int wpiPinToGpio (int wpiPin)
*********************************************************************************
*/
-static void piBoardRevOops (char *why)
+static void piBoardRevOops (const char *why)
{
fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ;
fprintf (stderr, " -> %s\n", why) ;
@@ -556,6 +627,58 @@ int piBoardRev (void)
}
+/*
+ * wpiPinToGpio:
+ * Translate a wiringPi Pin number to native GPIO pin number.
+ * Provided for external support.
+ *********************************************************************************
+ */
+
+int wpiPinToGpio (int wpiPin)
+{
+ return pinToGpio [wpiPin & 63] ;
+}
+
+
+/*
+ * physPinToGpio:
+ * Translate a physical Pin number to native GPIO pin number.
+ * Provided for external support.
+ *********************************************************************************
+ */
+
+int physPinToGpio (int physPin)
+{
+ return physToGpio [physPin & 63] ;
+}
+
+
+/*
+ * setPadDrive:
+ * Set the PAD driver value
+ *********************************************************************************
+ */
+
+void setPadDrive (int group, int value)
+{
+ uint32_t wrVal ;
+
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+ {
+ if ((group < 0) || (group > 2))
+ return ;
+
+ wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
+ *(pads + group + 11) = wrVal ;
+
+ if (wiringPiDebug)
+ {
+ printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
+ printf ("Read : %08X\n", *(pads + group + 11)) ;
+ }
+ }
+}
+
/*
* getAlt:
@@ -564,12 +687,19 @@ int piBoardRev (void)
*********************************************************************************
*/
-int getAltGpio (int pin)
+int getAlt (int pin)
{
int fSel, shift, alt ;
pin &= 63 ;
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return 0 ;
+
fSel = gpioToGPFSEL [pin] ;
shift = gpioToShift [pin] ;
@@ -578,70 +708,66 @@ int getAltGpio (int pin)
return alt ;
}
-int getAltWPi (int pin)
-{
- return getAltGpio (pinToGpio [pin & 63]) ;
-}
-
-int getAltSys (int pin)
-{
- return 0 ;
-}
-
/*
- * pwmControl:
- * Allow the user to control some of the PWM functions
+ * pwmSetMode:
+ * Select the native "balanced" mode, or standard mark:space mode
*********************************************************************************
*/
-void pwmSetModeWPi (int mode)
+void pwmSetMode (int mode)
{
- if (mode == PWM_MODE_MS)
- *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
- else
- *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+ {
+ if (mode == PWM_MODE_MS)
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ;
+ else
+ *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ;
+ }
}
-void pwmSetModeSys (int mode)
-{
- return ;
-}
+/*
+ * pwmSetRange:
+ * Set the PWM range register. We set both range registers to the same
+ * value. If you want different in your own code, then write your own.
+ *********************************************************************************
+ */
-void pwmSetRangeWPi (unsigned int range)
+void pwmSetRange (unsigned int range)
{
- *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
- *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+ {
+ *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ;
+ *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ;
+ }
}
-void pwmSetRangeSys (unsigned int range)
-{
- return ;
-}
/*
- * pwmSetClockWPi:
+ * pwmSetClock:
* Set/Change the PWM clock. Originally my code, but changed
* (for the better!) by Chris Hall,
* after further study of the manual and testing with a 'scope
*********************************************************************************
*/
-void pwmSetClockWPi (int divisor)
+void pwmSetClock (int divisor)
{
uint32_t pwm_control ;
divisor &= 4095 ;
- if (wiringPiDebug)
- printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
+ if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
+ {
+ if (wiringPiDebug)
+ printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
- pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
+ pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL
// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY
// stays high.
- *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
+ *(pwm + PWM_CONTROL) = 0 ; // Stop PWM
// Stop PWM clock before changing divisor. The delay after this does need to
// this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY
@@ -649,226 +775,249 @@ void pwmSetClockWPi (int divisor)
// adjusted the clock sometimes switches to very slow, once slow further DIV
// adjustments do nothing and it's difficult to get out of this mode.
- *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
- delayMicroseconds (110) ; // prevents clock going sloooow
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock
+ delayMicroseconds (110) ; // prevents clock going sloooow
- while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
- delayMicroseconds (1) ;
+ while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY
+ delayMicroseconds (1) ;
- *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
+ *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ;
- *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
- *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
+ *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock
+ *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL
- if (wiringPiDebug)
- printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
-}
-
-void pwmSetClockSys (int divisor)
-{
- return ;
+ if (wiringPiDebug)
+ printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ;
+ }
}
-#ifdef notYetReady
/*
- * pinED01:
- * pinED10:
- * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
- * Pin must already be in input mode with appropriate pull up/downs set.
+ * gpioClockSet:
+ * Set the freuency on a GPIO clock pin
*********************************************************************************
*/
-void pinEnableED01Pi (int pin)
+void gpioClockSet (int pin, int freq)
{
- pin = pinToGpio [pin & 63] ;
-}
-#endif
+ int divi, divr, divf ;
+ pin &= 63 ;
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
+
+ divi = 19200000 / freq ;
+ divr = 19200000 % freq ;
+ divf = (int)((double)divr * 4096.0 / 19200000.0) ;
-/*
- * digitalWrite:
- * Set an output bit
- *********************************************************************************
- */
+ if (divi > 4095)
+ divi = 4095 ;
-void digitalWriteWPi (int pin, int value)
-{
- pin = pinToGpio [pin & 63] ;
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock
+ while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait
+ ;
- if (value == LOW)
- *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
- else
- *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
+ *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers
+ *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock
}
-void digitalWriteGpio (int pin, int value)
-{
- pin &= 63 ;
- if (value == LOW)
- *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
- else
- *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
-}
+/*
+ * wiringPiFindNode:
+ * Locate our device node
+ *********************************************************************************
+ */
-void digitalWriteSys (int pin, int value)
+static struct wiringPiNodeStruct *wiringPiFindNode (int pin)
{
- pin &= 63 ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- if (sysFds [pin] != -1)
- {
- if (value == LOW)
- write (sysFds [pin], "0\n", 2) ;
+ while (node != NULL)
+ if ((pin >= node->pinBase) && (pin <= node->pinMax))
+ return node ;
else
- write (sysFds [pin], "1\n", 2) ;
- }
+ node = node->next ;
+
+ return NULL ;
}
/*
- * digitalWriteByte:
- * Write an 8-bit byte to the first 8 GPIO pins - try to do it as
- * fast as possible.
- * However it still needs 2 operations to set the bits, so any external
- * hardware must not rely on seeing a change as there will be a change
- * to set the outputs bits to zero, then another change to set the 1's
+ * wiringPiNewNode:
+ * Create a new GPIO node into the wiringPi handling system
*********************************************************************************
*/
-void digitalWriteByteGpio (int value)
+static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; }
+static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; }
+static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; }
+static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; }
+static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; }
+
+struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins)
{
- uint32_t pinSet = 0 ;
- uint32_t pinClr = 0 ;
- int mask = 1 ;
- int pin ;
+ int pin ;
+ struct wiringPiNodeStruct *node ;
- for (pin = 0 ; pin < 8 ; ++pin)
- {
- if ((value & mask) == 0)
- pinClr |= (1 << pinToGpio [pin]) ;
- else
- pinSet |= (1 << pinToGpio [pin]) ;
+// Minimum pin base is 64
- mask <<= 1 ;
- }
+ if (pinBase < 64)
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ;
- *(gpio + gpioToGPCLR [0]) = pinClr ;
- *(gpio + gpioToGPSET [0]) = pinSet ;
-}
+// Check all pins in-case there is overlap:
-void digitalWriteByteSys (int value)
-{
- int mask = 1 ;
- int pin ;
+ for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin)
+ if (wiringPiFindNode (pin) != NULL)
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ;
- for (pin = 0 ; pin < 8 ; ++pin)
- {
- digitalWriteSys (pinToGpio [pin], value & mask) ;
- mask <<= 1 ;
- }
+ node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros
+ if (node == NULL)
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ;
+
+ node->pinBase = pinBase ;
+ node->pinMax = pinBase + numPins - 1 ;
+ node->pinMode = pinModeDummy ;
+ node->pullUpDnControl = pullUpDnControlDummy ;
+ node->digitalRead = digitalReadDummy ;
+ node->digitalWrite = digitalWriteDummy ;
+ node->pwmWrite = pwmWriteDummy ;
+ node->analogRead = analogReadDummy ;
+ node->analogWrite = analogWriteDummy ;
+ node->next = wiringPiNodes ;
+ wiringPiNodes = node ;
+
+ return node ;
}
+#ifdef notYetReady
/*
- * pwmWrite:
- * Set an output PWM value
+ * pinED01:
+ * pinED10:
+ * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0
+ * Pin must already be in input mode with appropriate pull up/downs set.
*********************************************************************************
*/
-void pwmWriteGpio (int pin, int value)
+void pinEnableED01Pi (int pin)
{
- int port ;
-
- pin = pin & 63 ;
- port = gpioToPwmPort [pin] ;
-
- *(pwm + port) = value ;
+ pin = pinToGpio [pin & 63] ;
}
+#endif
-void pwmWriteWPi (int pin, int value)
-{
- pwmWriteGpio (pinToGpio [pin & 63], value) ;
-}
-void pwmWriteSys (int pin, int value)
-{
- return ;
-}
+/*
+ *********************************************************************************
+ * Core Functions
+ *********************************************************************************
+ */
/*
- * gpioClockSet:
- * Set the freuency on a GPIO clock pin
+ * pinMode:
+ * Sets the mode of a pin to be input, output or PWM output
*********************************************************************************
*/
-void gpioClockSetGpio (int pin, int freq)
+void pinMode (int pin, int mode)
{
- int divi, divr, divf ;
+ int fSel, shift, alt ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- pin &= 63 ;
-
- divi = 19200000 / freq ;
- divr = 19200000 % freq ;
- divf = (int)((double)divr * 4096.0 / 19200000.0) ;
+ if ((pin & PI_GPIO_MASK) == 0) // On-board pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
- if (divi > 4095)
- divi = 4095 ;
+ fSel = gpioToGPFSEL [pin] ;
+ shift = gpioToShift [pin] ;
- *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock
- while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait
- ;
+ /**/ if (mode == INPUT)
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
+ else if (mode == OUTPUT)
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
+ else if (mode == PWM_OUTPUT)
+ {
+ if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
+ return ;
- *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers
- *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock
-}
+// Set pin to PWM mode
-void gpioClockSetWPi (int pin, int freq)
-{
- gpioClockSetGpio (pinToGpio [pin & 63], freq) ;
-}
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
+ delayMicroseconds (110) ; // See comments in pwmSetClockWPi
-void gpioClockSetSys (int pin, int freq)
-{
- return ;
+ pwmSetMode (PWM_MODE_BAL) ; // Pi default mode
+ pwmSetRange (1024) ; // Default range of 1024
+ pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
+ }
+ else if (mode == GPIO_CLOCK)
+ {
+ if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
+ return ;
+
+// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
+
+ *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
+ delayMicroseconds (110) ;
+ gpioClockSet (pin, 100000) ;
+ }
+ }
+ else
+ {
+ if ((node = wiringPiFindNode (pin)) != NULL)
+ node->pinMode (node, pin, mode) ;
+ return ;
+ }
}
/*
- * setPadDrive:
- * Set the PAD driver value
+ * pullUpDownCtrl:
+ * Control the internal pull-up/down resistors on a GPIO pin
+ * The Arduino only has pull-ups and these are enabled by writing 1
+ * to a port when in input mode - this paradigm doesn't quite apply
+ * here though.
*********************************************************************************
*/
-void setPadDriveWPi (int group, int value)
+void pullUpDnControl (int pin, int pud)
{
- uint32_t wrVal ;
-
- if ((group < 0) || (group > 2))
- return ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- wrVal = BCM_PASSWORD | 0x18 | (value & 7) ;
- *(pads + group + 11) = wrVal ;
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
- if (wiringPiDebug)
+ *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ;
+ *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
+
+ *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
+ *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
+ }
+ else // Extension module
{
- printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ;
- printf ("Read : %08X\n", *(pads + group + 11)) ;
+ if ((node = wiringPiFindNode (pin)) != NULL)
+ node->pullUpDnControl (node, pin, pud) ;
+ return ;
}
}
-void setPadDriveGpio (int group, int value)
-{
- setPadDriveWPi (group, value) ;
-}
-
-void setPadDriveSys (int group, int value)
-{
- return ;
-}
-
/*
* digitalRead:
@@ -876,134 +1025,202 @@ void setPadDriveSys (int group, int value)
*********************************************************************************
*/
-int digitalReadWPi (int pin)
+int digitalRead (int pin)
{
- pin = pinToGpio [pin & 63] ;
+ char c ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
+
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
+ {
+ if (sysFds [pin] == -1)
+ return LOW ;
- if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
- return HIGH ;
+ lseek (sysFds [pin], 0L, SEEK_SET) ;
+ read (sysFds [pin], &c, 1) ;
+ return (c == '0') ? LOW : HIGH ;
+ }
+ else if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return LOW ;
+
+ if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
+ return HIGH ;
+ else
+ return LOW ;
+ }
else
- return LOW ;
+ {
+ if ((node = wiringPiFindNode (pin)) == NULL)
+ return LOW ;
+ return node->digitalRead (node, pin) ;
+ }
}
-int digitalReadGpio (int pin)
-{
- pin &= 63 ;
- if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0)
- return HIGH ;
- else
- return LOW ;
-}
+/*
+ * digitalWrite:
+ * Set an output bit
+ *********************************************************************************
+ */
-int digitalReadSys (int pin)
+void digitalWrite (int pin, int value)
{
- char c ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- pin &= 63 ;
-
- if (sysFds [pin] == -1)
- return 0 ;
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode
+ {
+ if (sysFds [pin] != -1)
+ {
+ if (value == LOW)
+ write (sysFds [pin], "0\n", 2) ;
+ else
+ write (sysFds [pin], "1\n", 2) ;
+ }
+ return ;
+ }
+ else if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
- lseek (sysFds [pin], 0L, SEEK_SET) ;
- read (sysFds [pin], &c, 1) ;
- return (c == '0') ? 0 : 1 ;
+ if (value == LOW)
+ *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ;
+ else
+ *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ;
+ }
+ else
+ {
+ if ((node = wiringPiFindNode (pin)) != NULL)
+ node->digitalWrite (node, pin, value) ;
+ }
}
/*
- * pullUpDownCtrl:
- * Control the internal pull-up/down resistors on a GPIO pin
- * The Arduino only has pull-ups and these are enabled by writing 1
- * to a port when in input mode - this paradigm doesn't quite apply
- * here though.
+ * pwmWrite:
+ * Set an output PWM value
*********************************************************************************
*/
-void pullUpDnControlGpio (int pin, int pud)
+void pwmWrite (int pin, int value)
{
- pin &= 63 ;
- pud &= 3 ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- *(gpio + GPPUD) = pud ; delayMicroseconds (5) ;
- *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ;
-
- *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ;
- *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ;
-}
+ if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
+ {
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+ else if (wiringPiMode != WPI_MODE_GPIO)
+ return ;
-void pullUpDnControlWPi (int pin, int pud)
-{
- pullUpDnControlGpio (pinToGpio [pin & 63], pud) ;
+ *(pwm + gpioToPwmPort [pin]) = value ;
+ }
+ else
+ {
+ if ((node = wiringPiFindNode (pin)) != NULL)
+ node->pwmWrite (node, pin, value) ;
+ }
}
-void pullUpDnControlSys (int pin, int pud)
+
+/*
+ * analogRead:
+ * Read the analog value of a given Pin.
+ * There is no on-board Pi analog hardware,
+ * so this needs to go to a new node.
+ *********************************************************************************
+ */
+
+int analogRead (int pin)
{
- return ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
+
+ if ((node = wiringPiFindNode (pin)) == NULL)
+ return 0 ;
+ else
+ return node->analogRead (node, pin) ;
}
/*
- * pinMode:
- * Sets the mode of a pin to be input, output or PWM output
+ * analogWrite:
+ * Write the analog value to the given Pin.
+ * There is no on-board Pi analog hardware,
+ * so this needs to go to a new node.
*********************************************************************************
*/
-void pinModeGpio (int pin, int mode)
+void analogWrite (int pin, int value)
{
-// register int barrier ;
+ struct wiringPiNodeStruct *node = wiringPiNodes ;
- int fSel, shift, alt ;
+ if ((node = wiringPiFindNode (pin)) == NULL)
+ return ;
- pin &= 63 ;
+ node->analogWrite (node, pin, value) ;
+}
- fSel = gpioToGPFSEL [pin] ;
- shift = gpioToShift [pin] ;
- /**/ if (mode == INPUT)
- *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input
- else if (mode == OUTPUT)
- *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
- else if (mode == PWM_OUTPUT)
- {
- if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin
- return ;
-// Set pin to PWM mode
+/*
+ * digitalWriteByte:
+ * Pi Specific
+ * Write an 8-bit byte to the first 8 GPIO pins - try to do it as
+ * fast as possible.
+ * However it still needs 2 operations to set the bits, so any external
+ * hardware must not rely on seeing a change as there will be a change
+ * to set the outputs bits to zero, then another change to set the 1's
+ *********************************************************************************
+ */
- *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
- delayMicroseconds (110) ; // See comments in pwmSetClockWPi
+void digitalWriteByte (int value)
+{
+ uint32_t pinSet = 0 ;
+ uint32_t pinClr = 0 ;
+ int mask = 1 ;
+ int pin ;
- pwmSetModeWPi (PWM_MODE_BAL) ; // Pi default mode
- pwmSetRangeWPi (1024) ; // Default range of 1024
- pwmSetClockWPi (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM
+ /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS)
+ {
+ for (pin = 0 ; pin < 8 ; ++pin)
+ {
+ digitalWrite (pin, value & mask) ;
+ mask <<= 1 ;
+ }
+ return ;
}
- else if (mode == GPIO_CLOCK)
+ else
{
- if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
- return ;
+ for (pin = 0 ; pin < 8 ; ++pin)
+ {
+ if ((value & mask) == 0)
+ pinClr |= (1 << pinToGpio [pin]) ;
+ else
+ pinSet |= (1 << pinToGpio [pin]) ;
-// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
+ mask <<= 1 ;
+ }
- *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
- delayMicroseconds (110) ;
- gpioClockSetGpio (pin, 100000) ;
+ *(gpio + gpioToGPCLR [0]) = pinClr ;
+ *(gpio + gpioToGPSET [0]) = pinSet ;
}
}
-void pinModeWPi (int pin, int mode)
-{
- pinModeGpio (pinToGpio [pin & 63], mode) ;
-}
-
-void pinModeSys (int pin, int mode)
-{
- return ;
-}
-
/*
* waitForInterrupt:
+ * Pi Specific.
* Wait for Interrupt on a GPIO pin.
* This is actually done via the /sys/class/gpio interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
@@ -1011,13 +1228,18 @@ void pinModeSys (int pin, int mode)
*********************************************************************************
*/
-int waitForInterruptSys (int pin, int mS)
+int waitForInterrupt (int pin, int mS)
{
int fd, x ;
uint8_t c ;
struct pollfd polls ;
- if ((fd = sysFds [pin & 63]) == -1)
+ /**/ if (wiringPiMode == WPI_MODE_PINS)
+ pin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ pin = physToGpio [pin] ;
+
+ if ((fd = sysFds [pin]) == -1)
return -2 ;
// Setup poll structure
@@ -1037,16 +1259,6 @@ int waitForInterruptSys (int pin, int mS)
return x ;
}
-int waitForInterruptWPi (int pin, int mS)
-{
- return waitForInterruptSys (pinToGpio [pin & 63], mS) ;
-}
-
-int waitForInterruptGpio (int pin, int mS)
-{
- return waitForInterruptSys (pin, mS) ;
-}
-
/*
* interruptHandler:
@@ -1058,12 +1270,15 @@ int waitForInterruptGpio (int pin, int mS)
static void *interruptHandler (void *arg)
{
- int myPin = *(int *)arg ;
+ int myPin ;
(void)piHiPri (55) ; // Only effective if we run as root
+ myPin = pinPass ;
+ pinPass = -1 ;
+
for (;;)
- if (waitForInterruptSys (myPin, -1) > 0)
+ if (waitForInterrupt (myPin, -1) > 0)
isrFunctions [myPin] () ;
return NULL ;
@@ -1072,6 +1287,7 @@ static void *interruptHandler (void *arg)
/*
* wiringPiISR:
+ * Pi Specific.
* Take the details and create an interrupt handler that will do a call-
* back to the user supplied function.
*********************************************************************************
@@ -1080,22 +1296,24 @@ static void *interruptHandler (void *arg)
int wiringPiISR (int pin, int mode, void (*function)(void))
{
pthread_t threadId ;
+ const char *modeS ;
char fName [64] ;
- char *modeS ;
char pinS [8] ;
pid_t pid ;
int count, i ;
- uint8_t c ;
+ char c ;
+ int bcmGpioPin ;
pin &= 63 ;
- if (wiringPiMode == WPI_MODE_UNINITIALISED)
- {
- fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
- exit (EXIT_FAILURE) ;
- }
+ /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED)
+ return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ;
else if (wiringPiMode == WPI_MODE_PINS)
- pin = pinToGpio [pin] ;
+ bcmGpioPin = pinToGpio [pin] ;
+ else if (wiringPiMode == WPI_MODE_PHYS)
+ bcmGpioPin = physToGpio [pin] ;
+ else
+ bcmGpioPin = pin ;
// Now export the pin and set the right edge
// We're going to use the gpio program to do this, so it assumes
@@ -1112,7 +1330,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
else
modeS = "both" ;
- sprintf (pinS, "%d", pin) ;
+ sprintf (pinS, "%d", bcmGpioPin) ;
if ((pid = fork ()) < 0) // Fail
return pid ;
@@ -1127,23 +1345,29 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
}
// Now pre-open the /sys/class node - it may already be open if
-// we are in Sys mode, but this will do no harm.
+// we are in Sys mode or if we call here twice, if-so, we'll close it.
+
+ if (sysFds [bcmGpioPin] != -1)
+ close (sysFds [bcmGpioPin]) ;
- sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
- if ((sysFds [pin] = open (fName, O_RDWR)) < 0)
+ sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ;
+ if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0)
return -1 ;
// Clear any initial pending interrupt
- ioctl (sysFds [pin], FIONREAD, &count) ;
+ ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ;
for (i = 0 ; i < count ; ++i)
- read (sysFds [pin], &c, 1) ;
+ read (sysFds [bcmGpioPin], &c, 1) ;
isrFunctions [pin] = function ;
- pthread_create (&threadId, NULL, interruptHandler, &pin) ;
-
- delay (1) ;
+ pthread_mutex_lock (&pinMutex) ;
+ pinPass = pin ;
+ pthread_create (&threadId, NULL, interruptHandler, NULL) ;
+ while (pinPass != -1)
+ delay (1) ;
+ pthread_mutex_unlock (&pinMutex) ;
return 0 ;
}
@@ -1152,7 +1376,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void))
/*
* initialiseEpoch:
* Initialise our start-of-time variable to be the current unix
- * time in milliseconds.
+ * time in milliseconds and microseconds.
*********************************************************************************
*/
@@ -1165,9 +1389,10 @@ static void initialiseEpoch (void)
epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ;
}
+
/*
* delay:
- * Wait for some number of milli seconds
+ * Wait for some number of milliseconds
*********************************************************************************
*/
@@ -1280,124 +1505,66 @@ int wiringPiSetup (void)
int fd ;
int boardRev ;
- if (geteuid () != 0)
- {
- fprintf (stderr, "wiringPi:\n Must be root to call wiringPiSetup().\n (Did you forget sudo?)\n") ;
- exit (EXIT_FAILURE) ;
- }
-
- if (getenv ("WIRINGPI_DEBUG") != NULL)
- {
- printf ("wiringPi: Debug mode enabled\n") ;
+ if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;
- }
+
+ if (getenv (ENV_CODES) != NULL)
+ wiringPiReturnCodes = TRUE ;
+
+ if (geteuid () != 0)
+ (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ;
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetup called\n") ;
- pinMode = pinModeWPi ;
- getAlt = getAltWPi ;
- pullUpDnControl = pullUpDnControlWPi ;
- digitalWrite = digitalWriteWPi ;
- digitalWriteByte = digitalWriteByteGpio ; // Same code
- gpioClockSet = gpioClockSetWPi ;
- pwmWrite = pwmWriteWPi ;
- setPadDrive = setPadDriveWPi ;
- digitalRead = digitalReadWPi ;
- waitForInterrupt = waitForInterruptWPi ;
- pwmSetMode = pwmSetModeWPi ;
- pwmSetRange = pwmSetRangeWPi ;
- pwmSetClock = pwmSetClockWPi ;
-
boardRev = piBoardRev () ;
if (boardRev == 1)
- pinToGpio = pinToGpioR1 ;
+ {
+ pinToGpio = pinToGpioR1 ;
+ physToGpio = physToGpioR1 ;
+ }
else
- pinToGpio = pinToGpioR2 ;
+ {
+ pinToGpio = pinToGpioR2 ;
+ physToGpio = physToGpioR2 ;
+ }
// Open the master /dev/memory device
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ;
// GPIO:
gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
if ((int32_t)gpio == -1)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ;
// PWM
pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
if ((int32_t)pwm == -1)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
// Clock control (needed for PWM)
clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ;
if ((int32_t)clk == -1)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
// The drive pads
pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
if ((int32_t)pads == -1)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
+#ifdef USE_TIMER
// The system timer
timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
if ((int32_t)timer == -1)
- {
- if (wiringPiDebug)
- {
- int serr = errno ;
- fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ;
- errno = serr ;
- }
- return -1 ;
- }
+ return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ;
// Set the timer to free-running, 1MHz.
// 0xF9 is 249, the timer divide is base clock / (divide+1)
@@ -1406,6 +1573,7 @@ int wiringPiSetup (void)
*(timer + TIMER_CONTROL) = 0x0000280 ;
*(timer + TIMER_PRE_DIV) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ;
+#endif
initialiseEpoch () ;
@@ -1426,34 +1594,11 @@ int wiringPiSetup (void)
int wiringPiSetupGpio (void)
{
- int x ;
-
- if (geteuid () != 0)
- {
- fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ;
- exit (EXIT_FAILURE) ;
- }
-
- if ((x = wiringPiSetup ()) < 0)
- return x ;
+ (void)wiringPiSetup () ;
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupGpio called\n") ;
- pinMode = pinModeGpio ;
- getAlt = getAltGpio ;
- pullUpDnControl = pullUpDnControlGpio ;
- digitalWrite = digitalWriteGpio ;
- digitalWriteByte = digitalWriteByteGpio ;
- gpioClockSet = gpioClockSetGpio ;
- pwmWrite = pwmWriteGpio ;
- setPadDrive = setPadDriveGpio ;
- digitalRead = digitalReadGpio ;
- waitForInterrupt = waitForInterruptGpio ;
- pwmSetMode = pwmSetModeWPi ;
- pwmSetRange = pwmSetRangeWPi ;
- pwmSetClock = pwmSetClockWPi ;
-
wiringPiMode = WPI_MODE_GPIO ;
return 0 ;
@@ -1461,6 +1606,28 @@ int wiringPiSetupGpio (void)
/*
+ * wiringPiSetupPhys:
+ * Must be called once at the start of your program execution.
+ *
+ * Phys setup: Initialises the system into Physical Pin mode and uses the
+ * memory mapped hardware directly.
+ *********************************************************************************
+ */
+
+int wiringPiSetupPhys (void)
+{
+ (void)wiringPiSetup () ;
+
+ if (wiringPiDebug)
+ printf ("wiringPi: wiringPiSetupPhys called\n") ;
+
+ wiringPiMode = WPI_MODE_PHYS ;
+
+ return 0 ;
+}
+
+
+/*
* wiringPiSetupSys:
* Must be called once at the start of your program execution.
*
@@ -1475,32 +1642,27 @@ int wiringPiSetupSys (void)
int pin ;
char fName [128] ;
- if (getenv ("WIRINGPI_DEBUG") != NULL)
+ if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ;
+ if (getenv (ENV_CODES) != NULL)
+ wiringPiReturnCodes = TRUE ;
+
if (wiringPiDebug)
printf ("wiringPi: wiringPiSetupSys called\n") ;
- pinMode = pinModeSys ;
- getAlt = getAltSys ;
- pullUpDnControl = pullUpDnControlSys ;
- digitalWrite = digitalWriteSys ;
- digitalWriteByte = digitalWriteByteSys ;
- gpioClockSet = gpioClockSetSys ;
- pwmWrite = pwmWriteSys ;
- setPadDrive = setPadDriveSys ;
- digitalRead = digitalReadSys ;
- waitForInterrupt = waitForInterruptSys ;
- pwmSetMode = pwmSetModeSys ;
- pwmSetRange = pwmSetRangeSys ;
- pwmSetClock = pwmSetClockSys ;
-
boardRev = piBoardRev () ;
if (boardRev == 1)
- pinToGpio = pinToGpioR1 ;
+ {
+ pinToGpio = pinToGpioR1 ;
+ physToGpio = physToGpioR1 ;
+ }
else
- pinToGpio = pinToGpioR2 ;
+ {
+ pinToGpio = pinToGpioR2 ;
+ physToGpio = physToGpioR2 ;
+ }
// Open and scan the directory, looking for exported GPIOs, and pre-open
// the 'value' interface to speed things up for later
diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h
index 18c6da5..600c851 100644
--- a/wiringPi/wiringPi.h
+++ b/wiringPi/wiringPi.h
@@ -29,7 +29,8 @@
#define WPI_MODE_PINS 0
#define WPI_MODE_GPIO 1
#define WPI_MODE_GPIO_SYS 2
-#define WPI_MODE_PIFACE 3
+#define WPI_MODE_PHYS 3
+#define WPI_MODE_PIFACE 4
#define WPI_MODE_UNINITIALISED -1
// Pin modes
@@ -64,6 +65,42 @@
#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
@@ -73,46 +110,61 @@
extern "C" {
#endif
-// Basic wiringPi functions
+// Internal
+
+extern int wiringPiFailure (int fatal, const char *message, ...) ;
+
+// Core wiringPi functions
+
+extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
extern int wiringPiSetup (void) ;
extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
-extern int wiringPiSetupPiFace (void) ;
+extern int wiringPiSetupPhys (void) ;
-extern int piBoardRev (void) ;
-extern int wpiPinToGpio (int wpiPin) ;
+extern void pinMode (int pin, int mode) ;
+extern void pullUpDnControl (int pin, int pud) ;
+extern int digitalRead (int pin) ;
+extern void digitalWrite (int pin, int value) ;
+extern void pwmWrite (int pin, int value) ;
+extern int analogRead (int pin) ;
+extern void analogWrite (int pin, int value) ;
+
+// PiFace specifics
+// (Deprecated)
+extern int wiringPiSetupPiFace (void) ;
extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only
-extern void (*pinMode) (int pin, int mode) ;
-extern int (*getAlt) (int pin) ;
-extern void (*pullUpDnControl) (int pin, int pud) ;
-extern void (*digitalWrite) (int pin, int value) ;
-extern void (*digitalWriteByte) (int value) ;
-extern void (*gpioClockSet) (int pin, int freq) ;
-extern void (*pwmWrite) (int pin, int value) ;
-extern void (*setPadDrive) (int group, int value) ;
-extern int (*digitalRead) (int pin) ;
-extern void (*pwmSetMode) (int mode) ;
-extern void (*pwmSetRange) (unsigned int range) ;
-extern void (*pwmSetClock) (int divisor) ;
+// On-Board Raspberry Pi hardware specific stuff
+
+extern int piBoardRev (void) ;
+extern int wpiPinToGpio (int wpiPin) ;
+extern int physPinToGpio (int physPin) ;
+extern void setPadDrive (int group, int value) ;
+extern int getAlt (int pin) ;
+extern void digitalWriteByte (int value) ;
+extern void pwmSetMode (int mode) ;
+extern void pwmSetRange (unsigned int range) ;
+extern void pwmSetClock (int divisor) ;
+extern void gpioClockSet (int pin, int freq) ;
// Interrupts
+// (Also Pi hardware specific)
-extern int (*waitForInterrupt) (int pin, int mS) ;
+extern int waitForInterrupt (int pin, int mS) ;
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
// Threads
-extern int piThreadCreate (void *(*fn)(void *)) ;
-extern void piLock (int key) ;
-extern void piUnlock (int key) ;
+extern int piThreadCreate (void *(*fn)(void *)) ;
+extern void piLock (int key) ;
+extern void piUnlock (int key) ;
// Schedulling priority
-extern int piHiPri (int pri) ;
-
+extern int piHiPri (const int pri) ;
// Extras from arduino land
diff --git a/wiringPi/wiringPiFace.c b/wiringPi/wiringPiFace.c
deleted file mode 100644
index ac3c6fa..0000000
--- a/wiringPi/wiringPiFace.c
+++ /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 .
- ***********************************************************************
- */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#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 ;
-}
diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c
index 93fe1d3..d370b60 100644
--- a/wiringPi/wiringPiI2C.c
+++ b/wiringPi/wiringPiI2C.c
@@ -22,15 +22,93 @@
***********************************************************************
*/
+/*
+ * 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
#include
+#include
+#include
+#include
#include
#include
-#include
#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:
@@ -40,7 +118,12 @@
int wiringPiI2CRead (int fd)
{
- return i2c_smbus_read_byte (fd) ;
+ union i2c_smbus_data data ;
+
+ if (i2c_smbus_access (fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data))
+ return -1 ;
+ else
+ return data.byte & 0xFF ;
}
@@ -52,12 +135,22 @@ int wiringPiI2CRead (int fd)
int wiringPiI2CReadReg8 (int fd, int reg)
{
- return i2c_smbus_read_byte_data (fd, reg) ;
+ union i2c_smbus_data data;
+
+ if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data))
+ return -1 ;
+ else
+ return data.byte & 0xFF ;
}
int wiringPiI2CReadReg16 (int fd, int reg)
{
- return i2c_smbus_read_word_data (fd, reg) ;
+ union i2c_smbus_data data;
+
+ if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data))
+ return -1 ;
+ else
+ return data.byte & 0xFF ;
}
@@ -69,7 +162,7 @@ int wiringPiI2CReadReg16 (int fd, int reg)
int wiringPiI2CWrite (int fd, int data)
{
- return i2c_smbus_write_byte (fd, data) ;
+ return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ;
}
@@ -79,14 +172,41 @@ int wiringPiI2CWrite (int fd, int data)
*********************************************************************************
*/
-int wiringPiI2CWriteReg8 (int fd, int reg, int data)
+int wiringPiI2CWriteReg8 (int fd, int reg, int value)
{
- return i2c_smbus_write_byte_data (fd, reg, data) ;
+ union i2c_smbus_data data ;
+
+ data.byte = value ;
+ return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ;
}
-int wiringPiI2CWriteReg16 (int fd, int reg, int data)
+int wiringPiI2CWriteReg16 (int fd, int reg, int value)
{
- return i2c_smbus_write_word_data (fd, reg, data) ;
+ union i2c_smbus_data data ;
+
+ data.word = value ;
+ return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ;
+}
+
+
+/*
+ * wiringPiI2CSetupInterface:
+ * Undocumented access to set the interface explicitly - might be used
+ * for the Pi's 2nd I2C interface...
+ *********************************************************************************
+ */
+
+int wiringPiI2CSetupInterface (const char *device, int devId)
+{
+ int fd ;
+
+ if ((fd = open (device, O_RDWR)) < 0)
+ return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ;
+
+ if (ioctl (fd, I2C_SLAVE, devId) < 0)
+ return wiringPiFailure (WPI_ALMOST, "Unable to select I2C device: %s\n", strerror (errno)) ;
+
+ return fd ;
}
@@ -96,27 +216,17 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int data)
*********************************************************************************
*/
-int wiringPiI2CSetup (int devId)
+int wiringPiI2CSetup (const int devId)
{
- int rev, fd ;
- char *device ;
+ int rev ;
+ const char *device ;
- if ((rev = piBoardRev ()) < 0)
- {
- fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ;
- exit (1) ;
- }
+ rev = piBoardRev () ;
if (rev == 1)
device = "/dev/i2c-0" ;
else
device = "/dev/i2c-1" ;
- if ((fd = open (device, O_RDWR)) < 0)
- return -1 ;
-
- if (ioctl (fd, I2C_SLAVE, devId) < 0)
- return -1 ;
-
- return fd ;
+ return wiringPiI2CSetupInterface (device, devId) ;
}
diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h
index 6710ff4..6db8c68 100644
--- a/wiringPi/wiringPiI2C.h
+++ b/wiringPi/wiringPiI2C.h
@@ -26,15 +26,16 @@
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
}
diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c
index 4441498..ded07ba 100644
--- a/wiringPi/wiringPiSPI.c
+++ b/wiringPi/wiringPiSPI.c
@@ -25,20 +25,24 @@
#include
#include
+#include
+#include
#include